michael@0: /* michael@0: * Copyright 2013 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef SkDecodingImageGenerator_DEFINED michael@0: #define SkDecodingImageGenerator_DEFINED michael@0: michael@0: #include "SkBitmap.h" michael@0: #include "SkImageGenerator.h" michael@0: michael@0: class SkData; michael@0: class SkStreamRewindable; michael@0: michael@0: /** michael@0: * An implementation of SkImageGenerator that calls into michael@0: * SkImageDecoder. michael@0: */ michael@0: class SkDecodingImageGenerator : public SkImageGenerator { michael@0: public: michael@0: virtual ~SkDecodingImageGenerator(); michael@0: virtual SkData* refEncodedData() SK_OVERRIDE; michael@0: // This implementaion of getInfo() always returns true. michael@0: virtual bool getInfo(SkImageInfo* info) SK_OVERRIDE; michael@0: virtual bool getPixels(const SkImageInfo& info, michael@0: void* pixels, michael@0: size_t rowBytes) SK_OVERRIDE; michael@0: /** michael@0: * These options will be passed on to the image decoder. The michael@0: * defaults are sensible. michael@0: * michael@0: * @param fSampleSize If set to > 1, tells the decoder to return a michael@0: * smaller than original bitmap, sampling 1 pixel for michael@0: * every size pixels. e.g. if sample size is set to 3, michael@0: * then the returned bitmap will be 1/3 as wide and high, michael@0: * and will contain 1/9 as many pixels as the original. michael@0: * Note: this is a hint, and the codec may choose to michael@0: * ignore this, or only approximate the sample size. michael@0: * michael@0: * @param fDitherImage Set to true if the the decoder should try to michael@0: * dither the resulting image when decoding to a smaller michael@0: * color-space. The default is true. michael@0: * michael@0: * @param fRequestedColorType If not given, then use whichever michael@0: * config the decoder wants. Else try to use this color michael@0: * type. If the decoder won't support this color type, michael@0: * SkDecodingImageGenerator::Create will return michael@0: * NULL. kIndex_8_SkColorType is not supported. michael@0: */ michael@0: struct Options { michael@0: Options() michael@0: : fSampleSize(1) michael@0: , fDitherImage(true) michael@0: , fUseRequestedColorType(false) michael@0: , fRequestedColorType() { } michael@0: Options(int sampleSize, bool dither) michael@0: : fSampleSize(sampleSize) michael@0: , fDitherImage(dither) michael@0: , fUseRequestedColorType(false) michael@0: , fRequestedColorType() { } michael@0: Options(int sampleSize, bool dither, SkColorType colorType) michael@0: : fSampleSize(sampleSize) michael@0: , fDitherImage(dither) michael@0: , fUseRequestedColorType(true) michael@0: , fRequestedColorType(colorType) { } michael@0: const int fSampleSize; michael@0: const bool fDitherImage; michael@0: const bool fUseRequestedColorType; michael@0: const SkColorType fRequestedColorType; michael@0: }; michael@0: michael@0: /** michael@0: * These two functions return a SkImageGenerator that calls into michael@0: * SkImageDecoder. They return NULL on failure. michael@0: * michael@0: * The SkData version of this function is preferred. If the stream michael@0: * has an underlying SkData (such as a SkMemoryStream) pass that in. michael@0: * michael@0: * This object will unref the stream when done or on failure. Since michael@0: * streams have internal state (position), the caller should not pass michael@0: * a shared stream in. Pass either a new duplicated stream in or michael@0: * transfer ownership of the stream. This factory asserts michael@0: * stream->unique(). michael@0: * michael@0: * For example: michael@0: * SkStreamRewindable* stream; michael@0: * ... michael@0: * SkImageGenerator* gen michael@0: * = SkDecodingImageGenerator::Create( michael@0: * stream->duplicate(), SkDecodingImageGenerator::Options()); michael@0: * ... michael@0: * SkDELETE(gen); michael@0: * michael@0: * @param Options (see above) michael@0: * michael@0: * @return NULL on failure, a new SkImageGenerator on success. michael@0: */ michael@0: static SkImageGenerator* Create(SkStreamRewindable* stream, michael@0: const Options& opt); michael@0: michael@0: /** michael@0: * @param data Contains the encoded image data that will be used by michael@0: * the SkDecodingImageGenerator. Will be ref()ed by the michael@0: * SkImageGenerator constructor and and unref()ed on deletion. michael@0: */ michael@0: static SkImageGenerator* Create(SkData* data, const Options& opt); michael@0: michael@0: private: michael@0: SkData* fData; michael@0: SkStreamRewindable* fStream; michael@0: const SkImageInfo fInfo; michael@0: const int fSampleSize; michael@0: const bool fDitherImage; michael@0: michael@0: SkDecodingImageGenerator(SkData* data, michael@0: SkStreamRewindable* stream, michael@0: const SkImageInfo& info, michael@0: int sampleSize, michael@0: bool ditherImage); michael@0: static SkImageGenerator* Create(SkData*, SkStreamRewindable*, michael@0: const Options&); michael@0: typedef SkImageGenerator INHERITED; michael@0: }; michael@0: michael@0: // // Example of most basic use case: michael@0: // michael@0: // bool install_data(SkData* data, SkBitmap* dst) { michael@0: // return SkInstallDiscardablePixelRef( michael@0: // SkDecodingImageGenerator::Create( michael@0: // data, SkDecodingImageGenerator::Options()), dst, NULL); michael@0: // } michael@0: // bool install_stream(SkStreamRewindable* stream, SkBitmap* dst) { michael@0: // return SkInstallDiscardablePixelRef( michael@0: // SkDecodingImageGenerator::Create( michael@0: // stream, SkDecodingImageGenerator::Options()), dst, NULL); michael@0: // } michael@0: michael@0: #endif // SkDecodingImageGenerator_DEFINED