[libpng16] Improved pngstest speed by not doing redundant tests and add const

to the background parameter of png_image_finish_read. The --background
option is now done automagically only when required, so that commandline
option no longer exists.
diff --git a/ANNOUNCE b/ANNOUNCE
index 59b6c88..c15b993 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -150,6 +150,10 @@
   Moved automake options to AM_INIT_AUTOMAKE in configure.ac
   Added color-tests, silent-rules (Not yet implemented in Makefile.am) and
     version checking to configure.ac
+  Improved pngstest speed by not doing redundant tests and add const to
+    the background parameter of png_image_finish_read. The --background
+    option is now done automagically only when required, so that commandline
+    option no longer exists.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index f6ccee0..affd6e8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3901,6 +3901,10 @@
   Moved automake options to AM_INIT_AUTOMAKE in configure.ac
   Added color-tests, silent-rules (Not yet implemented in Makefile.am) and
     version checking to configure.ac
+  Improved pngstest speed by not doing redundant tests and add const to
+    the background parameter of png_image_finish_read. The --background
+    option is now done automagically only when required, so that commandline
+    option no longer exists.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/contrib/libtests/pngstest.c b/contrib/libtests/pngstest.c
index a871f76..e6c2e8a 100644
--- a/contrib/libtests/pngstest.c
+++ b/contrib/libtests/pngstest.c
@@ -44,6 +44,44 @@
 #  define voidcast(type, value) (value)
 #endif /* __cplusplus */
 
+/* Generate random bytes.  This uses a boring repeatable algorithm and it
+ * is implemented here so that it gives the same set of numbers on every
+ * architecture.  It's a linear congruential generator (Knuth or Sedgewick
+ * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
+ * Hill, "The Art of Electronics".
+ */
+static void
+make_random_bytes(png_uint_32* seed, void* pv, size_t size)
+{
+   png_uint_32 u0 = seed[0], u1 = seed[1];
+   png_bytep bytes = voidcast(png_bytep, pv);
+
+   /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
+    * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.
+    */
+   size_t i;
+   for (i=0; i<size; ++i)
+   {
+      /* First generate 8 new bits then shift them in at the end. */
+      png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
+      u1 <<= 8;
+      u1 |= u0 >> 24;
+      u0 <<= 8;
+      u0 |= u;
+      *bytes++ = (png_byte)u;
+   }
+
+   seed[0] = u0;
+   seed[1] = u1;
+}
+
+static void
+random_color(png_colorp color)
+{
+   static png_uint_32 color_seed[2] = { 0x12345678, 0x9abcdef };
+   make_random_bytes(color_seed, color, sizeof *color);
+}
+
 /* Math support - neither Cygwin nor Visual Studio have C99 support and we need
  * a predictable rounding function, so make one here:
  */
@@ -110,9 +148,6 @@
       double e = fabs(
          pow(linear_from_sRGB(vd), 1/2.2) - sRGB_from_linear(pow(vd, 2.2)));
 
-      /* TODO: remove this, it's a math check */
-      if (e*255 >= 17) abort();
-
       /* Always allow an extra 1 here for rounding errors */
       e = 1+floor(255 * e);
       return (int)e;
@@ -194,7 +229,7 @@
 
 #define READ_FILE 1      /* else memory */
 #define USE_STDIO 2      /* else use file name */
-#define USE_BACKGROUND 4 /* else composite in place */
+/* 4: unused */
 #define VERBOSE 8
 #define KEEP_TMPFILES 16 /* else delete temporary files */
 #define KEEP_GOING 32
@@ -206,8 +241,6 @@
       printf(" --file");
    if (opts & USE_STDIO)
       printf(" --stdio");
-   if (opts & USE_BACKGROUND)
-      printf(" --background");
    if (opts & VERBOSE)
       printf(" --verbose");
    if (opts & KEEP_TMPFILES)
@@ -330,21 +363,23 @@
 {
    int i;
    for (i=0; i<FORMAT_SET_COUNT; ++i)
-      pf->bits[i] = ~(png_uint_32)0;
+      pf->bits[i] = 0; /* All off */
 }
 
+#if 0 /* currently unused */
 static void format_clear(format_list *pf)
 {
    int i;
    for (i=0; i<FORMAT_SET_COUNT; ++i)
       pf->bits[i] = 0;
 }
+#endif
 
 static int format_is_initial(format_list *pf)
 {
    int i;
    for (i=0; i<FORMAT_SET_COUNT; ++i)
-      if (pf->bits[i] != ~(png_uint_32)0)
+      if (pf->bits[i] != 0)
          return 0;
 
    return 1;
@@ -374,6 +409,38 @@
       (pf->bits[format >> 5] & (((png_uint_32)1) << (format & 31))) != 0;
 }
 
