Make setjmp in jpeg code thread safe.

This commit is contained in:
Steve Herrell 2010-12-07 11:25:37 -05:00
parent f4796cc776
commit dca28c8f6e
6 changed files with 115 additions and 88 deletions

View File

@ -13,7 +13,7 @@ set (RTENGINESOURCEFILES colortemp.cc curves.cc dcraw.cc iccstore.cc dfmanager.c
stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc
processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc
iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc
jpeg_memsrc.c jpeg_memsrc.c jdatasrc.c
PF_correct_RT.cc PF_correct_RT.cc
wavelet_dec.cc ipequalizer.cc dirpyrLab_denoise.cc dirpyrLab_equalizer.cc dirpyr_equalizer.cc) wavelet_dec.cc ipequalizer.cc dirpyrLab_denoise.cc dirpyrLab_equalizer.cc dirpyr_equalizer.cc)

View File

@ -31,11 +31,11 @@
#endif #endif
#include <iptcpairs.h> #include <iptcpairs.h>
#include <libiptcdata/iptc-jpeg.h> #include <libiptcdata/iptc-jpeg.h>
extern "C" { extern "C" {
#include "jdatasrc.c"
#include <jpeglib.h>
#include <iccjpeg.h> #include <iccjpeg.h>
} }
#include "jpeg.h"
Glib::ustring safe_locale_to_utf8 (const std::string& src); Glib::ustring safe_locale_to_utf8 (const std::string& src);
@ -257,20 +257,16 @@ int ImageIO::loadPNG (Glib::ustring fname) {
return IMIO_SUCCESS; return IMIO_SUCCESS;
} }
extern jmp_buf jpeg_jmp_buf;
extern "C" {
void jpeg_memory_src (jpeg_decompress_struct* cinfo, const char* buffer, int bufsize);
}
int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize) int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
{ {
jpeg_decompress_struct cinfo; jpeg_decompress_struct cinfo;
jpeg_error_mgr jerr; jpeg_error_mgr jerr;
cinfo.err = my_jpeg_std_error(&jerr); cinfo.err = my_jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo); jpeg_create_decompress(&cinfo);
jpeg_memory_src (&cinfo,buffer,bufsize);
jpeg_memory_src (&cinfo,(const JOCTET*)buffer,bufsize);
if ( setjmp(((rt_jpeg_error_mgr*)cinfo.src)->error_jmp_buf) == 0 )
{
if (pl) { if (pl) {
pl->setProgressStr ("Loading JPEG file..."); pl->setProgressStr ("Loading JPEG file...");
pl->setProgress (0.0); pl->setProgress (0.0);
@ -279,8 +275,7 @@ int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize)
setup_read_icc_profile (&cinfo); setup_read_icc_profile (&cinfo);
if (!setjmp(jpeg_jmp_buf)) { //jpeg_memory_src (&cinfo,buffer,bufsize);
jpeg_memory_src (&cinfo,buffer,bufsize);
jpeg_read_header(&cinfo, TRUE); jpeg_read_header(&cinfo, TRUE);
unsigned int proflen; unsigned int proflen;
@ -338,8 +333,11 @@ int ImageIO::loadJPEG (Glib::ustring fname) {
jpeg_error_mgr jerr; jpeg_error_mgr jerr;
cinfo.err = my_jpeg_std_error(&jerr); cinfo.err = my_jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo); jpeg_create_decompress(&cinfo);
my_jpeg_stdio_src (&cinfo,file);
my_jpeg_stdio_src (&cinfo,file);
if ( setjmp(((rt_jpeg_error_mgr*)cinfo.src)->error_jmp_buf) == 0 )
{
if (pl) { if (pl) {
pl->setProgressStr ("Loading JPEG file..."); pl->setProgressStr ("Loading JPEG file...");
pl->setProgress (0.0); pl->setProgress (0.0);
@ -348,8 +346,7 @@ int ImageIO::loadJPEG (Glib::ustring fname) {
setup_read_icc_profile (&cinfo); setup_read_icc_profile (&cinfo);
if (!setjmp(jpeg_jmp_buf)) { //jpeg_stdio_src(&cinfo,file);
jpeg_stdio_src(&cinfo,file);
jpeg_read_header(&cinfo, TRUE); jpeg_read_header(&cinfo, TRUE);
unsigned int proflen; unsigned int proflen;

View File

@ -1,7 +1,10 @@
#ifndef WIN32 #ifndef WIN32
#define jboolean boolean #define jboolean boolean
#endif #endif
#include <setjmp.h> #include <stdio.h>
#include <jpeglib.h>
#include <jerror.h>
#include "jpeg.h"
/* /*
* jdatasrc.c * jdatasrc.c
@ -21,9 +24,6 @@
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ /* this is not a core library module, so it doesn't define JPEG_INTERNALS */
//#include "jinclude.h" //#include "jinclude.h"
#include <stdio.h>
#include <jpeglib.h>
#include <jerror.h>
#define JFREAD(file,buf,sizeofbuf) \ #define JFREAD(file,buf,sizeofbuf) \
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
@ -37,6 +37,7 @@
typedef struct { typedef struct {
struct jpeg_source_mgr pub; /* public fields */ struct jpeg_source_mgr pub; /* public fields */
jmp_buf error_jmp_buf; /* error handler for this instance */
FILE * infile; /* source stream */ FILE * infile; /* source stream */
JOCTET * buffer; /* start of buffer */ JOCTET * buffer; /* start of buffer */
@ -227,8 +228,6 @@ my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
src->pub.next_input_byte = NULL; /* until buffer loaded */ src->pub.next_input_byte = NULL; /* until buffer loaded */
} }
jmp_buf jpeg_jmp_buf;
METHODDEF(void) METHODDEF(void)
my_error_exit (j_common_ptr cinfo) my_error_exit (j_common_ptr cinfo)
{ {
@ -236,9 +235,10 @@ my_error_exit (j_common_ptr cinfo)
(*cinfo->err->output_message) (cinfo); (*cinfo->err->output_message) (cinfo);
/* Let the memory manager delete any temp files before we die */ /* Let the memory manager delete any temp files before we die */
jpeg_destroy(cinfo); //jpeg_destroy(cinfo);
longjmp (jpeg_jmp_buf, 1); j_decompress_ptr dinfo = (j_decompress_ptr)cinfo;
longjmp (((rt_jpeg_error_mgr*)(dinfo->src))->error_jmp_buf, 1);
} }

35
rtengine/jpeg.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef _RT_JPEG_H
#define _RT_JPEG_H
#include <setjmp.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <jpeglib.h>
extern GLOBAL(struct jpeg_error_mgr *)
my_jpeg_std_error (struct jpeg_error_mgr * err);
extern GLOBAL(void)
my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile);
GLOBAL(void)
jpeg_memory_src (j_decompress_ptr cinfo, const JOCTET * buffer, size_t bufsize);
/**
* @brief jpeg from file and memory use this as base to managers
*/
typedef struct
{
struct jpeg_source_mgr pub; /* public fields */
jmp_buf error_jmp_buf; /* error handler for this instance */
} rt_jpeg_error_mgr;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -22,12 +22,14 @@
#include <stdio.h> #include <stdio.h>
#include <jpeglib.h> #include <jpeglib.h>
#include <jerror.h> #include <jerror.h>
#include "jpeg.h"
/* Expanded data source object for memory input */ /* Expanded data source object for memory input */
typedef struct { typedef struct {
struct jpeg_source_mgr pub; /* public fields */ struct jpeg_source_mgr pub; /* public fields */
jmp_buf error_jmp_buf; /* error handler for this instance */
JOCTET eoi_buffer[2]; /* a place to put a dummy EOI */ JOCTET eoi_buffer[2]; /* a place to put a dummy EOI */
} my_source_mgr; } my_source_mgr;

View File

@ -34,15 +34,7 @@
#include <setjmp.h> #include <setjmp.h>
#include <safekeyfile.h> #include <safekeyfile.h>
#include <rawimage.h> #include <rawimage.h>
#include "jpeg.h"
extern "C" {
#include <jpeglib.h>
extern jmp_buf jpeg_jmp_buf;
extern GLOBAL(struct jpeg_error_mgr *)
my_jpeg_std_error (struct jpeg_error_mgr * err);
extern GLOBAL(void)
my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile);
}
#define MAXVAL 0xffff #define MAXVAL 0xffff
#define CLIP(a) ((a)>0?((a)<MAXVAL?(a):MAXVAL):0) #define CLIP(a) ((a)>0?((a)<MAXVAL?(a):MAXVAL):0)
@ -1130,10 +1122,11 @@ bool Thumbnail::readImage (const Glib::ustring& fname) {
return false; return false;
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr; struct jpeg_error_mgr jerr;
if (!setjmp(jpeg_jmp_buf)) {
cinfo.err = my_jpeg_std_error (&jerr); cinfo.err = my_jpeg_std_error (&jerr);
jpeg_create_decompress (&cinfo); jpeg_create_decompress (&cinfo);
my_jpeg_stdio_src (&cinfo,f); my_jpeg_stdio_src (&cinfo,f);
if ( setjmp(((rt_jpeg_error_mgr*)cinfo.src)->error_jmp_buf) == 0 )
{
jpeg_read_header (&cinfo, TRUE); jpeg_read_header (&cinfo, TRUE);
int width, height; int width, height;
width = cinfo.image_width; width = cinfo.image_width;