* extended the jpeg_error_mgr structure to hold the jmp_buf that we need
in the critical error handler. In the high level function, the jmp_buf is now allocated on the stack and placed in the "cinfo->err" structure. This should make the mechanism thread-safe. Unfortunately, we don't use the original libjpeg anymore as is, but this seems to be frozen code since a few years anyways. If you have any better suggestions, please don't hesitate to mention them! :-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23560 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -85,8 +85,10 @@ translation_format outputFormats[] = {
|
||||
|
||||
// Main functions of translator :)
|
||||
static status_t Copy(BPositionIO *in, BPositionIO *out);
|
||||
static status_t Compress(BPositionIO *in, BPositionIO *out);
|
||||
static status_t Decompress(BPositionIO *in, BPositionIO *out, BMessage* ioExtension);
|
||||
static status_t Compress(BPositionIO *in, BPositionIO *out,
|
||||
const jmp_buf* longJumpBuffer);
|
||||
static status_t Decompress(BPositionIO *in, BPositionIO *out,
|
||||
BMessage* ioExtension, const jmp_buf* longJumpBuffer);
|
||||
static status_t Error(j_common_ptr cinfo, status_t error = B_ERROR);
|
||||
|
||||
|
||||
@@ -1101,9 +1103,6 @@ Identify(BPositionIO *inSource, const translation_format *inFormat,
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
static jmp_buf sLongJumpBuffer;
|
||||
jmp_buf* gLongJumpBuffer = &sLongJumpBuffer;
|
||||
|
||||
/*! Arguably the most important method in the add-on */
|
||||
status_t
|
||||
Translate(BPositionIO *inSource, const translator_info *inInfo,
|
||||
@@ -1120,7 +1119,8 @@ Translate(BPositionIO *inSource, const translator_info *inInfo,
|
||||
// this place. If this happens, it is as if the setjmp() call is called
|
||||
// a second time, but this time the return value will be 1. The first
|
||||
// invokation will return 0.
|
||||
int jmpRet = setjmp(sLongJumpBuffer);
|
||||
jmp_buf longJumpBuffer;
|
||||
int jmpRet = setjmp(longJumpBuffer);
|
||||
if (jmpRet == 1)
|
||||
return B_ERROR;
|
||||
|
||||
@@ -1130,10 +1130,11 @@ Translate(BPositionIO *inSource, const translator_info *inInfo,
|
||||
return Copy(inSource, outDestination);
|
||||
} else if (inInfo->type == B_TRANSLATOR_BITMAP
|
||||
&& outType == JPEG_FORMAT) {
|
||||
return Compress(inSource, outDestination);
|
||||
return Compress(inSource, outDestination, &longJumpBuffer);
|
||||
} else if (inInfo->type == JPEG_FORMAT
|
||||
&& outType == B_TRANSLATOR_BITMAP) {
|
||||
return Decompress(inSource, outDestination, ioExtension);
|
||||
return Decompress(inSource, outDestination, ioExtension,
|
||||
&longJumpBuffer);
|
||||
}
|
||||
} catch (...) {
|
||||
fprintf(stderr, "libjpeg encoutered a critical error "
|
||||
@@ -1180,7 +1181,7 @@ Copy(BPositionIO *in, BPositionIO *out)
|
||||
|
||||
/*! Encode into the native format */
|
||||
static status_t
|
||||
Compress(BPositionIO *in, BPositionIO *out)
|
||||
Compress(BPositionIO *in, BPositionIO *out, const jmp_buf* longJumpBuffer)
|
||||
{
|
||||
// Load Settings
|
||||
jpeg_settings settings;
|
||||
@@ -1298,7 +1299,7 @@ Compress(BPositionIO *in, BPositionIO *out)
|
||||
// Set basic things needed for jpeg writing
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
cinfo.err = be_jpeg_std_error(&jerr, &settings);
|
||||
cinfo.err = be_jpeg_std_error(&jerr, &settings, longJumpBuffer);
|
||||
jpeg_create_compress(&cinfo);
|
||||
be_jpeg_stdio_dest(&cinfo, out);
|
||||
|
||||
@@ -1393,7 +1394,8 @@ Compress(BPositionIO *in, BPositionIO *out)
|
||||
|
||||
/*! Decode the native format */
|
||||
static status_t
|
||||
Decompress(BPositionIO *in, BPositionIO *out, BMessage* ioExtension)
|
||||
Decompress(BPositionIO *in, BPositionIO *out, BMessage* ioExtension,
|
||||
const jmp_buf* longJumpBuffer)
|
||||
{
|
||||
// Load Settings
|
||||
jpeg_settings settings;
|
||||
@@ -1402,7 +1404,7 @@ Decompress(BPositionIO *in, BPositionIO *out, BMessage* ioExtension)
|
||||
// Set basic things needed for jpeg reading
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
cinfo.err = be_jpeg_std_error(&jerr, &settings);
|
||||
cinfo.err = be_jpeg_std_error(&jerr, &settings, longJumpBuffer);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
be_jpeg_stdio_src(&cinfo, in);
|
||||
|
||||
|
||||
@@ -213,8 +213,8 @@ EXTERN(void) be_jpeg_stdio_dest(j_compress_ptr cinfo, BPositionIO *outfile); //
|
||||
// modified to use settings
|
||||
// (so user can decide to show dialog-boxes or not)
|
||||
//---------------------------------------------------
|
||||
EXTERN(struct jpeg_error_mgr *) be_jpeg_std_error (struct jpeg_error_mgr * err, jpeg_settings * settings); // from "be_jerror.cpp"
|
||||
|
||||
extern jmp_buf* gLongJumpBuffer;
|
||||
EXTERN(struct jpeg_error_mgr *) be_jpeg_std_error (struct jpeg_error_mgr * err,
|
||||
jpeg_settings * settings, const jmp_buf* longJumpBuffer);
|
||||
// implemented in "be_jerror.cpp"
|
||||
|
||||
#endif // _JPEGTRANSLATOR_H_
|
||||
|
||||
@@ -69,10 +69,14 @@ be_error_exit (j_common_ptr cinfo)
|
||||
|
||||
fprintf(stderr, "JPEG Library Error: %s\n", buffer);
|
||||
|
||||
jmp_buf longJumpBuffer;
|
||||
memcpy(&longJumpBuffer, &(cinfo->err->long_jump_buffer), sizeof(jmp_buf));
|
||||
|
||||
/* Let the memory manager delete any temp files before we die */
|
||||
jpeg_destroy(cinfo);
|
||||
|
||||
longjmp(*gLongJumpBuffer, 0);
|
||||
// jump back directly to the high level function's "breakpoint"
|
||||
longjmp(longJumpBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +91,8 @@ be_output_message (j_common_ptr cinfo)
|
||||
/* Create the message */
|
||||
(*cinfo->err->format_message) (cinfo, buffer);
|
||||
|
||||
cinfo->err->num_warnings++;
|
||||
|
||||
/* If it's compressing or decompressing and user turned messages on */
|
||||
if (!cinfo->is_decompressor || cinfo->err->ShowReadWarnings) {
|
||||
/* show warning message */
|
||||
@@ -103,7 +109,8 @@ be_output_message (j_common_ptr cinfo)
|
||||
*/
|
||||
|
||||
GLOBAL(struct jpeg_error_mgr *)
|
||||
be_jpeg_std_error (struct jpeg_error_mgr * err, jpeg_settings *settings)
|
||||
be_jpeg_std_error (struct jpeg_error_mgr * err, jpeg_settings *settings,
|
||||
const jmp_buf* longJumpBuffer)
|
||||
{
|
||||
jpeg_std_error(err);
|
||||
|
||||
@@ -111,6 +118,7 @@ be_jpeg_std_error (struct jpeg_error_mgr * err, jpeg_settings *settings)
|
||||
err->output_message = be_output_message;
|
||||
|
||||
err->ShowReadWarnings = settings->ShowReadWarningBox;
|
||||
memcpy(&(err->long_jump_buffer), longJumpBuffer, sizeof(jmp_buf));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#endif
|
||||
#include "jmorecfg.h" /* seldom changed options */
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -713,6 +715,8 @@ struct jpeg_error_mgr {
|
||||
const char * const * addon_message_table; /* Non-library errors */
|
||||
int first_addon_message; /* code for first string in addon table */
|
||||
int last_addon_message; /* code for last string in addon table */
|
||||
|
||||
jmp_buf long_jump_buffer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user