diff options
author | scroggo <scroggo@chromium.org> | 2015-07-09 08:16:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-09 08:16:03 -0700 |
commit | eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5 (patch) | |
tree | 215b749275afb908430c31af335b82cd5ce0fa11 /include/codec | |
parent | 72394ef87c2ea023d00d79cd65013e1688ea30d3 (diff) |
SkCodec no longer inherits from SkImageGenerator.
SkImageGenerator makes some assumptions that are not necessarily valid
for SkCodec. For example, SkCodec does not assume that it can always be
rewound.
We also have an ongoing question of what an SkCodec should report as
its default settings (i.e. the return from getInfo). It makes sense for
an SkCodec to report that its pixels are unpremultiplied, if that is
the case for the underlying data, but if a client of SkImageGenerator
uses the default settings (as many do), they will receive
unpremultiplied pixels which cannot (currently) be drawn with Skia. We
may ultimately decide to revisit SkCodec reporting an SkImageInfo, but
I have left it unchanged for now.
Import features of SkImageGenerator used by SkCodec into SkCodec.
I have left SkImageGenerator unchanged for now, but it no longer needs
Result or Options. This will require changes to Chromium.
Manually handle the lifetime of fScanlineDecoder, so SkScanlineDecoder.h
can include SkCodec.h (where Result is), and SkCodec.h does not need
to include it (to delete fScanlineDecoder).
In many places, make the following simple changes:
- Now include SkScanlineDecoder.h, which is no longer included by
SkCodec.h
- Use the enums in SkCodec, rather than SkImageGenerator
- Stop including SkImageGenerator.h where no longer needed
Review URL: https://codereview.chromium.org/1220733013
Diffstat (limited to 'include/codec')
-rw-r--r-- | include/codec/SkCodec.h | 143 | ||||
-rw-r--r-- | include/codec/SkScanlineDecoder.h | 18 |
2 files changed, 140 insertions, 21 deletions
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h index e462be2e7d..54bd6ff5d6 100644 --- a/include/codec/SkCodec.h +++ b/include/codec/SkCodec.h @@ -8,21 +8,21 @@ #ifndef SkCodec_DEFINED #define SkCodec_DEFINED +#include "SkColor.h" #include "SkEncodedFormat.h" -#include "SkImageGenerator.h" #include "SkImageInfo.h" -#include "SkScanlineDecoder.h" #include "SkSize.h" #include "SkStream.h" #include "SkTemplates.h" #include "SkTypes.h" class SkData; +class SkScanlineDecoder; /** * Abstraction layer directly on top of an image codec. */ -class SkCodec : public SkImageGenerator { +class SkCodec : SkNoncopyable { public: /** * If this stream represents an encoded image that we know how to decode, @@ -41,12 +41,17 @@ public: */ static SkCodec* NewFromData(SkData*); + virtual ~SkCodec(); + + /** + * Return the ImageInfo associated with this codec. + */ + const SkImageInfo& getInfo() const { return fInfo; } + /** * Return a size that approximately supports the desired scale factor. * The codec may not be able to scale efficiently to the exact scale * factor requested, so return a size that approximates that scale. - * - * FIXME: Move to SkImageGenerator? */ SkISize getScaledDimensions(float desiredScale) const { return this->onGetScaledDimensions(desiredScale); @@ -58,6 +63,115 @@ public: SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } /** + * Used to describe the result of a call to getPixels(). + * + * Result is the union of possible results from subclasses. + */ + enum Result { + /** + * General return value for success. + */ + kSuccess, + /** + * The input is incomplete. A partial image was generated. + */ + kIncompleteInput, + /** + * The generator cannot convert to match the request, ignoring + * dimensions. + */ + kInvalidConversion, + /** + * The generator cannot scale to requested size. + */ + kInvalidScale, + /** + * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes + * too small, etc. + */ + kInvalidParameters, + /** + * The input did not contain a valid image. + */ + kInvalidInput, + /** + * Fulfilling this request requires rewinding the input, which is not + * supported for this input. + */ + kCouldNotRewind, + /** + * This method is not implemented by this generator. + */ + kUnimplemented, + }; + + /** + * Whether or not the memory passed to getPixels is zero initialized. + */ + enum ZeroInitialized { + /** + * The memory passed to getPixels is zero initialized. The SkCodec + * may take advantage of this by skipping writing zeroes. + */ + kYes_ZeroInitialized, + /** + * The memory passed to getPixels has not been initialized to zero, + * so the SkCodec must write all zeroes to memory. + * + * This is the default. It will be used if no Options struct is used. + */ + kNo_ZeroInitialized, + }; + + /** + * Additional options to pass to getPixels. + */ + struct Options { + Options() + : fZeroInitialized(kNo_ZeroInitialized) {} + + ZeroInitialized fZeroInitialized; + }; + + /** + * Decode into the given pixels, a block of memory of size at + * least (info.fHeight - 1) * rowBytes + (info.fWidth * + * bytesPerPixel) + * + * Repeated calls to this function should give the same results, + * allowing the PixelRef to be immutable. + * + * @param info A description of the format (config, size) + * expected by the caller. This can simply be identical + * to the info returned by getInfo(). + * + * This contract also allows the caller to specify + * different output-configs, which the implementation can + * decide to support or not. + * + * A size that does not match getInfo() implies a request + * to scale. If the generator cannot perform this scale, + * it will return kInvalidScale. + * + * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 + * SkPMColor values in ctable. On success the generator must copy N colors into that storage, + * (where N is the logical number of table entries) and set ctableCount to N. + * + * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount + * is not null, it will be set to 0. + * + * @return Result kSuccess, or another value explaining the type of failure. + */ + Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*, + SkPMColor ctable[], int* ctableCount); + + /** + * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and + * uses the default Options. + */ + Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); + + /** * Return an object which can be used to decode individual scanlines. * * This object is owned by the SkCodec, which will handle its lifetime. The @@ -118,6 +232,10 @@ protected: virtual SkEncodedFormat onGetEncodedFormat() const = 0; + virtual Result onGetPixels(const SkImageInfo& info, + void* pixels, size_t rowBytes, const Options&, + SkPMColor ctable[], int* ctableCount) = 0; + /** * Override if your codec supports scanline decoding. * @@ -182,7 +300,7 @@ protected: * created a new scanline decoder. */ SkScanlineDecoder* scanlineDecoder() { - return fScanlineDecoder.get(); + return fScanlineDecoder; } /** @@ -191,14 +309,15 @@ protected: * in the destructor of the subclass. */ SkScanlineDecoder* detachScanlineDecoder() { - return fScanlineDecoder.detach(); + SkScanlineDecoder* scanlineDecoder = fScanlineDecoder; + fScanlineDecoder = NULL; + return scanlineDecoder; } private: - SkAutoTDelete<SkStream> fStream; - bool fNeedsRewind; - SkAutoTDelete<SkScanlineDecoder> fScanlineDecoder; - - typedef SkImageGenerator INHERITED; + const SkImageInfo fInfo; + SkAutoTDelete<SkStream> fStream; + bool fNeedsRewind; + SkScanlineDecoder* fScanlineDecoder; }; #endif // SkCodec_DEFINED diff --git a/include/codec/SkScanlineDecoder.h b/include/codec/SkScanlineDecoder.h index eac31ef40f..942c1b986f 100644 --- a/include/codec/SkScanlineDecoder.h +++ b/include/codec/SkScanlineDecoder.h @@ -9,8 +9,8 @@ #define SkScanlineDecoder_DEFINED #include "SkTypes.h" +#include "SkCodec.h" #include "SkTemplates.h" -#include "SkImageGenerator.h" #include "SkImageInfo.h" class SkScanlineDecoder : public SkNoncopyable { @@ -40,12 +40,12 @@ public: * @param rowBytes Number of bytes per row. Must be large enough to hold * a scanline based on the SkImageInfo used to create this object. */ - SkImageGenerator::Result getScanlines(void* dst, int countLines, size_t rowBytes) { + SkCodec::Result getScanlines(void* dst, int countLines, size_t rowBytes) { if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0 || fCurrScanline + countLines > fDstInfo.height()) { - return SkImageGenerator::kInvalidParameters; + return SkCodec::kInvalidParameters; } - const SkImageGenerator::Result result = this->onGetScanlines(dst, countLines, rowBytes); + const SkCodec::Result result = this->onGetScanlines(dst, countLines, rowBytes); fCurrScanline += countLines; return result; } @@ -58,14 +58,14 @@ public: * will make reallyHasAlpha return true, when it could have returned * false. */ - SkImageGenerator::Result skipScanlines(int countLines) { + SkCodec::Result skipScanlines(int countLines) { if (fCurrScanline + countLines > fDstInfo.height()) { // Arguably, we could just skip the scanlines which are remaining, // and return kSuccess. We choose to return invalid so the client // can catch their bug. - return SkImageGenerator::kInvalidParameters; + return SkCodec::kInvalidParameters; } - const SkImageGenerator::Result result = this->onSkipScanlines(countLines); + const SkCodec::Result result = this->onSkipScanlines(countLines); fCurrScanline += countLines; return result; } @@ -96,7 +96,7 @@ private: int fCurrScanline; // Naive default version just calls onGetScanlines on temp memory. - virtual SkImageGenerator::Result onSkipScanlines(int countLines) { + virtual SkCodec::Result onSkipScanlines(int countLines) { SkAutoMalloc storage(fDstInfo.minRowBytes()); // Note that we pass 0 to rowBytes so we continue to use the same memory. // Also note that while getScanlines checks that rowBytes is big enough, @@ -106,7 +106,7 @@ private: return this->onGetScanlines(storage.get(), countLines, 0); } - virtual SkImageGenerator::Result onGetScanlines(void* dst, int countLines, + virtual SkCodec::Result onGetScanlines(void* dst, int countLines, size_t rowBytes) = 0; }; |