Index: src/images/SkImageDecoder_libpng.cpp |
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp |
index d967a69e84668c502ecf1bbd2c37dead68776447..ac334fc24d55ddd2fd9b3132517c07ea93614fe8 100644 |
--- a/src/images/SkImageDecoder_libpng.cpp |
+++ b/src/images/SkImageDecoder_libpng.cpp |
@@ -80,8 +80,9 @@ private: |
SkPNGImageIndex* fImageIndex; |
bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_ptrp); |
- bool decodePalette(png_structp png_ptr, png_infop info_ptr, bool *hasAlphap, |
- bool *reallyHasAlphap, SkColorTable **colorTablep); |
+ bool decodePalette(png_structp png_ptr, png_infop info_ptr, |
+ bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, |
+ SkColorTable **colorTablep); |
bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
SkBitmap::Config *config, bool *hasAlpha, |
bool *doDither, SkPMColor *theTranspColor); |
@@ -311,7 +312,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, |
if (!reuseBitmap) { |
decodedBitmap->setConfig(config, sampler.scaledWidth(), |
- sampler.scaledHeight(), 0); |
+ sampler.scaledHeight()); |
} |
if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
return true; |
@@ -435,6 +436,13 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, |
if (0 != theTranspColor) { |
reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); |
} |
+ if (reallyHasAlpha && this->getRequireUnpremultipliedColors() && |
+ SkBitmap::kARGB_8888_Config != decodedBitmap->config()) { |
+ // If the caller wants an unpremultiplied bitmap, and we let them get |
+ // away with a config other than 8888, and it has alpha after all, |
+ // return false, since the result will have premultiplied colors. |
+ return false; |
+ } |
decodedBitmap->setIsOpaque(!reallyHasAlpha); |
if (reuseBitmap) { |
decodedBitmap->notifyPixelsChanged(); |
@@ -445,7 +453,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, |
bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
- SkBitmap::Config *configp, bool *hasAlphap, |
+ SkBitmap::Config *configp, bool * SK_RESTRICT hasAlphap, |
bool *doDitherp, SkPMColor *theTranspColorp) { |
png_uint_32 origWidth, origHeight; |
int bitDepth, colorType; |
@@ -546,9 +554,20 @@ bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
} |
} |
- return this->chooseFromOneChoice(*configp, origWidth, origHeight); |
+ if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) { |
+ return false; |
+ } |
+ |
+ // If the image has alpha and the decoder wants unpremultiplied |
+ // colors, the only supported config is 8888. |
+ if (this->getRequireUnpremultipliedColors() && *hasAlphap) { |
+ *configp = SkBitmap::kARGB_8888_Config; |
+ } |
+ return true; |
} |
+typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); |
+ |
bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
bool *hasAlphap, bool *reallyHasAlphap, |
SkColorTable **colorTablep) { |
@@ -587,9 +606,17 @@ bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
int index = 0; |
int transLessThanFF = 0; |
+ // Choose which function to use to create the color table. If the final destination's |
+ // config is unpremultiplied, the color table will store unpremultiplied colors. |
+ PackColorProc proc; |
+ if (this->getRequireUnpremultipliedColors()) { |
+ proc = &SkPackARGB32NoCheck; |
+ } else { |
+ proc = &SkPreMultiplyARGB; |
+ } |
for (; index < numTrans; index++) { |
transLessThanFF |= (int)*trans - 0xFF; |
- *colorPtr++ = SkPreMultiplyARGB(*trans++, palette->red, palette->green, palette->blue); |
+ *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue); |
reed1
2013/06/13 13:51:39
Is there a measurable perf-hit with this change (f
scroggo
2013/06/13 19:04:49
We don't actually use an inlineable function (thou
|
palette++; |
} |
reallyHasAlpha |= (transLessThanFF < 0); |
@@ -679,7 +706,7 @@ bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize); |
SkBitmap decodedBitmap; |
- decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0); |
+ decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); |
// from here down we are concerned with colortables and pixels |
@@ -690,7 +717,7 @@ bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
SkColorTable* colorTable = NULL; |
if (colorType == PNG_COLOR_TYPE_PALETTE) { |
- decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable); |
+ decodePalette(png_ptr, info_ptr, config, &hasAlpha, &reallyHasAlpha, &colorTable); |
} |
SkAutoUnref aur(colorTable); |