diff options
-rw-r--r-- | include/images/SkImageDecoder.h | 6 | ||||
-rw-r--r-- | src/images/SkImageDecoder.cpp | 16 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libjpeg.cpp | 51 |
3 files changed, 52 insertions, 21 deletions
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h index 3c904ca..0f71a3f 100644 --- a/include/images/SkImageDecoder.h +++ b/include/images/SkImageDecoder.h @@ -205,9 +205,9 @@ public: note: document use of Allocator, Peeker and Chooser */ - bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode); - bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) { - return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode); + bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode, bool reuseBitmap = false); + bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode, bool reuseBitmap = false) { + return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode, reuseBitmap); } /** diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp index 7713e86..a46471b 100644 --- a/src/images/SkImageDecoder.cpp +++ b/src/images/SkImageDecoder.cpp @@ -153,7 +153,9 @@ SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth, } bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, - SkBitmap::Config pref, Mode mode) { + SkBitmap::Config pref, Mode mode, bool reuseBitmap) { + SkAutoLockPixels alp(*bm); + bool hasPixels = (bm->getPixels() != NULL); // pass a temporary bitmap, so that if we return false, we are assured of // leaving the caller's bitmap untouched. SkBitmap tmp; @@ -163,10 +165,16 @@ bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, // assign this, for use by getPrefConfig(), in case fUsePrefTable is false fDefaultPref = pref; - if (!this->onDecode(stream, &tmp, mode)) { - return false; + if (reuseBitmap && hasPixels) { + if (!this->onDecode(stream, bm, mode)) { + return false; + } + } else { + if (!this->onDecode(stream, &tmp, mode)) { + return false; + } + bm->swap(tmp); } - bm->swap(tmp); return true; } diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp index 7e425c1..358861e 100644 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ b/src/images/SkImageDecoder_libjpeg.cpp @@ -325,16 +325,26 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { (config == SkBitmap::kRGB_565_Config && cinfo.out_color_space == JCS_RGB_565))) { - bm->setConfig(config, cinfo.output_width, cinfo.output_height); - bm->setIsOpaque(true); - if (SkImageDecoder::kDecodeBounds_Mode == mode) { + bm->lockPixels(); + JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); + bm->unlockPixels(); + bool reuseBitmap = (rowptr != NULL && (int) cinfo.output_width == bm->width() && + (int) cinfo.output_height == bm->height()); + + if (!reuseBitmap) { + bm->setConfig(config, cinfo.output_width, cinfo.output_height); + bm->setIsOpaque(true); + if (SkImageDecoder::kDecodeBounds_Mode == mode) { + return true; + } + if (!this->allocPixelRef(bm, NULL)) { + return return_false(cinfo, *bm, "allocPixelRef"); + } + } else if (SkImageDecoder::kDecodeBounds_Mode == mode) { return true; } - if (!this->allocPixelRef(bm, NULL)) { - return return_false(cinfo, *bm, "allocPixelRef"); - } SkAutoLockPixels alp(*bm); - JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); + rowptr = (JSAMPLE*)bm->getPixels(); INT32 const bpr = bm->rowBytes(); while (cinfo.output_scanline < cinfo.output_height) { @@ -349,6 +359,9 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { } rowptr += bpr; } + if (reuseBitmap) { + bm->notifyPixelsChanged(); + } jpeg_finish_decompress(&cinfo); return true; } @@ -374,16 +387,26 @@ 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()); - // jpegs are always opauqe (i.e. have no per-pixel alpha) - bm->setIsOpaque(true); + bm->lockPixels(); + JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); + bool reuseBitmap = (rowptr != NULL && sampler.scaledWidth() == bm->width() && + sampler.scaledHeight() == bm->height()); + bm->unlockPixels(); + + if (!reuseBitmap) { + bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); + // jpegs are always opaque (i.e. have no per-pixel alpha) + bm->setIsOpaque(true); - if (SkImageDecoder::kDecodeBounds_Mode == mode) { + if (SkImageDecoder::kDecodeBounds_Mode == mode) { + return true; + } + if (!this->allocPixelRef(bm, NULL)) { + return return_false(cinfo, *bm, "allocPixelRef"); + } + } else if (SkImageDecoder::kDecodeBounds_Mode == mode) { return true; } - if (!this->allocPixelRef(bm, NULL)) { - return return_false(cinfo, *bm, "allocPixelRef"); - } SkAutoLockPixels alp(*bm); if (!sampler.begin(bm, sc, this->getDitherImage())) { |