+static void format_default(format_list *pf, int redundant)
+{
+   if (redundant)
+   {
+      int i;
+      
+      /* set everything, including flags that are pointless */
+      for (i=0; i<FORMAT_SET_COUNT; ++i)
+         pf->bits[i] = ~(png_uint_32)0;
+   }
+
+   else
+   {
+      png_uint_32 f;
+
+      for (f=0; f<FORMAT_COUNT; ++f)
+      {
+         /* Eliminate redundant settings. */
+         /* BGR is meaningless if no color: */
+         if ((f & PNG_FORMAT_FLAG_COLOR) == 0 && (f & PNG_FORMAT_FLAG_BGR) != 0)
+            continue;
+
+         /* AFIRST is meaningless if no alpha: */
+         if ((f & PNG_FORMAT_FLAG_ALPHA) == 0 &&
+            (f & PNG_FORMAT_FLAG_AFIRST) != 0)
+            continue;
+
+         format_set(pf, f);
+      }
+   }
+}
+
 /* THE Image STRUCTURE */
 /* The super-class of a png_image, contains the decoded image plus the input
  * data necessary to re-read the file with a different format.
@@ -391,7 +458,7 @@
    ptrdiff_t   stride;
    png_size_t  bufsize;
    png_size_t  allocsize;
-   png_color   background;
+   /* png_color   background; */
    char        tmpfile_name[32];
    png_uint_16 colormap[256*4];
 }
@@ -1315,7 +1382,7 @@
              */
             if ((a->format & PNG_FORMAT_FLAG_COLOR) == 0)
             {
-               /*TODO: grayscale input */
+               /* grayscale input, currently generates no additional errors */
             }
 
             else if ((a->format & PNG_FORMAT_FLAG_COLORMAP) == 0)
@@ -1474,7 +1541,8 @@
  * to * give image 'b'.  The formats may have been changed.
  */
 static int
