diff options
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 21 | ||||
-rw-r--r-- | src/codec/SkJpegDecoderMgr.cpp | 8 | ||||
-rw-r--r-- | src/codec/SkJpegDecoderMgr.h | 6 | ||||
-rw-r--r-- | src/codec/SkJpegPriv.h | 19 | ||||
-rw-r--r-- | src/codec/SkJpegUtility.cpp | 5 | ||||
-rw-r--r-- | src/images/SkJPEGWriteUtility.cpp | 5 | ||||
-rw-r--r-- | src/images/SkJpegEncoder.cpp | 9 |
7 files changed, 49 insertions, 24 deletions
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index f69a0b8616..8a8b23b248 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -192,7 +192,8 @@ SkCodec::Result SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, std::unique_ptr<JpegDecoderMgr> decoderMgr(new JpegDecoderMgr(stream)); // libjpeg errors will be caught and reported here - if (setjmp(decoderMgr->getJmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(decoderMgr->errorMgr()); + if (setjmp(jmp)) { return decoderMgr->returnFailure("ReadHeader", kInvalidInput); } @@ -449,7 +450,8 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) { * dimensions if possible */ bool SkJpegCodec::onDimensionsSupported(const SkISize& size) { - if (setjmp(fDecoderMgr->getJmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr()); + if (setjmp(jmp)) { return fDecoderMgr->returnFalse("onDimensionsSupported"); } @@ -488,7 +490,8 @@ bool SkJpegCodec::onDimensionsSupported(const SkISize& size) { int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options& opts) { // Set the jump location for libjpeg-turbo errors - if (setjmp(fDecoderMgr->getJmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr()); + if (setjmp(jmp)) { return 0; } @@ -575,7 +578,8 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo(); // Set the jump location for libjpeg errors - if (setjmp(fDecoderMgr->getJmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr()); + if (setjmp(jmp)) { return fDecoderMgr->returnFailure("setjmp", kInvalidInput); } @@ -679,7 +683,8 @@ SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options) { // Set the jump location for libjpeg errors - if (setjmp(fDecoderMgr->getJmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr()); + if (setjmp(jmp)) { SkCodecPrintf("setjmp: Error from libjpeg\n"); return kInvalidInput; } @@ -755,7 +760,8 @@ int SkJpegCodec::onGetScanlines(void* dst, int count, size_t dstRowBytes) { bool SkJpegCodec::onSkipScanlines(int count) { // Set the jump location for libjpeg errors - if (setjmp(fDecoderMgr->getJmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr()); + if (setjmp(jmp)) { return fDecoderMgr->returnFalse("onSkipScanlines"); } @@ -852,7 +858,8 @@ SkCodec::Result SkJpegCodec::onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void } // Set the jump location for libjpeg errors - if (setjmp(fDecoderMgr->getJmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fDecoderMgr->errorMgr()); + if (setjmp(jmp)) { return fDecoderMgr->returnFailure("setjmp", kInvalidInput); } diff --git a/src/codec/SkJpegDecoderMgr.cpp b/src/codec/SkJpegDecoderMgr.cpp index c2837aa2b4..e8a31f94e6 100644 --- a/src/codec/SkJpegDecoderMgr.cpp +++ b/src/codec/SkJpegDecoderMgr.cpp @@ -91,11 +91,3 @@ JpegDecoderMgr::~JpegDecoderMgr() { jpeg_destroy_decompress(&fDInfo); } } - -jmp_buf& JpegDecoderMgr::getJmpBuf() { - return fErrorMgr.fJmpBuf; -} - -jpeg_decompress_struct* JpegDecoderMgr::dinfo() { - return &fDInfo; -} diff --git a/src/codec/SkJpegDecoderMgr.h b/src/codec/SkJpegDecoderMgr.h index 272c5b4b1c..f3834fe79b 100644 --- a/src/codec/SkJpegDecoderMgr.h +++ b/src/codec/SkJpegDecoderMgr.h @@ -54,14 +54,14 @@ public: ~JpegDecoderMgr(); /* - * Get the jump buffer in order to set an error return point + * Get the skjpeg_error_mgr in order to set an error return jmp_buf */ - jmp_buf& getJmpBuf(); + skjpeg_error_mgr* errorMgr() { return &fErrorMgr; } /* * Get function for the decompress info struct */ - jpeg_decompress_struct* dinfo(); + jpeg_decompress_struct* dinfo() { return &fDInfo; } private: diff --git a/src/codec/SkJpegPriv.h b/src/codec/SkJpegPriv.h index e4e5b12763..ce2da56225 100644 --- a/src/codec/SkJpegPriv.h +++ b/src/codec/SkJpegPriv.h @@ -10,6 +10,7 @@ #define SkJpegPriv_DEFINED #include "SkStream.h" +#include "SkTArray.h" #include <setjmp.h> // stdio is needed for jpeglib @@ -30,7 +31,23 @@ static constexpr uint8_t kICCSig[] = { * Error handling struct */ struct skjpeg_error_mgr : jpeg_error_mgr { - jmp_buf fJmpBuf; + class AutoPushJmpBuf { + public: + AutoPushJmpBuf(skjpeg_error_mgr* mgr) : fMgr(mgr) { + fMgr->fJmpBufStack.push_back(&fJmpBuf); + } + ~AutoPushJmpBuf() { + SkASSERT(fMgr->fJmpBufStack.back() == &fJmpBuf); + fMgr->fJmpBufStack.pop_back(); + } + operator jmp_buf&() { return fJmpBuf; } + + private: + skjpeg_error_mgr* const fMgr; + jmp_buf fJmpBuf; + }; + + SkSTArray<4, jmp_buf*> fJmpBufStack; }; #endif diff --git a/src/codec/SkJpegUtility.cpp b/src/codec/SkJpegUtility.cpp index 7bfb6bf5e6..4eee287336 100644 --- a/src/codec/SkJpegUtility.cpp +++ b/src/codec/SkJpegUtility.cpp @@ -17,7 +17,10 @@ void skjpeg_err_exit(j_common_ptr dinfo) { // JpegDecoderMgr will take care of freeing memory skjpeg_error_mgr* error = (skjpeg_error_mgr*) dinfo->err; (*error->output_message) (dinfo); - longjmp(error->fJmpBuf, 1); + if (error->fJmpBufStack.empty()) { + SK_ABORT("JPEG error with no jmp_buf set."); + } + longjmp(*error->fJmpBufStack.back(), 1); } // Functions for buffered sources // diff --git a/src/images/SkJPEGWriteUtility.cpp b/src/images/SkJPEGWriteUtility.cpp index aa0d3ec4d9..118662d68d 100644 --- a/src/images/SkJPEGWriteUtility.cpp +++ b/src/images/SkJPEGWriteUtility.cpp @@ -60,5 +60,8 @@ void skjpeg_error_exit(j_common_ptr cinfo) { /* Let the memory manager delete any temp files before we die */ jpeg_destroy(cinfo); - longjmp(error->fJmpBuf, -1); + if (error->fJmpBufStack.empty()) { + SK_ABORT("JPEG error with no jmp_buf set."); + } + longjmp(*error->fJmpBufStack.back(), -1); } diff --git a/src/images/SkJpegEncoder.cpp b/src/images/SkJpegEncoder.cpp index 9fade2449a..1c542a66a7 100644 --- a/src/images/SkJpegEncoder.cpp +++ b/src/images/SkJpegEncoder.cpp @@ -40,7 +40,7 @@ public: jpeg_compress_struct* cinfo() { return &fCInfo; } - jmp_buf& jmpBuf() { return fErrMgr.fJmpBuf; } + skjpeg_error_mgr* errorMgr() { return &fErrMgr; } transform_scanline_proc proc() const { return fProc; } @@ -187,7 +187,9 @@ std::unique_ptr<SkEncoder> SkJpegEncoder::Make(SkWStream* dst, const SkPixmap& s } std::unique_ptr<SkJpegEncoderMgr> encoderMgr = SkJpegEncoderMgr::Make(dst); - if (setjmp(encoderMgr->jmpBuf())) { + + skjpeg_error_mgr::AutoPushJmpBuf jmp(encoderMgr->errorMgr()); + if (setjmp(jmp)) { return nullptr; } @@ -224,7 +226,8 @@ SkJpegEncoder::SkJpegEncoder(std::unique_ptr<SkJpegEncoderMgr> encoderMgr, const SkJpegEncoder::~SkJpegEncoder() {} bool SkJpegEncoder::onEncodeRows(int numRows) { - if (setjmp(fEncoderMgr->jmpBuf())) { + skjpeg_error_mgr::AutoPushJmpBuf jmp(fEncoderMgr->errorMgr()); + if (setjmp(jmp)) { return false; } |