diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-12-18 18:33:15 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-12-18 18:33:15 +0000 |
commit | 1ad518bf38184ae820f31f9b79dfb4e4daf5841a (patch) | |
tree | 32b276fb330b81c18a69c864fd22dfbf79388591 /src/images | |
parent | 1cd71fb013643b983b372fee24eab3708aae70e9 (diff) |
Reason for revert: Test failures
R=scroggo@google.com, djsollen@google.com, reed@google.com, halcanary@google.com
TBR=djsollen@google.com, halcanary@google.com, reed@google.com, scroggo@google.com
NOTREECHECKS=true
NOTRY=true
Author: robertphillips@google.com
Review URL: https://codereview.chromium.org/103753007
git-svn-id: http://skia.googlecode.com/svn/trunk@12747 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/images')
-rw-r--r-- | src/images/SkDecodingImageGenerator.cpp | 307 | ||||
-rw-r--r-- | src/images/SkDecodingImageGenerator.h | 181 |
2 files changed, 194 insertions, 294 deletions
diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp index 153d1e220b..a833c636ff 100644 --- a/src/images/SkDecodingImageGenerator.cpp +++ b/src/images/SkDecodingImageGenerator.cpp @@ -5,14 +5,13 @@ * found in the LICENSE file. */ -#include "SkData.h" #include "SkDecodingImageGenerator.h" +#include "SkData.h" #include "SkImageDecoder.h" -#include "SkImageInfo.h" #include "SkImageGenerator.h" #include "SkImagePriv.h" #include "SkStream.h" -#include "SkUtils.h" + namespace { /** @@ -21,89 +20,50 @@ namespace { */ class TargetAllocator : public SkBitmap::Allocator { public: - TargetAllocator(void* target, - size_t rowBytes, - int width, - int height, - SkBitmap::Config config) + TargetAllocator(void* target, size_t rowBytes, const SkImageInfo& info) : fTarget(target) , fRowBytes(rowBytes) - , fWidth(width) - , fHeight(height) - , fConfig(config) { } - - bool isReady() { return (fTarget != NULL); } + , fInfo(info) { } - virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) { - if ((NULL == fTarget) - || (fConfig != bm->config()) - || (fWidth != bm->width()) - || (fHeight != bm->height()) - || (ct != NULL)) { - // Call default allocator. - return bm->allocPixels(NULL, ct); + virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE { + if ((SkImageInfoToBitmapConfig(fInfo) != bm->config()) + || (bm->width() != fInfo.fWidth) + || (bm->height() != fInfo.fHeight)) { + return false; } - // 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); - fTarget = NULL; // never alloc same pixels twice! + bm->setConfig(bm->config(), bm->width(), bm->height(), + fRowBytes, bm->alphaType()); + bm->setPixels(fTarget, ct); return true; } private: - 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; + void* fTarget; + size_t fRowBytes; + SkImageInfo fInfo; typedef SkBitmap::Allocator INHERITED; }; - -// TODO(halcanary): Give this macro a better name and move it into SkTypes.h -#ifdef SK_DEBUG - #define SkCheckResult(expr, value) SkASSERT((value) == (expr)) -#else - #define SkCheckResult(expr, value) (void)(expr) -#endif - -#ifdef SK_DEBUG -inline bool check_alpha(SkAlphaType reported, SkAlphaType actual) { - return ((reported == actual) - || ((reported == kPremul_SkAlphaType) - && (actual == kOpaque_SkAlphaType))); -} -#endif // SK_DEBUG - } // namespace //////////////////////////////////////////////////////////////////////////////// -SkDecodingImageGenerator::SkDecodingImageGenerator( - SkData* data, - SkStreamRewindable* stream, - const SkImageInfo& info, - int sampleSize, - bool ditherImage, - SkBitmap::Config requestedConfig) +SkDecodingImageGenerator::SkDecodingImageGenerator(SkData* data) : fData(data) + , fHasInfo(false) + , fDoCopyTo(false) { + SkASSERT(fData != NULL); + fStream = SkNEW_ARGS(SkMemoryStream, (fData)); + SkASSERT(fStream != NULL); + SkASSERT(fStream->unique()); + fData->ref(); +} + +SkDecodingImageGenerator::SkDecodingImageGenerator(SkStreamRewindable* stream) + : fData(NULL) , fStream(stream) - , fInfo(info) - , fSampleSize(sampleSize) - , fDitherImage(ditherImage) - , fRequestedConfig(requestedConfig) { - SkASSERT(stream != NULL); - SkSafeRef(fData); // may be NULL. + , fHasInfo(false) + , fDoCopyTo(false) { + SkASSERT(fStream != NULL); + SkASSERT(fStream->unique()); } SkDecodingImageGenerator::~SkDecodingImageGenerator() { @@ -111,16 +71,15 @@ SkDecodingImageGenerator::~SkDecodingImageGenerator() { fStream->unref(); } -bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) { - if (info != NULL) { - *info = fInfo; - } - return true; -} +// TODO(halcanary): Give this macro a better name and move it into SkTypes.h +#ifdef SK_DEBUG + #define SkCheckResult(expr, value) SkASSERT((value) == (expr)) +#else + #define SkCheckResult(expr, value) (void)(expr) +#endif SkData* SkDecodingImageGenerator::refEncodedData() { // This functionality is used in `gm --serialize` - // Does not encode options. if (fData != NULL) { return SkSafeRef(fData); } @@ -139,149 +98,111 @@ SkData* SkDecodingImageGenerator::refEncodedData() { return SkSafeRef(fData); } +bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) { + // info can be NULL. If so, will update fInfo, fDoCopyTo, and fHasInfo. + if (fHasInfo) { + if (info != NULL) { + *info = fInfo; + } + return true; + } + SkAssertResult(fStream->rewind()); + SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); + if (NULL == decoder.get()) { + return false; + } + SkBitmap bitmap; + if (!decoder->decode(fStream, &bitmap, + SkImageDecoder::kDecodeBounds_Mode)) { + return false; + } + if (bitmap.config() == SkBitmap::kNo_Config) { + return false; + } + if (!bitmap.asImageInfo(&fInfo)) { + // We can't use bitmap.config() as is. + if (!bitmap.canCopyTo(SkBitmap::kARGB_8888_Config)) { + SkDEBUGFAIL("!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)"); + return false; + } + fDoCopyTo = true; + fInfo.fWidth = bitmap.width(); + fInfo.fHeight = bitmap.height(); + fInfo.fColorType = kPMColor_SkColorType; + fInfo.fAlphaType = bitmap.alphaType(); + } + if (info != NULL) { + *info = fInfo; + } + fHasInfo = true; + return true; +} + bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { if (NULL == pixels) { return false; } - if (fInfo != info) { - // The caller has specified a different info. This is an - // error for this kind of SkImageGenerator. Use the Options - // to change the settings. + if (!this->getInfo(NULL)) { return false; } - int bpp = SkBitmap::ComputeBytesPerPixel(fRequestedConfig); - if (static_cast<size_t>(bpp * info.fWidth) > rowBytes) { - // The caller has specified a bad rowBytes. - return false; + if (SkImageInfoToBitmapConfig(info) == SkBitmap::kNo_Config) { + return false; // Unsupported SkColorType. } - SkAssertResult(fStream->rewind()); SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); if (NULL == decoder.get()) { return false; } - decoder->setDitherImage(fDitherImage); - decoder->setSampleSize(fSampleSize); - + if (fInfo != info) { + // The caller has specified a different info. For now, this + // is an error. In the future, we will check to see if we can + // convert. + return false; + } + int bpp = SkBitmap::ComputeBytesPerPixel(SkImageInfoToBitmapConfig(info)); + if (static_cast<size_t>(bpp * info.fWidth) > rowBytes) { + return false; + } SkBitmap bitmap; - TargetAllocator allocator(pixels, rowBytes, info.fWidth, - info.fHeight, fRequestedConfig); - decoder->setAllocator(&allocator); - bool success = decoder->decode(fStream, &bitmap, fRequestedConfig, + if (!bitmap.setConfig(info, rowBytes)) { + return false; + } + + TargetAllocator allocator(pixels, rowBytes, info); + if (!fDoCopyTo) { + decoder->setAllocator(&allocator); + } + bool success = decoder->decode(fStream, &bitmap, SkImageDecoder::kDecodePixels_Mode); decoder->setAllocator(NULL); if (!success) { return false; } - if (allocator.isReady()) { // Did not use pixels! - SkBitmap bm; - SkASSERT(bitmap.canCopyTo(fRequestedConfig)); - if (!bitmap.copyTo(&bm, fRequestedConfig, &allocator) - || allocator.isReady()) { - SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed."); - // Earlier we checked canCopyto(); we expect consistency. - return false; - } - SkASSERT(check_alpha(fInfo.fAlphaType, bm.alphaType())); - } else { - SkASSERT(check_alpha(fInfo.fAlphaType, bitmap.alphaType())); + if (fDoCopyTo) { + SkBitmap bm8888; + bitmap.copyTo(&bm8888, SkBitmap::kARGB_8888_Config, &allocator); } return true; } - -SkImageGenerator* SkDecodingImageGenerator::Create( - SkData* data, - const SkDecodingImageGenerator::Options& opts) { +bool SkDecodingImageGenerator::Install(SkData* data, SkBitmap* dst, + SkDiscardableMemory::Factory* factory) { SkASSERT(data != NULL); - if (NULL == data) { - return NULL; - } - SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data)); - SkASSERT(stream != NULL); - SkASSERT(stream->unique()); - return SkDecodingImageGenerator::Create(data, stream, opts); + SkASSERT(dst != NULL); + SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (data))); + return SkInstallDiscardablePixelRef(gen, dst, factory); } -SkImageGenerator* SkDecodingImageGenerator::Create( - SkStreamRewindable* stream, - const SkDecodingImageGenerator::Options& opts) { +bool SkDecodingImageGenerator::Install(SkStreamRewindable* stream, + SkBitmap* dst, + SkDiscardableMemory::Factory* factory) { SkASSERT(stream != NULL); - SkASSERT(stream->unique()); + SkASSERT(dst != NULL); if ((stream == NULL) || !stream->unique()) { SkSafeUnref(stream); - return NULL; - } - return SkDecodingImageGenerator::Create(NULL, stream, opts); -} - -// A contructor-type function that returns NULL on failure. This -// prevents the returned SkImageGenerator from ever being in a bad -// state. Called by both Create() functions -SkImageGenerator* SkDecodingImageGenerator::Create( - SkData* data, - SkStreamRewindable* stream, - const SkDecodingImageGenerator::Options& opts) { - SkASSERT(stream); - SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. - if (opts.fUseRequestedColorType && - (kIndex_8_SkColorType == opts.fRequestedColorType)) { - // We do not support indexed color with SkImageGenerators, - return NULL; - } - SkAssertResult(autoStream->rewind()); - SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream)); - if (NULL == decoder.get()) { - return NULL; - } - SkBitmap bitmap; - decoder->setSampleSize(opts.fSampleSize); - if (!decoder->decode(stream, &bitmap, - SkImageDecoder::kDecodeBounds_Mode)) { - return NULL; - } - if (bitmap.config() == SkBitmap::kNo_Config) { - return NULL; - } - - SkImageInfo info; - SkBitmap::Config config; - - if (!opts.fUseRequestedColorType) { - // Use default config. - if (SkBitmap::kIndex8_Config == bitmap.config()) { - // 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); - return NULL; // Can not translate to needed config. - } - info.fWidth = bitmap.width(); - info.fHeight = bitmap.height(); - info.fColorType = opts.fRequestedColorType; - info.fAlphaType = bitmap.alphaType(); - - // Sanity check. - SkDEBUGCODE(SkColorType tmp;) - SkASSERT(SkBitmapConfigToColorType(config, &tmp)); - SkASSERT(tmp == opts.fRequestedColorType); + return false; } - return SkNEW_ARGS(SkDecodingImageGenerator, - (data, autoStream.detach(), info, - opts.fSampleSize, opts.fDitherImage, config)); + SkImageGenerator* gen(SkNEW_ARGS(SkDecodingImageGenerator, (stream))); + return SkInstallDiscardablePixelRef(gen, dst, factory); } diff --git a/src/images/SkDecodingImageGenerator.h b/src/images/SkDecodingImageGenerator.h index 12a49d59c4..dba234bcf1 100644 --- a/src/images/SkDecodingImageGenerator.h +++ b/src/images/SkDecodingImageGenerator.h @@ -8,134 +8,113 @@ #ifndef SkDecodingImageGenerator_DEFINED #define SkDecodingImageGenerator_DEFINED -#include "SkBitmap.h" +#include "SkDiscardableMemory.h" #include "SkImageGenerator.h" +#include "SkImageInfo.h" -class SkData; +class SkBitmap; class SkStreamRewindable; /** - * An implementation of SkImageGenerator that calls into - * SkImageDecoder. + * Calls into SkImageDecoder::DecodeMemoryToTarget to implement a + * SkImageGenerator */ class SkDecodingImageGenerator : public SkImageGenerator { public: + /* + * The constructor will take a reference to the SkData. The + * destructor will unref() it. + */ + explicit SkDecodingImageGenerator(SkData* data); + + /* + * The SkData version of this constructor is preferred. If the + * stream has an underlying SkData (such as a SkMemoryStream) + * pass that in. + * + * This object will unref the stream when done. Since streams + * have internal state (position), the caller should not pass a + * shared stream in. Pass either a new duplicated stream in or + * transfer ownership of the stream. In the latter case, be sure + * that there are no other consumers of the stream who will + * modify the stream's position. This constructor asserts + * stream->unique(). + * + * For example: + * SkStreamRewindable* stream; + * ... + * SkImageGenerator* gen + * = SkNEW_ARGS(SkDecodingImageGenerator, + * (stream->duplicate())); + * ... + * SkDELETE(gen); + */ + explicit SkDecodingImageGenerator(SkStreamRewindable* stream); + virtual ~SkDecodingImageGenerator(); + virtual SkData* refEncodedData() SK_OVERRIDE; - // This implementaion of getInfo() always returns true. + virtual bool getInfo(SkImageInfo* info) SK_OVERRIDE; + virtual bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) SK_OVERRIDE; + /** - * These options will be passed on to the image decoder. The - * defaults are sensible. + * Install the SkData into the destination bitmap, using a new + * SkDiscardablePixelRef and a new SkDecodingImageGenerator. + * + * @param data Contains the encoded image data that will be used + * by the SkDecodingImageGenerator. Will be ref()ed. * - * @param fSampleSize If set to > 1, tells the decoder to return a - * smaller than original bitmap, sampling 1 pixel for - * every size pixels. e.g. if sample size is set to 3, - * then the returned bitmap will be 1/3 as wide and high, - * and will contain 1/9 as many pixels as the original. - * Note: this is a hint, and the codec may choose to - * ignore this, or only approximate the sample size. + * @param destination Upon success, this bitmap will be + * configured and have a pixelref installed. * - * @param fDitherImage Set to true if the the decoder should try to - * dither the resulting image when decoding to a smaller - * color-space. The default is true. + * @param factory If not NULL, this object will be used as a + * source of discardable memory when decoding. If NULL, then + * SkDiscardableMemory::Create() will be called. * - * @param fRequestedColorType If not given, then use whichever - * config the decoder wants. Else try to use this color - * type. If the decoder won't support this color type, - * SkDecodingImageGenerator::Create will return - * NULL. kIndex_8_SkColorType is not supported. + * @return true iff successful. */ - struct Options { - Options() - : fSampleSize(1) - , fDitherImage(true) - , fUseRequestedColorType(false) - , fRequestedColorType() { } - Options(int sampleSize, bool dither) - : fSampleSize(sampleSize) - , fDitherImage(dither) - , fUseRequestedColorType(false) - , fRequestedColorType() { } - Options(int sampleSize, bool dither, SkColorType colorType) - : fSampleSize(sampleSize) - , fDitherImage(dither) - , fUseRequestedColorType(true) - , fRequestedColorType(colorType) { } - const int fSampleSize; - const bool fDitherImage; - const bool fUseRequestedColorType; - const SkColorType fRequestedColorType; - }; - + static bool Install(SkData* data, SkBitmap* destination, + SkDiscardableMemory::Factory* factory = NULL); /** - * These two functions return a SkImageGenerator that calls into - * SkImageDecoder. They return NULL on failure. + * Install the stream into the destination bitmap, using a new + * SkDiscardablePixelRef and a new SkDecodingImageGenerator. * - * The SkData version of this function is preferred. If the stream - * has an underlying SkData (such as a SkMemoryStream) pass that in. + * The SkData version of this function is preferred. If the + * stream has an underlying SkData (such as a SkMemoryStream) + * pass that in. * - * This object will unref the stream when done or on failure. Since - * streams have internal state (position), the caller should not pass - * a shared stream in. Pass either a new duplicated stream in or - * transfer ownership of the stream. This factory asserts - * stream->unique(). + * @param stream The source of encoded data that will be passed + * to the decoder. The installed SkDecodingImageGenerator will + * unref the stream when done. If false is returned, this + * function will perform the unref. Since streams have internal + * state (position), the caller should not pass a shared stream + * in. Pass either a new duplicated stream in or transfer + * ownership of the stream. In the latter case, be sure that + * there are no other consumers of the stream who will modify the + * stream's position. This function will fail if + * (!stream->unique()). * - * For example: - * SkStreamRewindable* stream; - * ... - * SkImageGenerator* gen - * = SkDecodingImageGenerator::Create( - * stream->duplicate(), SkDecodingImageGenerator::Options()); - * ... - * SkDELETE(gen); + * @param destination Upon success, this bitmap will be + * configured and have a pixelref installed. * - * @param Options (see above) + * @param factory If not NULL, this object will be used as a + * source of discardable memory when decoding. If NULL, then + * SkDiscardableMemory::Create() will be called. * - * @return NULL on failure, a new SkImageGenerator on success. + * @return true iff successful. */ - static SkImageGenerator* Create(SkStreamRewindable* stream, - const Options& opt); - - /** - * @param data Contains the encoded image data that will be used by - * the SkDecodingImageGenerator. Will be ref()ed by the - * SkImageGenerator constructor and and unref()ed on deletion. - */ - static SkImageGenerator* Create(SkData* data, const Options& opt); + static bool Install(SkStreamRewindable* stream, SkBitmap* destination, + SkDiscardableMemory::Factory* factory = NULL); private: - SkData* fData; - SkStreamRewindable* fStream; - const SkImageInfo fInfo; - const int fSampleSize; - const bool fDitherImage; - const SkBitmap::Config fRequestedConfig; - SkDecodingImageGenerator(SkData* data, - SkStreamRewindable* stream, - const SkImageInfo& info, - int sampleSize, - bool ditherImage, - SkBitmap::Config requestedConfig); - static SkImageGenerator* Create(SkData*, SkStreamRewindable*, - const Options&); - typedef SkImageGenerator INHERITED; + SkData* fData; + SkStreamRewindable* fStream; + SkImageInfo fInfo; + bool fHasInfo; + bool fDoCopyTo; }; - -// // Example of most basic use case: -// -// bool install_data(SkData* data, SkBitmap* dst) { -// return SkInstallDiscardablePixelRef( -// SkDecodingImageGenerator::Create( -// data, SkDecodingImageGenerator::Options()), dst, NULL); -// } -// bool install_stream(SkStreamRewindable* stream, SkBitmap* dst) { -// return SkInstallDiscardablePixelRef( -// SkDecodingImageGenerator::Create( -// stream, SkDecodingImageGenerator::Options()), dst, NULL); -// } - #endif // SkDecodingImageGenerator_DEFINED |