Chromium Code Reviews| Index: src/codec/SkCodec_libpng.cpp |
| diff --git a/src/codec/SkCodec_libpng.cpp b/src/codec/SkCodec_libpng.cpp |
| index 9f9c110cc68bcc06ed9d38c7c272cdecea42341a..b80287c4205ed7ea3211a8fcf143d354749f2141 100644 |
| --- a/src/codec/SkCodec_libpng.cpp |
| +++ b/src/codec/SkCodec_libpng.cpp |
| @@ -594,13 +594,40 @@ SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* |
| class SkPngScanlineDecoder : public SkScanlineDecoder { |
| public: |
| - SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) |
| - : INHERITED(dstInfo) |
| + SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) |
| + : INHERITED(srcInfo) |
| , fCodec(codec) |
| , fHasAlpha(false) |
| + {} |
| + |
| + SkCodec::Result onReset(const SkImageInfo& dstInfo, |
|
emmaleer
2015/07/29 22:40:48
Is reset required to be called, for the ScanlineDe
msarett
2015/07/30 12:58:46
NewSDFromStream sets an SkImageInfo with the recom
scroggo
2015/07/30 15:11:35
Yes. I considered making reset unnecessary, but if
msarett
2015/07/30 15:37:55
Did you have thoughts on having both a start() and
emmaleer
2015/07/30 15:49:48
I think calling reset to start is less intuitive t
scroggo
2015/07/30 16:48:48
FWIW, I do not think setInfo is a good name. It se
|
| + const SkCodec::Options& options, |
| + SkPMColor ctable[], int* ctableCount) override |
| { |
| + if (!fCodec->handleRewind()) { |
| + return SkCodec::kCouldNotRewind; |
| + } |
| + |
| + if (!conversion_possible(dstInfo, this->getInfo())) { |
| + return SkCodec::kInvalidConversion; |
| + } |
| + |
| + // Check to see if scaling was requested. |
| + if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| + return SkCodec::kInvalidScale; |
| + } |
| + |
| + const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, options, ctable, |
| + ctableCount); |
| + if (result != SkCodec::kSuccess) { |
| + return result; |
| + } |
| + |
| + fHasAlpha = false; |
| fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcConfig)); |
| fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
| + |
| + return SkCodec::kSuccess; |
| } |
| SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) override { |
| @@ -648,16 +675,44 @@ private: |
| class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { |
| public: |
| - SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) |
| - : INHERITED(dstInfo) |
| + SkPngInterlacedScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) |
| + : INHERITED(srcInfo) |
| , fCodec(codec) |
| , fHasAlpha(false) |
| , fCurrentRow(0) |
| - , fHeight(dstInfo.height()) |
| + , fHeight(srcInfo.height()) |
| + {} |
| + |
| + SkCodec::Result onReset(const SkImageInfo& dstInfo, |
| + const SkCodec::Options& options, |
| + SkPMColor ctable[], int* ctableCount) override |
| { |
| + // No need to handleRewind here, since it will be done in each call to |
| + // getScanlines. |
| + |
| + if (!conversion_possible(dstInfo, this->getInfo())) { |
| + return SkCodec::kInvalidConversion; |
| + } |
| + |
| + // Check to see if scaling was requested. |
| + if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| + return SkCodec::kInvalidScale; |
| + } |
| + |
| + const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, options, ctable, |
| + ctableCount); |
| + if (result != SkCodec::kSuccess) { |
| + return result; |
| + } |
| + |
| + fHasAlpha = false; |
| + fCurrentRow = 0; |
| + fHeight = dstInfo.height(); |
| fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcConfig); |
| fGarbageRow.reset(fSrcRowBytes); |
| fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
| + |
| + return SkCodec::kSuccess; |
| } |
| SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) override { |
| @@ -722,38 +777,21 @@ private: |
| typedef SkScanlineDecoder INHERITED; |
| }; |
| - |
| -SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, |
| - const Options& options, SkPMColor ctable[], int* ctableCount) { |
| - if (!conversion_possible(dstInfo, this->getInfo())) { |
| - SkCodecPrintf("no conversion possible\n"); |
| - return NULL; |
| - } |
| - // Check to see if scaling was requested. |
| - if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| - return NULL; |
| - } |
| - // Create a new SkPngCodec, to be owned by the scanline decoder. |
| - SkStream* stream = this->stream()->duplicate(); |
| - if (!stream) { |
| - return NULL; |
| - } |
| +SkScanlineDecoder* SkPngCodec::NewSDFromStream(SkStream* stream) { |
| SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFromStream(stream))); |
|
msarett
2015/07/30 12:58:46
I'm noticing that we still need to create a codec
scroggo
2015/07/30 15:11:35
This is an implementation detail, though. We *coul
|
| if (!codec) { |
| return NULL; |
| } |
| - if (codec->initializeSwizzler(dstInfo, options, ctable, ctableCount) != kSuccess) { |
| - SkCodecPrintf("failed to initialize the swizzler.\n"); |
| - return NULL; |
| - } |
| - |
| + codec->fNumberPasses = png_set_interlace_handling(codec->fPng_ptr); |
| SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); |
| + |
| + const SkImageInfo& srcInfo = codec->getInfo(); |
| if (codec->fNumberPasses > 1) { |
| // interlaced image |
| - return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach())); |
| + return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach())); |
| } |
| - return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); |
| + return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); |
| } |