Index: src/images/SkImageDecoder.cpp |
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp |
index 7b4267615fc563b5eb0752f7a353c667f4db23a6..1e3b03929fd21d9b67051f22be6f448d77fd3dea 100644 |
--- a/src/images/SkImageDecoder.cpp |
+++ b/src/images/SkImageDecoder.cpp |
@@ -12,11 +12,23 @@ |
#include "SkPixelRef.h" |
#include "SkStream.h" |
#include "SkTemplates.h" |
+#include "SkCanvas.h" |
SK_DEFINE_INST_COUNT(SkImageDecoder::Peeker) |
SK_DEFINE_INST_COUNT(SkImageDecoder::Chooser) |
SK_DEFINE_INST_COUNT(SkImageDecoderFactory) |
+const char *SkImageDecoder::sFormatName[] = { |
+ "Unknown Format", |
+ "BMP", |
+ "GIF", |
+ "ICO", |
+ "JPEG", |
+ "PNG", |
+ "WBMP", |
+ "WEBP", |
+}; |
+ |
static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; |
SkBitmap::Config SkImageDecoder::GetDeviceConfig() |
@@ -34,7 +46,7 @@ void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) |
SkImageDecoder::SkImageDecoder() |
: fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1), |
fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true), |
- fUsePrefTable(false) { |
+ fUsePrefTable(false),fPreferQualityOverSpeed(false) { |
} |
SkImageDecoder::~SkImageDecoder() { |
@@ -47,6 +59,11 @@ SkImageDecoder::Format SkImageDecoder::getFormat() const { |
return kUnknown_Format; |
} |
+const char* SkImageDecoder::getFormatName() const { |
+ SkASSERT(SK_ARRAY_COUNT(sFormatName) == kLastKnownFormat); |
+ return sFormatName[this->getFormat()]; |
+} |
+ |
SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { |
SkRefCnt_SafeAssign(fPeeker, peeker); |
return peeker; |
@@ -129,16 +146,22 @@ SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth, |
} |
bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, |
- SkBitmap::Config pref, Mode mode) { |
- // pass a temporary bitmap, so that if we return false, we are assured of |
- // leaving the caller's bitmap untouched. |
- SkBitmap tmp; |
- |
+ SkBitmap::Config pref, Mode mode, bool reuseBitmap) { |
// we reset this to false before calling onDecode |
fShouldCancelDecode = false; |
// assign this, for use by getPrefConfig(), in case fUsePrefTable is false |
fDefaultPref = pref; |
+ if (reuseBitmap) { |
+ SkAutoLockPixels alp(*bm); |
+ if (NULL != bm->getPixels()) { |
+ return this->onDecode(stream, bm, mode); |
+ } |
+ } |
+ |
+ // pass a temporary bitmap, so that if we return false, we are assured of |
+ // leaving the caller's bitmap untouched. |
+ SkBitmap tmp; |
if (!this->onDecode(stream, &tmp, mode)) { |
return false; |
} |
@@ -146,6 +169,55 @@ bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, |
return true; |
} |
+bool SkImageDecoder::decodeRegion(SkBitmap* bm, const SkIRect& rect, |
+ SkBitmap::Config pref) { |
+ // we reset this to false before calling onDecodeRegion |
+ fShouldCancelDecode = false; |
+ // assign this, for use by getPrefConfig(), in case fUsePrefTable is false |
+ fDefaultPref = pref; |
+ |
+ return this->onDecodeRegion(bm, rect); |
+} |
+ |
+bool SkImageDecoder::buildTileIndex(SkStream* stream, |
+ int *width, int *height) { |
+ // we reset this to false before calling onBuildTileIndex |
+ fShouldCancelDecode = false; |
+ |
+ 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) { |
+ int w = width / sampleSize; |
+ int h = height / sampleSize; |
+ // if the destination has no pixels then we must allocate them. |
+ if (dst->isNull()) { |
+ dst->setConfig(src->getConfig(), w, h); |
+ dst->setIsOpaque(src->isOpaque()); |
+ |
+ if (!this->allocPixelRef(dst, NULL)) { |
+ SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); |
+ return; |
+ } |
+ } |
+ // 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); |
+ |
+ // Set the Src_Mode for the paint to prevent transparency issue in the |
+ // dest in the event that the dest was being re-used. |
+ SkPaint paint; |
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
+ |
+ SkCanvas canvas(*dst); |
+ canvas.drawSprite(*src, (srcX - dstX) / sampleSize, |
+ (srcY - dstY) / sampleSize, |
+ &paint); |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////// |
bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, |