[libpng15] Fixes to alpha swap on read, simplified write and filler add code
diff --git a/pngread.c b/pngread.c
index f6ab7e5..18ed042 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1804,10 +1804,12 @@
          else /* output needs an alpha channel */
          {
             /* This is tricky because it happens before the swap operation has
-             * been accomplished, so always add the alpha channel after the
-             * component channels.
+             * been accomplished however the swap does *not* swap the added
+             * alpha channel (weird API), so it must be added in the correct
+             * place.
              */
             png_uint_32 filler; /* opaque filler */
+            int where;
 
             if (linear)
                filler = 65535;
@@ -1815,9 +1817,21 @@
             else
                filler = 255;
 
-            png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
+#           ifdef PNG_FORMAT_AFIRST_SUPPORTED
+               if (format & PNG_FORMAT_FLAG_AFIRST)
+               {
+                  where = PNG_FILLER_BEFORE;
+                  change &= ~PNG_FORMAT_FLAG_AFIRST;
+               }
+
+               else
+#           endif
+               where = PNG_FILLER_AFTER;
+
+            png_set_add_alpha(png_ptr, filler, where);
          }
 
+         /* This stops the (irrelevant) call to swap_alpha below. */
          change &= ~PNG_FORMAT_FLAG_ALPHA;
       }
 
@@ -1841,7 +1855,7 @@
       }
 
 #     ifdef PNG_FORMAT_BGR_SUPPORTED
-         if (format & PNG_FORMAT_FLAG_BGR)
+         if (change & PNG_FORMAT_FLAG_BGR)
          {
             /* Check only the output format; PNG is never BGR, don't do this if
              * the output is gray, but fix up the 'format' value in that case.
@@ -1857,7 +1871,7 @@
 #     endif
 
 #     ifdef PNG_FORMAT_AFIRST_SUPPORTED
-         if (format & PNG_FORMAT_FLAG_AFIRST)
+         if (change & PNG_FORMAT_FLAG_AFIRST)
          {
             /* Only relevant if there is an alpha channel - it's particularly
              * important to handle this correctly because do_local_compose may
@@ -1924,7 +1938,9 @@
 #     endif
 
 #     ifdef PNG_FORMAT_AFIRST_SUPPORTED
-         if (png_ptr->transformations & PNG_SWAP_ALPHA)
+         if (png_ptr->transformations & PNG_SWAP_ALPHA ||
+            ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
+            (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
             info_format |= PNG_FORMAT_FLAG_AFIRST;
 #     endif
 
diff --git a/pngrutil.c b/pngrutil.c
index c04974b..fc450ea 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -3900,6 +3900,16 @@
 
    max_pixel_depth = png_ptr->pixel_depth;
 
+   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
+    * calculations to calculate the final pixel depth, then
+    * png_do_read_transforms actually does the transforms.  This means that the
+    * code which effectively calculates this value is actually repeated in three
+    * separate places.  They must all match.  Innocent changes to the order of
+    * transformations can and will break libpng in a way that causes memory
+    * overwrites.
+    *
+    * TODO: fix this.
+    */
 #ifdef PNG_READ_PACK_SUPPORTED
    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
       max_pixel_depth = 8;
@@ -3958,10 +3968,7 @@
 #ifdef PNG_READ_FILLER_SUPPORTED
    if (png_ptr->transformations & (PNG_FILLER))
    {
-      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-         max_pixel_depth = 32;
-
-      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
       {
          if (max_pixel_depth <= 8)
             max_pixel_depth = 16;
@@ -3970,7 +3977,8 @@
             max_pixel_depth = 32;
       }
 
-      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
       {
          if (max_pixel_depth <= 32)
             max_pixel_depth = 32;
diff --git a/pngwrite.c b/pngwrite.c
index 594e8e3..def53b0 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -1805,7 +1805,7 @@
          ++out_ptr;
       }
 
-      png_write_row(png_ptr, (png_bytep)output_row);
+      png_write_row(png_ptr, display->local_row);
       input_row += display->row_bytes/(sizeof (png_uint_16));
    }
 
@@ -1911,7 +1911,7 @@
             ++out_ptr;
          } /* while out_ptr < row_end */
 
-         png_write_row(png_ptr, output_row);
+         png_write_row(png_ptr, display->local_row);
          input_row += display->row_bytes/(sizeof (png_uint_16));
       } /* while y */
    }
@@ -1998,11 +1998,9 @@
 
    /* Now set up the data transformations (*after* the header is written),
     * remove the handled transformations from the 'format' flags for checking.
+    *
+    * First check for a little endian system if writing 16 bit files.
     */
-   format &= ~(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
-      PNG_FORMAT_FLAG_ALPHA);
-
-   /* Check for a little endian system if writing 16 bit files. */
    if (write_16bit)
    {
       PNG_CONST png_uint_16 le = 0x0001;
@@ -2014,7 +2012,8 @@
 #  ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
       if (format & PNG_FORMAT_FLAG_BGR)
       {
-         png_set_bgr(png_ptr);
+         if (format & PNG_FORMAT_FLAG_COLOR)
+            png_set_bgr(png_ptr);
          format &= ~PNG_FORMAT_FLAG_BGR;
       }
 #  endif
@@ -2022,13 +2021,15 @@
 #  ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
       if (format & PNG_FORMAT_FLAG_AFIRST)
       {
-         png_set_swap_alpha(png_ptr);
+         if (format & PNG_FORMAT_FLAG_ALPHA)
+            png_set_swap_alpha(png_ptr);
          format &= ~PNG_FORMAT_FLAG_AFIRST;
       }
 #  endif
 
-   /* That should have handled all the transforms. */
-   if (format != 0)
+   /* That should have handled all (both) the transforms. */
+   if ((format & ~(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
+         PNG_FORMAT_FLAG_ALPHA)) != 0)
       png_error(png_ptr, "png_write_image: unsupported transformation");
 
    {