[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.)
diff --git a/ANNOUNCE b/ANNOUNCE
index 855b8c7..c47edd4 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
 
-Libpng 1.5.0beta33 - June 26, 2010
+Libpng 1.5.0beta33 - June 29, 2010
 
 This is not intended to be a public release.  It will be replaced
 within a few weeks by a public version or by another test version.
@@ -77,6 +77,7 @@
 version 1.5.0beta11 [March 6, 2010]
   Removed checking for already-included setjmp.h from pngconf.h
   Fixed inconsistent indentations and made numerous cosmetic changes.
+  Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5
 
 version 1.5.0beta12 [March 9, 2010]
   Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from
@@ -225,7 +226,7 @@
     offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf.
   Added more blank lines for readability.
 
-version 1.5.0beta25 [June 26, 2010]
+version 1.5.0beta25 [June 29, 2010]
   In pngpread.c: png_push_have_row() add check for new_row > height
   Removed the now-redundant check for out-of-bounds new_row from example.c
 
@@ -251,16 +252,29 @@
   Revised pngpread.c patch of beta28 to avoid an endless loop.
   Removed some trailing blanks.
 
-version 1.5.0beta32 [June 26, 2010]
+version 1.5.0beta32 [June 29, 2010]
   Removed leftover scripts/options.patch and scripts/options.rej
 
-version 1.5.0beta32 [June 26, 2010]
+version 1.5.0beta32 [June 29, 2010]
   Made FIXED and FLOATING options consistent in the APIs they enable and
     disable.  Corrected scripts/options.awk to handle both command line
     options and options specified in the .dfa files.
   Changed char *msg to PNG_CONST char *msg in pngrutil.c
   Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or
     floating point APIs, but not both.
+  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.)
+  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.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index f6b6731..e9cb0f4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2557,6 +2557,7 @@
 version 1.5.0beta11 [March 6, 2010]
   Removed checking for already-included setjmp.h from pngconf.h
   Fixed inconsistent indentations and made numerous cosmetic changes.
+  Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5
 
 version 1.5.0beta12 [March 9, 2010]
   Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from
@@ -2736,13 +2737,26 @@
 version 1.5.0beta32 [June 26, 2010]
   Removed leftover scripts/options.patch and scripts/options.rej
 
-version 1.5.0beta33 [June 26, 2010]
+version 1.5.0beta33 [June 29, 2010]
   Made FIXED and FLOATING options consistent in the APIs they enable and
     disable.  Corrected scripts/options.awk to handle both command line
     options and options specified in the .dfa files.
   Changed char *msg to PNG_CONST char *msg in pngrutil.c
   Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or
     floating point APIs, but not both.
+  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.)
+  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.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/contrib/gregbook/readpng2.c b/contrib/gregbook/readpng2.c
index 42addbf..4644b09 100644
--- a/contrib/gregbook/readpng2.c
+++ b/contrib/gregbook/readpng2.c
@@ -66,6 +66,7 @@
 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 @@
     /* 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 @@
     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);
+}
diff --git a/contrib/gregbook/rpng-win.c b/contrib/gregbook/rpng-win.c
index 543a0bb..2020961 100644
--- a/contrib/gregbook/rpng-win.c
+++ b/contrib/gregbook/rpng-win.c
@@ -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.
 
   ---------------------------------------------------------------------------
 
diff --git a/contrib/gregbook/rpng-x.c b/contrib/gregbook/rpng-x.c
index e2dd19b..e821cfb 100644
--- a/contrib/gregbook/rpng-x.c
+++ b/contrib/gregbook/rpng-x.c
@@ -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.
 
   ---------------------------------------------------------------------------
 
diff --git a/contrib/gregbook/rpng2-win.c b/contrib/gregbook/rpng2-win.c
index 638024b..8c831db 100644
--- a/contrib/gregbook/rpng2-win.c
+++ b/contrib/gregbook/rpng2-win.c
@@ -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
 
   ---------------------------------------------------------------------------
 
diff --git a/contrib/gregbook/rpng2-x.c b/contrib/gregbook/rpng2-x.c
index 206b00a..2c24734 100644
--- a/contrib/gregbook/rpng2-x.c
+++ b/contrib/gregbook/rpng2-x.c
@@ -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 @@
     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);
diff --git a/contrib/gregbook/wpng.c b/contrib/gregbook/wpng.c
index 753fef3..a06e352 100644
--- a/contrib/gregbook/wpng.c
+++ b/contrib/gregbook/wpng.c
@@ -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
diff --git a/contrib/gregbook/writepng.c b/contrib/gregbook/writepng.c
index 1d67f89..f07f4a8 100644
--- a/contrib/gregbook/writepng.c
+++ b/contrib/gregbook/writepng.c
@@ -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 @@
     /* 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 @@
     /* 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 @@
     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);
+}