[libpng15] Add ability to call png_read_update_info multiple times to pngvalid.c
diff --git a/ANNOUNCE b/ANNOUNCE
index ec5b38f..3de83eb 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
 
-Libpng 1.5.6beta06 - October 14, 2011
+Libpng 1.5.6beta06 - October 15, 2011
 
 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.
@@ -70,10 +70,11 @@
     previously possible because the png_struct buffer was always misaligned.
   Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01.
 
-Version 1.5.6beta06 [October 14, 2011]
+Version 1.5.6beta06 [October 15, 2011]
   Removed two redundant tests for unitialized row.
   Fixed a relatively harmless memory overwrite in compressed text writing
     with a 1 byte zlib buffer.
+  Add ability to call png_read_update_info multiple times to pngvalid.c
   Fixes for multiple calls to png_read_update_info. These fixes attend to
     most of the errors revealed in pngvalid, however doing the gamma work
     twice results in inaccuracies that can't be easily fixed.  There is now
diff --git a/CHANGES b/CHANGES
index dd7967a..beb153d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3631,10 +3631,11 @@
     previously possible because the png_struct buffer was always misaligned.
   Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01.
 
-Version 1.5.6beta06 [October 14, 2011]
+Version 1.5.6beta06 [October 15, 2011]
   Removed two redundant tests for unitialized row.
   Fixed a relatively harmless memory overwrite in compressed text writing
     with a 1 byte zlib buffer.
+  Add ability to call png_read_update_info multiple times to pngvalid.c.
   Fixes for multiple calls to png_read_update_info. These fixes attend to
     most of the errors revealed in pngvalid, however doing the gamma work
     twice results in inaccuracies that can't be easily fixed.  There is now
diff --git a/pngvalid.c b/pngvalid.c
index c895220..28cceaa 100644
--- a/pngvalid.c
+++ b/pngvalid.c
@@ -1715,6 +1715,11 @@
    double                   error_indexed;
 
    /* Flags: */
+   /* Whether to call png_read_update_info, not png_read_start_image, and how
+    * many times to call it.
+    */
+   int                      use_update_info;
+
    /* Whether or not to interlace. */
    int                      interlace_type :9; /* int, but must store '1' */
 
@@ -1798,6 +1803,7 @@
    pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
    pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
    pm->error_indexed = 0;
+   pm->use_update_info = 0;
    pm->interlace_type = PNG_INTERLACE_NONE;
    pm->test_standard = 0;
    pm->test_size = 0;
@@ -3884,6 +3890,7 @@
    int         do_interlace;   /* Do interlacing internally */
    int         is_transparent; /* Transparency information was present. */
    int         speed;          /* Doing a speed test */
+   int         use_update_info;/* Call update_info, not start_image */
    struct
    {
       png_uint_16 red;
@@ -3897,7 +3904,7 @@
 
 static void
 standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
-   int do_interlace)
+   int do_interlace, int use_update_info)
 {
    memset(dp, 0, sizeof *dp);
 
@@ -3921,6 +3928,7 @@
    dp->do_interlace = do_interlace;
    dp->is_transparent = 0;
    dp->speed = ps->speed;
+   dp->use_update_info = use_update_info;
    dp->npalette = 0;
    /* Preset the transparent color to black: */
    memset(&dp->transparent, 0, sizeof dp->transparent);
@@ -4278,7 +4286,16 @@
    /* And the info callback has to call this (or png_read_update_info - see
     * below in the png_modifier code for that variant.
     */
-   png_start_read_image(pp);
+   if (dp->use_update_info)
+   {
+      /* For debugging the effect of multiple calls: */
+      int i = dp->use_update_info;
+      while (i-- > 0)
+         png_read_update_info(pp, pi);
+   }
+
+   else
+      png_start_read_image(pp);
 
    /* Validate the height, width and rowbytes plus ensure that sufficient buffer
     * exists for decoding the image.
@@ -4496,7 +4513,7 @@
 /* A single test run checking the standard image to ensure it is not damaged. */
 static void
 standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id,
-   int do_interlace)
+   int do_interlace, int use_update_info)
 {
    standard_display d;
    context(psIn, fault);
@@ -4504,7 +4521,7 @@
    /* Set up the display (stack frame) variables from the arguments to the
     * function and initialize the locals that are filled in later.
     */
-   standard_display_init(&d, psIn, id, do_interlace);
+   standard_display_init(&d, psIn, id, do_interlace, use_update_info);
 
    /* Everything is protected by a Try/Catch.  The functions called also
     * typically have local Try/Catch blocks.
@@ -4591,7 +4608,7 @@
            interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
       {
          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
-            interlace_type, 0, 0, 0), 0/*do_interlace*/);
+            interlace_type, 0, 0, 0), 0/*do_interlace*/, pm->use_update_info);
 
          if (fail(pm))
             return 0;
@@ -4650,25 +4667,29 @@
           * to validate.
           */
          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
-            PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/);
+            PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,
+            pm->use_update_info);
 
          if (fail(pm))
             return 0;
 
          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
-            PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/);
+            PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,
+            pm->use_update_info);
 
          if (fail(pm))
             return 0;
 
          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
-            PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/);
+            PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
+            pm->use_update_info);
 
          if (fail(pm))
             return 0;
 
          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
-            PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/);
+            PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,
+            pm->use_update_info);
 
          if (fail(pm))
             return 0;
@@ -4678,13 +4699,15 @@
           * to the code used in the non-interlaced case too.
           */
          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
-            PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/);
+            PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,
+            pm->use_update_info);
 
          if (fail(pm))
             return 0;
 
          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
-            PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/);
+            PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
+            pm->use_update_info);
 
          if (fail(pm))
             return 0;
@@ -5159,7 +5182,8 @@
    memset(dp, 0, sizeof dp);
 
    /* Standard fields */
-   standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/);
+   standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/,
+      1/*use_update_info*/);
 
    /* Parameter fields */
    dp->pm = pm;
@@ -5180,7 +5204,13 @@
    dp->transform_list->set(dp->transform_list, dp, pp, pi);
 
    /* Update the info structure for these transforms: */
-   png_read_update_info(pp, pi);
+   {
+      int i = dp->this.use_update_info;
+      /* Always do one call, even if use_update_info is 0. */
+      do
+         png_read_update_info(pp, pi);
+      while (--i > 0);
+   }
 
    /* And get the output information into the standard_display */
    standard_info_part2(&dp->this, pp, pi, 1/*images*/);
@@ -7012,7 +7042,8 @@
     double background_gamma)
 {
    /* Standard fields */
-   standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/);
+   standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/,
+      1/*use_update_info*/);
 
    /* Parameter fields */
    dp->pm = pm;
@@ -7141,7 +7172,13 @@
       }
    }
 
-   png_read_update_info(pp, pi);
+   {
+      int i = dp->this.use_update_info;
+      /* Always do one call, even if use_update_info is 0. */
+      do
+         png_read_update_info(pp, pi);
+      while (--i > 0);
+   }
 
    /* Now we may get a different cbRow: */
    standard_info_part2(&dp->this, pp, pi, 1 /*images*/);
@@ -9372,6 +9409,9 @@
       else if (strcmp(*argv, "--progressive-read") == 0)
          pm.this.progressive = 1;
 
+      else if (strcmp(*argv, "--use-update-info") == 0)
+         ++pm.use_update_info; /* Can call multiple times */
+
       else if (strcmp(*argv, "--interlace") == 0)
          pm.interlace_type = PNG_INTERLACE_ADAM7;