| Index: src/images/SkDecodingImageGenerator.cpp
|
| diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp
|
| index 1e2813660329ad29821704cadf79916df0aab153..7e3bb9b2fb6e61e2bc4763ca238580b6a57dfbcb 100644
|
| --- a/src/images/SkDecodingImageGenerator.cpp
|
| +++ b/src/images/SkDecodingImageGenerator.cpp
|
| @@ -14,60 +14,50 @@
|
| #include "SkStream.h"
|
| #include "SkUtils.h"
|
|
|
| +static bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) {
|
| + return a.width() == b.width() && a.height() == b.height() &&
|
| + a.colorType() == b.colorType();
|
| +}
|
| +
|
| namespace {
|
| /**
|
| * Special allocator used by getPixels(). Uses preallocated memory
|
| - * provided.
|
| + * provided if possible, else fall-back on the default allocator
|
| */
|
| class TargetAllocator : public SkBitmap::Allocator {
|
| public:
|
| - TargetAllocator(void* target,
|
| - size_t rowBytes,
|
| - int width,
|
| - int height,
|
| - SkBitmap::Config config)
|
| - : fTarget(target)
|
| + TargetAllocator(const SkImageInfo& info,
|
| + void* target,
|
| + size_t rowBytes)
|
| + : fInfo(info)
|
| + , fTarget(target)
|
| , fRowBytes(rowBytes)
|
| - , fWidth(width)
|
| - , fHeight(height)
|
| - , fConfig(config) { }
|
| + {}
|
|
|
| bool isReady() { return (fTarget != NULL); }
|
|
|
| virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
|
| - if ((NULL == fTarget)
|
| - || (fConfig != bm->config())
|
| - || (fWidth != bm->width())
|
| - || (fHeight != bm->height())
|
| - || (ct != NULL)) {
|
| + if (NULL == fTarget || !equal_modulo_alpha(fInfo, bm->info())) {
|
| // Call default allocator.
|
| return bm->allocPixels(NULL, ct);
|
| }
|
| - // make sure fRowBytes is correct.
|
| - bm->setConfig(fConfig, fWidth, fHeight, fRowBytes, bm->alphaType());
|
| +
|
| // TODO(halcanary): verify that all callers of this function
|
| // will respect new RowBytes. Will be moot once rowbytes belongs
|
| // to PixelRef.
|
| - bm->setPixels(fTarget, NULL);
|
| + bm->installPixels(fInfo, fTarget, fRowBytes, NULL, NULL);
|
| +
|
| fTarget = NULL; // never alloc same pixels twice!
|
| return true;
|
| }
|
|
|
| private:
|
| + const SkImageInfo fInfo;
|
| void* fTarget; // Block of memory to be supplied as pixel memory
|
| // in allocPixelRef. Must be large enough to hold
|
| - // a bitmap described by fWidth, fHeight, and
|
| - // fRowBytes.
|
| - size_t fRowBytes; // rowbytes for the destination bitmap
|
| - int fWidth; // Along with fHeight and fConfig, the information
|
| - int fHeight; // about the bitmap whose pixels this allocator is
|
| - // expected to allocate. If they do not match the
|
| - // bitmap passed to allocPixelRef, it is assumed
|
| - // that the bitmap will be copied to a bitmap with
|
| - // the correct info using this allocator, so the
|
| - // default allocator will be used instead of
|
| - // fTarget.
|
| - SkBitmap::Config fConfig;
|
| + // a bitmap described by fInfo and fRowBytes
|
| + const size_t fRowBytes; // rowbytes for the destination bitmap
|
| +
|
| typedef SkBitmap::Allocator INHERITED;
|
| };
|
|
|
| @@ -94,14 +84,13 @@ SkDecodingImageGenerator::SkDecodingImageGenerator(
|
| SkStreamRewindable* stream,
|
| const SkImageInfo& info,
|
| int sampleSize,
|
| - bool ditherImage,
|
| - SkBitmap::Config requestedConfig)
|
| + bool ditherImage)
|
| : fData(data)
|
| , fStream(stream)
|
| , fInfo(info)
|
| , fSampleSize(sampleSize)
|
| , fDitherImage(ditherImage)
|
| - , fRequestedConfig(requestedConfig) {
|
| +{
|
| SkASSERT(stream != NULL);
|
| SkSafeRef(fData); // may be NULL.
|
| }
|
| @@ -151,8 +140,7 @@ bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info,
|
| // to change the settings.
|
| return false;
|
| }
|
| - int bpp = SkBitmap::ComputeBytesPerPixel(fRequestedConfig);
|
| - if (static_cast<size_t>(bpp * info.fWidth) > rowBytes) {
|
| + if (info.minRowBytes() > rowBytes) {
|
| // The caller has specified a bad rowBytes.
|
| return false;
|
| }
|
| @@ -166,10 +154,11 @@ bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info,
|
| decoder->setSampleSize(fSampleSize);
|
|
|
| SkBitmap bitmap;
|
| - TargetAllocator allocator(pixels, rowBytes, info.fWidth,
|
| - info.fHeight, fRequestedConfig);
|
| + TargetAllocator allocator(fInfo, pixels, rowBytes);
|
| decoder->setAllocator(&allocator);
|
| - bool success = decoder->decode(fStream, &bitmap, fRequestedConfig,
|
| + // TODO: need to be able to pass colortype directly to decoder
|
| + SkBitmap::Config legacyConfig = SkColorTypeToBitmapConfig(info.colorType());
|
| + bool success = decoder->decode(fStream, &bitmap, legacyConfig,
|
| SkImageDecoder::kDecodePixels_Mode);
|
| decoder->setAllocator(NULL);
|
| if (!success) {
|
| @@ -177,16 +166,16 @@ bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info,
|
| }
|
| if (allocator.isReady()) { // Did not use pixels!
|
| SkBitmap bm;
|
| - SkASSERT(bitmap.canCopyTo(fRequestedConfig));
|
| - if (!bitmap.copyTo(&bm, fRequestedConfig, &allocator)
|
| - || allocator.isReady()) {
|
| + SkASSERT(bitmap.canCopyTo(info.colorType()));
|
| + bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator);
|
| + if (!copySuccess || allocator.isReady()) {
|
| SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed.");
|
| // Earlier we checked canCopyto(); we expect consistency.
|
| return false;
|
| }
|
| - SkASSERT(check_alpha(fInfo.fAlphaType, bm.alphaType()));
|
| + SkASSERT(check_alpha(info.alphaType(), bm.alphaType()));
|
| } else {
|
| - SkASSERT(check_alpha(fInfo.fAlphaType, bitmap.alphaType()));
|
| + SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType()));
|
| }
|
| return true;
|
| }
|
| @@ -245,38 +234,23 @@ SkImageGenerator* SkDecodingImageGenerator::Create(
|
| return NULL;
|
| }
|
|
|
| - SkImageInfo info;
|
| - SkBitmap::Config config;
|
| + SkImageInfo info = bitmap.info();
|
|
|
| if (!opts.fUseRequestedColorType) {
|
| - // Use default config.
|
| - if (SkBitmap::kIndex8_Config == bitmap.config()) {
|
| + // Use default
|
| + if (kIndex_8_SkColorType == bitmap.colorType()) {
|
| // We don't support kIndex8 because we don't support
|
| // colortables in this workflow.
|
| - config = SkBitmap::kARGB_8888_Config;
|
| - info.fWidth = bitmap.width();
|
| - info.fHeight = bitmap.height();
|
| info.fColorType = kPMColor_SkColorType;
|
| - info.fAlphaType = bitmap.alphaType();
|
| - } else {
|
| - config = bitmap.config(); // Save for later!
|
| - if (!bitmap.asImageInfo(&info)) {
|
| - SkDEBUGFAIL("Getting SkImageInfo from bitmap failed.");
|
| - return NULL;
|
| - }
|
| }
|
| } else {
|
| - config = SkColorTypeToBitmapConfig(opts.fRequestedColorType);
|
| - if (!bitmap.canCopyTo(config)) {
|
| - SkASSERT(bitmap.config() != config);
|
| + if (!bitmap.canCopyTo(opts.fRequestedColorType)) {
|
| + SkASSERT(bitmap.colorType() != opts.fRequestedColorType);
|
| return NULL; // Can not translate to needed config.
|
| }
|
| - info.fWidth = bitmap.width();
|
| - info.fHeight = bitmap.height();
|
| info.fColorType = opts.fRequestedColorType;
|
| - info.fAlphaType = bitmap.alphaType();
|
| }
|
| return SkNEW_ARGS(SkDecodingImageGenerator,
|
| (data, autoStream.detach(), info,
|
| - opts.fSampleSize, opts.fDitherImage, config));
|
| + opts.fSampleSize, opts.fDitherImage));
|
| }
|
|
|