Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: src/images/SkImageDecoder_libjpeg.cpp

Issue 26210007: Image decoder fixes (mostly) around A8. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/images/SkImageDecoder_libpng.cpp » ('j') | src/images/SkImageDecoder_libpng.cpp » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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]
« no previous file with comments | « no previous file | src/images/SkImageDecoder_libpng.cpp » ('j') | src/images/SkImageDecoder_libpng.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698