Index: src/images/SkImageDecoder_libpng.cpp |
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp |
index acaeda538d1a28cd9dca76f97d5c452429012ae9..c074268cffbc996ef1b0f01765402f806504ba8c 100644 |
--- a/src/images/SkImageDecoder_libpng.cpp |
+++ b/src/images/SkImageDecoder_libpng.cpp |
@@ -97,7 +97,7 @@ 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, int bitDepth, |
+ bool decodePalette(png_structp png_ptr, png_infop info_ptr, |
bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, |
SkColorTable **colorTablep); |
bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha, |
@@ -350,7 +350,7 @@ SkImageDecoder::Result SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap |
SkColorTable* colorTable = NULL; |
if (pngColorType == PNG_COLOR_TYPE_PALETTE) { |
- decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, &colorTable); |
+ decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable); |
} |
SkAutoUnref aur(colorTable); |
@@ -657,8 +657,7 @@ bool SkPNGImageDecoder::getBitmapColorType(png_structp png_ptr, png_infop info_p |
typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); |
bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
- int bitDepth, bool *hasAlphap, |
- bool *reallyHasAlphap, |
+ bool *hasAlphap, bool *reallyHasAlphap, |
SkColorTable **colorTablep) { |
int numPalette; |
png_colorp palette; |
@@ -667,6 +666,13 @@ bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette); |
+ /* BUGGY IMAGE WORKAROUND |
+ |
+ We hit some images (e.g. fruit_.png) who contain bytes that are == colortable_count |
+ which is a problem since we use the byte as an index. To work around this we grow |
+ the colortable by 1 (if its < 256) and duplicate the last color into that slot. |
+ */ |
+ int colorCount = numPalette + (numPalette < 256); |
SkPMColor colorStorage[256]; // worst-case storage |
SkPMColor* colorPtr = colorStorage; |
@@ -705,19 +711,9 @@ bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr, |
palette++; |
} |
- /* BUGGY IMAGE WORKAROUND |
- |
- Invalid images could contain pixel values that are greater than the number of palette |
- entries. Since we use pixel values as indices into the palette this could result in reading |
- beyond the end of the palette which could leak the contents of uninitialized memory. To |
- ensure this doesn't happen, we grow the colortable to the maximum size that can be |
- addressed by the bitdepth of the image and fill it with the last palette color or black if |
- the palette is empty (really broken image). |
- */ |
- int colorCount = SkTMax(numPalette, 1 << SkTMin(bitDepth, 8)); |
- SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0); |
- for (; index < colorCount; index++) { |
- *colorPtr++ = lastColor; |
+ // see BUGGY IMAGE WORKAROUND comment above |
+ if (numPalette < 256) { |
+ *colorPtr = colorPtr[-1]; |
} |
*colorTablep = SkNEW_ARGS(SkColorTable, (colorStorage, colorCount)); |
@@ -807,7 +803,7 @@ bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
SkColorTable* colorTable = NULL; |
if (pngColorType == PNG_COLOR_TYPE_PALETTE) { |
- decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable, bitDepth); |
+ decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable); |
} |
SkAutoUnref aur(colorTable); |