| Index: src/codec/SkJpegCodec.cpp
|
| diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
|
| index 858e305b067132b78dd25bd03403090eadd6d2e5..28e1e12bfc4ed7aa3272947a32662c03d72593c1 100644
|
| --- a/src/codec/SkJpegCodec.cpp
|
| +++ b/src/codec/SkJpegCodec.cpp
|
| @@ -303,13 +303,6 @@ bool SkJpegCodec::scaleToDimensions(uint32_t dstWidth, uint32_t dstHeight) {
|
| SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
|
| void* dst, size_t dstRowBytes,
|
| const Options& options, SkPMColor*, int*) {
|
| -
|
| - // Do not allow a regular decode if the caller has asked for a scanline decoder
|
| - if (NULL != this->scanlineDecoder()) {
|
| - return fDecoderMgr->returnFailure("cannot getPixels() if a scanline decoder has been"
|
| - "created", kInvalidParameters);
|
| - }
|
| -
|
| // Rewind the stream if needed
|
| if (!this->handleRewind()) {
|
| return fDecoderMgr->returnFailure("could not rewind stream", kCouldNotRewind);
|
| @@ -380,25 +373,6 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
|
| }
|
|
|
| /*
|
| - * We override the destructor to ensure that the scanline decoder is left in a
|
| - * finished state before destroying the decode manager.
|
| - */
|
| -SkJpegCodec::~SkJpegCodec() {
|
| - SkAutoTDelete<SkScanlineDecoder> decoder(this->detachScanlineDecoder());
|
| - if (NULL != decoder) {
|
| - if (setjmp(fDecoderMgr->getJmpBuf())) {
|
| - SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n");
|
| - return;
|
| - }
|
| -
|
| - // We may not have decoded the entire image. Prevent libjpeg-turbo from failing on a
|
| - // partial decode.
|
| - fDecoderMgr->dinfo()->output_scanline = this->getInfo().height();
|
| - turbo_jpeg_finish_decompress(fDecoderMgr->dinfo());
|
| - }
|
| -}
|
| -
|
| -/*
|
| * Enable scanline decoding for jpegs
|
| */
|
| class SkJpegScanlineDecoder : public SkScanlineDecoder {
|
| @@ -408,6 +382,18 @@ public:
|
| , fCodec(codec)
|
| {}
|
|
|
| + virtual ~SkJpegScanlineDecoder() {
|
| + if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
|
| + SkCodecPrintf("setjmp: Error in libjpeg finish_decompress\n");
|
| + return;
|
| + }
|
| +
|
| + // We may not have decoded the entire image. Prevent libjpeg-turbo from failing on a
|
| + // partial decode.
|
| + fCodec->fDecoderMgr->dinfo()->output_scanline = fCodec->getInfo().height();
|
| + turbo_jpeg_finish_decompress(fCodec->fDecoderMgr->dinfo());
|
| + }
|
| +
|
| SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) override {
|
| // Set the jump location for libjpeg errors
|
| if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
|
| @@ -460,7 +446,7 @@ public:
|
| }
|
|
|
| private:
|
| - SkJpegCodec* fCodec; // unowned
|
| + SkAutoTDelete<SkJpegCodec> fCodec;
|
|
|
| typedef SkScanlineDecoder INHERITED;
|
| };
|
| @@ -480,24 +466,33 @@ SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
|
| return NULL;
|
| }
|
|
|
| + SkStream* stream = this->stream()->duplicate();
|
| + if (!stream) {
|
| + return NULL;
|
| + }
|
| + SkAutoTDelete<SkJpegCodec> codec(static_cast<SkJpegCodec*>(SkJpegCodec::NewFromStream(stream)));
|
| + if (!codec) {
|
| + return NULL;
|
| + }
|
| +
|
| // Check if we can decode to the requested destination and set the output color space
|
| - if (!this->setOutputColorSpace(dstInfo)) {
|
| + if (!codec->setOutputColorSpace(dstInfo)) {
|
| SkCodecPrintf("Cannot convert to output type\n");
|
| return NULL;
|
| }
|
|
|
| // Perform the necessary scaling
|
| - if (!this->scaleToDimensions(dstInfo.width(), dstInfo.height())) {
|
| + if (!codec->scaleToDimensions(dstInfo.width(), dstInfo.height())) {
|
| SkCodecPrintf("Cannot scale to output dimensions\n");
|
| return NULL;
|
| }
|
|
|
| // Now, given valid output dimensions, we can start the decompress
|
| - if (!turbo_jpeg_start_decompress(fDecoderMgr->dinfo())) {
|
| + if (!turbo_jpeg_start_decompress(codec->fDecoderMgr->dinfo())) {
|
| SkCodecPrintf("start decompress failed\n");
|
| return NULL;
|
| }
|
|
|
| // Return the new scanline decoder
|
| - return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, this));
|
| + return SkNEW_ARGS(SkJpegScanlineDecoder, (dstInfo, codec.detach()));
|
| }
|
|
|