[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25053] trunk/blender/source/blender/imbuf /intern/jpeg.c: fix for [#19990] file browser crash
Andrea Weikert
elubie at gmx.net
Tue Dec 1 21:38:02 CET 2009
Revision: 25053
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25053
Author: elubie
Date: 2009-12-01 21:37:26 +0100 (Tue, 01 Dec 2009)
Log Message:
-----------
fix for [#19990] file browser crash
needed to fix jpg error handling to not return control to the library from jpg_error used as error exit. Needed to add structured exception handling (setjmp/longjmp) - not very nice but needed in this case. (Also recommended in example.c from libjpg and used in gimp ;) )
Modified Paths:
--------------
trunk/blender/source/blender/imbuf/intern/jpeg.c
Modified: trunk/blender/source/blender/imbuf/intern/jpeg.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/jpeg.c 2009-12-01 19:43:09 UTC (rev 25052)
+++ trunk/blender/source/blender/imbuf/intern/jpeg.c 2009-12-01 20:37:26 UTC (rev 25053)
@@ -32,6 +32,8 @@
/* This little block needed for linking to Blender... */
#include <stdio.h>
+#include <setjmp.h>
+
#include "BLI_blenlib.h"
#include "imbuf.h"
@@ -41,6 +43,7 @@
#include "IMB_imginfo.h"
#include "IMB_jpeg.h"
#include "jpeglib.h"
+#include "jerror.h"
/* the types are from the jpeg lib */
static void jpeg_error (j_common_ptr cinfo);
@@ -66,7 +69,6 @@
* 4. jmax - no scaling in the components
*/
-static int jpeg_failed = FALSE;
static int jpeg_default_quality;
static int ibuf_ftype;
@@ -76,15 +78,30 @@
return 0;
}
+//----------------------------------------------------------
+// JPG ERROR HANDLING
+//----------------------------------------------------------
+
+typedef struct my_error_mgr {
+ struct jpeg_error_mgr pub; /* "public" fields */
+
+ jmp_buf setjmp_buffer; /* for return to caller */
+} my_error_mgr;
+
+typedef my_error_mgr * my_error_ptr;
+
static void jpeg_error (j_common_ptr cinfo)
{
+ my_error_ptr err = (my_error_ptr)cinfo->err;
+
/* Always display the message */
(*cinfo->err->output_message) (cinfo);
/* Let the memory manager delete any temp files before we die */
jpeg_destroy(cinfo);
- jpeg_failed = TRUE;
+ /* return control to the setjmp point */
+ longjmp(err->setjmp_buffer, 1);
}
//----------------------------------------------------------
@@ -255,7 +272,7 @@
x = cinfo->image_width;
y = cinfo->image_height;
depth = cinfo->num_components;
-
+
if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK;
jpeg_start_decompress(cinfo);
@@ -407,15 +424,25 @@
ImBuf * imb_ibJpegImageFromFilename (const char * filename, int flags)
{
struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
- struct jpeg_error_mgr jerr;
+ struct my_error_mgr jerr;
FILE * infile;
ImBuf * ibuf;
if ((infile = fopen(filename, "rb")) == NULL) return 0;
- cinfo->err = jpeg_std_error(&jerr);
- jerr.error_exit = jpeg_error;
+ cinfo->err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error;
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_decompress(cinfo);
+ fclose(infile);
+ return NULL;
+ }
+
jpeg_create_decompress(cinfo);
jpeg_stdio_src(cinfo, infile);
@@ -428,12 +455,21 @@
ImBuf * imb_ibJpegImageFromMemory (unsigned char * buffer, int size, int flags)
{
struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
- struct jpeg_error_mgr jerr;
+ struct my_error_mgr jerr;
ImBuf * ibuf;
- cinfo->err = jpeg_std_error(&jerr);
- jerr.error_exit = jpeg_error;
+ cinfo->err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error;
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_decompress(cinfo);
+ return NULL;
+ }
+
jpeg_create_decompress(cinfo);
memory_source(cinfo, buffer, size);
@@ -521,11 +557,9 @@
}
jpeg_write_scanlines(cinfo, row_pointer, 1);
-
- if (jpeg_failed) break;
}
- if (jpeg_failed == FALSE) jpeg_finish_compress(cinfo);
+ jpeg_finish_compress(cinfo);
free(row_pointer[0]);
}
@@ -577,14 +611,25 @@
{
FILE * outfile;
struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
- struct jpeg_error_mgr jerr;
+ struct my_error_mgr jerr;
if ((outfile = fopen(name, "wb")) == NULL) return 0;
jpeg_default_quality = 75;
- cinfo->err = jpeg_std_error(&jerr);
- jerr.error_exit = jpeg_error;
+ cinfo->err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error;
+ /* Establish the setjmp return context for jpeg_error to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_compress(cinfo);
+ fclose(outfile);
+ remove(name);
+ return 0;
+ }
+
init_jpeg(outfile, cinfo, ibuf);
write_jpeg(cinfo, ibuf);
@@ -592,10 +637,6 @@
fclose(outfile);
jpeg_destroy_compress(cinfo);
- if (jpeg_failed) {
- remove(name);
- return 0;
- }
return 1;
}
@@ -604,14 +645,25 @@
{
FILE * outfile;
struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
- struct jpeg_error_mgr jerr;
+ struct my_error_mgr jerr;
if ((outfile = fopen(name, "wb")) == NULL) return 0;
jpeg_default_quality = 90;
- cinfo->err = jpeg_std_error(&jerr);
- jerr.error_exit = jpeg_error;
+ cinfo->err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error;
+ /* Establish the setjmp return context for jpeg_error to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_compress(cinfo);
+ fclose(outfile);
+ remove(name);
+ return 0;
+ }
+
init_jpeg(outfile, cinfo, ibuf);
/* adjust scaling factors */
@@ -625,10 +677,6 @@
fclose(outfile);
jpeg_destroy_compress(cinfo);
- if (jpeg_failed) {
- remove(name);
- return 0;
- }
return 1;
}
@@ -667,14 +715,25 @@
{
FILE * outfile;
struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
- struct jpeg_error_mgr jerr;
+ struct my_error_mgr jerr;
if ((outfile = fopen(name, "wb")) == NULL) return 0;
jpeg_default_quality = 100;
- cinfo->err = jpeg_std_error(&jerr);
- jerr.error_exit = jpeg_error;
+ cinfo->err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error;
+ /* Establish the setjmp return context for jpeg_error to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_compress(cinfo);
+ fclose(outfile);
+ remove(name);
+ return 0;
+ }
+
init_jpeg(outfile, cinfo, ibuf);
/* adjust scaling factors */
@@ -688,10 +747,6 @@
fclose(outfile);
jpeg_destroy_compress(cinfo);
- if (jpeg_failed) {
- remove(name);
- return 0;
- }
return 1;
}
More information about the Bf-blender-cvs
mailing list