| Index: src/images/SkImageDecoder_libpng.cpp
|
| diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
|
| index d967a69e84668c502ecf1bbd2c37dead68776447..729f87169a435cceb2ffa3ebd0be4ebd6f485314 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;
|
| @@ -383,7 +384,8 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
| upscale png's palette to a direct model
|
| */
|
| SkAutoLockColors ctLock(colorTable);
|
| - if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors())) {
|
| + if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors(),
|
| + this->getRequireUnpremultipliedColors())) {
|
| return false;
|
| }
|
| const int height = decodedBitmap->height();
|
| @@ -435,6 +437,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 +454,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 +555,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 +607,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);
|
| palette++;
|
| }
|
| reallyHasAlpha |= (transLessThanFF < 0);
|
| @@ -679,7 +707,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
|
|
|
| @@ -773,7 +801,8 @@ bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) {
|
| upscale png's palette to a direct model
|
| */
|
| SkAutoLockColors ctLock(colorTable);
|
| - if (!sampler.begin(&decodedBitmap, sc, doDither, ctLock.colors())) {
|
| + if (!sampler.begin(&decodedBitmap, sc, doDither, ctLock.colors(),
|
| + this->getRequireUnpremultipliedColors())) {
|
| return false;
|
| }
|
| const int height = decodedBitmap.height();
|
|
|