mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[devel] Reverted changes to call png_longjmp in contrib/gregbook
where it is not appropriate. If mainprog->jmpbuf is used by setjmp, then png_longjmp cannot be used. Reversed patch to remove error handler when the jmp_buf is stored in the main program structure, not the png_struct. The error handler is needed because the default handler in libpng will always use the jmp_buf in the library control structure; this is never set. The gregbook code is a useful example because, even though it uses setjmp/longjmp, it shows how error handling can be implemented using control mechanisms not directly supported by libpng. The technique will work correctly with mechanisms such as Microsoft Structure Exceptions or C++ exceptions (compiler willing - note that gcc does not by default support interworking of C and C++ error handling.)
This commit is contained in:
@@ -66,6 +66,7 @@ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr);
|
||||
static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
|
||||
png_uint_32 row_num, int pass);
|
||||
static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);
|
||||
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +102,7 @@ int readpng2_init(mainprog_info *mainprog_ptr)
|
||||
/* could also replace libpng warning-handler (final NULL), but no need: */
|
||||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
|
||||
NULL, NULL);
|
||||
readpng2_error_handler, NULL);
|
||||
if (!png_ptr)
|
||||
return 4; /* out of memory */
|
||||
|
||||
@@ -450,3 +451,41 @@ void readpng2_cleanup(mainprog_info *mainprog_ptr)
|
||||
mainprog_ptr->png_ptr = NULL;
|
||||
mainprog_ptr->info_ptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
|
||||
{
|
||||
mainprog_info *mainprog_ptr;
|
||||
|
||||
/* This function, aside from the extra step of retrieving the "error
|
||||
* pointer" (below) and the fact that it exists within the application
|
||||
* rather than within libpng, is essentially identical to libpng's
|
||||
* default error handler. The second point is critical: since both
|
||||
* setjmp() and longjmp() are called from the same code, they are
|
||||
* guaranteed to have compatible notions of how big a jmp_buf is,
|
||||
* regardless of whether _BSD_SOURCE or anything else has (or has not)
|
||||
* been defined. */
|
||||
|
||||
fprintf(stderr, "readpng2 libpng error: %s\n", msg);
|
||||
fflush(stderr);
|
||||
|
||||
mainprog_ptr = png_get_error_ptr(png_ptr);
|
||||
if (mainprog_ptr == NULL) { /* we are completely hosed now */
|
||||
fprintf(stderr,
|
||||
"readpng2 severe error: jmpbuf not recoverable; terminating.\n");
|
||||
fflush(stderr);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
/* Now we have our data structure we can use the information in it
|
||||
* to return control to our own higher level code (all the points
|
||||
* where 'setjmp' is called in this file.) This will work with other
|
||||
* error handling mechanisms as well - libpng always calls png_error
|
||||
* when it can proceed no further, thus, so long as the error handler
|
||||
* is intercepted, application code can do its own error recovery.
|
||||
*/
|
||||
longjmp(mainprog_ptr->jmpbuf, 1);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
- 1.10: enabled "message window"/console (thanks to David Geldreich)
|
||||
- 2.00: dual-licensed (added GNU GPL)
|
||||
- 2.01: fixed improper display of usage screen on PNG error(s)
|
||||
- 2.02: removed special error-handling which is no longer needed
|
||||
because of the new libpng png_longjmp() feature in libpng-1.5.0.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
- 1.14: added support for X resources (thanks to Gerhard Niklasch)
|
||||
- 2.00: dual-licensed (added GNU GPL)
|
||||
- 2.01: fixed improper display of usage screen on PNG error(s)
|
||||
- 2.02: removed special error-handling which is no longer needed
|
||||
because of the new libpng png_longjmp() feature in libpng-1.5.0.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
- 2.01: fixed 64-bit typo in readpng2.c
|
||||
- 2.02: fixed improper display of usage screen on PNG error(s); fixed
|
||||
unexpected-EOF and file-read-error cases
|
||||
- 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options;
|
||||
removed special error-handling which is no longer needed
|
||||
because of the new libpng png_longjmp() feature in libpng-1.5.0.
|
||||
- 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
unexpected-EOF and file-read-error cases; fixed Trace() cut-and-
|
||||
paste bugs
|
||||
- 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options
|
||||
removed special error-handling which is no longer needed
|
||||
because of the new libpng png_longjmp() feature in libpng-1.5.0.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
@@ -786,8 +784,9 @@ static void rpng2_x_init(void)
|
||||
if (rpng2_x_create_window()) {
|
||||
|
||||
/* GRR TEMPORARY HACK: this is fundamentally no different from cases
|
||||
* above; libpng should longjmp() back to us when png_ptr goes away.
|
||||
* If we/it segfault instead, seems like a libpng bug... */
|
||||
* above; libpng should call our error handler to longjmp() back to us
|
||||
* when png_ptr goes away. If we/it segfault instead, seems like a
|
||||
* libpng bug... */
|
||||
|
||||
/* we're here via libpng callback, so if window fails, clean and bail */
|
||||
readpng2_cleanup(&rpng2_info);
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
- 1.04: fixed DOS/OS2/Win32 detection, including partial Cygwin fix
|
||||
(see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff)
|
||||
- 2.00: dual-licensed (added GNU GPL)
|
||||
- 2.01: removed special error-handling which is no longer needed
|
||||
because of the new libpng png_longjmp() feature in libpng-1.5.0.
|
||||
|
||||
[REPORTED BUG (win32 only): "contrib/gregbook/wpng.c - cmd line
|
||||
dose not work! In order to do something useful I needed to redirect
|
||||
|
||||
@@ -60,6 +60,10 @@
|
||||
#include "writepng.h" /* typedefs, common macros, public prototypes */
|
||||
|
||||
|
||||
/* local prototype */
|
||||
|
||||
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
|
||||
|
||||
|
||||
|
||||
void writepng_version_info(void)
|
||||
@@ -86,7 +90,7 @@ int writepng_init(mainprog_info *mainprog_ptr)
|
||||
/* could also replace libpng warning-handler (final NULL), but no need: */
|
||||
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
|
||||
NULL, NULL);
|
||||
writepng_error_handler, NULL);
|
||||
if (!png_ptr)
|
||||
return 4; /* out of memory */
|
||||
|
||||
@@ -100,7 +104,8 @@ int writepng_init(mainprog_info *mainprog_ptr)
|
||||
/* setjmp() must be called in every function that calls a PNG-writing
|
||||
* libpng function, unless an alternate error handler was installed--
|
||||
* but compatible error handlers must either use longjmp() themselves
|
||||
* (as in this program) or exit immediately, so here we go: */
|
||||
* (as in this program) or some other method to return control to
|
||||
* application code, so here we go: */
|
||||
|
||||
if (setjmp(mainprog_ptr->jmpbuf)) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
@@ -355,3 +360,41 @@ void writepng_cleanup(mainprog_info *mainprog_ptr)
|
||||
if (png_ptr && info_ptr)
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
|
||||
{
|
||||
mainprog_info *mainprog_ptr;
|
||||
|
||||
/* This function, aside from the extra step of retrieving the "error
|
||||
* pointer" (below) and the fact that it exists within the application
|
||||
* rather than within libpng, is essentially identical to libpng's
|
||||
* default error handler. The second point is critical: since both
|
||||
* setjmp() and longjmp() are called from the same code, they are
|
||||
* guaranteed to have compatible notions of how big a jmp_buf is,
|
||||
* regardless of whether _BSD_SOURCE or anything else has (or has not)
|
||||
* been defined. */
|
||||
|
||||
fprintf(stderr, "writepng libpng error: %s\n", msg);
|
||||
fflush(stderr);
|
||||
|
||||
mainprog_ptr = png_get_error_ptr(png_ptr);
|
||||
if (mainprog_ptr == NULL) { /* we are completely hosed now */
|
||||
fprintf(stderr,
|
||||
"writepng severe error: jmpbuf not recoverable; terminating.\n");
|
||||
fflush(stderr);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
/* Now we have our data structure we can use the information in it
|
||||
* to return control to our own higher level code (all the points
|
||||
* where 'setjmp' is called in this file.) This will work with other
|
||||
* error handling mechanisms as well - libpng always calls png_error
|
||||
* when it can proceed no further, thus, so long as the error handler
|
||||
* is intercepted, application code can do its own error recovery.
|
||||
*/
|
||||
longjmp(mainprog_ptr->jmpbuf, 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user