| Index: include/codec/SkScanlineDecoder.h
|
| diff --git a/include/codec/SkScanlineDecoder.h b/include/codec/SkScanlineDecoder.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c047223d7cb27a1b85e0205920919fccc3d2dcb5
|
| --- /dev/null
|
| +++ b/include/codec/SkScanlineDecoder.h
|
| @@ -0,0 +1,115 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#ifndef SkScanlineDecoder_DEFINED
|
| +#define SkScanlineDecoder_DEFINED
|
| +
|
| +#include "SkTypes.h"
|
| +#include "SkTemplates.h"
|
| +#include "SkImageGenerator.h"
|
| +#include "SkImageInfo.h"
|
| +
|
| +class SkScanlineDecoder : public SkNoncopyable {
|
| +public:
|
| + // Note for implementations: An SkScanlineDecoder will be deleted by (and
|
| + // therefore *before*) its associated SkCodec, in case the order matters.
|
| + virtual ~SkScanlineDecoder() {}
|
| +
|
| + /**
|
| + * Write the next countLines scanlines into dst.
|
| + *
|
| + * @param dst Must be non-null, and large enough to hold countLines
|
| + * scanlines of size rowBytes.
|
| + * @param countLines Number of lines to write.
|
| + * @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) {
|
| + if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
|
| + || fCurrScanline + countLines > fDstInfo.height()) {
|
| + return SkImageGenerator::kInvalidParameters;
|
| + }
|
| + const SkImageGenerator::Result result = this->onGetScanlines(dst, countLines, rowBytes);
|
| + this->checkForFinish(countLines);
|
| + return result;
|
| + }
|
| +
|
| + /**
|
| + * Skip count scanlines.
|
| + *
|
| + * The default version just calls onGetScanlines and discards the dst.
|
| + * NOTE: If skipped lines are the only lines with alpha, this default
|
| + * will make reallyHasAlpha return true, when it could have returned
|
| + * false.
|
| + */
|
| + SkImageGenerator::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;
|
| + }
|
| + const SkImageGenerator::Result result = this->onSkipScanlines(countLines);
|
| + this->checkForFinish(countLines);
|
| + return result;
|
| + }
|
| +
|
| + /**
|
| + * Some images may initially report that they have alpha due to the format
|
| + * of the encoded data, but then never use any colors which have alpha
|
| + * less than 100%. This function can be called *after* decoding to
|
| + * determine if such an image truly had alpha. Calling it before decoding
|
| + * is undefined.
|
| + * FIXME: see skbug.com/3582.
|
| + */
|
| + bool reallyHasAlpha() const {
|
| + return this->onReallyHasAlpha();
|
| + }
|
| +
|
| +protected:
|
| + SkScanlineDecoder(const SkImageInfo& requested)
|
| + : fDstInfo(requested)
|
| + , fCurrScanline(0) {}
|
| +
|
| + virtual bool onReallyHasAlpha() const { return false; }
|
| +
|
| +private:
|
| + const SkImageInfo fDstInfo;
|
| + int fCurrScanline;
|
| +
|
| + // Naive default version just calls onGetScanlines on temp memory.
|
| + virtual SkImageGenerator::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,
|
| + // onGetScanlines bypasses that check.
|
| + // Calling the virtual method also means we do not double count
|
| + // countLines.
|
| + return this->onGetScanlines(storage.get(), countLines, 0);
|
| + }
|
| +
|
| + virtual SkImageGenerator::Result onGetScanlines(void* dst, int countLines,
|
| + size_t rowBytes) = 0;
|
| +
|
| + /**
|
| + * Called after any set of scanlines read/skipped. Updates fCurrScanline,
|
| + * and, if we are at the end, calls onFinish().
|
| + */
|
| + void checkForFinish(int countLines) {
|
| + fCurrScanline += countLines;
|
| + if (fCurrScanline >= fDstInfo.height()) {
|
| + this->onFinish();
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * This function will be called after reading/skipping all scanlines to do
|
| + * any necessary cleanups.
|
| + */
|
| + virtual void onFinish() {} // Default does nothing.
|
| +};
|
| +#endif // SkScanlineDecoder_DEFINED
|
|
|