| 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,
|
|
|