-compare_two_images(Image *a, Image *b, int via_linear)
+compare_two_images(Image *a, Image *b, int via_linear,
+   png_const_colorp background)
 {
    png_uint_32 width = a->image.width;
    png_uint_32 height = a->image.height;
@@ -1492,8 +1560,6 @@
    png_byte swap_mask[4];
    png_uint_32 x, y;
    png_const_bytep ppa, ppb;
-   const png_color *background =
-      ((b->opts & USE_BACKGROUND) ? &b->background : NULL);
 
    /* This should never happen: */
    if (width != b->image.width || height != b->image.height)
@@ -1968,7 +2034,7 @@
  * input_memory have been set.
  */
 static int
-read_file(Image *image, png_uint_32 format)
+read_file(Image *image, png_uint_32 format, png_const_colorp background)
 {
    memset(&image->image, 0, sizeof image->image);
    image->image.version = PNG_IMAGE_VERSION;
@@ -1999,22 +2065,27 @@
       int result;
       png_uint_32 image_format;
 
-      /* Various random settings for detecting overwrites */
-      image->background.red = 89;
-      image->background.green = 78;
-      image->background.blue = 178;
-
       /* Print both original and output formats. */
       image_format = image->image.format;
 
       if (image->opts & VERBOSE)
-         printf("%s %lu x %lu %s -> %s\n", image->file_name,
+      {
+         printf("%s %lu x %lu %s -> %s", image->file_name,
             (unsigned long)image->image.width,
             (unsigned long)image->image.height,
             format_names[image_format & FORMAT_MASK],
             (format & FORMAT_NO_CHANGE) != 0 || image->image.format == format
             ? "no change" : format_names[format & FORMAT_MASK]);
 
+         if (background != NULL)
+            printf(" background(%d,%d,%d)\n", background->red,
+               background->green, background->blue);
+         else
+            printf("\n");
+
+         fflush(stdout);
+      }
+
       /* 'NO_CHANGE' combined with the color-map flag forces the base format
        * flags to be set on read to ensure that the original representation is
        * not lost in the pass through a colormap format.
@@ -2031,16 +2102,10 @@
 
       image->image.format = format;
 
-      /* Force the background if the output is colormapped and not linear */
-      if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
-         (format & PNG_FORMAT_FLAG_LINEAR) == 0)
-         image->opts |= USE_BACKGROUND;
-
       image->stride = PNG_IMAGE_ROW_STRIDE(image->image) + image->stride_extra;
       allocbuffer(image);
 
-      result = png_image_finish_read(&image->image,
-         (image->opts & USE_BACKGROUND) ? &image->background : NULL,
+      result = png_image_finish_read(&image->image, background,
          image->buffer+16, (png_int_32)image->stride, image->colormap);
 
       checkbuffer(image, image->file_name);
@@ -2054,10 +2119,11 @@
 }
 
 /* Reads from a filename, which must be in image->file_name, but uses
- * image->opts to choose the method.
+ * image->opts to choose the method.  The file is always read in its native
+ * format (the one the simplified API suggests).
  */
 static int
-read_one_file(Image *image, png_uint_32 format)
+read_one_file(Image *image)
 {
    if (!(image->opts & READ_FILE) || (image->opts & USE_STDIO))
    {
@@ -2117,7 +2183,7 @@
             strerror(errno));
    }
 
-   return read_file(image, format);
+   return read_file(image, FORMAT_NO_CHANGE, NULL);
 }
 
 static int
@@ -2186,7 +2252,7 @@
     * the linear, color and maybe alpha flags, this will cause spurious failures
     * under some circumstances.
     */
-   if (read_file(output, image->image.format | FORMAT_NO_CHANGE))
+   if (read_file(output, image->image.format | FORMAT_NO_CHANGE, NULL))
    {
       png_uint_32 original_format = image->image.format;
 
@@ -2198,7 +2264,7 @@
          return logerror(image, image->file_name, ": format changed on read: ",
             output->file_name);
 
-      return compare_two_images(image, output, 0);
+      return compare_two_images(image, output, 0/*via linear*/, NULL);
    }
 
    else
@@ -2227,23 +2293,69 @@
    image->tmpfile_name[0] = 0;
 
    {
-      png_uint_32 format;
+      png_uint_32 counter;
       Image output;
 
       newimage(&output);
       
       result = 1;
-      for (format=0; format<64; ++format)
-         if (format_isset(pf, format))
+
+      /* Use the low bit of 'counter' to indicate whether or not to do alpha
+       * removal with a background color or by composting onto the image; this
+       * step gets skipped if it isn't relevant
+       */
+      for (counter=0; counter<2*FORMAT_COUNT; ++counter)
+         if (format_isset(pf, counter >> 1))
       {
+         png_uint_32 format = counter >> 1;
+
+         png_color background_color;
+         png_colorp background = NULL;
+
+         /* If there is a format change that removes the alpha channel then
+          * the background is relevant.  If the output is 8-bit color-mapped
+          * then a background color *must* be provided, otherwise there are
+          * two tests to do - one with a color, the other with NULL.  The
+          * NULL test happens second.
+          */
+         if ((counter & 1) == 0)
+         {
+            if ((format & PNG_FORMAT_FLAG_ALPHA) == 0 &&
+               (image->image.format & PNG_FORMAT_FLAG_ALPHA) != 0)
+            {
+               /* Alpha/transparency will be removed, the background is
+                * relevant: make it a color the first time
+                */
+               random_color(&background_color);
+               background = &background_color;
+
+               /* BUT if the output is to a color-mapped 8-bit format then
+                * the background must always be a color, so increment 'counter'
+                * to skip the NULL test.
+                */
+               if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
+                  (format & PNG_FORMAT_FLAG_LINEAR) == 0)
+                  ++counter;
+            }
+
+            /* Otherwise an alpha channel is not being eliminated, just leave
+             * background NULL and skip the (counter & 1) NULL test.
+             */
+            else
+               ++counter;
+         }
+         /* else just use NULL for background */
+
+
          resetimage(&copy);
-         copy.opts = opts; /* because read_file can change it */
-         result = read_file(&copy, format);
+         copy.opts = opts; /* in case read_file needs to change it */
+
+         result = read_file(&copy, format, background);
          if (!result)
             break;
 
          /* Make sure the file just read matches the original file. */
-         result = compare_two_images(image, &copy, 0);
+         result = compare_two_images(image, &copy, 0/*via linear*/, background);
          if (!result)
             break;
 
@@ -2255,8 +2367,10 @@
          if (!result)
             break;
 
-         /* Validate against the original too: */
-         result = compare_two_images(image, &output, 0);
+         /* Validate against the original too; the background is needed here
+          * as well so that compare_two_images knows what color was used.
+          */
+         result = compare_two_images(image, &output, 0, background);
          if (!result)
             break;
 
@@ -2278,7 +2392,8 @@
              * linear), handle this by composing on black when doing the
              * comparison.
              */
-            result = compare_two_images(image, &output, 1/*via_linear*/);
+            result = compare_two_images(image, &output, 1/*via_linear*/,
+               background);
             if (!result)
                break;
          }
@@ -2299,6 +2414,7 @@
    format_list formats;
    const char *touch = NULL;
    int log_pass = 0;
+   int redundant = 0;
    int stride_extra = 0;
    int retval = 0;
    int c;
