Index: src/codec/SkIcoCodec.cpp |
diff --git a/src/codec/SkIcoCodec.cpp b/src/codec/SkIcoCodec.cpp |
index 0e81b72407218778b9d469e72b95941149b83309..97f4846642e49823701d7d7034937ce6942f39ed 100644 |
--- a/src/codec/SkIcoCodec.cpp |
+++ b/src/codec/SkIcoCodec.cpp |
@@ -186,6 +186,7 @@ SkIcoCodec::SkIcoCodec(int width, int height, const SkEncodedInfo& info, |
: INHERITED(width, height, info, nullptr) |
, fEmbeddedCodecs(codecs) |
, fCurrScanlineCodec(nullptr) |
+ , fCurrIncrementalCodec(nullptr) |
{} |
/* |
@@ -289,6 +290,7 @@ SkCodec::Result SkIcoCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, |
result = embeddedCodec->startScanlineDecode(dstInfo, &options, colorTable, colorCount); |
if (kSuccess == result) { |
fCurrScanlineCodec = embeddedCodec; |
+ fCurrIncrementalCodec = nullptr; |
return result; |
} |
@@ -309,13 +311,64 @@ bool SkIcoCodec::onSkipScanlines(int count) { |
return fCurrScanlineCodec->skipScanlines(count); |
} |
+SkCodec::Result SkIcoCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo, |
+ void* pixels, size_t rowBytes, const SkCodec::Options& options, |
+ SkPMColor* colorTable, int* colorCount) { |
+ int index = 0; |
+ while (true) { |
+ index = this->chooseCodec(dstInfo.dimensions(), index); |
+ if (index < 0) { |
+ break; |
+ } |
+ |
+ SkCodec* embeddedCodec = fEmbeddedCodecs->operator[](index); |
+ if (SkCodec::kSuccess == embeddedCodec->startIncrementalDecode(dstInfo, |
+ pixels, rowBytes, &options, colorTable, colorCount)) { |
+ fCurrIncrementalCodec = embeddedCodec; |
+ fCurrScanlineCodec = nullptr; |
+ return SkCodec::kSuccess; |
+ } |
+ |
+ index++; |
+ } |
+ |
+ // FIXME: As long as PNG only supports incremental decode and BMP only |
+ // supports scanline decoding, which image the client gets depends on |
+ // which entry point they use, meaning getScaledDimensions could return |
+ // a set of dimensions that is only supported by one or the other. |
+ SkCodecPrintf("Error: No matching candidate image in ico.\n"); |
+ return kInvalidScale; |
+} |
+ |
+SkCodec::Result SkIcoCodec::onIncrementalDecode(int* rowsDecoded) { |
+ SkASSERT(fCurrIncrementalCodec); |
+ return fCurrIncrementalCodec->incrementalDecode(rowsDecoded); |
+} |
+ |
SkCodec::SkScanlineOrder SkIcoCodec::onGetScanlineOrder() const { |
// FIXME: This function will possibly return the wrong value if it is called |
- // before startScanlineDecode(). |
- return fCurrScanlineCodec ? fCurrScanlineCodec->getScanlineOrder() : |
- INHERITED::onGetScanlineOrder(); |
+ // before startScanlineDecode()/startIncrementalDecode(). |
+ if (fCurrScanlineCodec) { |
+ SkASSERT(!fCurrIncrementalCodec); |
+ return fCurrScanlineCodec->getScanlineOrder(); |
+ } |
+ |
+ if (fCurrIncrementalCodec) { |
+ return fCurrIncrementalCodec->getScanlineOrder(); |
+ } |
+ |
+ return INHERITED::onGetScanlineOrder(); |
} |
SkSampler* SkIcoCodec::getSampler(bool createIfNecessary) { |
- return fCurrScanlineCodec ? fCurrScanlineCodec->getSampler(createIfNecessary) : nullptr; |
+ if (fCurrScanlineCodec) { |
+ SkASSERT(!fCurrIncrementalCodec); |
+ return fCurrScanlineCodec->getSampler(createIfNecessary); |
+ } |
+ |
+ if (fCurrIncrementalCodec) { |
+ return fCurrIncrementalCodec->getSampler(createIfNecessary); |
+ } |
+ |
+ return nullptr; |
} |