Chromium Code Reviews| Index: src/images/SkImageDecoder_libjpeg.cpp |
| diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp |
| index 3e34a277fd0494a46dfafc7fa8a2364f889c2915..b738a88ed9afefba30006d9901e77c5607619262 100644 |
| --- a/src/images/SkImageDecoder_libjpeg.cpp |
| +++ b/src/images/SkImageDecoder_libjpeg.cpp |
| @@ -480,6 +480,39 @@ static void fill_below_level(int y, SkBitmap* bitmap) { |
| canvas.drawColor(SK_ColorWHITE); |
| } |
| +/** |
| + * Get the config and bytes per pixel of the source data. Return |
| + * whether the data is supported. |
| + */ |
| +static bool get_src_config(const jpeg_decompress_struct& cinfo, |
| + SkScaledBitmapSampler::SrcConfig* sc, |
| + int* srcBytesPerPixel) { |
| + SkASSERT(sc != NULL && srcBytesPerPixel != NULL); |
| + if (JCS_CMYK == cinfo.out_color_space) { |
| + // In this case we will manually convert the CMYK values to RGB |
| + *sc = SkScaledBitmapSampler::kRGBX; |
| + // The CMYK work-around relies on 4 components per pixel here |
| + *srcBytesPerPixel = 4; |
| + } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_space) { |
| + *sc = SkScaledBitmapSampler::kRGB; |
| + *srcBytesPerPixel = 3; |
| +#ifdef ANDROID_RGB |
| + } else if (JCS_RGBA_8888 == cinfo.out_color_space) { |
| + *sc = SkScaledBitmapSampler::kRGBX; |
| + *srcBytesPerPixel = 4; |
| + } else if (JCS_RGB_565 == cinfo.out_color_space) { |
| + *sc = SkScaledBitmapSampler::kRGB_565; |
| + *srcBytesPerPixel = 2; |
| +#endif |
| + } else if (1 == cinfo.out_color_components && |
| + JCS_GRAYSCALE == cinfo.out_color_space) { |
| + *sc = SkScaledBitmapSampler::kGray; |
| + *srcBytesPerPixel = 1; |
| + } else { |
| + return false; |
| + } |
| + return true; |
| +} |
| bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| #ifdef TIME_DECODE |
| @@ -529,6 +562,10 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { |
| bm->setConfig(config, cinfo.image_width, cinfo.image_height); |
| + // Assume an A8 bitmap is opaque to avoid the check of each |
|
reed1
2013/10/08 16:24:17
"is not" ?
same question for all copies of this c
scroggo
2013/10/10 21:46:59
Done.
|
| + // individual pixel. It is very unlikely to be opaque, since |
| + // an opaque A8 bitmap would not be very interesting. |
| + // Otherwise, a jpeg image is opaque. |
| bm->setIsOpaque(config != SkBitmap::kA8_Config); |
| return true; |
| } |
| @@ -551,6 +588,10 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, |
| recompute_sampleSize(sampleSize, cinfo)); |
| bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight()); |
| + // Assume an A8 bitmap is opaque to avoid the check of each |
| + // individual pixel. It is very unlikely to be opaque, since |
| + // an opaque A8 bitmap would not be very interesting. |
| + // Otherwise, a jpeg image is opaque. |
| bm->setIsOpaque(config != SkBitmap::kA8_Config); |
| return true; |
| } else { |
| @@ -566,6 +607,10 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize); |
| bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); |
| + // Assume an A8 bitmap is opaque to avoid the check of each |
| + // individual pixel. It is very unlikely to be opaque, since |
| + // an opaque A8 bitmap would not be very interesting. |
| + // Otherwise, a jpeg image is opaque. |
| bm->setIsOpaque(config != SkBitmap::kA8_Config); |
| if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
| return true; |
| @@ -610,21 +655,9 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| // check for supported formats |
| SkScaledBitmapSampler::SrcConfig sc; |
| - if (JCS_CMYK == cinfo.out_color_space) { |
| - // In this case we will manually convert the CMYK values to RGB |
| - sc = SkScaledBitmapSampler::kRGBX; |
| - } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_space) { |
| - sc = SkScaledBitmapSampler::kRGB; |
| -#ifdef ANDROID_RGB |
| - } else if (JCS_RGBA_8888 == cinfo.out_color_space) { |
| - sc = SkScaledBitmapSampler::kRGBX; |
| - } else if (JCS_RGB_565 == cinfo.out_color_space) { |
| - sc = SkScaledBitmapSampler::kRGB_565; |
| -#endif |
| - } else if (1 == cinfo.out_color_components && |
| - JCS_GRAYSCALE == cinfo.out_color_space) { |
| - sc = SkScaledBitmapSampler::kGray; |
| - } else { |
| + int srcBytesPerPixel; |
| + |
| + if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) { |
| return return_false(cinfo, *bm, "jpeg colorspace"); |
| } |
| @@ -632,8 +665,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| return return_false(cinfo, *bm, "sampler.begin"); |
| } |
| - // The CMYK work-around relies on 4 components per pixel here |
| - SkAutoMalloc srcStorage(cinfo.output_width * 4); |
| + SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel); |
| uint8_t* srcRow = (uint8_t*)srcStorage.get(); |
| // Possibly skip initial rows [sampler.srcY0] |
| @@ -787,7 +819,11 @@ bool SkJPEGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
| SkBitmap bitmap; |
| bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); |
| - bitmap.setIsOpaque(true); |
| + // Assume an A8 bitmap is opaque to avoid the check of each |
| + // individual pixel. It is very unlikely to be opaque, since |
| + // an opaque A8 bitmap would not be very interesting. |
| + // Otherwise, a jpeg image is opaque. |
| + bitmap.setIsOpaque(config != SkBitmap::kA8_Config); |
| // Check ahead of time if the swap(dest, src) is possible or not. |
| // If yes, then we will stick to AllocPixelRef since it's cheaper with the |
| @@ -854,21 +890,9 @@ bool SkJPEGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
| // check for supported formats |
| SkScaledBitmapSampler::SrcConfig sc; |
| - if (JCS_CMYK == cinfo->out_color_space) { |
| - // In this case we will manually convert the CMYK values to RGB |
| - sc = SkScaledBitmapSampler::kRGBX; |
| - } else if (3 == cinfo->out_color_components && JCS_RGB == cinfo->out_color_space) { |
| - sc = SkScaledBitmapSampler::kRGB; |
| -#ifdef ANDROID_RGB |
| - } else if (JCS_RGBA_8888 == cinfo->out_color_space) { |
| - sc = SkScaledBitmapSampler::kRGBX; |
| - } else if (JCS_RGB_565 == cinfo->out_color_space) { |
| - sc = SkScaledBitmapSampler::kRGB_565; |
| -#endif |
| - } else if (1 == cinfo->out_color_components && |
| - JCS_GRAYSCALE == cinfo->out_color_space) { |
| - sc = SkScaledBitmapSampler::kGray; |
| - } else { |
| + int srcBytesPerPixel; |
| + |
| + if (!get_src_config(*cinfo, &sc, &srcBytesPerPixel)) { |
| return return_false(*cinfo, *bm, "jpeg colorspace"); |
| } |
| @@ -876,8 +900,7 @@ bool SkJPEGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) { |
| return return_false(*cinfo, bitmap, "sampler.begin"); |
| } |
| - // The CMYK work-around relies on 4 components per pixel here |
| - SkAutoMalloc srcStorage(width * 4); |
| + SkAutoMalloc srcStorage(width * srcBytesPerPixel); |
| uint8_t* srcRow = (uint8_t*)srcStorage.get(); |
| // Possibly skip initial rows [sampler.srcY0] |