Chromium Code Reviews| Index: src/lazy/SkBitmapFactory.cpp |
| diff --git a/src/lazy/SkBitmapFactory.cpp b/src/lazy/SkBitmapFactory.cpp |
| index 1bbb6f0de7d7dc53dfb192ed4d7325f6134c048e..128933df94aa071f728754baf2c3ce2fc194a233 100644 |
| --- a/src/lazy/SkBitmapFactory.cpp |
| +++ b/src/lazy/SkBitmapFactory.cpp |
| @@ -12,6 +12,7 @@ |
| #include "SkImageCache.h" |
| #include "SkImagePriv.h" |
| #include "SkLazyPixelRef.h" |
| +#include "SkMallocPixelRef.h" |
| SK_DEFINE_INST_COUNT(SkBitmapFactory::CacheSelector) |
| @@ -43,38 +44,86 @@ void SkBitmapFactory::setCacheSelector(CacheSelector* selector) { |
| } |
| } |
| -bool SkBitmapFactory::installPixelRef(SkData* data, SkBitmap* dst) { |
| - if (NULL == data || 0 == data->size() || dst == NULL) { |
| - return false; |
| - } |
| +namespace { |
| +typedef SkBitmapFactory::DecodeProc DecodeProc; |
| + |
| +class FlexibleGenerator : public SkImageGenerator { |
|
reed1
2013/11/25 18:06:56
Not sure why this is named Flexible. Can you add a
|
| +public: |
| + FlexibleGenerator(SkData* data, |
| + SkBitmapFactory::DecodeProc proc); |
| + virtual ~FlexibleGenerator(); |
| + virtual SkData* refEncodedData() SK_OVERRIDE; |
| + virtual bool getInfo(SkImageInfo* info) SK_OVERRIDE; |
| + virtual bool getPixels(const SkImageInfo& info, |
| + void* pixels, |
| + size_t rowBytes) SK_OVERRIDE; |
| +private: |
| + SkData* fData; |
| + DecodeProc fDecodeProc; |
| + SkImageInfo fInfo; |
| + bool fError; |
| +}; |
| +FlexibleGenerator::FlexibleGenerator(SkData* data, DecodeProc proc) |
| + : fData(data) |
| + , fDecodeProc(proc) |
| + , fError(false) { |
| + SkASSERT(fDecodeProc != NULL); |
| + SkASSERT(fData != NULL); |
| + fData->ref(); |
| + fError = !fDecodeProc(fData->data(), fData->size(), &fInfo, NULL); |
| +} |
| + |
| +FlexibleGenerator::~FlexibleGenerator() { |
| + fData->unref(); |
| +} |
| + |
| +SkData* FlexibleGenerator::refEncodedData() { |
| + fData->ref(); |
| + return fData; |
| +} |
| - SkImageInfo info; |
| - if (!fDecodeProc(data->data(), data->size(), &info, NULL)) { |
| +bool FlexibleGenerator::getInfo(SkImageInfo* info) { |
| + if (fError) |
| return false; |
| - } |
| + SkASSERT(info != NULL); |
| + *info = fInfo; |
| + return true; |
| +} |
| - SkBitmap::Config config = SkImageInfoToBitmapConfig(info); |
| +bool FlexibleGenerator::getPixels(const SkImageInfo& info, |
| + void* pixels, |
| + size_t rowBytes) { |
| + if (fError) |
| + return false; |
| + SkASSERT(pixels != NULL); |
| + SkBitmapFactory::Target target = {pixels, rowBytes}; |
| + SkImageInfo tmpInfo = info; |
| + return fDecodeProc(fData->data(), fData->size(), &tmpInfo, &target); |
| +} |
| +} // namespace |
| - Target target; |
| - // FIMXE: There will be a problem if this rowbytes is calculated differently from |
| - // in SkLazyPixelRef. |
| - target.fRowBytes = SkImageMinRowBytes(info); |
| - dst->setConfig(config, info.fWidth, info.fHeight, target.fRowBytes, info.fAlphaType); |
| +bool SkBitmapFactory::installPixelRef(SkData* data, SkBitmap* dst) { |
| + if (NULL == data || 0 == data->size() || dst == NULL) { |
| + return false; |
| + } |
| + FlexibleGenerator* gen = SkNEW_ARGS(FlexibleGenerator, |
| + (data, fDecodeProc)); |
| // fImageCache and fCacheSelector are mutually exclusive. |
| SkASSERT(NULL == fImageCache || NULL == fCacheSelector); |
| - |
| - SkImageCache* cache = NULL == fCacheSelector ? fImageCache : fCacheSelector->selectCache(info); |
| + SkImageCache* cache = fImageCache; |
| + if ((cache == NULL) && (NULL != fCacheSelector)) { |
| + SkImageInfo info; |
| + if (!gen->getInfo(&info)) { |
| + SkDELETE(gen); |
| + return false; |
| + } |
| + cache = fCacheSelector->selectCache(info); |
| + } |
| if (cache != NULL) { |
| - // Now set a new LazyPixelRef on dst. |
| - SkAutoTUnref<SkLazyPixelRef> lazyRef(SkNEW_ARGS(SkLazyPixelRef, |
| - (data, fDecodeProc, cache))); |
| - dst->setPixelRef(lazyRef); |
| - return true; |
| + return SkLazyPixelRef::Install(gen, cache, dst); |
| } else { |
| - dst->allocPixels(); |
| - target.fAddr = dst->getPixels(); |
| - return fDecodeProc(data->data(), data->size(), &info, &target); |
| + return SkMallocPixelRef::Install(gen, dst); |
| } |
| } |