From bc7d2fb5be746f6e0d9bd60c9e181eec20fe31ea Mon Sep 17 00:00:00 2001 From: "reed@android.com" Date: Fri, 5 Feb 2010 15:43:07 +0000 Subject: check for null cmap in libgif support bounds-only in libjpeg even if we can't complete start_decompress git-svn-id: http://skia.googlecode.com/svn/trunk@486 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/images/SkImageDecoder_libgif.cpp | 4 +-- src/images/SkImageDecoder_libjpeg.cpp | 50 +++++++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 13 deletions(-) (limited to 'src/images') diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp index 86ead1faff..258a8a017d 100644 --- a/src/images/SkImageDecoder_libgif.cpp +++ b/src/images/SkImageDecoder_libgif.cpp @@ -119,8 +119,8 @@ static const ColorMapObject* find_colormap(const GifFileType* gif) { cmap = gif->SColorMap; } // some sanity checks - if ((unsigned)cmap->ColorCount > 256 || - cmap->ColorCount != (1 << cmap->BitsPerPixel)) { + if (cmap && ((unsigned)cmap->ColorCount > 256 || + cmap->ColorCount != (1 << cmap->BitsPerPixel))) { cmap = NULL; } return cmap; diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp index fa2188eb6d..476cfa13a1 100644 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ b/src/images/SkImageDecoder_libjpeg.cpp @@ -114,6 +114,25 @@ static void overwrite_mem_buffer_size(j_decompress_ptr cinfo) { /////////////////////////////////////////////////////////////////////////////// +/* If we need to better match the request, we might examine the image and + output dimensions, and determine if the downsampling jpeg provided is + not sufficient. If so, we can recompute a modified sampleSize value to + make up the difference. + + To skip this additional scaling, just set sampleSize = 1; below. + */ +static int recompute_sampleSize(int sampleSize, + const jpeg_decompress_struct& cinfo) { + return sampleSize * cinfo.output_width / cinfo.image_width; +} + +static bool valid_output_dimensions(const jpeg_decompress_struct& cinfo) { + /* These are initialized to 0, so if they have non-zero values, we assume + they are "valid" (i.e. have been computed by libjpeg) + */ + return cinfo.output_width != 0 && cinfo.output_height != 0; +} + static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, int count) { for (int i = 0; i < count; i++) { @@ -235,18 +254,27 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, jpeg_start_decompress(), and then read output_width and output_height. */ if (!jpeg_start_decompress(&cinfo)) { - return return_false(cinfo, *bm, "start_decompress"); + /* If we failed here, we may still have enough information to return + to the caller if they just wanted (subsampled bounds). If sampleSize + was 1, then we would have already returned. Thus we just check if + we're in kDecodeBounds_Mode, and that we have valid output sizes. + + One reason to fail here is that we have insufficient stream data + to complete the setup. However, output dimensions seem to get + computed very early, which is why this special check can pay off. + */ + if (SkImageDecoder::kDecodeBounds_Mode == mode && + valid_output_dimensions(cinfo)) { + SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, + recompute_sampleSize(sampleSize, cinfo)); + bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight()); + bm->setIsOpaque(true); + return true; + } else { + return return_false(cinfo, *bm, "start_decompress"); + } } - - /* If we need to better match the request, we might examine the image and - output dimensions, and determine if the downsampling jpeg provided is - not sufficient. If so, we can recompute a modified sampleSize value to - make up the difference. - - To skip this additional scaling, just set sampleSize = 1; below. - */ - sampleSize = sampleSize * cinfo.output_width / cinfo.image_width; - + sampleSize = recompute_sampleSize(sampleSize, cinfo); // should we allow the Chooser (if present) to pick a config for us??? if (!this->chooseFromOneChoice(config, cinfo.output_width, -- cgit v1.2.3