Index: include/codec/SkScanlineDecoder.h |
diff --git a/include/codec/SkScanlineDecoder.h b/include/codec/SkScanlineDecoder.h |
index 79469739817ba8abd47239173c213ab284fbfa23..f1083ac0fd0b76d160d1f07bb7fdbbd513b6bebb 100644 |
--- a/include/codec/SkScanlineDecoder.h |
+++ b/include/codec/SkScanlineDecoder.h |
@@ -153,21 +153,84 @@ public: |
SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } |
/** |
- * returns true if the image must be scaled, in the y direction, after reading, not during. |
- * To scale afterwards, we first decode every line and then sample the lines we want afterwards. |
- * An example is interlaced pngs, where calling getScanlines once (regardless of the count |
- * used) needs to read the entire image, therefore it is inefficient to call |
- * getScanlines more than once. Instead, it should only ever be called with all the |
- * rows needed. |
- */ |
- bool requiresPostYSampling() { |
- return this->onRequiresPostYSampling(); |
+ * The order in which rows are output from the scanline decoder is not the |
+ * same for all variations of all image types. This explains the possible |
+ * output row orderings. |
+ */ |
+ enum SkScanlineOrder { |
+ /* |
+ * By far the most common, this indicates that the image can be decoded |
+ * reliably using the scanline decoder, and that rows will be output in |
+ * the logical order. |
+ */ |
+ kTopDown_SkScanlineOrder, |
+ |
+ /* |
+ * This indicates that the scanline decoder reliably outputs rows, but |
+ * they will be returned in reverse order. If the scanline format is |
+ * kBottomUp, the getY() API can be used to determine the actual |
+ * y-coordinates of the output rows, but the client is not forced to |
+ * take advantage of this, given that it's not too tough to keep track |
+ * independently. |
+ * |
+ * For this scanline ordering, it may be advisable to get and skip |
scroggo
2015/08/28 13:28:47
Why do they need to skip scanlines one at a time?
msarett
2015/08/28 14:05:57
They can skip more, but it's a bit a risky, they n
|
+ * scanlines one at a time. If multiple scanlines are requested, we |
+ * will in fact invert them to be top-down in the provided memory. |
+ * However, this capability should be used carefully, as it can lead |
+ * to strange behavior if the client requests multiple chunks of |
+ * scanlines where count > 1. |
scroggo
2015/08/28 13:28:47
It seems like we *could* make this work, in at lea
msarett
2015/08/28 14:05:57
So we do invert the rows if they ask for more than
|
+ * |
+ * Upside down bmps are an example. |
+ */ |
+ kBottomUp_SkScanlineOrder, |
+ |
+ /* |
+ * This indicates that the scanline decoder reliably outputs rows, but |
+ * they will not be in logical order. If the scanline format is |
+ * kOutOfOrder, the getY() API should be used to determine the actual |
+ * y-coordinates of the output rows. |
+ * |
+ * For this scanline ordering, it is advisable to get and skip |
+ * scanlines one at a time. |
+ * |
+ * Interlaced gifs are an example. |
+ */ |
+ kOutOfOrder_SkScanlineOrder, |
+ |
+ /* |
+ * Indicates that the entire image must be decoded in order to output |
+ * any amount of scanlines. In this case, it is a REALLY BAD IDEA to |
+ * request scanlines 1-by-1 or in small chunks. The client should |
+ * determine which scanlines are needed and ask for all of them in |
+ * a single call to getScanlines(). |
+ * |
+ * Interlaced pngs are an example. |
+ */ |
+ kNone_SkScanlineOrder, |
+ }; |
+ |
+ /** |
+ * An enum representing the order in which scanlines will be returned by |
+ * the scanline decoder. |
+ */ |
+ SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); } |
+ |
+ /** |
+ * Returns the y-coordinate of the next row to be returned by the scanline |
+ * decoder. This will be overridden in the case of |
+ * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of |
+ * kNone_SkScanlineOrder. |
+ */ |
+ int getY() const { |
+ SkASSERT(kNone_SkScanlineOrder != this->getScanlineOrder()); |
+ return this->onGetY(); |
} |
protected: |
SkScanlineDecoder(const SkImageInfo& srcInfo) |
: fSrcInfo(srcInfo) |
, fDstInfo() |
+ , fOptions() |
, fCurrScanline(0) {} |
virtual SkISize onGetScaledDimensions(float /* desiredScale */) { |
@@ -180,16 +243,23 @@ protected: |
virtual bool onReallyHasAlpha() const { return false; } |
/** |
- * returns true if the image type is hard to sample and must be scaled after reading, not during |
- * An example is interlaced pngs, where the entire image must be read for each decode |
+ * Most images types will be kTopDown and will not need to override this function. |
*/ |
- virtual bool onRequiresPostYSampling() { return false; } |
+ virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; } |
+ |
+ /** |
+ * Most images will be kTopDown and will not need to override this function. |
+ */ |
+ virtual int onGetY() const { return fCurrScanline; } |
const SkImageInfo& dstInfo() const { return fDstInfo; } |
+ const SkCodec::Options& options() const { return fOptions; } |
+ |
private: |
const SkImageInfo fSrcInfo; |
SkImageInfo fDstInfo; |
+ SkCodec::Options fOptions; |
int fCurrScanline; |
virtual SkCodec::Result onStart(const SkImageInfo& dstInfo, |