@@ -2319,10 +2435,6 @@
          opts |= USE_STDIO;
       else if (strcmp(arg, "--name") == 0)
          opts &= ~USE_STDIO;
-      else if (strcmp(arg, "--background") == 0)
-         opts |= USE_BACKGROUND;
-      else if (strcmp(arg, "--composite") == 0)
-         opts &= ~USE_BACKGROUND;
       else if (strcmp(arg, "--verbose") == 0)
          opts |= VERBOSE;
       else if (strcmp(arg, "--quiet") == 0)
@@ -2333,6 +2445,8 @@
          opts &= ~KEEP_TMPFILES;
       else if (strcmp(arg, "--keep-going") == 0)
          opts |= KEEP_GOING;
+      else if (strcmp(arg, "--redundant") == 0)
+         redundant = 1;
       else if (strcmp(arg, "--stop") == 0)
          opts &= ~KEEP_GOING;
       else if (strcmp(arg, "--touch") == 0)
@@ -2355,9 +2469,6 @@
          if (format > FORMAT_COUNT)
             exit(1);
 
-         if (format_is_initial(&formats))
-            format_clear(&formats);
-
          format_set(&formats, format);
       }
       else if (arg[0] == '-')
@@ -2371,9 +2482,12 @@
          int result;
          Image image;
 
+         if (format_is_initial(&formats))
+            format_default(&formats, redundant);
+
          newimage(&image);
          initimage(&image, opts, arg, stride_extra);
-         result = read_one_file(&image, FORMAT_NO_CHANGE);
+         result = read_one_file(&image);
          if (result)
             result = testimage(&image, opts, &formats);
          freeimage(&image);
diff --git a/png.h b/png.h
index 83c9240..e7b5f47 100644
--- a/png.h
+++ b/png.h
@@ -1,7 +1,7 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.6.0beta08 - January 28, 2012
+ * libpng version 1.6.0beta08 - January 29, 2012
  * Copyright (c) 1998-2012 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -11,7 +11,7 @@
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.6.0beta08 - January 28, 2012: Glenn
+ *   libpng versions 0.97, January 1998, through 1.6.0beta08 - January 29, 2012: Glenn
  *   See also "Contributing Authors", below.
  *
  * Note about libpng version numbers:
@@ -198,7 +198,7 @@
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.2.6, August 15, 2004, through 1.6.0beta08, January 28, 2012, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.0beta08, January 29, 2012, are
  * Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are
  * distributed according to the same disclaimer and license as libpng-1.2.5
  * with the following individual added to the list of Contributing Authors:
@@ -310,7 +310,7 @@
  * Y2K compliance in libpng:
  * =========================
  *
- *    January 28, 2012
+ *    January 29, 2012
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
@@ -376,7 +376,7 @@
 /* Version information for png.h - this should match the version in png.c */
 #define PNG_LIBPNG_VER_STRING "1.6.0beta08"
 #define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.6.0beta08 - January 28, 2012\n"
+     " libpng version 1.6.0beta08 - January 29, 2012\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
@@ -2948,7 +2948,7 @@
    /* The PNG header is read from the given memory buffer. */
 
 PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
-   png_colorp background, void *buffer, png_int_32 row_stride,
+   png_const_colorp background, void *buffer, png_int_32 row_stride,
    void *colormap));
    /* Finish reading the image into the supplied buffer and clean up the
     * png_image structure.
diff --git a/pngread.c b/pngread.c
index 7ff4d08..c4cc05a 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1191,7 +1191,7 @@
    png_voidp  buffer;
    png_int_32 row_stride;
    png_voidp  colormap;
-   png_colorp background;
+   png_const_colorp background;
    /* Local variables: */
    png_bytep       local_row;
    png_bytep       first_row;
@@ -3882,8 +3882,8 @@
 }
 
 int PNGAPI
-png_image_finish_read(png_imagep image, png_colorp background, void *buffer,
-   png_int_32 row_stride, void *colormap)
+png_image_finish_read(png_imagep image, png_const_colorp background,
+   void *buffer, png_int_32 row_stride, void *colormap)
 {
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
diff --git a/test-pngstest.sh b/test-pngstest.sh
index 2068c38..7b1f4cc 100755
--- a/test-pngstest.sh
+++ b/test-pngstest.sh
@@ -7,7 +7,7 @@
 echo "============ pngstest.sh ==============" >> pngtest-log.txt
 
 echo "Running test-pngstest.sh on contrib/pngsuite/*.png"
-for opts in "" "--background"
+for opts in ""
 do
    if ./pngstest --log "$@" $opts ${srcdir}/contrib/pngsuite/bas*.png \
       >>pngtest-log.txt 2>&1