diff options
-rw-r--r-- | include/core/SkTemplates.h | 7 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libjpeg.cpp | 19 | ||||
-rw-r--r-- | src/images/SkImageDecoder_libpng.cpp | 31 |
3 files changed, 44 insertions, 13 deletions
diff --git a/include/core/SkTemplates.h b/include/core/SkTemplates.h index 27ebd41..d484389 100644 --- a/include/core/SkTemplates.h +++ b/include/core/SkTemplates.h @@ -61,8 +61,10 @@ private: template <typename T> class SkAutoTDelete : SkNoncopyable { public: - SkAutoTDelete(T* obj) : fObj(obj) {} - ~SkAutoTDelete() { delete fObj; } + SkAutoTDelete(T* obj, bool deleteWhenDone = true) : fObj(obj) { + this->deleteWhenDone = deleteWhenDone; + } + ~SkAutoTDelete() { if (deleteWhenDone) delete fObj; } T* get() const { return fObj; } void free() { delete fObj; fObj = NULL; } @@ -70,6 +72,7 @@ public: private: T* fObj; + bool deleteWhenDone; }; template <typename T> class SkAutoTDeleteArray : SkNoncopyable { diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp index 358861e..514118d 100644 --- a/src/images/SkImageDecoder_libjpeg.cpp +++ b/src/images/SkImageDecoder_libjpeg.cpp @@ -328,8 +328,12 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, 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()); + bool reuseBitmap = (rowptr != NULL); + if (reuseBitmap && ((int) cinfo.output_width != bm->width() || + (int) cinfo.output_height != bm->height())) { + // Dimensions must match + return false; + } if (!reuseBitmap) { bm->setConfig(config, cinfo.output_width, cinfo.output_height); @@ -389,9 +393,13 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { bm->lockPixels(); JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); - bool reuseBitmap = (rowptr != NULL && sampler.scaledWidth() == bm->width() && - sampler.scaledHeight() == bm->height()); + bool reuseBitmap = (rowptr != NULL); bm->unlockPixels(); + if (reuseBitmap && (sampler.scaledWidth() != bm->width() || + sampler.scaledHeight() != bm->height())) { + // Dimensions must match + return false; + } if (!reuseBitmap) { bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); @@ -447,6 +455,9 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { cinfo.output_height - cinfo.output_scanline)) { return return_false(cinfo, *bm, "skip rows"); } + if (reuseBitmap) { + bm->notifyPixelsChanged(); + } jpeg_finish_decompress(&cinfo); // SkDebugf("------------------- bm2 size %d [%d %d] %d\n", bm->getSize(), bm->width(), bm->height(), bm->config()); diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp index e550767..5cd86f7 100644 --- a/src/images/SkImageDecoder_libpng.cpp +++ b/src/images/SkImageDecoder_libpng.cpp @@ -291,8 +291,20 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, const int sampleSize = this->getSampleSize(); SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); - decodedBitmap->setConfig(config, sampler.scaledWidth(), - sampler.scaledHeight(), 0); + decodedBitmap->lockPixels(); + void* rowptr = (void*) decodedBitmap->getPixels(); + bool reuseBitmap = (rowptr != NULL); + decodedBitmap->unlockPixels(); + if (reuseBitmap && (sampler.scaledWidth() != decodedBitmap->width() || + sampler.scaledHeight() != decodedBitmap->height())) { + // Dimensions must match + return false; + } + + if (!reuseBitmap) { + decodedBitmap->setConfig(config, sampler.scaledWidth(), + sampler.scaledHeight(), 0); + } if (SkImageDecoder::kDecodeBounds_Mode == mode) { return true; } @@ -312,10 +324,12 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, SkAutoUnref aur(colorTable); - if (!this->allocPixelRef(decodedBitmap, - SkBitmap::kIndex8_Config == config ? - colorTable : NULL)) { - return false; + if (!reuseBitmap) { + if (!this->allocPixelRef(decodedBitmap, + SkBitmap::kIndex8_Config == config ? + colorTable : NULL)) { + return false; + } } SkAutoLockPixels alp(*decodedBitmap); @@ -416,6 +430,9 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); } decodedBitmap->setIsOpaque(!reallyHasAlpha); + if (reuseBitmap) { + decodedBitmap->notifyPixelsChanged(); + } return true; } @@ -684,7 +701,7 @@ bool SkPNGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect rect) { png_ptr->pass = 0; png_read_update_info(png_ptr, info_ptr); - SkDebugf("Request size %d %d\n", requestedWidth, requestedHeight); + // SkDebugf("Request size %d %d\n", requestedWidth, requestedHeight); int actualTop = rect.fTop; |