[aapt2] Add a compression control option to 'compile'
aapt2 recompresses all PNGs it compiles, and by default it
uses the best (and slowest) zlib compression level, 9.
This change adds a command line option --png-compression-level
to control that, so it's possible to set it to something faster
e.g. 6 which is usually 5x faster and around 101% of the size
of level 9 PNGs
Test: manual, compile Framework
Flag: EXEMPT tool
Change-Id: Ibe5f47b82e1c13be0a4ffff0e07e675871abc956
diff --git a/libs/androidfw/PngCrunch.cpp b/libs/androidfw/PngCrunch.cpp
index cf3c0ee..e945405 100644
--- a/libs/androidfw/PngCrunch.cpp
+++ b/libs/androidfw/PngCrunch.cpp
@@ -506,8 +506,7 @@
// Set up the write functions which write to our custom data sources.
png_set_write_fn(write_ptr, (png_voidp)out, WriteDataToStream, nullptr);
- // We want small files and can take the performance hit to achieve this goal.
- png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);
+ png_set_compression_level(write_ptr, options.compression_level);
// Begin analysis of the image data.
// Scan the entire image and determine if:
diff --git a/libs/androidfw/include/androidfw/Png.h b/libs/androidfw/include/androidfw/Png.h
index 2ece43e..72be59b 100644
--- a/libs/androidfw/include/androidfw/Png.h
+++ b/libs/androidfw/include/androidfw/Png.h
@@ -31,6 +31,8 @@
struct PngOptions {
int grayscale_tolerance = 0;
+ // By default we want small files and can take the performance hit to achieve this goal.
+ int compression_level = 9;
};
/**
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 52372fa..a5e18d35 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -605,8 +605,9 @@
}
// Write the crunched PNG.
- if (!android::WritePng(image.get(), nine_patch.get(), &crunched_png_buffer_out, {},
- &source_diag, context->IsVerbose())) {
+ if (!android::WritePng(image.get(), nine_patch.get(), &crunched_png_buffer_out,
+ {.compression_level = options.png_compression_level_int}, &source_diag,
+ context->IsVerbose())) {
return false;
}
@@ -924,6 +925,19 @@
}
}
+ if (!options_.png_compression_level) {
+ options_.png_compression_level_int = 9;
+ } else {
+ if (options_.png_compression_level->size() != 1 ||
+ options_.png_compression_level->front() < '0' ||
+ options_.png_compression_level->front() > '9') {
+ context.GetDiagnostics()->Error(
+ android::DiagMessage() << "PNG compression level should be a number in [0..9] range");
+ return 1;
+ }
+ options_.png_compression_level_int = options_.png_compression_level->front() - '0';
+ }
+
return Compile(&context, file_collection.get(), archive_writer.get(), options_);
}
diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h
index 70c8791..e244546 100644
--- a/tools/aapt2/cmd/Compile.h
+++ b/tools/aapt2/cmd/Compile.h
@@ -47,6 +47,8 @@
bool verbose = false;
std::optional<std::string> product_;
FeatureFlagValues feature_flag_values;
+ std::optional<std::string> png_compression_level;
+ int png_compression_level_int = 9;
};
/** Parses flags and compiles resources to be used in linking. */
@@ -65,6 +67,9 @@
AddOptionalSwitch("--pseudo-localize", "Generate resources for pseudo-locales "
"(en-XA and ar-XB)", &options_.pseudolocalize);
AddOptionalSwitch("--no-crunch", "Disables PNG processing", &options_.no_png_crunch);
+ AddOptionalFlag("--png-compression-level",
+ "Set the zlib compression level for crunched PNG images, [0-9], 9 by default.",
+ &options_.png_compression_level);
AddOptionalSwitch("--legacy", "Treat errors that used to be valid in AAPT as warnings",
&options_.legacy_mode);
AddOptionalSwitch("--preserve-visibility-of-styleables",