aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec')
-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
5 files changed, 39 insertions, 20 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 //