| Index: src/codec/SkCodec_libpng.cpp
|
| diff --git a/src/codec/SkCodec_libpng.cpp b/src/codec/SkCodec_libpng.cpp
|
| index 9f9c110cc68bcc06ed9d38c7c272cdecea42341a..3f3ddebcf1c6d7639636476b93379fc50e85512d 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 onStart(const SkImageInfo& dstInfo,
|
| + 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 onStart(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)));
|
| 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()));
|
| }
|
|
|
|
|