aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/codec/SkJpegCodec.cpp21
-rw-r--r--src/codec/SkJpegDecoderMgr.cpp8
-rw-r--r--src/codec/SkJpegDecoderMgr.h6
-rw-r--r--src/codec/SkJpegPriv.h19
-rw-r--r--src/codec/SkJpegUtility.cpp5
-rw-r--r--src/images/SkJPEGWriteUtility.cpp5
-rw-r--r--src/images/SkJpegEncoder.cpp9
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;
}