diff options
author | Wei-Ta Chen <weita@google.com> | 2010-10-12 20:19:47 -0700 |
---|---|---|
committer | Wei-Ta Chen <weita@google.com> | 2011-01-11 23:12:54 -0800 |
commit | b4f070ed646ef1cbb92c3eaaa073640e30954873 (patch) | |
tree | 7912299e8965b19115d7c43a8b642c81471d266b | |
parent | 956f20cebc0d9c7a1c59dc18a556b7aaff22b39c (diff) | |
download | skia-gingerbread.tar.gz |
Do not merge.android-sdk-2.3.4_r1android-cts-2.3_r5android-cts-2.3_r4android-cts-2.3_r3android-cts-2.3_r2android-cts-2.3_r12android-cts-2.3_r11android-cts-2.3_r10android-2.3.7_r1android-2.3.6_r1android-2.3.6_r0.9android-2.3.5_r1android-2.3.4_r1android-2.3.4_r0.9android-2.3.3_r1aandroid-2.3.3_r1.1android-2.3.3_r1linaro_android_2.3.3gingerbread-releasegingerbread-mr4-releasegingerbread
Backport changes/fixes related to tile-based decoder from Honeycomb to
Gingerbread.
Bug: 3309014
////////////////////////////////////////////////////////////////////
This is a combination of 3 commits.
Fix 3071104, where decodeRegion returned false for some large image.
decodeRegion() returns false when it cannot find a suitable color config
for SkScaledBitmapSampler. Currently SkScaledBitmapSampler does not
support RGB_565. If cinfo->out_color_space is set to RGB_565 and we
require SkScaledBitmapSampler to do the extra sampling, we will fail in
finding a suitable color config for SkScaledBitmapSampler.
To fix it, we add support of RGB_565 into SkSclaedBitmapSampler.
Change-Id: I506f4f8c55518ff356345e616e16c4b4cd0712de
Fix 3117581, where BitmapRegionDecoder fails in building tile index for
PNG files.
The virtual method of building tile index in SkImageDecoder was changed to onBuildTileIndex().
SkPNGImageDecoder needs to override the method.
Change-Id: I7c78844a4d4f7aadff5fa8fa1aa99173317139b2
Add fPreferQualityOverSpeed to SkImageDecoder.
Currently the field only affects JPEG decode, in that when it is set
to true, we choose a more accurate, but slightly slower, IDCT method.
Bug: 3238925
/////////////////////////////////////////////////////////////////////
-rw-r--r-- | include/images/SkImageDecoder.h | 15 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libjpeg.cpp | 45 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libpng.cpp | 28 | ||||
-rw-r--r-- | src/images/SkScaledBitmapSampler.cpp | 26 | ||||
-rw-r--r-- | src/images/SkScaledBitmapSampler.h | 3 |
5 files changed, 70 insertions, 47 deletions
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h index 3bb287d49e..3c904ca3b4 100644 --- a/include/images/SkImageDecoder.h +++ b/include/images/SkImageDecoder.h @@ -75,6 +75,20 @@ public: */ void setDitherImage(bool dither) { fDitherImage = dither; } + /** Returns true if the decoder should try to decode the + resulting image to a higher quality even at the expense of + the decoding speed. + */ + bool getPreferQualityOverSpeed() const { return fPreferQualityOverSpeed; } + + /** Set to true if the the decoder should try to decode the + resulting image to a higher quality even at the expense of + the decoding speed. + */ + void setPreferQualityOverSpeed(bool qualityOverSpeed) { + fPreferQualityOverSpeed = qualityOverSpeed; + } + /** \class Peeker Base class for optional callbacks to retrieve meta/chunk data out of @@ -389,6 +403,7 @@ private: bool fDitherImage; bool fUsePrefTable; mutable bool fShouldCancelDecode; + bool fPreferQualityOverSpeed; // illegal SkImageDecoder(const SkImageDecoder&); diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp index e3aefeabf3..7e425c1d3c 100644 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ b/src/images/SkImageDecoder_libjpeg.cpp @@ -236,7 +236,12 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { */ int sampleSize = this->getSampleSize(); - cinfo.dct_method = JDCT_IFAST; + if (this->getPreferQualityOverSpeed()) { + cinfo.dct_method = JDCT_ISLOW; + } else { + cinfo.dct_method = JDCT_IFAST; + } + cinfo.scale_num = 1; cinfo.scale_denom = sampleSize; @@ -264,13 +269,9 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { if (config == SkBitmap::kARGB_8888_Config) { cinfo.out_color_space = JCS_RGBA_8888; } else if (config == SkBitmap::kRGB_565_Config) { - if (sampleSize == 1) { - // SkScaledBitmapSampler can't handle RGB_565 yet, - // so don't even try. - cinfo.out_color_space = JCS_RGB_565; - if (this->getDitherImage()) { - cinfo.dither_mode = JDITHER_ORDERED; - } + cinfo.out_color_space = JCS_RGB_565; + if (this->getDitherImage()) { + cinfo.dither_mode = JDITHER_ORDERED; } } #endif @@ -360,8 +361,8 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { #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; + } 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) { @@ -468,7 +469,6 @@ bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, index->index = (huffman_index*)malloc(sizeof(huffman_index)); jpeg_create_huffman_index(cinfo, index->index); - cinfo->dct_method = JDCT_IFAST; cinfo->scale_num = 1; cinfo->scale_denom = 1; if (!jpeg_build_huffman_index(cinfo, index->index)) { @@ -497,7 +497,6 @@ bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream, //jpeg_start_decompress(cinfo); jpeg_start_tile_decompress(cinfo); - cinfo->dct_method = JDCT_IFAST; cinfo->scale_num = 1; index->cinfo = cinfo; *height = cinfo->output_height; @@ -526,24 +525,30 @@ bool SkJPEGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect region) { int requestedSampleSize = this->getSampleSize(); cinfo->scale_denom = requestedSampleSize; + if (this->getPreferQualityOverSpeed()) { + cinfo->dct_method = JDCT_ISLOW; + } else { + cinfo->dct_method = JDCT_IFAST; + } + SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false); if (config != SkBitmap::kARGB_8888_Config && config != SkBitmap::kARGB_4444_Config && config != SkBitmap::kRGB_565_Config) { config = SkBitmap::kARGB_8888_Config; } + + /* default format is RGB */ + cinfo->out_color_space = JCS_RGB; + #ifdef ANDROID_RGB cinfo->dither_mode = JDITHER_NONE; if (config == SkBitmap::kARGB_8888_Config) { cinfo->out_color_space = JCS_RGBA_8888; } else if (config == SkBitmap::kRGB_565_Config) { - if (requestedSampleSize == 1) { - // SkScaledBitmapSampler can't handle RGB_565 yet, - // so don't even try. - cinfo->out_color_space = JCS_RGB_565; - if (this->getDitherImage()) { - cinfo->dither_mode = JDITHER_ORDERED; - } + cinfo->out_color_space = JCS_RGB_565; + if (this->getDitherImage()) { + cinfo->dither_mode = JDITHER_ORDERED; } } #endif @@ -606,6 +611,8 @@ bool SkJPEGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect region) { #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) { diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp index 2b6a28e555..cd240b44e0 100644 --- a/src/images/SkImageDecoder_libpng.cpp +++ b/src/images/SkImageDecoder_libpng.cpp @@ -62,10 +62,10 @@ public: delete index; } } - virtual bool buildTileIndex(SkStream *stream, - int *width, int *height, bool isShareable); protected: + virtual bool onBuildTileIndex(SkStream *stream, + int *width, int *height); virtual bool onDecodeRegion(SkBitmap* bitmap, SkIRect rect); virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode); @@ -419,33 +419,13 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, return true; } -bool SkPNGImageDecoder::buildTileIndex(SkStream* sk_stream, - int *width, int *height, bool isShareable) { +bool SkPNGImageDecoder::onBuildTileIndex(SkStream* sk_stream, int *width, + int *height) { png_structp png_ptr; png_infop info_ptr; this->index = new SkPNGImageIndex(); - if (!isShareable) { - size_t len, inputLen = 0; - size_t bufferSize = 4096; - void *tmp = sk_malloc_throw(bufferSize); - - while ((len = sk_stream->read((char*) tmp + inputLen, - bufferSize - inputLen)) != 0) { - inputLen += len; - if (inputLen == bufferSize) { - bufferSize *= 2; - tmp = sk_realloc_throw(tmp, bufferSize); - } - } - tmp = sk_realloc_throw(tmp, inputLen); - - SkMemoryStream *mem_stream = new SkMemoryStream(tmp, inputLen, true); - this->index->inputStream = mem_stream; - sk_stream = mem_stream; - } - if (onDecodeInit(sk_stream, &png_ptr, &info_ptr) == false) { return false; } diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp index 3ba38f7b16..32b78efcc9 100644 --- a/src/images/SkScaledBitmapSampler.cpp +++ b/src/images/SkScaledBitmapSampler.cpp @@ -93,6 +93,18 @@ static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, return false; } +static bool Sample_D565_D565(void* SK_RESTRICT dstRow, + const uint8_t* SK_RESTRICT src, + int width, int deltaSrc, int, const SkPMColor[]) { + uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; + uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src; + for (int x = 0; x < width; x++) { + dst[x] = castedSrc[0]; + castedSrc += deltaSrc >> 1; + } + return false; +} + static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, int deltaSrc, int y, const SkPMColor[]) { @@ -335,21 +347,25 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither, Sample_RGBx_D8888, Sample_RGBx_D8888, Sample_RGBA_D8888, Sample_RGBA_D8888, Sample_Index_D8888, Sample_Index_D8888, + NULL, NULL, // 565 (no alpha distinction) Sample_Gray_D565, Sample_Gray_D565_D, Sample_RGBx_D565, Sample_RGBx_D565_D, Sample_RGBx_D565, Sample_RGBx_D565_D, Sample_Index_D565, Sample_Index_D565_D, + Sample_D565_D565, Sample_D565_D565, // 4444 Sample_Gray_D4444, Sample_Gray_D4444_D, Sample_RGBx_D4444, Sample_RGBx_D4444_D, Sample_RGBA_D4444, Sample_RGBA_D4444_D, Sample_Index_D4444, Sample_Index_D4444_D, + NULL, NULL, // Index8 NULL, NULL, NULL, NULL, NULL, NULL, Sample_Index_DI, Sample_Index_DI, + NULL, NULL, }; fCTable = ctable; @@ -379,6 +395,10 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither, fSrcPixelSize = 1; index += 6; break; + case SkScaledBitmapSampler::kRGB_565: + fSrcPixelSize = 2; + index += 8; + break; default: return false; } @@ -388,13 +408,13 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither, index += 0; break; case SkBitmap::kRGB_565_Config: - index += 8; + index += 10; break; case SkBitmap::kARGB_4444_Config: - index += 16; + index += 20; break; case SkBitmap::kIndex8_Config: - index += 24; + index += 30; break; default: return false; diff --git a/src/images/SkScaledBitmapSampler.h b/src/images/SkScaledBitmapSampler.h index 84a75ba544..43f166946a 100644 --- a/src/images/SkScaledBitmapSampler.h +++ b/src/images/SkScaledBitmapSampler.h @@ -21,7 +21,8 @@ public: kIndex, // 1 byte per pixel kRGB, // 3 bytes per pixel kRGBX, // 4 byes per pixel (ignore 4th) - kRGBA // 4 bytes per pixel + kRGBA, // 4 bytes per pixel + kRGB_565 // 2 bytes per pixel }; // Given a dst bitmap (with pixels already allocated) and a src-config, |