summaryrefslogtreecommitdiff
path: root/tools/aapt/Images.cpp
diff options
context:
space:
mode:
authorMatt Sarett <msarett@google.com>2016-01-29 18:02:41 -0500
committerMatt Sarett <msarett@google.com>2016-02-01 14:15:35 +0000
commit33fcd11bc296fa495a4f4584f782c1c0fe4fe592 (patch)
treefb44746d2dfeda5dfd09522810a2ea789ea8141b /tools/aapt/Images.cpp
parentfc1159c808962a32746cbddd088ed069f78afcc2 (diff)
Encode paletted PNGs more efficiently (part 2)
Many PNGs have multiple distinct pixels with zero alpha. This CL allows us to treat all of those pixels as a single zero pixel. This saves space in the color palette and also may help save memory pages when we skip writing zeros. There is also a potential disadvantage: if someone intended to decode this image as unpremultiplied with particular transfer modes where their color components have an effect even though alpha is zero, this will prevent that. At the moment, we do not support unpremul as a source, so this won't affect anyone trying to draw with the view system. This change originated in: https://googleplex-android-review.git.corp.google.com/#/c/854580/ Change-Id: I702c7bd22d431cc7c775ed29bbd73c930f945ca3
Diffstat (limited to 'tools/aapt/Images.cpp')
-rw-r--r--tools/aapt/Images.cpp32
1 files changed, 28 insertions, 4 deletions
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 867a6ffa97bc..a2a42a35429d 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -906,10 +906,34 @@ static void analyze_image(const char *imageName, image_info &imageInfo, int gray
png_bytep row = imageInfo.rows[j];
png_bytep out = outRows[j];
for (i = 0; i < w; i++) {
- rr = *row++;
- gg = *row++;
- bb = *row++;
- aa = *row++;
+
+ // Make sure any zero alpha pixels are fully zeroed. On average,
+ // each of our PNG assets seem to have about four distinct pixels
+ // with zero alpha.
+ // There are several advantages to setting these to zero:
+ // (1) Images are more likely able to be encodable with a palette.
+ // (2) Image palettes will be smaller.
+ // (3) Premultiplied and unpremultiplied PNG decodes can skip
+ // writing zeros to memory, often saving significant numbers
+ // of memory pages.
+ aa = *(row + 3);
+ if (aa == 0) {
+ rr = 0;
+ gg = 0;
+ bb = 0;
+
+ // Also set red, green, and blue to zero in "row". If we later
+ // decide to encode the PNG as RGB or RGBA, we will use the
+ // values stored there.
+ *(row) = 0;
+ *(row + 1) = 0;
+ *(row + 2) = 0;
+ } else {
+ rr = *(row);
+ gg = *(row + 1);
+ bb = *(row + 2);
+ }
+ row += 4;
int odev = maxGrayDeviation;
maxGrayDeviation = MAX(ABS(rr - gg), maxGrayDeviation);