Chromium Code Reviews| Index: src/images/SkImageDecoder_libgif.cpp |
| diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp |
| index f484441c8c3e340d938582eff80c481b538cbf18..5271d08016df62b56ddcc5e62eb573f4ecfbc1b7 100644 |
| --- a/src/images/SkImageDecoder_libgif.cpp |
| +++ b/src/images/SkImageDecoder_libgif.cpp |
| @@ -185,6 +185,43 @@ static bool skip_src_rows(GifFileType* gif, uint8_t* dst, int width, int rowsToS |
| return true; |
| } |
| +static void sanitize_indexed_bitmap(SkBitmap* bm) { |
|
robertphillips
2013/12/19 20:30:38
// Indexed GIFs with fewer then 256 color entries
hal.canary
2013/12/19 20:50:11
Done.
|
| + if ((SkBitmap::kIndex8_Config == bm->config()) && !(bm->empty())) { |
| + SkAutoLockPixels alp(*bm); |
| + if (NULL != bm->getPixels()) { |
| + SkColorTable* ct = bm->getColorTable(); // Index8 must have it. |
| + SkASSERT(ct != NULL); |
| + uint32_t count = ct->count(); |
| + SkASSERT(count > 0); |
| + SkASSERT(count <= 0x100); |
| + if (count != 0x100) { // Full colortables can't go wrong. |
| + // Count is a power of 2; asserted elsewhere. |
| + uint8_t byteMask = (~(count - 1)); |
| + bool warning = false; |
| + uint8_t* addr = static_cast<uint8_t*>(bm->getPixels()); |
| + int height = bm->height(); |
| + int width = bm->width(); |
| + size_t rowBytes = bm->rowBytes(); |
| + while (--height >= 0) { |
| + uint8_t* ptr = addr; |
| + int x = width; |
| + while (--x >= 0) { |
| + if (0 != ((*ptr) & byteMask)) { |
| + warning = true; |
| + *ptr = 0; |
| + } |
| + ++ptr; |
| + } |
| + addr += rowBytes; |
| + } |
| + if (warning) { |
| + gif_warning(*bm, "Index out of bounds."); |
| + } |
| + } |
| + } |
| + } |
| +} |
| + |
| bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { |
| #if GIFLIB_MAJOR < 5 |
| GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc); |
| @@ -289,6 +326,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { |
| const ColorMapObject* cmap = find_colormap(gif); |
| SkAlphaType alphaType = kOpaque_SkAlphaType; |
| if (cmap != NULL) { |
| + SkASSERT(cmap->ColorCount == (1 << (cmap->BitsPerPixel))); |
| colorCount = cmap->ColorCount; |
| if (colorCount > 256) { |
| colorCount = 256; // our kIndex8 can't support more |
| @@ -410,6 +448,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { |
| SkASSERT(read <= innerHeight); |
| skip_src_rows(gif, scanline, innerWidth, innerHeight - read); |
| } |
| + sanitize_indexed_bitmap(bm); |
| return true; |
| } break; |
| @@ -454,6 +493,7 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { |
| } |
| } while (recType != TERMINATE_RECORD_TYPE); |
| + sanitize_indexed_bitmap(bm); |
| return true; |
| } |