| Index: include/codec/SkScanlineDecoder.h
|
| diff --git a/include/codec/SkScanlineDecoder.h b/include/codec/SkScanlineDecoder.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..00d586aaa4fa3d800d1fade4c7950ed26a2e1015
|
| --- /dev/null
|
| +++ b/include/codec/SkScanlineDecoder.h
|
| @@ -0,0 +1,120 @@
|
| +/*
|
| + * Copyright 2015 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkCodec.h"
|
| +#include "SkImageGenerator.h"
|
| +#include "SkImageInfo.h"
|
| +
|
| +class SkStream;
|
| +
|
| +class SkScanlineDecoder : public SkNoncopyable {
|
| +public:
|
| + // Note for implementations: An SkScanlineDecoder should be deleted
|
| + // *before* its associated SkCodec, in case the order matters.
|
| + virtual ~SkScanlineDecoder() {}
|
| +
|
| + /**
|
| + * Write the next scanline into dst.
|
| + *
|
| + * @param dst Must be non-null, and large enough to hold a scanline based
|
| + * on the info used to create this object.
|
| + * @return kSuccess or error code explaining failure.
|
| + */
|
| + SkImageGenerator::Result getNextScanline(void* dst) {
|
| + return this->onGetNextScanline(dst);
|
| + }
|
| +
|
| + /**
|
| + * Write the next countLines scanlines into dst.
|
| + *
|
| + * @param dst Must be non-null, and large enough to hold countLines
|
| + * scanlines based on rowBytes.
|
| + * @param countLines Number of lines to write.
|
| + * @param rowBytes Number of bytes per row.
|
| + */
|
| + SkImageGenerator::Result getScanlines(void* dst, int countLines, size_t rowBytes) {
|
| + // Should we keep track of how many scanlines have been read, at
|
| + // least in debug mode? Then we can make an even smarter check
|
| + // regarding countLines.
|
| + if (rowBytes < fDstInfo.minRowBytes() || countLines < 0
|
| + || countLines > fDstInfo.height()) {
|
| + return SkCodec::kInvalidParameters;
|
| + }
|
| + return this->onGetScanlines(dst, countLines, rowBytes);
|
| + }
|
| +
|
| + /**
|
| + * Skip count scanlines.
|
| + *
|
| + * The default version just calls onGetScanline and discards the dst.
|
| + */
|
| + SkImageGenerator::Result skipScanlines(int count) {
|
| + return this->onSkipScanlines(count);
|
| + }
|
| +
|
| + /**
|
| + * Call this function after reading/skipping all scanlines.
|
| + */
|
| + SkImageGenerator::Result finish() {
|
| + return this->onFinish();
|
| + }
|
| +
|
| + /**
|
| + * 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.
|
| + */
|
| + bool reallyHasAlpha() const {
|
| + return this->onReallyHasAlpha();
|
| + }
|
| +
|
| +protected:
|
| + SkScanlineDecoder(const SkImageInfo& original, const SkImageInfo& requested)
|
| + : fSrcInfo(original)
|
| + , fDstInfo(requested) {}
|
| +
|
| + virtual bool onReallyHasAlpha() const { return false; }
|
| +
|
| +private:
|
| + // FIXME: Is fSrcInfo needed for subsetting? Not needed so far...
|
| + const SkImageInfo fSrcInfo;
|
| + const SkImageInfo fDstInfo;
|
| +
|
| + virtual SkImageGenerator::Result onGetNextScanline(void* dst) = 0;
|
| +
|
| + // Naive default version just calls onGetNextScanline on temp memory.
|
| + virtual SkImageGenerator::Result onSkipScanlines(int count) {
|
| + SkAutoMalloc storage(fDstInfo.minRowBytes());
|
| + for (int i = 0; i < count; ++i) {
|
| + SkImageGenerator::Result res = this->onGetNextScanline(storage.get());
|
| + if (res != SkImageGenerator::kSuccess) {
|
| + return res;
|
| + }
|
| + }
|
| + return SkCodec::kSuccess;
|
| + }
|
| +
|
| + // Naive default version just calls onGetNextScanline
|
| + virtual SkImageGenerator::Result onGetScanlines(void* dst, int countLines, size_t rowBytes) {
|
| + void* dstRow = dst;
|
| + for (int i = 0; i < countLines; ++i) {
|
| + const SkImageGenerator::Result result = this->onGetNextScanline(dstRow);
|
| + if (result != SkCodec::kSuccess) {
|
| + return result;
|
| + }
|
| + dstRow = SkTAddOffset<void*>(dstRow, rowBytes);
|
| + }
|
| + return SkCodec::kSuccess;
|
| + }
|
| +
|
| + virtual SkImageGenerator::Result onFinish() {
|
| + // Return success by default, since this may not be necessary for all codecs.
|
| + return SkImageGenerator::kSuccess;
|
| + }
|
| +};
|
|
|