Index: src/images/SkImageDecoder.cpp |
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp |
index de0bc14c90e40cd54b49a1985fe535a5c86b0a7b..9ffae5f0e7f9bdac29d642641cc823ef2d806dcf 100644 |
--- a/src/images/SkImageDecoder.cpp |
+++ b/src/images/SkImageDecoder.cpp |
@@ -33,9 +33,14 @@ void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) |
/////////////////////////////////////////////////////////////////////////////// |
SkImageDecoder::SkImageDecoder() |
- : fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1), |
- fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true), |
- fUsePrefTable(false),fPreferQualityOverSpeed(false) { |
+ : fPeeker(NULL) |
+ , fChooser(NULL) |
+ , fAllocator(NULL) |
+ , fSampleSize(1) |
+ , fDefaultPref(SkBitmap::kNo_Config) |
+ , fDitherImage(true) |
+ , fUsePrefTable(false) |
+ , fPreferQualityOverSpeed(false) { |
} |
SkImageDecoder::~SkImageDecoder() { |
@@ -177,14 +182,14 @@ bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, |
return true; |
} |
-bool SkImageDecoder::decodeRegion(SkBitmap* bm, const SkIRect& rect, |
+bool SkImageDecoder::decodeSubset(SkBitmap* bm, const SkIRect& rect, |
SkBitmap::Config pref) { |
- // we reset this to false before calling onDecodeRegion |
+ // we reset this to false before calling onDecodeSubset |
fShouldCancelDecode = false; |
// assign this, for use by getPrefConfig(), in case fUsePrefTable is false |
fDefaultPref = pref; |
- return this->onDecodeRegion(bm, rect); |
+ return this->onDecodeSubset(bm, rect); |
} |
bool SkImageDecoder::buildTileIndex(SkStream* stream, |
@@ -195,11 +200,25 @@ bool SkImageDecoder::buildTileIndex(SkStream* stream, |
return this->onBuildTileIndex(stream, width, height); |
} |
-void SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, |
- int dstX, int dstY, int width, int height, |
- int srcX, int srcY) { |
+bool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, |
+ int dstX, int dstY, int width, int height, |
+ int srcX, int srcY) { |
int w = width / sampleSize; |
int h = height / sampleSize; |
+ if (src->getConfig() == SkBitmap::kIndex8_Config) { |
+ // kIndex8 does not allow drawing via an SkCanvas, as is done below. |
+ // Instead, use extractSubset. Note that this shares the SkPixelRef and |
+ // SkColorTable. |
+ // FIXME: Since src is discarded in practice, this holds on to more |
+ // pixels than is strictly necessary. Switch to a copy if memory |
+ // savings are more important than speed here. This also means |
+ // that the pixels in dst can not be reused (though there is no |
+ // allocation, which was already done on src). |
+ int x = (dstX - srcX) / sampleSize; |
+ int y = (dstY - srcY) / sampleSize; |
+ SkIRect subset = SkIRect::MakeXYWH(x, y, w, h); |
+ return src->extractSubset(dst, subset); |
+ } |
// if the destination has no pixels then we must allocate them. |
if (dst->isNull()) { |
dst->setConfig(src->getConfig(), w, h); |
@@ -207,13 +226,15 @@ void SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, |
if (!this->allocPixelRef(dst, NULL)) { |
SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); |
- return; |
+ return false; |
} |
} |
// check to see if the destination is large enough to decode the desired |
// region. If this assert fails we will just draw as much of the source |
// into the destination that we can. |
- SkASSERT(dst->width() >= w && dst->height() >= h); |
+ if (dst->width() < w || dst->height() < h) { |
+ SkDEBUGF(("SkImageDecoder::cropBitmap does not have a large enough bitmap.\n")); |
+ } |
// Set the Src_Mode for the paint to prevent transparency issue in the |
// dest in the event that the dest was being re-used. |
@@ -224,6 +245,7 @@ void SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, |
canvas.drawSprite(*src, (srcX - dstX) / sampleSize, |
(srcY - dstY) / sampleSize, |
&paint); |
+ return true; |
} |
/////////////////////////////////////////////////////////////////////////////// |