Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: include/codec/SkScanlineDecoder.h

Issue 1010903003: Add scanline decoding to SkCodec. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Cleanups Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
+ }
+};

Powered by Google App Engine
This is Rietveld 408576698