Index: src/images/SkImageDecoder_libpng.cpp |
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp |
index d967a69e84668c502ecf1bbd2c37dead68776447..8d32c68a1cc0cd763befcad6dd8724e170a52a75 100644 |
--- a/src/images/SkImageDecoder_libpng.cpp |
+++ b/src/images/SkImageDecoder_libpng.cpp |
@@ -80,7 +80,8 @@ 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 decodePalette(png_structp png_ptr, png_infop info_ptr, |
+ SkBitmap::Config finalConfig, bool *hasAlphap, |
bool *reallyHasAlphap, SkColorTable **colorTablep); |
bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
SkBitmap::Config *config, bool *hasAlpha, |
@@ -310,8 +311,12 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, |
} |
if (!reuseBitmap) { |
+ bool premul = true; |
+ if (SkBitmap::kARGB_8888_Config == config && this->getRequestUnpremultipliedColors()) { |
+ premul = false; |
+ } |
decodedBitmap->setConfig(config, sampler.scaledWidth(), |
- sampler.scaledHeight(), 0); |
+ sampler.scaledHeight(), 0, premul); |
} |
if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
return true; |
@@ -326,7 +331,7 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, |
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); |
@@ -549,9 +554,11 @@ bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
return this->chooseFromOneChoice(*configp, origWidth, origHeight); |
} |
+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) { |
+ SkBitmap::Config finalConfig, bool *hasAlphap, |
+ bool *reallyHasAlphap, SkColorTable **colorTablep) { |
int numPalette; |
png_colorp palette; |
png_bytep trans; |
@@ -587,9 +594,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 (SkBitmap::kARGB_8888_Config == finalConfig && this->getRequestUnpremultipliedColors()) { |
+ 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); |
palette++; |
} |
reallyHasAlpha |= (transLessThanFF < 0); |
@@ -679,7 +694,11 @@ bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize); |
SkBitmap decodedBitmap; |
- decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0); |
+ bool premul = true; |
+ if (SkBitmap::kARGB_8888_Config == config && this->getRequestUnpremultipliedColors()) { |
+ premul = false; |
+ } |
+ decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0, premul); |
// from here down we are concerned with colortables and pixels |
@@ -690,7 +709,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); |