Chromium Code Reviews| Index: src/codec/SkIcoCodec.cpp |
| diff --git a/src/codec/SkIcoCodec.cpp b/src/codec/SkIcoCodec.cpp |
| index 0e81b72407218778b9d469e72b95941149b83309..abcf4dc7d2af88e80c7e690adf37c81bd92f7e54 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,82 @@ 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); |
| + switch (embeddedCodec->startIncrementalDecode(dstInfo, |
| + pixels, rowBytes, &options, colorTable, colorCount)) { |
| + case kSuccess: |
| + fCurrIncrementalCodec = embeddedCodec; |
| + fCurrScanlineCodec = nullptr; |
| + return kSuccess; |
| + case kUnimplemented: |
| + // FIXME: embeddedCodec is a BMP. If scanline decoding would work, |
| + // return kUnimplemented so that SkSampledCodec will fall through |
| + // to use the scanline decoder. |
| + // Note that calling startScanlineDecode will require an extra |
| + // rewind. The embedded codec has an SkMemoryStream, which is |
| + // cheap to rewind, though it will do extra work re-reading the |
| + // header. |
| + // Also note that we pass nullptr for Options. This is because |
| + // Options that are valid for incremental decoding may not be |
| + // valid for scanline decoding. |
| + // Once BMP supports incremental decoding this workaround can go |
| + // away. |
| + if (embeddedCodec->startScanlineDecode(dstInfo, nullptr, |
|
scroggo
2016/05/26 16:10:58
In patch set 9, I just called dimensionsSupported(
msarett
2016/05/26 16:45:22
Acknowledged.
|
| + colorTable, colorCount) == kSuccess) { |
| + return kUnimplemented; |
| + } |
| + // Move on to the next embedded codec. |
| + break; |
| + default: |
| + break; |
| + } |
| + |
| + index++; |
| + } |
| + |
| + 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; |
| } |