aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/images/SkImageDecoder.h6
-rw-r--r--src/images/SkImageDecoder.cpp16
-rw-r--r--src/images/SkImageDecoder_libjpeg.cpp51
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())) {