Selaa lähdekoodia

libpng: New version 1.6.27

Warning: libpng 1.6 is strict about iCCp chunks being incorrect,
solution is to fix the profile. On *nix ImageMagicks "convert" works
on windows optiPNG.
J08nY 9 vuotta sitten
vanhempi
commit
f0290e643b

+ 27 - 124
drivers/png/arm/arm_init.c

@@ -1,9 +1,9 @@
 
 /* arm_init.c - NEON optimised filter functions
  *
- * Copyright (c) 2013 Glenn Randers-Pehrson
+ * Copyright (c) 2014,2016 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.8 [December 19, 2013]
+ * Last changed in libpng 1.6.22 [June 9, 2016]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -17,134 +17,36 @@
 #include "../pngpriv.h"
 
 #ifdef PNG_READ_SUPPORTED
+
 #if PNG_ARM_NEON_OPT > 0
 #ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */
-#include <signal.h> /* for sig_atomic_t */
-
-#ifdef __ANDROID__
-/* Linux provides access to information about CPU capabilites via
- * /proc/self/auxv, however Android blocks this while still claiming to be
- * Linux.  The Andoid NDK, however, provides appropriate support.
+/* WARNING: it is strongly recommended that you do not build libpng with
+ * run-time checks for CPU features if at all possible.  In the case of the ARM
+ * NEON instructions there is no processor-specific way of detecting the
+ * presence of the required support, therefore run-time detection is extremely
+ * OS specific.
  *
- * Documentation: http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
- */
-#include <cpu-features.h>
-
-static int
-png_have_neon(png_structp png_ptr)
-{
-   /* This is a whole lot easier than the mess below, however it is probably
-    * implemented as below, therefore it is better to cache the result (these
-    * function calls may be slow!)
-    */
-   PNG_UNUSED(png_ptr)
-   return android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&
-      (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
-}
-#elif defined(__linux__)
-/* The generic __linux__ implementation requires reading /proc/self/auxv and
- * looking at each element for one that records NEON capabilities.
- */
-#include <unistd.h> /* for POSIX 1003.1 */
-#include <errno.h>  /* for EINTR */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <elf.h>
-#include <asm/hwcap.h>
-
-/* A read call may be interrupted, in which case it returns -1 and sets errno to
- * EINTR if nothing was done, otherwise (if something was done) a partial read
- * may result.
+ * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing
+ * a fragment of C source code which defines the png_have_neon function.  There
+ * are a number of implementations in contrib/arm-neon, but the only one that
+ * has partial support is contrib/arm-neon/linux.c - a generic Linux
+ * implementation which reads /proc/cpufino.
  */
-static size_t
-safe_read(png_structp png_ptr, int fd, void *buffer_in, size_t nbytes)
-{
-   size_t ntotal = 0;
-   char *buffer = png_voidcast(char*, buffer_in);
-
-   while (nbytes > 0)
-   {
-      unsigned int nread;
-      int iread;
-
-      /* Passing nread > INT_MAX to read is implementation defined in POSIX
-       * 1003.1, therefore despite the unsigned argument portable code must
-       * limit the value to INT_MAX!
-       */
-      if (nbytes > INT_MAX)
-         nread = INT_MAX;
-
-      else
-         nread = (unsigned int)/*SAFE*/nbytes;
-
-      iread = read(fd, buffer, nread);
-
-      if (iread == -1)
-      {
-         /* This is the devil in the details, a read can terminate early with 0
-          * bytes read because of EINTR, yet it still returns -1 otherwise end
-          * of file cannot be distinguished.
-          */
-         if (errno != EINTR)
-         {
-            png_warning(png_ptr, "/proc read failed");
-            return 0; /* I.e., a permanent failure */
-         }
-      }
-
-      else if (iread < 0)
-      {
-         /* Not a valid 'read' result: */
-         png_warning(png_ptr, "OS /proc read bug");
-         return 0;
-      }
-
-      else if (iread > 0)
-      {
-         /* Continue reading until a permanent failure, or EOF */
-         buffer += iread;
-         nbytes -= (unsigned int)/*SAFE*/iread;
-         ntotal += (unsigned int)/*SAFE*/iread;
-      }
-
-      else
-         return ntotal;
-   }
-
-   return ntotal; /* nbytes == 0 */
-}
+#ifndef PNG_ARM_NEON_FILE
+#  ifdef __linux__
+#     define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
+#  endif
+#endif
 
-static int
-png_have_neon(png_structp png_ptr)
-{
-   int fd = open("/proc/self/auxv", O_RDONLY);
-   Elf32_auxv_t aux;
+#ifdef PNG_ARM_NEON_FILE
 
-   /* Failsafe: failure to open means no NEON */
-   if (fd == -1)
-   {
-      png_warning(png_ptr, "/proc/self/auxv open failed");
-      return 0;
-   }
-
-   while (safe_read(png_ptr, fd, &aux, sizeof aux) == sizeof aux)
-   {
-      if (aux.a_type == AT_HWCAP && (aux.a_un.a_val & HWCAP_NEON) != 0)
-      {
-         close(fd);
-         return 1;
-      }
-   }
+#include <signal.h> /* for sig_atomic_t */
+static int png_have_neon(png_structp png_ptr);
+#include PNG_ARM_NEON_FILE
 
-   close(fd);
-   return 0;
-}
-#else
-   /* We don't know how to do a run-time check on this system */
-#  error "no support for run-time ARM NEON checks"
-#endif /* OS checks */
+#else  /* PNG_ARM_NEON_FILE */
+#  error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks"
+#endif /* PNG_ARM_NEON_FILE */
 #endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
 
 #ifndef PNG_ALIGNED_MEMORY_SUPPORTED
@@ -164,6 +66,7 @@ png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
     * wrong order of the 'ON' and 'default' cases.  UNSET now defaults to OFF,
     * as documented in png.h
     */
+   png_debug(1, "in png_init_filter_functions_neon");
 #ifdef PNG_ARM_NEON_API_SUPPORTED
    switch ((pp->options >> PNG_ARM_NEON) & 3)
    {
@@ -229,4 +132,4 @@ png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
    }
 }
 #endif /* PNG_ARM_NEON_OPT > 0 */
-#endif /* PNG_READ_SUPPORTED */
+#endif /* READ */

+ 22 - 4
drivers/png/arm/filter_neon.S

@@ -1,17 +1,17 @@
 
 /* filter_neon.S - NEON optimised filter functions
  *
- * Copyright (c) 2013 Glenn Randers-Pehrson
+ * Copyright (c) 2014 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.5.17 [June 27, 2013]
+ * Last changed in libpng 1.6.16 [December 22, 2014]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
-/* This is required to get the symbol renames, which are #defines, and also
- * includes the definition (or not) of PNG_ARM_NEON_OPT.
+/* This is required to get the symbol renames, which are #defines, and the
+ * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION.
  */
 #define PNG_VERSION_INFO_ONLY
 #include "../pngpriv.h"
@@ -20,6 +20,15 @@
 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
 #endif
 
+#ifdef PNG_READ_SUPPORTED
+
+/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
+ * ARM64).  The code in arm/filter_neon_intrinsics.c supports ARM64, however it
+ * only works if -mfpu=neon is specified on the GCC command line.  See pngpriv.h
+ * for the logic which sets PNG_USE_ARM_NEON_ASM:
+ */
+#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
+
 #if PNG_ARM_NEON_OPT > 0
 
 #ifdef __ELF__
@@ -38,6 +47,13 @@ ELF     .size   \name, . - \name
         .purgem endfunc
     .endm
         .text
+
+        /* Explicitly specifying alignment here because some versions of
+         * GAS don't align code correctly.  This is harmless in correctly
+         * written versions of GAS.
+         */
+        .align 2
+
     .if \export
         .global \name
     .endif
@@ -233,3 +249,5 @@ func    png_read_filter_row_paeth3_neon, export=1
         pop             {r4,pc}
 endfunc
 #endif /* PNG_ARM_NEON_OPT > 0 */
+#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */
+#endif /* READ */

+ 387 - 0
drivers/png/arm/filter_neon_intrinsics.c

@@ -0,0 +1,387 @@
+
+/* filter_neon_intrinsics.c - NEON optimised filter functions
+ *
+ * Copyright (c) 2014,2016 Glenn Randers-Pehrson
+ * Written by James Yu <james.yu at linaro.org>, October 2013.
+ * Based on filter_neon.S, written by Mans Rullgard, 2011.
+ *
+ * Last changed in libpng 1.6.22 [June 9, 2016]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* This code requires -mfpu=neon on the command line: */
+#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
+
+#include <arm_neon.h>
+
+/* libpng row pointers are not necessarily aligned to any particular boundary,
+ * however this code will only work with appropriate alignment.  arm/arm_init.c
+ * checks for this (and will not compile unless it is done). This code uses
+ * variants of png_aligncast to avoid compiler warnings.
+ */
+#define png_ptr(type,pointer) png_aligncast(type *,pointer)
+#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
+
+/* The following relies on a variable 'temp_pointer' being declared with type
+ * 'type'.  This is written this way just to hide the GCC strict aliasing
+ * warning; note that the code is safe because there never is an alias between
+ * the input and output pointers.
+ */
+#define png_ldr(type,pointer)\
+   (temp_pointer = png_ptr(type,pointer), *temp_pointer)
+
+#if PNG_ARM_NEON_OPT > 0
+
+void
+png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+   png_const_bytep pp = prev_row;
+
+   png_debug(1, "in png_read_filter_row_up_neon");
+
+   for (; rp < rp_stop; rp += 16, pp += 16)
+   {
+      uint8x16_t qrp, qpp;
+
+      qrp = vld1q_u8(rp);
+      qpp = vld1q_u8(pp);
+      qrp = vaddq_u8(qrp, qpp);
+      vst1q_u8(rp, qrp);
+   }
+}
+
+void
+png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x16_t vtmp = vld1q_u8(rp);
+   uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
+   uint8x8x2_t vrp = *vrpt;
+
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   png_debug(1, "in png_read_filter_row_sub3_neon");
+
+   for (; rp < rp_stop;)
+   {
+      uint8x8_t vtmp1, vtmp2;
+      uint32x2_t *temp_pointer;
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+      vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+      vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
+      vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
+
+      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+      vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
+      vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
+
+      vtmp = vld1q_u8(rp + 12);
+      vrpt = png_ptr(uint8x8x2_t, &vtmp);
+      vrp = *vrpt;
+
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+      rp += 3;
+   }
+
+   PNG_UNUSED(prev_row)
+}
+
+void
+png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   png_debug(1, "in png_read_filter_row_sub4_neon");
+
+   for (; rp < rp_stop; rp += 16)
+   {
+      uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
+      uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
+      uint8x8x4_t vrp = *vrpt;
+      uint32x2x4_t *temp_pointer;
+
+      vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+      vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
+      vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
+      vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
+      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+   }
+
+   PNG_UNUSED(prev_row)
+}
+
+void
+png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_const_bytep pp = prev_row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x16_t vtmp;
+   uint8x8x2_t *vrpt;
+   uint8x8x2_t vrp;
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   vtmp = vld1q_u8(rp);
+   vrpt = png_ptr(uint8x8x2_t,&vtmp);
+   vrp = *vrpt;
+
+   png_debug(1, "in png_read_filter_row_avg3_neon");
+
+   for (; rp < rp_stop; pp += 12)
+   {
+      uint8x8_t vtmp1, vtmp2, vtmp3;
+
+      uint8x8x2_t *vppt;
+      uint8x8x2_t vpp;
+
+      uint32x2_t *temp_pointer;
+
+      vtmp = vld1q_u8(pp);
+      vppt = png_ptr(uint8x8x2_t,&vtmp);
+      vpp = *vppt;
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+      vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+      vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
+      vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
+      vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
+      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+
+      vtmp = vld1q_u8(rp + 12);
+      vrpt = png_ptr(uint8x8x2_t,&vtmp);
+      vrp = *vrpt;
+
+      vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
+      vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
+
+      vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+      vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
+      vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+      rp += 3;
+   }
+}
+
+void
+png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+   png_const_bytep pp = prev_row;
+
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   png_debug(1, "in png_read_filter_row_avg4_neon");
+
+   for (; rp < rp_stop; rp += 16, pp += 16)
+   {
+      uint32x2x4_t vtmp;
+      uint8x8x4_t *vrpt, *vppt;
+      uint8x8x4_t vrp, vpp;
+      uint32x2x4_t *temp_pointer;
+
+      vtmp = vld4_u32(png_ptr(uint32_t,rp));
+      vrpt = png_ptr(uint8x8x4_t,&vtmp);
+      vrp = *vrpt;
+      vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+      vppt = png_ptr(uint8x8x4_t,&vtmp);
+      vpp = *vppt;
+
+      vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+      vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
+      vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+      vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
+      vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+      vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
+      vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+   }
+}
+
+static uint8x8_t
+paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c)
+{
+   uint8x8_t d, e;
+   uint16x8_t p1, pa, pb, pc;
+
+   p1 = vaddl_u8(a, b); /* a + b */
+   pc = vaddl_u8(c, c); /* c * 2 */
+   pa = vabdl_u8(b, c); /* pa */
+   pb = vabdl_u8(a, c); /* pb */
+   pc = vabdq_u16(p1, pc); /* pc */
+
+   p1 = vcleq_u16(pa, pb); /* pa <= pb */
+   pa = vcleq_u16(pa, pc); /* pa <= pc */
+   pb = vcleq_u16(pb, pc); /* pb <= pc */
+
+   p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
+
+   d = vmovn_u16(pb);
+   e = vmovn_u16(p1);
+
+   d = vbsl_u8(d, b, c);
+   e = vbsl_u8(e, a, d);
+
+   return e;
+}
+
+void
+png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_const_bytep pp = prev_row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+
+   uint8x16_t vtmp;
+   uint8x8x2_t *vrpt;
+   uint8x8x2_t vrp;
+   uint8x8_t vlast = vdup_n_u8(0);
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   vtmp = vld1q_u8(rp);
+   vrpt = png_ptr(uint8x8x2_t,&vtmp);
+   vrp = *vrpt;
+
+   png_debug(1, "in png_read_filter_row_paeth3_neon");
+
+   for (; rp < rp_stop; pp += 12)
+   {
+      uint8x8x2_t *vppt;
+      uint8x8x2_t vpp;
+      uint8x8_t vtmp1, vtmp2, vtmp3;
+      uint32x2_t *temp_pointer;
+
+      vtmp = vld1q_u8(pp);
+      vppt = png_ptr(uint8x8x2_t,&vtmp);
+      vpp = *vppt;
+
+      vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+      vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+      vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]);
+      vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+      vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
+      vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
+      vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2);
+      vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
+
+      vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+      vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+      vtmp = vld1q_u8(rp + 12);
+      vrpt = png_ptr(uint8x8x2_t,&vtmp);
+      vrp = *vrpt;
+
+      vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3);
+      vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+      vlast = vtmp2;
+
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+      rp += 3;
+      vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+      rp += 3;
+   }
+}
+
+void
+png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_bytep rp = row;
+   png_bytep rp_stop = row + row_info->rowbytes;
+   png_const_bytep pp = prev_row;
+
+   uint8x8_t vlast = vdup_n_u8(0);
+   uint8x8x4_t vdest;
+   vdest.val[3] = vdup_n_u8(0);
+
+   png_debug(1, "in png_read_filter_row_paeth4_neon");
+
+   for (; rp < rp_stop; rp += 16, pp += 16)
+   {
+      uint32x2x4_t vtmp;
+      uint8x8x4_t *vrpt, *vppt;
+      uint8x8x4_t vrp, vpp;
+      uint32x2x4_t *temp_pointer;
+
+      vtmp = vld4_u32(png_ptr(uint32_t,rp));
+      vrpt = png_ptr(uint8x8x4_t,&vtmp);
+      vrp = *vrpt;
+      vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+      vppt = png_ptr(uint8x8x4_t,&vtmp);
+      vpp = *vppt;
+
+      vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
+      vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+      vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]);
+      vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+      vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]);
+      vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+      vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]);
+      vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+      vlast = vpp.val[3];
+
+      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+   }
+}
+
+#endif /* PNG_ARM_NEON_OPT > 0 */
+#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */
+#endif /* READ */

+ 2 - 8
drivers/png/image_loader_png.cpp

@@ -30,7 +30,7 @@
 
 #include "print_string.h"
 #include "os/os.h"
-
+#include <string.h>
 
 
 void ImageLoaderPNG::_read_png_data(png_structp png_ptr,png_bytep data, png_size_t p_length) {
@@ -104,7 +104,6 @@ Error ImageLoaderPNG::_load_image(void *rf_up,png_rw_ptr p_func,Image *p_image)
 	png_read_info(png, info);
 	png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
 
-	png_textp t;
 	//https://svn.gov.pt/projects/ccidadao/repository/middleware-offline/trunk/_src/eidmw/FreeImagePTEiD/Source/FreeImage/PluginPNG.cpp
 	//png_get_text(png,info,)
 	/*
@@ -254,7 +253,7 @@ Error ImageLoaderPNG::load_image(Image *p_image,FileAccess *f) {
 }
 
 void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const {
-	
+
 	p_extensions->push_back("png");
 }
 
@@ -362,7 +361,6 @@ static DVector<uint8_t> _lossless_pack_png(const Image& p_image) {
 	}
 
 	int pngf=0;
-	int pngb=8;
 	int cs=0;
 
 	switch(img.get_format()) {
@@ -451,7 +449,3 @@ ImageLoaderPNG::ImageLoaderPNG() {
 
 
 }
-
-
-
-

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 576 - 224
drivers/png/png.c


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 241 - 275
drivers/png/png.h


+ 222 - 198
drivers/png/pngconf.h

@@ -1,9 +1,9 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.5.27, May 26, 2016
+ * libpng version 1.6.23, June 9, 2016
  *
- * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2015 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.)
  *
@@ -20,34 +20,50 @@
 #ifndef PNGCONF_H
 #define PNGCONF_H
 
-#ifndef PNG_BUILDING_SYMBOL_TABLE
-/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C
- * definition file for  machine specific limits, this may impact the
- * correctness of the definitions below (see uses of INT_MAX).
- */
-#  ifndef PNG_NO_LIMITS_H
-#    include <limits.h>
-#  endif
+#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
 
-/* For the memory copy APIs (i.e. the standard definitions of these),
- * because this file defines png_memcpy and so on the base APIs must
- * be defined here.
+/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
+ * compiler for correct compilation.  The following header files are required by
+ * the standard.  If your compiler doesn't provide these header files, or they
+ * do not match the standard, you will need to provide/improve them.
  */
-#  ifdef BSD
-#    include <strings.h>
-#  else
-#    include <string.h>
-#  endif
-
-/* For png_FILE_p - this provides the standard definition of a
- * FILE
+#include <limits.h>
+#include <stddef.h>
+
+/* Library header files.  These header files are all defined by ISOC90; libpng
+ * expects conformant implementations, however, an ISOC90 conformant system need
+ * not provide these header files if the functionality cannot be implemented.
+ * In this case it will be necessary to disable the relevant parts of libpng in
+ * the build of pnglibconf.h.
+ *
+ * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
+ * include this unnecessary header file.
  */
-#  ifdef PNG_STDIO_SUPPORTED
-#    include <stdio.h>
-#  endif
+
+#ifdef PNG_STDIO_SUPPORTED
+   /* Required for the definition of FILE: */
+#  include <stdio.h>
 #endif
 
-/* This controls optimization of the reading of 16 and 32 bit values
+#ifdef PNG_SETJMP_SUPPORTED
+   /* Required for the definition of jmp_buf and the declaration of longjmp: */
+#  include <setjmp.h>
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+   /* Required for struct tm: */
+#  include <time.h>
+#endif
+
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
+
+/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using
+ * PNG_NO_CONST; this is no longer supported except for data declarations which
+ * apparently still cause problems in 2011 on some compilers.
+ */
+#define PNG_CONST const /* backward compatibility only */
+
+/* This controls optimization of the reading of 16-bit and 32-bit values
  * from PNG files.  It can be set on a per-app-file basis - it
  * just changes whether a macro is used when the function is called.
  * The library builder sets the default; if read functions are not
@@ -70,28 +86,13 @@
  * may be changed on a per-file basis when compiling against libpng.
  */
 
-/* The PNGARG macro protects us against machines that don't have function
- * prototypes (ie K&R style headers).  If your compiler does not handle
- * function prototypes, define this macro and use the included ansi2knr.
- * I've always been able to use _NO_PROTO as the indicator, but you may
- * need to drag the empty declaration out in front of here, or change the
- * ifdef to suit your own needs.
+/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
+ * against legacy (pre ISOC90) compilers that did not understand function
+ * prototypes.  It is not required for modern C compilers.
  */
 #ifndef PNGARG
-
-#  ifdef OF /* zlib prototype munger */
-#    define PNGARG(arglist) OF(arglist)
-#  else
-
-#    ifdef _NO_PROTO
-#      define PNGARG(arglist) ()
-#    else
-#      define PNGARG(arglist) arglist
-#    endif /* _NO_PROTO */
-
-#  endif /* OF */
-
-#endif /* PNGARG */
+#  define PNGARG(arglist) arglist
+#endif
 
 /* Function calling conventions.
  * =============================
@@ -215,10 +216,11 @@
 #      define PNGAPI _stdcall
 #    endif
 #  endif /* compiler/api */
+
   /* NOTE: PNGCBAPI always defaults to PNGCAPI. */
 
 #  if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
-   ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed
+#     error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
 #  endif
 
 #  if (defined(_MSC_VER) && _MSC_VER < 800) ||\
@@ -293,11 +295,11 @@
     * table entries, so we discard it here.  See the .dfn files in the
     * scripts directory.
     */
-#ifndef PNG_EXPORTA
 
-#  define PNG_EXPORTA(ordinal, type, name, args, attributes)\
-      PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \
-        extern attributes)
+#ifndef PNG_EXPORTA
+#  define PNG_EXPORTA(ordinal, type, name, args, attributes) \
+      PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
+      PNG_LINKAGE_API attributes)
 #endif
 
 /* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
@@ -305,7 +307,7 @@
  */
 #define PNG_EMPTY /*empty list*/
 
-#define PNG_EXPORT(ordinal, type, name, args)\
+#define PNG_EXPORT(ordinal, type, name, args) \
    PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
 
 /* Use PNG_REMOVED to comment out a removed interface. */
@@ -332,12 +334,38 @@
 
 #ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
   /* Support for compiler specific function attributes.  These are used
-   * so that where compiler support is available incorrect use of API
+   * so that where compiler support is available, incorrect use of API
    * functions in png.h will generate compiler warnings.  Added at libpng
-   * version 1.2.41.
+   * version 1.2.41.  Disabling these removes the warnings but may also produce
+   * less efficient code.
    */
+#  if defined(__clang__) && defined(__has_attribute)
+     /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
+#    if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
+#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+#    endif
+#    if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
+#      define PNG_NORETURN __attribute__((__noreturn__))
+#    endif
+#    if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
+#      define PNG_ALLOCATED __attribute__((__malloc__))
+#    endif
+#    if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
+#      define PNG_DEPRECATED __attribute__((__deprecated__))
+#    endif
+#    if !defined(PNG_PRIVATE)
+#      ifdef __has_extension
+#        if __has_extension(attribute_unavailable_with_message)
+#          define PNG_PRIVATE __attribute__((__unavailable__(\
+             "This function is not exported by libpng.")))
+#        endif
+#      endif
+#    endif
+#    ifndef PNG_RESTRICT
+#      define PNG_RESTRICT __restrict
+#    endif
 
-#  if defined(__GNUC__)
+#  elif defined(__GNUC__)
 #    ifndef PNG_USE_RESULT
 #      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
 #    endif
@@ -360,15 +388,19 @@
             __attribute__((__deprecated__))
 #        endif
 #      endif
+#      if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
+#        ifndef PNG_RESTRICT
+#          define PNG_RESTRICT __restrict
+#        endif
+#      endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
 #    endif /* __GNUC__ >= 3 */
-#  endif /* __GNUC__ */
 
-#  if defined(_MSC_VER)  && (_MSC_VER >= 1300)
+#  elif defined(_MSC_VER)  && (_MSC_VER >= 1300)
 #    ifndef PNG_USE_RESULT
 #      define PNG_USE_RESULT /* not supported */
 #    endif
 #    ifndef PNG_NORETURN
-#      define PNG_NORETURN __declspec(noreturn)
+#      define PNG_NORETURN   __declspec(noreturn)
 #    endif
 #    ifndef PNG_ALLOCATED
 #      if (_MSC_VER >= 1400)
@@ -381,7 +413,17 @@
 #    ifndef PNG_PRIVATE
 #      define PNG_PRIVATE __declspec(deprecated)
 #    endif
-#  endif /* _MSC_VER */
+#    ifndef PNG_RESTRICT
+#      if (_MSC_VER >= 1400)
+#        define PNG_RESTRICT __restrict
+#      endif
+#    endif
+
+#  elif defined(__WATCOMC__)
+#    ifndef PNG_RESTRICT
+#      define PNG_RESTRICT __restrict
+#    endif
+#  endif
 #endif /* PNG_PEDANTIC_WARNINGS */
 
 #ifndef PNG_DEPRECATED
@@ -399,6 +441,10 @@
 #ifndef PNG_PRIVATE
 #  define PNG_PRIVATE     /* This is a private libpng function */
 #endif
+#ifndef PNG_RESTRICT
+#  define PNG_RESTRICT    /* The C99 "restrict" feature */
+#endif
+
 #ifndef PNG_FP_EXPORT     /* A floating point API. */
 #  ifdef PNG_FLOATING_POINT_SUPPORTED
 #     define PNG_FP_EXPORT(ordinal, type, name, args)\
@@ -416,183 +462,161 @@
 #  endif
 #endif
 
-/* The following uses const char * instead of char * for error
- * and warning message functions, so some compilers won't complain.
- * If you do not want to use const, define PNG_NO_CONST here.
+#ifndef PNG_BUILDING_SYMBOL_TABLE
+/* Some typedefs to get us started.  These should be safe on most of the common
+ * platforms.
  *
- * This should not change how the APIs are called, so it can be done
- * on a per-file basis in the application.
+ * png_uint_32 and png_int_32 may, currently, be larger than required to hold a
+ * 32-bit value however this is not normally advisable.
+ *
+ * png_uint_16 and png_int_16 should always be two bytes in size - this is
+ * verified at library build time.
+ *
+ * png_byte must always be one byte in size.
+ *
+ * The checks below use constants from limits.h, as defined by the ISOC90
+ * standard.
  */
-#ifndef PNG_CONST
-#  ifndef PNG_NO_CONST
-#    define PNG_CONST const
-#  else
-#    define PNG_CONST
-#  endif
+#if CHAR_BIT == 8 && UCHAR_MAX == 255
+   typedef unsigned char png_byte;
+#else
+#  error "libpng requires 8-bit bytes"
 #endif
 
-/* Some typedefs to get us started.  These should be safe on most of the
- * common platforms.  The typedefs should be at least as large as the
- * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
- * don't have to be exactly that size.  Some compilers dislike passing
- * unsigned shorts as function parameters, so you may be better off using
- * unsigned int for png_uint_16.
- */
+#if INT_MIN == -32768 && INT_MAX == 32767
+   typedef int png_int_16;
+#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
+   typedef short png_int_16;
+#else
+#  error "libpng requires a signed 16-bit type"
+#endif
 
-#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL)
-typedef unsigned int png_uint_32;
-typedef int png_int_32;
+#if UINT_MAX == 65535
+   typedef unsigned int png_uint_16;
+#elif USHRT_MAX == 65535
+   typedef unsigned short png_uint_16;
 #else
-typedef unsigned long png_uint_32;
-typedef long png_int_32;
+#  error "libpng requires an unsigned 16-bit type"
 #endif
-typedef unsigned short png_uint_16;
-typedef short png_int_16;
-typedef unsigned char png_byte;
 
-#ifdef PNG_NO_SIZE_T
-typedef unsigned int png_size_t;
+#if INT_MIN < -2147483646 && INT_MAX > 2147483646
+   typedef int png_int_32;
+#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
+   typedef long int png_int_32;
 #else
-typedef size_t png_size_t;
+#  error "libpng requires a signed 32-bit (or more) type"
 #endif
-#define png_sizeof(x) (sizeof (x))
 
-/* The following is needed for medium model support.  It cannot be in the
- * pngpriv.h header.  Needs modification for other compilers besides
- * MSC.  Model independent support declares all arrays and pointers to be
- * large using the far keyword.  The zlib version used must also support
- * model independent data.  As of version zlib 1.0.4, the necessary changes
- * have been made in zlib.  The USE_FAR_KEYWORD define triggers other
- * changes that are needed. (Tim Wegner)
- */
+#if UINT_MAX > 4294967294
+   typedef unsigned int png_uint_32;
+#elif ULONG_MAX > 4294967294
+   typedef unsigned long int png_uint_32;
+#else
+#  error "libpng requires an unsigned 32-bit (or more) type"
+#endif
 
-/* Separate compiler dependencies (problem here is that zlib.h always
- * defines FAR. (SJT)
- */
-#ifdef __BORLANDC__
-#  if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
-#    define LDATA 1
-#  else
-#    define LDATA 0
-#  endif
-  /* GRR:  why is Cygwin in here?  Cygwin is not Borland C... */
-#  if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
-#    define PNG_MAX_MALLOC_64K /* only used in build */
-#    if (LDATA != 1)
-#      ifndef FAR
-#        define FAR __far
-#      endif
-#      define USE_FAR_KEYWORD
-#    endif   /* LDATA != 1 */
-         /* Possibly useful for moving data out of default segment.
-          * Uncomment it if you want. Could also define FARDATA as
-          * const if your compiler supports it. (SJT)
-#        define FARDATA FAR
-          */
-#  endif  /* __WIN32__, __FLAT__, __CYGWIN__ */
-#endif   /* __BORLANDC__ */
-
-
-/* Suggest testing for specific compiler first before testing for
- * FAR.  The Watcom compiler defines both __MEDIUM__ and M_I86MM,
- * making reliance oncertain keywords suspect. (SJT)
+/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,
+ * requires an ISOC90 compiler and relies on consistent behavior of sizeof.
  */
+typedef size_t png_size_t;
+typedef ptrdiff_t png_ptrdiff_t;
 
-/* MSC Medium model */
-#ifdef FAR
-#  ifdef M_I86MM
-#    define USE_FAR_KEYWORD
-#    define FARDATA FAR
-#    include <dos.h>
+/* libpng needs to know the maximum value of 'size_t' and this controls the
+ * definition of png_alloc_size_t, below.  This maximum value of size_t limits
+ * but does not control the maximum allocations the library makes - there is
+ * direct application control of this through png_set_user_limits().
+ */
+#ifndef PNG_SMALL_SIZE_T
+   /* Compiler specific tests for systems where size_t is known to be less than
+    * 32 bits (some of these systems may no longer work because of the lack of
+    * 'far' support; see above.)
+    */
+#  if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
+   (defined(_MSC_VER) && defined(MAXSEG_64K))
+#     define PNG_SMALL_SIZE_T
 #  endif
 #endif
 
-/* SJT: default case */
-#ifndef FAR
-#  define FAR
+/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no
+ * smaller than png_uint_32.  Casts from png_size_t or png_uint_32 to
+ * png_alloc_size_t are not necessary; in fact, it is recommended not to use
+ * them at all so that the compiler can complain when something turns out to be
+ * problematic.
+ *
+ * Casts in the other direction (from png_alloc_size_t to png_size_t or
+ * png_uint_32) should be explicitly applied; however, we do not expect to
+ * encounter practical situations that require such conversions.
+ *
+ * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
+ * 4294967295 - i.e. less than the maximum value of png_uint_32.
+ */
+#ifdef PNG_SMALL_SIZE_T
+   typedef png_uint_32 png_alloc_size_t;
+#else
+   typedef png_size_t png_alloc_size_t;
 #endif
 
-/* At this point FAR is always defined */
-#ifndef FARDATA
-#  define FARDATA
-#endif
+/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
+ * implementations of Intel CPU specific support of user-mode segmented address
+ * spaces, where 16-bit pointers address more than 65536 bytes of memory using
+ * separate 'segment' registers.  The implementation requires two different
+ * types of pointer (only one of which includes the segment value.)
+ *
+ * If required this support is available in version 1.2 of libpng and may be
+ * available in versions through 1.5, although the correctness of the code has
+ * not been verified recently.
+ */
 
-/* Typedef for floating-point numbers that are converted
- * to fixed-point with a multiple of 100,000, e.g., gamma
+/* Typedef for floating-point numbers that are converted to fixed-point with a
+ * multiple of 100,000, e.g., gamma
  */
 typedef png_int_32 png_fixed_point;
 
 /* Add typedefs for pointers */
-typedef void                      FAR * png_voidp;
-typedef PNG_CONST void            FAR * png_const_voidp;
-typedef png_byte                  FAR * png_bytep;
-typedef PNG_CONST png_byte        FAR * png_const_bytep;
-typedef png_uint_32               FAR * png_uint_32p;
-typedef PNG_CONST png_uint_32     FAR * png_const_uint_32p;
-typedef png_int_32                FAR * png_int_32p;
-typedef PNG_CONST png_int_32      FAR * png_const_int_32p;
-typedef png_uint_16               FAR * png_uint_16p;
-typedef PNG_CONST png_uint_16     FAR * png_const_uint_16p;
-typedef png_int_16                FAR * png_int_16p;
-typedef PNG_CONST png_int_16      FAR * png_const_int_16p;
-typedef char                      FAR * png_charp;
-typedef PNG_CONST char            FAR * png_const_charp;
-typedef png_fixed_point           FAR * png_fixed_point_p;
-typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p;
-typedef png_size_t                FAR * png_size_tp;
-typedef PNG_CONST png_size_t      FAR * png_const_size_tp;
+typedef void                  * png_voidp;
+typedef const void            * png_const_voidp;
+typedef png_byte              * png_bytep;
+typedef const png_byte        * png_const_bytep;
+typedef png_uint_32           * png_uint_32p;
+typedef const png_uint_32     * png_const_uint_32p;
+typedef png_int_32            * png_int_32p;
+typedef const png_int_32      * png_const_int_32p;
+typedef png_uint_16           * png_uint_16p;
+typedef const png_uint_16     * png_const_uint_16p;
+typedef png_int_16            * png_int_16p;
+typedef const png_int_16      * png_const_int_16p;
+typedef char                  * png_charp;
+typedef const char            * png_const_charp;
+typedef png_fixed_point       * png_fixed_point_p;
+typedef const png_fixed_point * png_const_fixed_point_p;
+typedef png_size_t            * png_size_tp;
+typedef const png_size_t      * png_const_size_tp;
 
 #ifdef PNG_STDIO_SUPPORTED
 typedef FILE            * png_FILE_p;
 #endif
 
 #ifdef PNG_FLOATING_POINT_SUPPORTED
-typedef double           FAR * png_doublep;
-typedef PNG_CONST double FAR * png_const_doublep;
+typedef double       * png_doublep;
+typedef const double * png_const_doublep;
 #endif
 
 /* Pointers to pointers; i.e. arrays */
-typedef png_byte        FAR * FAR * png_bytepp;
-typedef png_uint_32     FAR * FAR * png_uint_32pp;
-typedef png_int_32      FAR * FAR * png_int_32pp;
-typedef png_uint_16     FAR * FAR * png_uint_16pp;
-typedef png_int_16      FAR * FAR * png_int_16pp;
-typedef PNG_CONST char  FAR * FAR * png_const_charpp;
-typedef char            FAR * FAR * png_charpp;
-typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
+typedef png_byte        * * png_bytepp;
+typedef png_uint_32     * * png_uint_32pp;
+typedef png_int_32      * * png_int_32pp;
+typedef png_uint_16     * * png_uint_16pp;
+typedef png_int_16      * * png_int_16pp;
+typedef const char      * * png_const_charpp;
+typedef char            * * png_charpp;
+typedef png_fixed_point * * png_fixed_point_pp;
 #ifdef PNG_FLOATING_POINT_SUPPORTED
-typedef double          FAR * FAR * png_doublepp;
+typedef double          * * png_doublepp;
 #endif
 
 /* Pointers to pointers to pointers; i.e., pointer to array */
-typedef char            FAR * FAR * FAR * png_charppp;
+typedef char            * * * png_charppp;
 
-/* png_alloc_size_t is guaranteed to be no smaller than png_size_t,
- * and no smaller than png_uint_32.  Casts from png_size_t or png_uint_32
- * to png_alloc_size_t are not necessary; in fact, it is recommended
- * not to use them at all so that the compiler can complain when something
- * turns out to be problematic.
- * Casts in the other direction (from png_alloc_size_t to png_size_t or
- * png_uint_32) should be explicitly applied; however, we do not expect
- * to encounter practical situations that require such conversions.
- */
-#if defined(__TURBOC__) && !defined(__FLAT__)
-   typedef unsigned long png_alloc_size_t;
-#else
-#  if defined(_MSC_VER) && defined(MAXSEG_64K)
-     typedef unsigned long    png_alloc_size_t;
-#  else
-     /* This is an attempt to detect an old Windows system where (int) is
-      * actually 16 bits, in that case png_malloc must have an argument with a
-      * bigger size to accomodate the requirements of the library.
-      */
-#    if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \
-        (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL)
-       typedef DWORD         png_alloc_size_t;
-#    else
-       typedef png_size_t    png_alloc_size_t;
-#    endif
-#  endif
-#endif
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
 
 #endif /* PNGCONF_H */

+ 2 - 2
drivers/png/pngdebug.h

@@ -1,8 +1,8 @@
 
 /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
  *
- * Last changed in libpng 1.5.18 [February 6, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.8 [December 19, 2013]
+ * Copyright (c) 1998-2002,2004,2006-2013 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.)
  *

+ 351 - 76
drivers/png/pngerror.c

@@ -1,7 +1,7 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * Last changed in libpng 1.5.19 [August 21, 2014]
+ * Last changed in libpng 1.6.15 [November 20, 2014]
  * Copyright (c) 1998-2002,2004,2006-2014 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.)
@@ -20,14 +20,14 @@
 
 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 
-static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr,
+static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
     png_const_charp error_message)),PNG_NORETURN);
 
 #ifdef PNG_WARNINGS_SUPPORTED
 static void /* PRIVATE */
-png_default_warning PNGARG((png_structp png_ptr,
+png_default_warning PNGARG((png_const_structrp png_ptr,
    png_const_charp warning_message));
-#endif /* PNG_WARNINGS_SUPPORTED */
+#endif /* WARNINGS */
 
 /* This function is called whenever there is a fatal error.  This function
  * should not be changed.  If there is a need to handle errors differently,
@@ -36,14 +36,15 @@ png_default_warning PNGARG((png_structp png_ptr,
  */
 #ifdef PNG_ERROR_TEXT_SUPPORTED
 PNG_FUNCTION(void,PNGAPI
-png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
+png_error,(png_const_structrp png_ptr, png_const_charp error_message),
+   PNG_NORETURN)
 {
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
    char msg[16];
    if (png_ptr != NULL)
    {
-      if (png_ptr->flags&
-         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+      if ((png_ptr->flags &
+         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
       {
          if (*error_message == PNG_LITERAL_SHARP)
          {
@@ -53,7 +54,7 @@ png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
                if (error_message[offset] == ' ')
                   break;
 
-            if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
             {
                int i;
                for (i = 0; i < offset - 1; i++)
@@ -68,7 +69,7 @@ png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
 
       else
       {
-         if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+         if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
          {
             msg[0] = '0';
             msg[1] = '\0';
@@ -79,7 +80,8 @@ png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
    }
 #endif
    if (png_ptr != NULL && png_ptr->error_fn != NULL)
-      (*(png_ptr->error_fn))(png_ptr, error_message);
+      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
+          error_message);
 
    /* If the custom handler doesn't exist, or if it returns,
       use the default handler, which will not return. */
@@ -87,7 +89,7 @@ png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN)
 }
 #else
 PNG_FUNCTION(void,PNGAPI
-png_err,(png_structp png_ptr),PNG_NORETURN)
+png_err,(png_const_structrp png_ptr),PNG_NORETURN)
 {
    /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
     * erroneously as '\0', instead of the empty string "".  This was
@@ -95,13 +97,13 @@ png_err,(png_structp png_ptr),PNG_NORETURN)
     * will crash in this case.
     */
    if (png_ptr != NULL && png_ptr->error_fn != NULL)
-      (*(png_ptr->error_fn))(png_ptr, "");
+      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
 
    /* If the custom handler doesn't exist, or if it returns,
       use the default handler, which will not return. */
    png_default_error(png_ptr, "");
 }
-#endif /* PNG_ERROR_TEXT_SUPPORTED */
+#endif /* ERROR_TEXT */
 
 /* Utility to safely appends strings to a buffer.  This never errors out so
  * error checking is not required in the caller.
@@ -150,7 +152,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
          case PNG_NUMBER_FORMAT_fixed:
             /* Needs five digits (the fraction) */
             mincount = 5;
-            if (output || number % 10 != 0)
+            if (output != 0 || number % 10 != 0)
             {
                *--end = digits[number % 10];
                output = 1;
@@ -187,7 +189,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
       ++count;
 
       /* Float a fixed number here: */
-      if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start)
+      if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))
       {
          /* End of the fraction, but maybe nothing was output?  In that case
           * drop the decimal point.  If the number is a true zero handle that
@@ -211,14 +213,14 @@ png_format_number(png_const_charp start, png_charp end, int format,
  * png_set_error_fn() to replace the warning function at run-time.
  */
 void PNGAPI
-png_warning(png_structp png_ptr, png_const_charp warning_message)
+png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
 {
    int offset = 0;
    if (png_ptr != NULL)
    {
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
-   if (png_ptr->flags&
-       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+   if ((png_ptr->flags &
+       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
 #endif
       {
          if (*warning_message == PNG_LITERAL_SHARP)
@@ -230,7 +232,8 @@ png_warning(png_structp png_ptr, png_const_charp warning_message)
       }
    }
    if (png_ptr != NULL && png_ptr->warning_fn != NULL)
-      (*(png_ptr->warning_fn))(png_ptr, warning_message + offset);
+      (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
+         warning_message + offset);
    else
       png_default_warning(png_ptr, warning_message + offset);
 }
@@ -278,7 +281,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
 }
 
 void
-png_formatted_warning(png_structp png_ptr, png_warning_parameters p,
+png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
    png_const_charp message)
 {
    /* The internal buffer is just 192 bytes - enough for all our messages,
@@ -346,29 +349,79 @@ png_formatted_warning(png_structp png_ptr, png_warning_parameters p,
    /* i is always less than (sizeof msg), so: */
    msg[i] = '\0';
 
-   /* And this is the formatted message, it may be larger than
-    * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these are
-    * not (currently) formatted.
+   /* And this is the formatted message. It may be larger than
+    * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
+    * are not (currently) formatted.
     */
    png_warning(png_ptr, msg);
 }
-#endif /* PNG_WARNINGS_SUPPORTED */
+#endif /* WARNINGS */
 
 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
 void PNGAPI
-png_benign_error(png_structp png_ptr, png_const_charp error_message)
+png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
 {
-  if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+   {
+#     ifdef PNG_READ_SUPPORTED
+         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+            png_ptr->chunk_name != 0)
+            png_chunk_warning(png_ptr, error_message);
+         else
+#     endif
+      png_warning(png_ptr, error_message);
+   }
+
+   else
+   {
+#     ifdef PNG_READ_SUPPORTED
+         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+            png_ptr->chunk_name != 0)
+            png_chunk_error(png_ptr, error_message);
+         else
+#     endif
+      png_error(png_ptr, error_message);
+   }
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
+}
+
+void /* PRIVATE */
+png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
+{
+  if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
      png_warning(png_ptr, error_message);
   else
      png_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
 }
-#endif
 
+void /* PRIVATE */
+png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
+{
+  if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
+     png_warning(png_ptr, error_message);
+  else
+     png_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
+}
+#endif /* BENIGN_ERRORS */
+
+#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */
+#if defined(PNG_WARNINGS_SUPPORTED) || \
+   (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
 /* These utilities are used internally to build an error message that relates
  * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
- * this is used to prefix the message.  The message is limited in length
- * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * which is used to prefix the message.  The message is limited in length
+ * to 63 bytes. The name characters are output as hex digits wrapped in []
  * if the character is invalid.
  */
 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
@@ -377,10 +430,8 @@ static PNG_CONST char png_digit[16] = {
    'A', 'B', 'C', 'D', 'E', 'F'
 };
 
-#define PNG_MAX_ERROR_TEXT 64
-#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
 static void /* PRIVATE */
-png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
+png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
     error_message)
 {
    png_uint_32 chunk_name = png_ptr->chunk_name;
@@ -391,7 +442,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
       int c = (int)(chunk_name >> ishift) & 0xff;
 
       ishift -= 8;
-      if (isnonalpha(c))
+      if (isnonalpha(c) != 0)
       {
          buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
          buffer[iout++] = png_digit[(c & 0xf0) >> 4];
@@ -422,11 +473,11 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
       buffer[iout] = '\0';
    }
 }
-#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
+#endif /* WARNINGS || ERROR_TEXT */
 
 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
 PNG_FUNCTION(void,PNGAPI
-png_chunk_error,(png_structp png_ptr, png_const_charp error_message),
+png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
    PNG_NORETURN)
 {
    char msg[18+PNG_MAX_ERROR_TEXT];
@@ -439,11 +490,11 @@ png_chunk_error,(png_structp png_ptr, png_const_charp error_message),
       png_error(png_ptr, msg);
    }
 }
-#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
+#endif /* READ && ERROR_TEXT */
 
 #ifdef PNG_WARNINGS_SUPPORTED
 void PNGAPI
-png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
+png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
 {
    char msg[18+PNG_MAX_ERROR_TEXT];
    if (png_ptr == NULL)
@@ -455,38 +506,83 @@ png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
       png_warning(png_ptr, msg);
    }
 }
-#endif /* PNG_WARNINGS_SUPPORTED */
+#endif /* WARNINGS */
 
 #ifdef PNG_READ_SUPPORTED
 #ifdef PNG_BENIGN_ERRORS_SUPPORTED
 void PNGAPI
-png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message)
+png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
+    error_message)
 {
-   if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
       png_chunk_warning(png_ptr, error_message);
 
    else
       png_chunk_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
 }
 #endif
-#endif /* PNG_READ_SUPPORTED */
+#endif /* READ */
+
+void /* PRIVATE */
+png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
+{
+#  ifndef PNG_WARNINGS_SUPPORTED
+      PNG_UNUSED(message)
+#  endif
+
+   /* This is always supported, but for just read or just write it
+    * unconditionally does the right thing.
+    */
+#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+#  endif
+
+#  ifdef PNG_READ_SUPPORTED
+      {
+         if (error < PNG_CHUNK_ERROR)
+            png_chunk_warning(png_ptr, message);
+
+         else
+            png_chunk_benign_error(png_ptr, message);
+      }
+#  endif
+
+#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+      else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+#  endif
+
+#  ifdef PNG_WRITE_SUPPORTED
+      {
+         if (error < PNG_CHUNK_WRITE_ERROR)
+            png_app_warning(png_ptr, message);
+
+         else
+            png_app_error(png_ptr, message);
+      }
+#  endif
+}
 
 #ifdef PNG_ERROR_TEXT_SUPPORTED
 #ifdef PNG_FLOATING_POINT_SUPPORTED
 PNG_FUNCTION(void,
-png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN)
+png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
 {
 #  define fixed_message "fixed point overflow in "
 #  define fixed_message_ln ((sizeof fixed_message)-1)
    int  iin;
    char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
-   png_memcpy(msg, fixed_message, fixed_message_ln);
+   memcpy(msg, fixed_message, fixed_message_ln);
    iin = 0;
-   if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
-   {
-      msg[fixed_message_ln + iin] = name[iin];
-      ++iin;
-   }
+   if (name != NULL)
+      while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
+      {
+         msg[fixed_message_ln + iin] = name[iin];
+         ++iin;
+      }
    msg[fixed_message_ln + iin] = 0;
    png_error(png_ptr, msg);
 }
@@ -498,14 +594,111 @@ png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN)
  * otherwise it is necessary for png_default_error to be overridden.
  */
 jmp_buf* PNGAPI
-png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
+png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
     size_t jmp_buf_size)
 {
-   if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf))
+   /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
+    * and it must not change after that.  Libpng doesn't care how big the
+    * buffer is, just that it doesn't change.
+    *
+    * If the buffer size is no *larger* than the size of jmp_buf when libpng is
+    * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
+    * semantics that this call will not fail.  If the size is larger, however,
+    * the buffer is allocated and this may fail, causing the function to return
+    * NULL.
+    */
+   if (png_ptr == NULL)
       return NULL;
 
+   if (png_ptr->jmp_buf_ptr == NULL)
+   {
+      png_ptr->jmp_buf_size = 0; /* not allocated */
+
+      if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
+         png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
+
+      else
+      {
+         png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
+            png_malloc_warn(png_ptr, jmp_buf_size));
+
+         if (png_ptr->jmp_buf_ptr == NULL)
+            return NULL; /* new NULL return on OOM */
+
+         png_ptr->jmp_buf_size = jmp_buf_size;
+      }
+   }
+
+   else /* Already allocated: check the size */
+   {
+      size_t size = png_ptr->jmp_buf_size;
+
+      if (size == 0)
+      {
+         size = (sizeof png_ptr->jmp_buf_local);
+         if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
+         {
+            /* This is an internal error in libpng: somehow we have been left
+             * with a stack allocated jmp_buf when the application regained
+             * control.  It's always possible to fix this up, but for the moment
+             * this is a png_error because that makes it easy to detect.
+             */
+            png_error(png_ptr, "Libpng jmp_buf still allocated");
+            /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
+         }
+      }
+
+      if (size != jmp_buf_size)
+      {
+         png_warning(png_ptr, "Application jmp_buf size changed");
+         return NULL; /* caller will probably crash: no choice here */
+      }
+   }
+
+   /* Finally fill in the function, now we have a satisfactory buffer. It is
+    * valid to change the function on every call.
+    */
    png_ptr->longjmp_fn = longjmp_fn;
-   return &png_ptr->longjmp_buffer;
+   return png_ptr->jmp_buf_ptr;
+}
+
+void /* PRIVATE */
+png_free_jmpbuf(png_structrp png_ptr)
+{
+   if (png_ptr != NULL)
+   {
+      jmp_buf *jb = png_ptr->jmp_buf_ptr;
+
+      /* A size of 0 is used to indicate a local, stack, allocation of the
+       * pointer; used here and in png.c
+       */
+      if (jb != NULL && png_ptr->jmp_buf_size > 0)
+      {
+
+         /* This stuff is so that a failure to free the error control structure
+          * does not leave libpng in a state with no valid error handling: the
+          * free always succeeds, if there is an error it gets ignored.
+          */
+         if (jb != &png_ptr->jmp_buf_local)
+         {
+            /* Make an internal, libpng, jmp_buf to return here */
+            jmp_buf free_jmp_buf;
+
+            if (!setjmp(free_jmp_buf))
+            {
+               png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
+               png_ptr->jmp_buf_size = 0; /* stack allocation */
+               png_ptr->longjmp_fn = longjmp;
+               png_free(png_ptr, jb); /* Return to setjmp on error */
+            }
+         }
+      }
+
+      /* *Always* cancel everything out: */
+      png_ptr->jmp_buf_size = 0;
+      png_ptr->jmp_buf_ptr = NULL;
+      png_ptr->longjmp_fn = 0;
+   }
 }
 #endif
 
@@ -515,7 +708,7 @@ png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn,
  * error function pointer in png_set_error_fn().
  */
 static PNG_FUNCTION(void /* PRIVATE */,
-png_default_error,(png_structp png_ptr, png_const_charp error_message),
+png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
    PNG_NORETURN)
 {
 #ifdef PNG_CONSOLE_IO_SUPPORTED
@@ -562,27 +755,23 @@ png_default_error,(png_structp png_ptr, png_const_charp error_message),
 }
 
 PNG_FUNCTION(void,PNGAPI
-png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN)
+png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
 {
 #ifdef PNG_SETJMP_SUPPORTED
-   if (png_ptr && png_ptr->longjmp_fn)
-   {
-#  ifdef USE_FAR_KEYWORD
-      {
-         jmp_buf tmp_jmpbuf;
-         png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf));
-         png_ptr->longjmp_fn(tmp_jmpbuf, val);
-      }
-
-#  else
-   png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val);
-#  endif
-   }
+   if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
+       png_ptr->jmp_buf_ptr != NULL)
+      png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
 #else
-   PNG_UNUSED(png_ptr);
-   PNG_UNUSED(val);
+   PNG_UNUSED(png_ptr)
+   PNG_UNUSED(val)
 #endif
-   /* Here if not setjmp support or if png_ptr is null. */
+
+   /* If control reaches this point, png_longjmp() must not return. The only
+    * choice is to terminate the whole process (or maybe the thread); to do
+    * this the ANSI-C abort() function is used unless a different method is
+    * implemented by overriding the default configuration setting for
+    * PNG_ABORT().
+    */
    PNG_ABORT();
 }
 
@@ -593,7 +782,7 @@ png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN)
  * not used, but it is passed in case it may be useful.
  */
 static void /* PRIVATE */
-png_default_warning(png_structp png_ptr, png_const_charp warning_message)
+png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
 {
 #ifdef PNG_CONSOLE_IO_SUPPORTED
 #  ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -635,15 +824,15 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message)
 #endif
    PNG_UNUSED(png_ptr) /* Make compiler happy */
 }
-#endif /* PNG_WARNINGS_SUPPORTED */
+#endif /* WARNINGS */
 
 /* This function is called when the application wants to use another method
  * of handling errors and warnings.  Note that the error function MUST NOT
  * return to the calling routine or serious problems will occur.  The return
- * method used in the default routine calls longjmp(png_ptr->longjmp_buffer, 1)
+ * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
  */
 void PNGAPI
-png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
+png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
     png_error_ptr error_fn, png_error_ptr warning_fn)
 {
    if (png_ptr == NULL)
@@ -664,7 +853,7 @@ png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
  * pointer before png_write_destroy and png_read_destroy are called.
  */
 png_voidp PNGAPI
-png_get_error_ptr(png_const_structp png_ptr)
+png_get_error_ptr(png_const_structrp png_ptr)
 {
    if (png_ptr == NULL)
       return NULL;
@@ -675,7 +864,7 @@ png_get_error_ptr(png_const_structp png_ptr)
 
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
 void PNGAPI
-png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
+png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
 {
    if (png_ptr != NULL)
    {
@@ -685,4 +874,90 @@ png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
    }
 }
 #endif
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+   /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
+    * possible to implement without setjmp support just so long as there is some
+    * way to handle the error return here:
+    */
+PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
+png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
+   PNG_NORETURN)
+{
+   const png_const_structrp png_ptr = png_nonconst_ptr;
+   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+   /* An error is always logged here, overwriting anything (typically a warning)
+    * that is already there:
+    */
+   if (image != NULL)
+   {
+      png_safecat(image->message, (sizeof image->message), 0, error_message);
+      image->warning_or_error |= PNG_IMAGE_ERROR;
+
+      /* Retrieve the jmp_buf from within the png_control, making this work for
+       * C++ compilation too is pretty tricky: C++ wants a pointer to the first
+       * element of a jmp_buf, but C doesn't tell us the type of that.
+       */
+      if (image->opaque != NULL && image->opaque->error_buf != NULL)
+         longjmp(png_control_jmp_buf(image->opaque), 1);
+
+      /* Missing longjmp buffer, the following is to help debugging: */
+      {
+         size_t pos = png_safecat(image->message, (sizeof image->message), 0,
+            "bad longjmp: ");
+         png_safecat(image->message, (sizeof image->message), pos,
+             error_message);
+      }
+   }
+
+   /* Here on an internal programming error. */
+   abort();
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void /* PRIVATE */ PNGCBAPI
+png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
+{
+   const png_const_structrp png_ptr = png_nonconst_ptr;
+   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+   /* A warning is only logged if there is no prior warning or error. */
+   if (image->warning_or_error == 0)
+   {
+      png_safecat(image->message, (sizeof image->message), 0, warning_message);
+      image->warning_or_error |= PNG_IMAGE_WARNING;
+   }
+}
+#endif
+
+int /* PRIVATE */
+png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
+{
+   volatile png_imagep image = image_in;
+   volatile int result;
+   volatile png_voidp saved_error_buf;
+   jmp_buf safe_jmpbuf;
+
+   /* Safely execute function(arg) with png_error returning to this function. */
+   saved_error_buf = image->opaque->error_buf;
+   result = setjmp(safe_jmpbuf) == 0;
+
+   if (result != 0)
+   {
+
+      image->opaque->error_buf = safe_jmpbuf;
+      result = function(arg);
+   }
+
+   image->opaque->error_buf = saved_error_buf;
+
+   /* And do the cleanup prior to any failure return. */
+   if (result == 0)
+      png_image_free(image);
+
+   return result;
+}
+#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
+#endif /* READ || WRITE */

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 248 - 209
drivers/png/pngget.c


+ 33 - 42
drivers/png/pnginfo.h

@@ -1,8 +1,8 @@
 
 /* pnginfo.h - header file for PNG reference library
  *
- * Last changed in libpng 1.5.0 [January 6, 2011]
- * Copyright (c) 1998-2002,2004,2006-2011 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2002,2004,2006-2013 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.)
  *
@@ -54,7 +54,7 @@
 
 struct png_info_def
 {
-   /* the following are necessary for every PNG file */
+   /* The following are necessary for every PNG file */
    png_uint_32 width;  /* width of image in pixels (from IHDR) */
    png_uint_32 height; /* height of image in pixels (from IHDR) */
    png_uint_32 valid;  /* valid chunk data (see PNG_INFO_ below) */
@@ -69,11 +69,17 @@ struct png_info_def
    png_byte filter_type;    /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
    png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
 
-   /* The following is informational only on read, and not used on writes. */
+   /* The following are set by png_set_IHDR, called from the application on
+    * write, but the are never actually used by the write code.
+    */
    png_byte channels;       /* number of data channels per pixel (1, 2, 3, 4) */
    png_byte pixel_depth;    /* number of bits per pixel */
    png_byte spare_byte;     /* to align the data, and for future use */
+
+#ifdef PNG_READ_SUPPORTED
+   /* This is never set during write */
    png_byte signature[8];   /* magic bytes read by libpng from start of file */
+#endif
 
    /* The rest of the data is optional.  If you are reading, check the
     * valid field to see if the information in these are valid.  If you
@@ -81,18 +87,25 @@ struct png_info_def
     * and initialize the appropriate fields below.
     */
 
-#if defined(PNG_gAMA_SUPPORTED)
-   /* The gAMA chunk describes the gamma characteristics of the system
-    * on which the image was created, normally in the range [1.0, 2.5].
-    * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+   /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
+    * defined.  When COLORSPACE is switched on all the colorspace-defining
+    * chunks should be enabled, when GAMMA is switched on all the gamma-defining
+    * chunks should be enabled.  If this is not done it becomes possible to read
+    * inconsistent PNG files and assign a probably incorrect interpretation to
+    * the information.  (In other words, by carefully choosing which chunks to
+    * recognize the system configuration can select an interpretation for PNG
+    * files containing ambiguous data and this will result in inconsistent
+    * behavior between different libpng builds!)
     */
-   png_fixed_point gamma;
+   png_colorspace colorspace;
 #endif
 
-#ifdef PNG_sRGB_SUPPORTED
-    /* GR-P, 0.96a */
-    /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
-   png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
+#ifdef PNG_iCCP_SUPPORTED
+   /* iCCP chunk data. */
+   png_charp iccp_name;     /* profile name */
+   png_bytep iccp_profile;  /* International Color Consortium profile data */
+   png_uint_32 iccp_proflen;  /* ICC profile data length */
 #endif
 
 #ifdef PNG_TEXT_SUPPORTED
@@ -107,7 +120,7 @@ struct png_info_def
    int num_text; /* number of comments read or comments to write */
    int max_text; /* current size of text array */
    png_textp text; /* array of comments read or comments to write */
-#endif /* PNG_TEXT_SUPPORTED */
+#endif /* TEXT */
 
 #ifdef PNG_tIME_SUPPORTED
    /* The tIME chunk holds the last time the displayed image data was
@@ -182,23 +195,6 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
    png_uint_16p hist;
 #endif
 
-#ifdef PNG_cHRM_SUPPORTED
-   /* The cHRM chunk describes the CIE color characteristics of the monitor
-    * on which the PNG was created.  This data allows the viewer to do gamut
-    * mapping of the input image to ensure that the viewer sees the same
-    * colors in the image as the creator.  Values are in the range
-    * [0.0, 0.8].  Data valid if (valid & PNG_INFO_cHRM) non-zero.
-    */
-   png_fixed_point x_white;
-   png_fixed_point y_white;
-   png_fixed_point x_red;
-   png_fixed_point y_red;
-   png_fixed_point x_green;
-   png_fixed_point y_green;
-   png_fixed_point x_blue;
-   png_fixed_point y_blue;
-#endif
-
 #ifdef PNG_pCAL_SUPPORTED
    /* The pCAL chunk describes a transformation between the stored pixel
     * values and original physical data values used to create the image.
@@ -223,25 +219,20 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
 /* New members added in libpng-1.0.6 */
    png_uint_32 free_me;     /* flags items libpng is responsible for freeing */
 
-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \
- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
    /* Storage for unknown chunks that the library doesn't recognize. */
    png_unknown_chunkp unknown_chunks;
-   int unknown_chunks_num;
-#endif
 
-#ifdef PNG_iCCP_SUPPORTED
-   /* iCCP chunk data. */
-   png_charp iccp_name;     /* profile name */
-   png_bytep iccp_profile;  /* International Color Consortium profile data */
-   png_uint_32 iccp_proflen;  /* ICC profile data length */
-   png_byte iccp_compression; /* Always zero */
+   /* The type of this field is limited by the type of
+    * png_struct::user_chunk_cache_max, else overflow can occur.
+    */
+   int                unknown_chunks_num;
 #endif
 
 #ifdef PNG_sPLT_SUPPORTED
    /* Data on sPLT chunks (there may be more than one). */
    png_sPLT_tp splt_palettes;
-   int splt_palettes_num;
+   int         splt_palettes_num; /* Match type returned by png_get API */
 #endif
 
 #ifdef PNG_sCAL_SUPPORTED

+ 34 - 6
drivers/png/pnglibconf.h

@@ -1,9 +1,10 @@
-/* 1.5.27 STANDARD API DEFINITION */
+/* libpng 1.6.23 STANDARD API DEFINITION */
+
 /* pnglibconf.h - library build configuration */
 
-/* libpng version 1.5.27 - May 26, 2016 */
+/* Libpng version 1.6.23 - June 9, 2016 */
 
-/* Copyright (c) 2011-2015 Glenn Randers-Pehrson */
+/* Copyright (c) 1998-2015 Glenn Randers-Pehrson */
 
 /* This code is released under the libpng license. */
 /* For conditions of distribution and use, see the disclaimer */
@@ -20,9 +21,11 @@
 /*#undef PNG_ARM_NEON_API_SUPPORTED*/
 /*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
 #define PNG_BENIGN_ERRORS_SUPPORTED
+#define PNG_BENIGN_READ_ERRORS_SUPPORTED
+/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
 #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
 #define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
-#define PNG_CHECK_cHRM_SUPPORTED
+#define PNG_COLORSPACE_SUPPORTED
 #define PNG_CONSOLE_IO_SUPPORTED
 #define PNG_CONVERT_tIME_SUPPORTED
 #define PNG_EASY_ACCESS_SUPPORTED
@@ -31,6 +34,9 @@
 #define PNG_FIXED_POINT_SUPPORTED
 #define PNG_FLOATING_ARITHMETIC_SUPPORTED
 #define PNG_FLOATING_POINT_SUPPORTED
+#define PNG_FORMAT_AFIRST_SUPPORTED
+#define PNG_FORMAT_BGR_SUPPORTED
+#define PNG_GAMMA_SUPPORTED
 #define PNG_GET_PALETTE_MAX_SUPPORTED
 #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 #define PNG_INCH_CONVERSIONS_SUPPORTED
@@ -91,13 +97,22 @@
 #define PNG_READ_tIME_SUPPORTED
 #define PNG_READ_tRNS_SUPPORTED
 #define PNG_READ_zTXt_SUPPORTED
-/*#undef PNG_SAFE_LIMITS_SUPPORTED*/
 #define PNG_SAVE_INT_32_SUPPORTED
+#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SEQUENTIAL_READ_SUPPORTED
 #define PNG_SETJMP_SUPPORTED
-/*#undef PNG_SET_OPTION_SUPPORTED*/
+#define PNG_SET_OPTION_SUPPORTED
+#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SET_USER_LIMITS_SUPPORTED
+#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_READ_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_SUPPORTED
 #define PNG_STDIO_SUPPORTED
+#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_TEXT_SUPPORTED
 #define PNG_TIME_RFC1123_SUPPORTED
 #define PNG_UNKNOWN_CHUNKS_SUPPORTED
@@ -173,15 +188,28 @@
 #define PNG_API_RULE 0
 #define PNG_DEFAULT_READ_MACROS 1
 #define PNG_GAMMA_THRESHOLD_FIXED 5000
+#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
+#define PNG_INFLATE_BUF_SIZE 1024
+#define PNG_LINKAGE_API extern
+#define PNG_LINKAGE_CALLBACK extern
+#define PNG_LINKAGE_DATA extern
+#define PNG_LINKAGE_FUNCTION extern
 #define PNG_MAX_GAMMA_8 11
 #define PNG_QUANTIZE_BLUE_BITS 5
 #define PNG_QUANTIZE_GREEN_BITS 5
 #define PNG_QUANTIZE_RED_BITS 5
+#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
 #define PNG_USER_CHUNK_CACHE_MAX 1000
 #define PNG_USER_CHUNK_MALLOC_MAX 8000000
 #define PNG_USER_HEIGHT_MAX 1000000
 #define PNG_USER_WIDTH_MAX 1000000
 #define PNG_ZBUF_SIZE 8192
+#define PNG_ZLIB_VERNUM 0 /* unknown */
+#define PNG_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
+#define PNG_Z_DEFAULT_STRATEGY 1
 #define PNG_sCAL_PRECISION 5
+#define PNG_sRGB_PROFILE_CHECKS 2
 /* end of settings */
 #endif /* PNGLCONF_H */

+ 145 - 528
drivers/png/pngmem.c

@@ -1,8 +1,8 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * Last changed in libpng 1.5.13 [September 27, 2012]
- * Copyright (c) 1998-2002,2004,2006-2012 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.15 [November 20, 2014]
+ * Copyright (c) 1998-2002,2004,2006-2014 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.)
  *
@@ -20,627 +20,244 @@
 #include "pngpriv.h"
 
 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-
-/* Borland DOS special memory handler */
-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
-/* If you change this, be sure to change the one in png.h also */
-
-/* Allocate memory for a png_struct.  The malloc and memset can be replaced
-   by a single call to calloc() if this is thought to improve performance. */
-PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct,(int type),PNG_ALLOCATED)
-{
-#  ifdef PNG_USER_MEM_SUPPORTED
-   return (png_create_struct_2(type, NULL, NULL));
-}
-
-/* Alternate version of png_create_struct, for use with user-defined malloc. */
-PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
-   PNG_ALLOCATED)
-{
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   png_size_t size;
-   png_voidp struct_ptr;
-
-   if (type == PNG_STRUCT_INFO)
-      size = png_sizeof(png_info);
-
-   else if (type == PNG_STRUCT_PNG)
-      size = png_sizeof(png_struct);
-
-   else
-      return (png_get_copyright(NULL));
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (malloc_fn != NULL)
-   {
-      png_struct dummy_struct;
-      png_memset(&dummy_struct, 0, sizeof dummy_struct);
-      dummy_struct.mem_ptr=mem_ptr;
-      struct_ptr = (*(malloc_fn))(&dummy_struct, (png_alloc_size_t)size);
-   }
-
-   else
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   struct_ptr = (png_voidp)farmalloc(size);
-   if (struct_ptr != NULL)
-      png_memset(struct_ptr, 0, size);
-
-   return (struct_ptr);
-}
-
-/* Free memory allocated by a png_create_struct() call */
+/* Free a png_struct */
 void /* PRIVATE */
-png_destroy_struct(png_voidp struct_ptr)
+png_destroy_png_struct(png_structrp png_ptr)
 {
-#  ifdef PNG_USER_MEM_SUPPORTED
-   png_destroy_struct_2(struct_ptr, NULL, NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
-    png_voidp mem_ptr)
-{
-#  endif
-   if (struct_ptr != NULL)
+   if (png_ptr != NULL)
    {
-#  ifdef PNG_USER_MEM_SUPPORTED
-      if (free_fn != NULL)
-      {
-         png_struct dummy_struct;
-         png_memset(&dummy_struct, 0, sizeof dummy_struct);
-         dummy_struct.mem_ptr=mem_ptr;
-         (*(free_fn))(&dummy_struct, struct_ptr);
-         return;
-      }
-
-#  endif /* PNG_USER_MEM_SUPPORTED */
-      farfree (struct_ptr);
+      /* png_free might call png_error and may certainly call
+       * png_get_mem_ptr, so fake a temporary png_struct to support this.
+       */
+      png_struct dummy_struct = *png_ptr;
+      memset(png_ptr, 0, (sizeof *png_ptr));
+      png_free(&dummy_struct, png_ptr);
+
+#     ifdef PNG_SETJMP_SUPPORTED
+         /* We may have a jmp_buf left to deallocate. */
+         png_free_jmpbuf(&dummy_struct);
+#     endif
    }
 }
 
 /* Allocate memory.  For reasonable files, size should never exceed
  * 64K.  However, zlib may allocate more than 64K if you don't tell
- * it not to.  See zconf.h and png.h for more information. zlib does
+ * it not to.  See zconf.h and png.h for more information.  zlib does
  * need to allocate exactly 64K, so whatever you call here must
  * have the ability to do that.
- *
- * Borland seems to have a problem in DOS mode for exactly 64K.
- * It gives you a segment with an offset of 8 (perhaps to store its
- * memory stuff).  zlib doesn't like this at all, so we have to
- * detect and deal with it.  This code should not be needed in
- * Windows or OS/2 modes, and only in 16 bit mode.  This code has
- * been updated by Alexander Lehmann for version 0.89 to waste less
- * memory.
- *
- * Note that we can't use png_size_t for the "size" declaration,
- * since on some systems a png_size_t is a 16-bit quantity, and as a
- * result, we would be truncating potentially larger memory requests
- * (which should cause a fatal error) and introducing major problems.
  */
 PNG_FUNCTION(png_voidp,PNGAPI
-png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
 {
    png_voidp ret;
 
-   ret = (png_malloc(png_ptr, size));
+   ret = png_malloc(png_ptr, size);
 
    if (ret != NULL)
-      png_memset(ret,0,(png_size_t)size);
-
-   return (ret);
-}
-
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ret;
-
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr->malloc_fn != NULL)
-      ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
-
-   else
-      ret = (png_malloc_default(png_ptr, size));
-
-   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-       png_error(png_ptr, "Out of memory");
+      memset(ret, 0, size);
 
-   return (ret);
+   return ret;
 }
 
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
+ * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
+ * Checking and error handling must happen outside this routine; it returns NULL
+ * if the allocation cannot be done (for any reason.)
+ */
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
+   PNG_ALLOCATED)
 {
-   png_voidp ret;
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-#  ifdef PNG_MAX_MALLOC_64K
-   if (size > (png_uint_32)65536L)
-   {
-      png_warning(png_ptr, "Cannot Allocate > 64K");
-      ret = NULL;
-   }
-
-   else
-#  endif
-
-   if (size != (size_t)size)
-      ret = NULL;
-
-   else if (size == (png_uint_32)65536L)
+   /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
+    * allocators have also been removed in 1.6.0, so any 16-bit system now has
+    * to implement a user memory handler.  This checks to be sure it isn't
+    * called with big numbers.
+    */
+#ifndef PNG_USER_MEM_SUPPORTED
+   PNG_UNUSED(png_ptr)
+#endif
+
+   /* Some compilers complain that this is always true.  However, it
+    * can be false when integer overflow happens.
+    */
+   if (size > 0 && size <= PNG_SIZE_MAX
+#     ifdef PNG_MAX_MALLOC_64K
+         && size <= 65536U
+#     endif
+      )
    {
-      if (png_ptr->offset_table == NULL)
-      {
-         /* Try to see if we need to do any of this fancy stuff */
-         ret = farmalloc(size);
-         if (ret == NULL || ((png_size_t)ret & 0xffff))
-         {
-            int num_blocks;
-            png_uint_32 total_size;
-            png_bytep table;
-            int i, mem_level, window_bits;
-            png_byte huge * hptr;
-            int window_bits
-
-            if (ret != NULL)
-            {
-               farfree(ret);
-               ret = NULL;
-            }
-
-            window_bits =
-                png_ptr->zlib_window_bits >= png_ptr->zlib_text_window_bits ?
-                png_ptr->zlib_window_bits : png_ptr->zlib_text_window_bits;
-
-            if (window_bits > 14)
-               num_blocks = (int)(1 << (window_bits - 14));
-
-            else
-               num_blocks = 1;
-
-            mem_level =
-                png_ptr->zlib_mem_level >= png_ptr->zlib_text_mem_level ?
-                png_ptr->zlib_mem_level : png_ptr->zlib_text_mem_level;
-
-            if (mem_level >= 7)
-               num_blocks += (int)(1 << (mem_level - 7));
-
-            else
-               num_blocks++;
-
-            total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
-
-            table = farmalloc(total_size);
-
-            if (table == NULL)
-            {
-#  ifndef PNG_USER_MEM_SUPPORTED
-               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-                  png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */
-
-               else
-                  png_warning(png_ptr, "Out Of Memory");
-#  endif
-               return (NULL);
-            }
-
-            if ((png_size_t)table & 0xfff0)
-            {
-#  ifndef PNG_USER_MEM_SUPPORTED
-               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-                  png_error(png_ptr,
-                    "Farmalloc didn't return normalized pointer");
-
-               else
-                  png_warning(png_ptr,
-                    "Farmalloc didn't return normalized pointer");
-#  endif
-               return (NULL);
-            }
-
-            png_ptr->offset_table = table;
-            png_ptr->offset_table_ptr = farmalloc(num_blocks *
-               png_sizeof(png_bytep));
-
-            if (png_ptr->offset_table_ptr == NULL)
-            {
-#  ifndef PNG_USER_MEM_SUPPORTED
-               if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-                  png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */
-
-               else
-                  png_warning(png_ptr, "Out Of memory");
-#  endif
-               return (NULL);
-            }
-
-            hptr = (png_byte huge *)table;
-            if ((png_size_t)hptr & 0xf)
-            {
-               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
-               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
-            }
-
-            for (i = 0; i < num_blocks; i++)
-            {
-               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
-               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
-            }
-
-            png_ptr->offset_table_number = num_blocks;
-            png_ptr->offset_table_count = 0;
-            png_ptr->offset_table_count_free = 0;
-         }
-      }
-
-      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
-      {
-#  ifndef PNG_USER_MEM_SUPPORTED
-         if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-            png_error(png_ptr, "Out of Memory"); /* Note "O" and "M" */
-
-         else
-            png_warning(png_ptr, "Out of Memory");
-#  endif
-         return (NULL);
-      }
-
-      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
-   }
-
-   else
-      ret = farmalloc(size);
-
-#  ifndef PNG_USER_MEM_SUPPORTED
-   if (ret == NULL)
-   {
-      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-         png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */
+#ifdef PNG_USER_MEM_SUPPORTED
+      if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
+         return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
 
       else
-         png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */
-   }
-#  endif
-
-   return (ret);
-}
-
-/* Free a pointer allocated by png_malloc().  In the default
- * configuration, png_ptr is not used, but is passed in case it
- * is needed.  If ptr is NULL, return without taking any action.
- */
-void PNGAPI
-png_free(png_structp png_ptr, png_voidp ptr)
-{
-   if (png_ptr == NULL || ptr == NULL)
-      return;
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr->free_fn != NULL)
-   {
-      (*(png_ptr->free_fn))(png_ptr, ptr);
-      return;
+#endif
+         return malloc((size_t)size); /* checked for truncation above */
    }
 
    else
-      png_free_default(png_ptr, ptr);
+      return NULL;
 }
 
-void PNGAPI
-png_free_default(png_structp png_ptr, png_voidp ptr)
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
+/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
+ * that arises because of the checks in png_realloc_array that are repeated in
+ * png_malloc_array.
+ */
+static png_voidp
+png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
+   size_t element_size)
 {
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-   if (png_ptr == NULL || ptr == NULL)
-      return;
+   png_alloc_size_t req = nelements; /* known to be > 0 */
 
-   if (png_ptr->offset_table != NULL)
-   {
-      int i;
+   if (req <= PNG_SIZE_MAX/element_size)
+      return png_malloc_base(png_ptr, req * element_size);
 
-      for (i = 0; i < png_ptr->offset_table_count; i++)
-      {
-         if (ptr == png_ptr->offset_table_ptr[i])
-         {
-            ptr = NULL;
-            png_ptr->offset_table_count_free++;
-            break;
-         }
-      }
-      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
-      {
-         farfree(png_ptr->offset_table);
-         farfree(png_ptr->offset_table_ptr);
-         png_ptr->offset_table = NULL;
-         png_ptr->offset_table_ptr = NULL;
-      }
-   }
-
-   if (ptr != NULL)
-      farfree(ptr);
+   /* The failure case when the request is too large */
+   return NULL;
 }
 
-#else /* Not the Borland DOS special memory handler */
-
-/* Allocate memory for a png_struct or a png_info.  The malloc and
-   memset can be replaced by a single call to calloc() if this is thought
-   to improve performance noticably. */
 PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct,(int type),PNG_ALLOCATED)
+png_malloc_array,(png_const_structrp png_ptr, int nelements,
+   size_t element_size),PNG_ALLOCATED)
 {
-#  ifdef PNG_USER_MEM_SUPPORTED
-   return (png_create_struct_2(type, NULL, NULL));
+   if (nelements <= 0 || element_size == 0)
+      png_error(png_ptr, "internal error: array alloc");
+
+   return png_malloc_array_checked(png_ptr, nelements, element_size);
 }
 
-/* Allocate memory for a png_struct or a png_info.  The malloc and
-   memset can be replaced by a single call to calloc() if this is thought
-   to improve performance noticably. */
 PNG_FUNCTION(png_voidp /* PRIVATE */,
-png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr),
-   PNG_ALLOCATED)
+png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
+   int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
 {
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   png_size_t size;
-   png_voidp struct_ptr;
-
-   if (type == PNG_STRUCT_INFO)
-      size = png_sizeof(png_info);
-
-   else if (type == PNG_STRUCT_PNG)
-      size = png_sizeof(png_struct);
-
-   else
-      return (NULL);
-
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (malloc_fn != NULL)
+   /* These are internal errors: */
+   if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
+      (old_array == NULL && old_elements > 0))
+      png_error(png_ptr, "internal error: array realloc");
+
+   /* Check for overflow on the elements count (so the caller does not have to
+    * check.)
+    */
+   if (add_elements <= INT_MAX - old_elements)
    {
-      png_struct dummy_struct;
-      png_structp png_ptr = &dummy_struct;
-      png_ptr->mem_ptr=mem_ptr;
-      struct_ptr = (*(malloc_fn))(png_ptr, size);
-
-      if (struct_ptr != NULL)
-         png_memset(struct_ptr, 0, size);
-
-      return (struct_ptr);
-   }
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-   struct_ptr = (png_voidp)farmalloc(size);
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-   struct_ptr = (png_voidp)halloc(size, 1);
-#    else
-   struct_ptr = (png_voidp)malloc(size);
-#    endif
-#  endif
-
-   if (struct_ptr != NULL)
-      png_memset(struct_ptr, 0, size);
-
-   return (struct_ptr);
-}
-
+      png_voidp new_array = png_malloc_array_checked(png_ptr,
+         old_elements+add_elements, element_size);
 
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct(png_voidp struct_ptr)
-{
-#  ifdef PNG_USER_MEM_SUPPORTED
-   png_destroy_struct_2(struct_ptr, NULL, NULL);
-}
-
-/* Free memory allocated by a png_create_struct() call */
-void /* PRIVATE */
-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
-    png_voidp mem_ptr)
-{
-#  endif /* PNG_USER_MEM_SUPPORTED */
-   if (struct_ptr != NULL)
-   {
-#  ifdef PNG_USER_MEM_SUPPORTED
-      if (free_fn != NULL)
+      if (new_array != NULL)
       {
-         png_struct dummy_struct;
-         png_structp png_ptr = &dummy_struct;
-         png_ptr->mem_ptr=mem_ptr;
-         (*(free_fn))(png_ptr, struct_ptr);
-         return;
-      }
-#  endif /* PNG_USER_MEM_SUPPORTED */
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-      farfree(struct_ptr);
-
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-      hfree(struct_ptr);
+         /* Because png_malloc_array worked the size calculations below cannot
+          * overflow.
+          */
+         if (old_elements > 0)
+            memcpy(new_array, old_array, element_size*(unsigned)old_elements);
 
-#    else
-      free(struct_ptr);
+         memset((char*)new_array + element_size*(unsigned)old_elements, 0,
+            element_size*(unsigned)add_elements);
 
-#    endif
-#  endif
+         return new_array;
+      }
    }
+
+   return NULL; /* error */
 }
+#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
 
-/* Allocate memory.  For reasonable files, size should never exceed
- * 64K.  However, zlib may allocate more than 64K if you don't tell
- * it not to.  See zconf.h and png.h for more information.  zlib does
- * need to allocate exactly 64K, so whatever you call here must
- * have the ability to do that.
+/* Various functions that have different error handling are derived from this.
+ * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
+ * function png_malloc_default is also provided.
  */
-
 PNG_FUNCTION(png_voidp,PNGAPI
-png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
 {
    png_voidp ret;
 
-   ret = (png_malloc(png_ptr, size));
+   if (png_ptr == NULL)
+      return NULL;
 
-   if (ret != NULL)
-      png_memset(ret,0,(png_size_t)size);
+   ret = png_malloc_base(png_ptr, size);
+
+   if (ret == NULL)
+       png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
 
-   return (ret);
+   return ret;
 }
 
+#ifdef PNG_USER_MEM_SUPPORTED
 PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
+   PNG_ALLOCATED PNG_DEPRECATED)
 {
    png_voidp ret;
 
-#  ifdef PNG_USER_MEM_SUPPORTED
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-   if (png_ptr->malloc_fn != NULL)
-      ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+   if (png_ptr == NULL)
+      return NULL;
 
-   else
-      ret = (png_malloc_default(png_ptr, size));
+   /* Passing 'NULL' here bypasses the application provided memory handler. */
+   ret = png_malloc_base(NULL/*use malloc*/, size);
 
-   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-       png_error(png_ptr, "Out of Memory");
+   if (ret == NULL)
+      png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
 
-   return (ret);
+   return ret;
 }
+#endif /* USER_MEM */
 
+/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
+ * function will issue a png_warning and return NULL instead of issuing a
+ * png_error, if it fails to allocate the requested memory.
+ */
 PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
+   PNG_ALLOCATED)
 {
-   png_voidp ret;
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-   if (png_ptr == NULL || size == 0)
-      return (NULL);
-
-#  ifdef PNG_MAX_MALLOC_64K
-   if (size > (png_uint_32)65536L)
+   if (png_ptr != NULL)
    {
-#    ifndef PNG_USER_MEM_SUPPORTED
-      if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-         png_error(png_ptr, "Cannot Allocate > 64K");
-
-      else
-#    endif
-         return NULL;
-   }
-#  endif
-
-   /* Check for overflow */
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-
-   if (size != (unsigned long)size)
-      ret = NULL;
-
-   else
-      ret = farmalloc(size);
-
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-   if (size != (unsigned long)size)
-      ret = NULL;
-
-   else
-      ret = halloc(size, 1);
+      png_voidp ret = png_malloc_base(png_ptr, size);
 
-#    else
-   if (size != (size_t)size)
-      ret = NULL;
+      if (ret != NULL)
+         return ret;
 
-   else
-      ret = malloc((size_t)size);
-#    endif
-#  endif
-
-#  ifndef PNG_USER_MEM_SUPPORTED
-   if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
-      png_error(png_ptr, "Out of Memory");
-#  endif
+      png_warning(png_ptr, "Out of memory");
+   }
 
-   return (ret);
+   return NULL;
 }
 
 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return
  * without taking any action.
  */
 void PNGAPI
-png_free(png_structp png_ptr, png_voidp ptr)
+png_free(png_const_structrp png_ptr, png_voidp ptr)
 {
    if (png_ptr == NULL || ptr == NULL)
       return;
 
-#  ifdef PNG_USER_MEM_SUPPORTED
+#ifdef PNG_USER_MEM_SUPPORTED
    if (png_ptr->free_fn != NULL)
-   {
-      (*(png_ptr->free_fn))(png_ptr, ptr);
-      return;
-   }
+      png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
 
    else
       png_free_default(png_ptr, ptr);
 }
 
-void PNGAPI
-png_free_default(png_structp png_ptr, png_voidp ptr)
+PNG_FUNCTION(void,PNGAPI
+png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
 {
    if (png_ptr == NULL || ptr == NULL)
       return;
+#endif /* USER_MEM */
 
-#  endif /* PNG_USER_MEM_SUPPORTED */
-
-#  if defined(__TURBOC__) && !defined(__FLAT__)
-   farfree(ptr);
-
-#  else
-#    if defined(_MSC_VER) && defined(MAXSEG_64K)
-   hfree(ptr);
-
-#    else
    free(ptr);
-
-#    endif
-#  endif
-}
-#endif /* Not Borland DOS special memory handler */
-
-/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
- * function will set up png_malloc() to issue a png_warning and return NULL
- * instead of issuing a png_error, if it fails to allocate the requested
- * memory.
- */
-PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
-{
-   png_voidp ptr;
-   png_uint_32 save_flags;
-   if (png_ptr == NULL)
-      return (NULL);
-
-   save_flags = png_ptr->flags;
-   png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
-   ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
-   png_ptr->flags=save_flags;
-   return(ptr);
 }
 
-
 #ifdef PNG_USER_MEM_SUPPORTED
 /* This function is called when the application wants to use another method
  * of allocating and freeing memory.
  */
 void PNGAPI
-png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
   malloc_fn, png_free_ptr free_fn)
 {
    if (png_ptr != NULL)
@@ -656,12 +273,12 @@ png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
  * pointer before png_write_destroy and png_read_destroy are called.
  */
 png_voidp PNGAPI
-png_get_mem_ptr(png_const_structp png_ptr)
+png_get_mem_ptr(png_const_structrp png_ptr)
 {
    if (png_ptr == NULL)
-      return (NULL);
+      return NULL;
 
-   return ((png_voidp)png_ptr->mem_ptr);
+   return png_ptr->mem_ptr;
 }
-#endif /* PNG_USER_MEM_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+#endif /* USER_MEM */
+#endif /* READ || WRITE */

+ 143 - 280
drivers/png/pngpread.c

@@ -1,8 +1,8 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * Last changed in libpng 1.5.23 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.23 [June 9, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 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.)
  *
@@ -25,8 +25,15 @@
 #define PNG_READ_iTXt_MODE  7
 #define PNG_ERROR_MODE      8
 
+#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
+if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
+   { png_push_save_buffer(png_ptr); return; }
+#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
+if (png_ptr->buffer_size < N) \
+   { png_push_save_buffer(png_ptr); return; }
+
 void PNGAPI
-png_process_data(png_structp png_ptr, png_infop info_ptr,
+png_process_data(png_structrp png_ptr, png_inforp info_ptr,
     png_bytep buffer, png_size_t buffer_size)
 {
    if (png_ptr == NULL || info_ptr == NULL)
@@ -41,11 +48,11 @@ png_process_data(png_structp png_ptr, png_infop info_ptr,
 }
 
 png_size_t PNGAPI
-png_process_data_pause(png_structp png_ptr, int save)
+png_process_data_pause(png_structrp png_ptr, int save)
 {
    if (png_ptr != NULL)
    {
-      /* It's easiest for the caller if we do the save, then the caller doesn't
+      /* It's easiest for the caller if we do the save; then the caller doesn't
        * have to supply the same data again:
        */
       if (save != 0)
@@ -68,16 +75,15 @@ png_process_data_pause(png_structp png_ptr, int save)
 }
 
 png_uint_32 PNGAPI
-png_process_data_skip(png_structp png_ptr)
+png_process_data_skip(png_structrp png_ptr)
 {
-    /* TODO: Deprecate and remove this API.
-     * Somewhere the implementation of this seems to have been lost,
-     * or abandoned.  It was only to support some internal back-door access
-     * to png_struct) in libpng-1.4.x.
-     */
-   png_warning(png_ptr,
-       "png_process_data_skip is not implemented in any current version"
-       " of libpng");
+  /* TODO: Deprecate and remove this API.
+   * Somewhere the implementation of this seems to have been lost,
+   * or abandoned.  It was only to support some internal back-door access
+   * to png_struct) in libpng-1.4.x.
+   */
+   png_app_warning(png_ptr,
+"png_process_data_skip is not implemented in any current version of libpng");
    return 0;
 }
 
@@ -85,7 +91,7 @@ png_process_data_skip(png_structp png_ptr)
  * doing before we ran out of data...
  */
 void /* PRIVATE */
-png_process_some_data(png_structp png_ptr, png_infop info_ptr)
+png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
 {
    if (png_ptr == NULL)
       return;
@@ -125,7 +131,7 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr)
  * routine.
  */
 void /* PRIVATE */
-png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
+png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
 {
    png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
        num_to_check = 8 - num_checked;
@@ -148,7 +154,6 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
       else
          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
    }
-
    else
    {
       if (png_ptr->sig_bytes >= 8)
@@ -159,27 +164,25 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
 }
 
 void /* PRIVATE */
-png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
+png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
 {
    png_uint_32 chunk_name;
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+   int keep; /* unknown handling method */
+#endif
 
-   /* First we make sure we have enough data for the 4 byte chunk name
-    * and the 4 byte chunk length before proceeding with decoding the
+   /* First we make sure we have enough data for the 4-byte chunk name
+    * and the 4-byte chunk length before proceeding with decoding the
     * chunk data.  To fully decode each of these chunks, we also make
-    * sure we have enough data in the buffer for the 4 byte CRC at the
+    * sure we have enough data in the buffer for the 4-byte CRC at the
     * end of every chunk (except IDAT, which is handled separately).
     */
-   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
    {
       png_byte chunk_length[4];
       png_byte chunk_tag[4];
 
-      if (png_ptr->buffer_size < 8)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_LT(8)
       png_push_fill_buffer(png_ptr, chunk_length, 4);
       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
       png_reset_crc(png_ptr);
@@ -193,14 +196,31 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 
    if (chunk_name == png_IDAT)
    {
-      /* This is here above the if/else case statement below because if the
-       * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
-       * completely skipped.
-       *
-       * TODO: there must be a better way of doing this.
-       */
-      if (png_ptr->mode & PNG_AFTER_IDAT)
+      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+      /* If we reach an IDAT chunk, this means we have read all of the
+       * header chunks, and we can start reading the image (or if this
+       * is called after the image has been read - we have an error).
+       */
+      if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+         png_error(png_ptr, "Missing IHDR before IDAT");
+
+      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+          (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+         png_error(png_ptr, "Missing PLTE before IDAT");
+
+      png_ptr->process_mode = PNG_READ_IDAT_MODE;
+
+      if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+         if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
+            if (png_ptr->push_length == 0)
+               return;
+
+      png_ptr->mode |= PNG_HAVE_IDAT;
+
+      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+         png_benign_error(png_ptr, "Too many IDATs found");
    }
 
    if (chunk_name == png_IHDR)
@@ -208,23 +228,13 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
       if (png_ptr->push_length != 13)
          png_error(png_ptr, "Invalid IHDR length");
 
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
    }
 
    else if (chunk_name == png_IEND)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
 
       png_ptr->process_mode = PNG_READ_DONE_MODE;
@@ -232,70 +242,25 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
    }
 
 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-   else if (png_chunk_unknown_handling(png_ptr, chunk_name))
+   else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
-      if (chunk_name == png_IDAT)
-         png_ptr->mode |= PNG_HAVE_IDAT;
-
-      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
 
       if (chunk_name == png_PLTE)
          png_ptr->mode |= PNG_HAVE_PLTE;
-
-      else if (chunk_name == png_IDAT)
-      {
-         if (!(png_ptr->mode & PNG_HAVE_IHDR))
-            png_error(png_ptr, "Missing IHDR before IDAT");
-
-         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-             !(png_ptr->mode & PNG_HAVE_PLTE))
-            png_error(png_ptr, "Missing PLTE before IDAT");
-      }
    }
 #endif
 
    else if (chunk_name == png_PLTE)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
    }
 
    else if (chunk_name == png_IDAT)
    {
-      /* If we reach an IDAT chunk, this means we have read all of the
-       * header chunks, and we can start reading the image (or if this
-       * is called after the image has been read - we have an error).
-       */
-
-      if (!(png_ptr->mode & PNG_HAVE_IHDR))
-         png_error(png_ptr, "Missing IHDR before IDAT");
-
-      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-          !(png_ptr->mode & PNG_HAVE_PLTE))
-         png_error(png_ptr, "Missing PLTE before IDAT");
-
-      if (png_ptr->mode & PNG_HAVE_IDAT)
-      {
-         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
-            if (png_ptr->push_length == 0)
-               return;
-
-         if (png_ptr->mode & PNG_AFTER_IDAT)
-            png_benign_error(png_ptr, "Too many IDATs found");
-      }
-
       png_ptr->idat_size = png_ptr->push_length;
-      png_ptr->mode |= PNG_HAVE_IDAT;
       png_ptr->process_mode = PNG_READ_IDAT_MODE;
       png_push_have_info(png_ptr, info_ptr);
       png_ptr->zstream.avail_out =
@@ -308,12 +273,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_gAMA_SUPPORTED
    else if (png_ptr->chunk_name == png_gAMA)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -321,12 +281,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_sBIT_SUPPORTED
    else if (png_ptr->chunk_name == png_sBIT)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -334,12 +289,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_cHRM_SUPPORTED
    else if (png_ptr->chunk_name == png_cHRM)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -347,12 +297,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_sRGB_SUPPORTED
    else if (chunk_name == png_sRGB)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -360,12 +305,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_iCCP_SUPPORTED
    else if (png_ptr->chunk_name == png_iCCP)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -373,12 +313,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_sPLT_SUPPORTED
    else if (chunk_name == png_sPLT)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -386,12 +321,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_tRNS_SUPPORTED
    else if (chunk_name == png_tRNS)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -399,12 +329,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_bKGD_SUPPORTED
    else if (chunk_name == png_bKGD)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -412,12 +337,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_hIST_SUPPORTED
    else if (chunk_name == png_hIST)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -425,12 +345,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_pHYs_SUPPORTED
    else if (chunk_name == png_pHYs)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -438,12 +353,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_oFFs_SUPPORTED
    else if (chunk_name == png_oFFs)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
    }
 #endif
@@ -451,12 +361,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_pCAL_SUPPORTED
    else if (chunk_name == png_pCAL)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -464,12 +369,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_sCAL_SUPPORTED
    else if (chunk_name == png_sCAL)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -477,12 +377,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_tIME_SUPPORTED
    else if (chunk_name == png_tIME)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -490,12 +385,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_tEXt_SUPPORTED
    else if (chunk_name == png_tEXt)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -503,12 +393,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_zTXt_SUPPORTED
    else if (chunk_name == png_zTXt)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -516,25 +401,16 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 #ifdef PNG_READ_iTXt_SUPPORTED
    else if (chunk_name == png_iTXt)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
    }
-
 #endif
 
    else
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
+      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
+         PNG_HANDLE_CHUNK_AS_DEFAULT);
    }
 
    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
@@ -549,8 +425,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
       return;
 
    ptr = buffer;
-
-   if (png_ptr->save_buffer_size)
+   if (png_ptr->save_buffer_size != 0)
    {
       png_size_t save_size;
 
@@ -560,15 +435,14 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
       else
          save_size = png_ptr->save_buffer_size;
 
-      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+      memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
       length -= save_size;
       ptr += save_size;
       png_ptr->buffer_size -= save_size;
       png_ptr->save_buffer_size -= save_size;
       png_ptr->save_buffer_ptr += save_size;
    }
-
-   if (length && png_ptr->current_buffer_size)
+   if (length != 0 && png_ptr->current_buffer_size != 0)
    {
       png_size_t save_size;
 
@@ -578,7 +452,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
       else
          save_size = png_ptr->current_buffer_size;
 
-      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+      memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
       png_ptr->buffer_size -= save_size;
       png_ptr->current_buffer_size -= save_size;
       png_ptr->current_buffer_ptr += save_size;
@@ -586,9 +460,9 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
 }
 
 void /* PRIVATE */
-png_push_save_buffer(png_structp png_ptr)
+png_push_save_buffer(png_structrp png_ptr)
 {
-   if (png_ptr->save_buffer_size)
+   if (png_ptr->save_buffer_size != 0)
    {
       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
       {
@@ -597,7 +471,6 @@ png_push_save_buffer(png_structp png_ptr)
          png_bytep dp;
 
          istop = png_ptr->save_buffer_size;
-
          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
              i < istop; i++, sp++, dp++)
          {
@@ -605,7 +478,6 @@ png_push_save_buffer(png_structp png_ptr)
          }
       }
    }
-
    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
        png_ptr->save_buffer_max)
    {
@@ -620,7 +492,8 @@ png_push_save_buffer(png_structp png_ptr)
 
       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
       old_buffer = png_ptr->save_buffer;
-      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, new_max);
+      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
+          (png_size_t)new_max);
 
       if (png_ptr->save_buffer == NULL)
       {
@@ -628,25 +501,26 @@ png_push_save_buffer(png_structp png_ptr)
          png_error(png_ptr, "Insufficient memory for save_buffer");
       }
 
-      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      if (old_buffer)
+         memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+      else if (png_ptr->save_buffer_size)
+         png_error(png_ptr, "save_buffer error");
       png_free(png_ptr, old_buffer);
       png_ptr->save_buffer_max = new_max;
    }
-
    if (png_ptr->current_buffer_size)
    {
-      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+      memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
       png_ptr->current_buffer_size = 0;
    }
-
    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
    png_ptr->buffer_size = 0;
 }
 
 void /* PRIVATE */
-png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
+png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
    png_size_t buffer_length)
 {
    png_ptr->current_buffer = buffer;
@@ -656,20 +530,15 @@ png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
 }
 
 void /* PRIVATE */
-png_push_read_IDAT(png_structp png_ptr)
+png_push_read_IDAT(png_structrp png_ptr)
 {
-   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
    {
       png_byte chunk_length[4];
       png_byte chunk_tag[4];
 
       /* TODO: this code can be commoned up with the same code in push_read */
-      if (png_ptr->buffer_size < 8)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_LT(8)
       png_push_fill_buffer(png_ptr, chunk_length, 4);
       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
       png_reset_crc(png_ptr);
@@ -681,7 +550,7 @@ png_push_read_IDAT(png_structp png_ptr)
       {
          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
 
-         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+         if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
             png_error(png_ptr, "Not enough compressed data");
 
          return;
@@ -690,7 +559,7 @@ png_push_read_IDAT(png_structp png_ptr)
       png_ptr->idat_size = png_ptr->push_length;
    }
 
-   if (png_ptr->idat_size && png_ptr->save_buffer_size)
+   if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
    {
       png_size_t save_size = png_ptr->save_buffer_size;
       png_uint_32 idat_size = png_ptr->idat_size;
@@ -699,7 +568,7 @@ png_push_read_IDAT(png_structp png_ptr)
        * are of different types and we don't know which variable has the fewest
        * bits.  Carefully select the smaller and cast it to the type of the
        * larger - this cannot overflow.  Do not cast in the following test - it
-       * will break on either 16 or 64 bit platforms.
+       * will break on either 16-bit or 64-bit platforms.
        */
       if (idat_size < save_size)
          save_size = (png_size_t)idat_size;
@@ -717,7 +586,7 @@ png_push_read_IDAT(png_structp png_ptr)
       png_ptr->save_buffer_ptr += save_size;
    }
 
-   if (png_ptr->idat_size && png_ptr->current_buffer_size)
+   if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
    {
       png_size_t save_size = png_ptr->current_buffer_size;
       png_uint_32 idat_size = png_ptr->idat_size;
@@ -743,22 +612,18 @@ png_push_read_IDAT(png_structp png_ptr)
       png_ptr->current_buffer_ptr += save_size;
    }
 
-   if (!png_ptr->idat_size)
+   if (png_ptr->idat_size == 0)
    {
-      if (png_ptr->buffer_size < 4)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_LT(4)
       png_crc_finish(png_ptr, 0);
       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
       png_ptr->mode |= PNG_AFTER_IDAT;
+      png_ptr->zowner = 0;
    }
 }
 
 void /* PRIVATE */
-png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
    png_size_t buffer_length)
 {
    /* The caller checks for a non-zero buffer length. */
@@ -770,13 +635,14 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
     * handle the uncompressed results.
     */
    png_ptr->zstream.next_in = buffer;
+   /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
    png_ptr->zstream.avail_in = (uInt)buffer_length;
 
    /* Keep going until the decompressed data is all processed
     * or the stream marked as finished.
     */
    while (png_ptr->zstream.avail_in > 0 &&
-          !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+      (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
    {
       int ret;
 
@@ -787,9 +653,9 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
        */
       if (!(png_ptr->zstream.avail_out > 0))
       {
-         png_ptr->zstream.avail_out =
-             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
-             png_ptr->iwidth) + 1;
+         /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
+         png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
+             png_ptr->iwidth) + 1);
 
          png_ptr->zstream.next_out = png_ptr->row_buf;
       }
@@ -801,19 +667,14 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
        * change the current behavior (see comments in inflate.c
        * for why this doesn't happen at present with zlib 1.2.5).
        */
-      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
-
-      /* Hack, added in 1.5.18: the progressive reader does not reset
-       * png_ptr->zstream, so any attempt to use it after the last IDAT fails
-       * (silently).  This allows the read code to do the reset when required.
-       */
-      png_ptr->flags |= PNG_FLAG_ZSTREAM_PROGRESSIVE;
+      ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
 
       /* Check for any failure before proceeding. */
       if (ret != Z_OK && ret != Z_STREAM_END)
       {
          /* Terminate the decompression. */
-         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+         png_ptr->zowner = 0;
 
          /* This may be a truncated stream (missing or
           * damaged end code).  Treat that as a warning.
@@ -841,7 +702,8 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
          {
             /* Extra data. */
             png_warning(png_ptr, "Extra compressed data in IDAT");
-            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+            png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+            png_ptr->zowner = 0;
 
             /* Do no more processing; skip the unprocessed
              * input check below.
@@ -856,7 +718,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
 
       /* And check for the end of the stream. */
       if (ret == Z_STREAM_END)
-         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
    }
 
    /* All the data should have been processed, if anything
@@ -868,7 +730,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
 }
 
 void /* PRIVATE */
-png_push_process_row(png_structp png_ptr)
+png_push_process_row(png_structrp png_ptr)
 {
    /* 1.5.6: row_info moved out of png_struct to a local here. */
    png_row_info row_info;
@@ -894,10 +756,10 @@ png_push_process_row(png_structp png_ptr)
     * it may not be in the future, so this was changed just to copy the
     * interlaced row count:
     */
-   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
+   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
 
 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
-   if (png_ptr->transformations)
+   if (png_ptr->transformations != 0)
       png_do_read_transformations(png_ptr, &row_info);
 #endif
 
@@ -914,15 +776,16 @@ png_push_process_row(png_structp png_ptr)
 
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* Blow up interlaced rows to full size */
-   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+   /* Expand interlaced rows to full size */
+   if (png_ptr->interlaced != 0 &&
+       (png_ptr->transformations & PNG_INTERLACE) != 0)
    {
       if (png_ptr->pass < 6)
          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
             png_ptr->transformations);
 
-    switch (png_ptr->pass)
-    {
+      switch (png_ptr->pass)
+      {
          case 0:
          {
             int i;
@@ -1097,26 +960,26 @@ png_push_process_row(png_structp png_ptr)
 }
 
 void /* PRIVATE */
-png_read_push_finish_row(png_structp png_ptr)
+png_read_push_finish_row(png_structrp png_ptr)
 {
 #ifdef PNG_READ_INTERLACING_SUPPORTED
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
-   static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+   static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
 
    /* Offset to next interlace block */
-   static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+   static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
 
    /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+   static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
 
    /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+   static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
 
    /* Height of interlace block.  This is not currently used - if you need
     * it, uncomment it here and in png.h
-   static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+   static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
    */
 #endif
 
@@ -1125,10 +988,10 @@ png_read_push_finish_row(png_structp png_ptr)
       return;
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
-   if (png_ptr->interlaced)
+   if (png_ptr->interlaced != 0)
    {
       png_ptr->row_number = 0;
-      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
 
       do
       {
@@ -1149,7 +1012,7 @@ png_read_push_finish_row(png_structp png_ptr)
              png_pass_start[png_ptr->pass]) /
              png_pass_inc[png_ptr->pass];
 
-         if (png_ptr->transformations & PNG_INTERLACE)
+         if ((png_ptr->transformations & PNG_INTERLACE) != 0)
             break;
 
          png_ptr->num_rows = (png_ptr->height +
@@ -1159,25 +1022,25 @@ png_read_push_finish_row(png_structp png_ptr)
 
       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
    }
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
+#endif /* READ_INTERLACING */
 }
 
 void /* PRIVATE */
-png_push_have_info(png_structp png_ptr, png_infop info_ptr)
+png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
 {
    if (png_ptr->info_fn != NULL)
       (*(png_ptr->info_fn))(png_ptr, info_ptr);
 }
 
 void /* PRIVATE */
-png_push_have_end(png_structp png_ptr, png_infop info_ptr)
+png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
 {
    if (png_ptr->end_fn != NULL)
       (*(png_ptr->end_fn))(png_ptr, info_ptr);
 }
 
 void /* PRIVATE */
-png_push_have_row(png_structp png_ptr, png_bytep row)
+png_push_have_row(png_structrp png_ptr, png_bytep row)
 {
    if (png_ptr->row_fn != NULL)
       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
@@ -1186,7 +1049,7 @@ png_push_have_row(png_structp png_ptr, png_bytep row)
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
 void PNGAPI
-png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
+png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
     png_const_bytep new_row)
 {
    if (png_ptr == NULL)
@@ -1199,10 +1062,10 @@ png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
    if (new_row != NULL)
       png_combine_row(png_ptr, old_row, 1/*blocky display*/);
 }
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
+#endif /* READ_INTERLACING */
 
 void PNGAPI
-png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
+png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
     png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
     png_progressive_end_ptr end_fn)
 {
@@ -1217,11 +1080,11 @@ png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
 }
 
 png_voidp PNGAPI
-png_get_progressive_ptr(png_const_structp png_ptr)
+png_get_progressive_ptr(png_const_structrp png_ptr)
 {
    if (png_ptr == NULL)
       return (NULL);
 
    return png_ptr->io_ptr;
 }
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+#endif /* PROGRESSIVE_READ */

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 501 - 336
drivers/png/pngpriv.h


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 290 - 380
drivers/png/pngread.c


+ 9 - 65
drivers/png/pngrio.c

@@ -1,8 +1,8 @@
 
 /* pngrio.c - functions for data input
  *
- * Last changed in libpng 1.5.0 [January 6, 2011]
- * Copyright (c) 1998-2002,2004,2006-2011 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2002,2004,2006-2015 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.)
  *
@@ -26,10 +26,10 @@
  * reads from a file pointer.  Note that this routine sometimes gets called
  * with very small lengths, so you should implement some kind of simple
  * buffering if you are using unbuffered reads.  This should never be asked
- * to read more than 64K on a 16 bit machine.
+ * to read more than 64K on a 16-bit machine.
  */
 void /* PRIVATE */
-png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
 {
    png_debug1(4, "reading %d bytes", (int)length);
 
@@ -46,7 +46,6 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  * read_data function and use it at run time with png_set_read_fn(), rather
  * than changing the library.
  */
-#  ifndef USE_FAR_KEYWORD
 void PNGCBAPI
 png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
@@ -58,68 +57,11 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
    /* fread() returns 0 on error, so it is OK to store this in a png_size_t
     * instead of an int, which is what fread() actually returns.
     */
-   check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr);
+   check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
 
    if (check != length)
       png_error(png_ptr, "Read Error");
 }
-#  else
-/* This is the model-independent version. Since the standard I/O library
-   can't handle far buffers in the medium and small models, we have to copy
-   the data.
-*/
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-static void PNGCBAPI
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_size_t check;
-   png_byte *n_data;
-   png_FILE_p io_ptr;
-
-   if (png_ptr == NULL)
-      return;
-
-   /* Check if data really is near. If so, use usual code. */
-   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
-
-   if ((png_bytep)n_data == data)
-   {
-      check = fread(n_data, 1, length, io_ptr);
-   }
-
-   else
-   {
-      png_byte buf[NEAR_BUF_SIZE];
-      png_size_t read, remaining, err;
-      check = 0;
-      remaining = length;
-
-      do
-      {
-         read = MIN(NEAR_BUF_SIZE, remaining);
-         err = fread(buf, 1, read, io_ptr);
-         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
-
-         if (err != read)
-            break;
-
-         else
-            check += err;
-
-         data += read;
-         remaining -= read;
-      }
-      while (remaining != 0);
-   }
-
-   if ((png_uint_32)check != (png_uint_32)length)
-      png_error(png_ptr, "read Error");
-}
-#  endif
 #endif
 
 /* This function allows the application to supply a new input function
@@ -142,7 +84,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  *                be used.
  */
 void PNGAPI
-png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
+png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
    png_rw_ptr read_data_fn)
 {
    if (png_ptr == NULL)
@@ -160,6 +102,7 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
    png_ptr->read_data_fn = read_data_fn;
 #endif
 
+#ifdef PNG_WRITE_SUPPORTED
    /* It is an error to write to a read device */
    if (png_ptr->write_data_fn != NULL)
    {
@@ -168,9 +111,10 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
           "Can't set both read_data_fn and write_data_fn in the"
           " same structure");
    }
+#endif
 
 #ifdef PNG_WRITE_FLUSH_SUPPORTED
    png_ptr->output_flush_fn = NULL;
 #endif
 }
-#endif /* PNG_READ_SUPPORTED */
+#endif /* READ */

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 207 - 172
drivers/png/pngrtran.c


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 622 - 341
drivers/png/pngrutil.c


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 235 - 285
drivers/png/pngset.c


+ 177 - 47
drivers/png/pngstruct.h

@@ -1,7 +1,7 @@
 
 /* pngstruct.h - header file for PNG reference library
  *
- * Last changed in libpng 1.5.23 [July 23, 2015]
+ * Last changed in libpng 1.6.18 [July 23, 2015]
  * Copyright (c) 1998-2002,2004,2006-2015 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.)
@@ -23,13 +23,130 @@
  * in this structure and is required for decompressing the LZ compressed
  * data in PNG files.
  */
+#ifndef ZLIB_CONST
+   /* We must ensure that zlib uses 'const' in declarations. */
+#  define ZLIB_CONST
+#endif
 #include "zlib.h"
+#ifdef const
+   /* zlib.h sometimes #defines const to nothing, undo this. */
+#  undef const
+#endif
+
+/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
+ * with older builds.
+ */
+#if ZLIB_VERNUM < 0x1260
+#  define PNGZ_MSG_CAST(s) png_constcast(char*,s)
+#  define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
+#else
+#  define PNGZ_MSG_CAST(s) (s)
+#  define PNGZ_INPUT_CAST(b) (b)
+#endif
+
+/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
+ * can handle at once.  This type need be no larger than 16 bits (so maximum of
+ * 65535), this define allows us to discover how big it is, but limited by the
+ * maximuum for png_size_t.  The value can be overriden in a library build
+ * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
+ * lower value (e.g. 255 works).  A lower value may help memory usage (slightly)
+ * and may even improve performance on some systems (and degrade it on others.)
+ */
+#ifndef ZLIB_IO_MAX
+#  define ZLIB_IO_MAX ((uInt)-1)
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+/* The type of a compression buffer list used by the write code. */
+typedef struct png_compression_buffer
+{
+   struct png_compression_buffer *next;
+   png_byte                       output[1]; /* actually zbuf_size */
+} png_compression_buffer, *png_compression_bufferp;
+
+#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
+   (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
+#endif
+
+/* Colorspace support; structures used in png_struct, png_info and in internal
+ * functions to hold and communicate information about the color space.
+ *
+ * PNG_COLORSPACE_SUPPORTED is only required if the application will perform
+ * colorspace corrections, otherwise all the colorspace information can be
+ * skipped and the size of libpng can be reduced (significantly) by compiling
+ * out the colorspace support.
+ */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* The chromaticities of the red, green and blue colorants and the chromaticity
+ * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
+ */
+typedef struct png_xy
+{
+   png_fixed_point redx, redy;
+   png_fixed_point greenx, greeny;
+   png_fixed_point bluex, bluey;
+   png_fixed_point whitex, whitey;
+} png_xy;
+
+/* The same data as above but encoded as CIE XYZ values.  When this data comes
+ * from chromaticities the sum of the Y values is assumed to be 1.0
+ */
+typedef struct png_XYZ
+{
+   png_fixed_point red_X, red_Y, red_Z;
+   png_fixed_point green_X, green_Y, green_Z;
+   png_fixed_point blue_X, blue_Y, blue_Z;
+} png_XYZ;
+#endif /* COLORSPACE */
+
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+/* A colorspace is all the above plus, potentially, profile information;
+ * however at present libpng does not use the profile internally so it is only
+ * stored in the png_info struct (if iCCP is supported.)  The rendering intent
+ * is retained here and is checked.
+ *
+ * The file gamma encoding information is also stored here and gamma correction
+ * is done by libpng, whereas color correction must currently be done by the
+ * application.
+ */
+typedef struct png_colorspace
+{
+#ifdef PNG_GAMMA_SUPPORTED
+   png_fixed_point gamma;        /* File gamma */
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+   png_xy      end_points_xy;    /* End points as chromaticities */
+   png_XYZ     end_points_XYZ;   /* End points as CIE XYZ colorant values */
+   png_uint_16 rendering_intent; /* Rendering intent of a profile */
+#endif
+
+   /* Flags are always defined to simplify the code. */
+   png_uint_16 flags;            /* As defined below */
+} png_colorspace, * PNG_RESTRICT png_colorspacerp;
+
+typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
+
+/* General flags for the 'flags' field */
+#define PNG_COLORSPACE_HAVE_GAMMA           0x0001
+#define PNG_COLORSPACE_HAVE_ENDPOINTS       0x0002
+#define PNG_COLORSPACE_HAVE_INTENT          0x0004
+#define PNG_COLORSPACE_FROM_gAMA            0x0008
+#define PNG_COLORSPACE_FROM_cHRM            0x0010
+#define PNG_COLORSPACE_FROM_sRGB            0x0020
+#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
+#define PNG_COLORSPACE_MATCHES_sRGB         0x0080 /* exact match on profile */
+#define PNG_COLORSPACE_INVALID              0x8000
+#define PNG_COLORSPACE_CANCEL(flags)        (0xffff ^ (flags))
+#endif /* COLORSPACE || GAMMA */
 
 struct png_struct_def
 {
 #ifdef PNG_SETJMP_SUPPORTED
-   jmp_buf longjmp_buffer;    /* used in png_error */
+   jmp_buf jmp_buf_local;     /* New name in 1.6.0 for jmp_buf in png_struct */
    png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
+   jmp_buf *jmp_buf_ptr;      /* passed to longjmp_fn */
+   size_t jmp_buf_size;       /* size of the above, if allocated */
 #endif
    png_error_ptr error_fn;    /* function for printing errors and aborting */
 #ifdef PNG_WARNINGS_SUPPORTED
@@ -62,22 +179,12 @@ struct png_struct_def
    png_uint_32 flags;         /* flags indicating various things to libpng */
    png_uint_32 transformations; /* which transformations to perform */
 
-   z_stream zstream;          /* pointer to decompression structure (below) */
-   png_bytep zbuf;            /* buffer for zlib */
-   uInt zbuf_size;            /* size of zbuf (typically 65536) */
-#ifdef PNG_WRITE_SUPPORTED
-
-/* Added in 1.5.4: state to keep track of whether the zstream has been
- * initialized and if so whether it is for IDAT or some other chunk.
- */
-#define PNG_ZLIB_UNINITIALIZED 0
-#define PNG_ZLIB_FOR_IDAT      1
-#define PNG_ZLIB_FOR_TEXT      2 /* anything other than IDAT */
-#define PNG_ZLIB_USE_MASK      3 /* bottom two bits */
-#define PNG_ZLIB_IN_USE        4 /* a flag value */
+   png_uint_32 zowner;        /* ID (chunk type) of zstream owner, 0 if none */
+   z_stream    zstream;       /* decompression structure */
 
-   png_uint_32 zlib_state;       /* State of zlib initialization */
-/* End of material added at libpng 1.5.4 */
+#ifdef PNG_WRITE_SUPPORTED
+   png_compression_bufferp zbuffer_list; /* Created on demand during write */
+   uInt                    zbuffer_size; /* size of the actual buffer */
 
    int zlib_level;            /* holds zlib compression level */
    int zlib_method;           /* holds zlib compression method */
@@ -86,8 +193,7 @@ struct png_struct_def
    int zlib_strategy;         /* holds zlib compression strategy */
 #endif
 /* Added at libpng 1.5.4 */
-#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \
-    defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED)
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
    int zlib_text_level;            /* holds zlib compression level */
    int zlib_text_method;           /* holds zlib compression method */
    int zlib_text_window_bits;      /* holds zlib compression window bits */
@@ -95,6 +201,14 @@ struct png_struct_def
    int zlib_text_strategy;         /* holds zlib compression strategy */
 #endif
 /* End of material added at libpng 1.5.4 */
+/* Added at libpng 1.6.0 */
+#ifdef PNG_WRITE_SUPPORTED
+   int zlib_set_level;        /* Actual values set into the zstream on write */
+   int zlib_set_method;
+   int zlib_set_window_bits;
+   int zlib_set_mem_level;
+   int zlib_set_strategy;
+#endif
 
    png_uint_32 width;         /* width of image in pixels */
    png_uint_32 height;        /* height of image in pixels */
@@ -105,15 +219,19 @@ struct png_struct_def
    png_uint_32 row_number;    /* current row in interlace pass */
    png_uint_32 chunk_name;    /* PNG_CHUNK() id of current chunk */
    png_bytep prev_row;        /* buffer to save previous (unfiltered) row.
-                               * This is a pointer into big_prev_row
+                               * While reading this is a pointer into
+                               * big_prev_row; while writing it is separately
+                               * allocated if needed.
                                */
    png_bytep row_buf;         /* buffer to save current (unfiltered) row.
-                               * This is a pointer into big_row_buf
+                               * While reading, this is a pointer into
+                               * big_row_buf; while writing it is separately
+                               * allocated.
                                */
-   png_bytep sub_row;         /* buffer to save "sub" row when filtering */
-   png_bytep up_row;          /* buffer to save "up" row when filtering */
-   png_bytep avg_row;         /* buffer to save "avg" row when filtering */
-   png_bytep paeth_row;       /* buffer to save "Paeth" row when filtering */
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   png_bytep try_row;    /* buffer to save trial row when filtering */
+   png_bytep tst_row;    /* buffer to save best trial row when filtering */
+#endif
    png_size_t info_rowbytes;  /* Added in 1.5.4: cache of updated row bytes */
 
    png_uint_32 idat_size;     /* current IDAT size for read */
@@ -137,15 +255,17 @@ struct png_struct_def
    png_byte usr_bit_depth;    /* bit depth of users row: write only */
    png_byte pixel_depth;      /* number of bits per pixel */
    png_byte channels;         /* number of channels in file */
+#ifdef PNG_WRITE_SUPPORTED
    png_byte usr_channels;     /* channels at start of write: write only */
+#endif
    png_byte sig_bytes;        /* magic bytes read/written from start of file */
    png_byte maximum_pixel_depth;
                               /* pixel depth used for the row buffers */
    png_byte transformed_pixel_depth;
                               /* pixel depth after read/write transforms */
-   png_byte io_chunk_string[5];
-                              /* string name of chunk */
-
+#if PNG_ZLIB_VERNUM >= 0x1240
+   png_byte zstream_start;    /* at start of an input zlib stream */
+#endif /* Zlib >= 1.2.4 */
 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
    png_uint_16 filler;           /* filler bytes for pixel expansion */
 #endif
@@ -158,7 +278,7 @@ struct png_struct_def
 #ifdef PNG_READ_GAMMA_SUPPORTED
    png_color_16 background_1; /* background normalized to gamma 1.0 */
 #endif
-#endif /* PNG_bKGD_SUPPORTED */
+#endif /* bKGD */
 
 #ifdef PNG_WRITE_FLUSH_SUPPORTED
    png_flush_ptr output_flush_fn; /* Function for flushing output */
@@ -168,7 +288,6 @@ struct png_struct_def
 
 #ifdef PNG_READ_GAMMA_SUPPORTED
    int gamma_shift;      /* number of "insignificant" bits in 16-bit gamma */
-   png_fixed_point gamma;        /* file gamma value */
    png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
 
    png_bytep gamma_table;     /* gamma table for 8-bit depth files */
@@ -216,7 +335,7 @@ struct png_struct_def
    int process_mode;                 /* what push library is currently doing */
    int cur_palette;                  /* current push library palette index */
 
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+#endif /* PROGRESSIVE_READ */
 
 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
 /* For the Borland special 64K segment handler */
@@ -232,14 +351,17 @@ struct png_struct_def
    png_bytep quantize_index; /* index translation for palette files */
 #endif
 
-#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
-   png_uint_16p hist;                /* histogram */
+/* Options */
+#ifdef PNG_SET_OPTION_SUPPORTED
+   png_byte options;           /* On/off state (up to 4 options) */
 #endif
 
+#if PNG_LIBPNG_VER < 10700
+/* To do: remove this from libpng-1.7 */
 #ifdef PNG_TIME_RFC1123_SUPPORTED
-   /* This is going to be unused in libpng16 and removed from libpng17 */
    char time_buffer[29]; /* String to hold RFC 1123 time text */
 #endif
+#endif
 
 /* New members added in libpng-1.0.6 */
 
@@ -247,17 +369,16 @@ struct png_struct_def
 
 #ifdef PNG_USER_CHUNKS_SUPPORTED
    png_voidp user_chunk_ptr;
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
 #endif
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-   int num_chunk_list;
-   png_bytep chunk_list;
 #endif
 
-#ifdef PNG_READ_sRGB_SUPPORTED
-   /* Added in 1.5.5 to record an sRGB chunk in the png. */
-   png_byte is_sRGB;
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+   int          unknown_default; /* As PNG_HANDLE_* */
+   unsigned int num_chunk_list;  /* Number of entries in the list */
+   png_bytep    chunk_list;      /* List of png_byte[5]; the textual chunk name
+                                  * followed by a PNG_HANDLE_* byte */
 #endif
 
 /* New members added in libpng-1.0.3 */
@@ -322,16 +443,24 @@ struct png_struct_def
 #endif
 
 /* New member added in libpng-1.0.25 and 1.2.17 */
-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
-   /* Storage for unknown chunk that the library doesn't recognize. */
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+   /* Temporary storage for unknown chunk that the library doesn't recognize,
+    * used while reading the chunk.
+    */
    png_unknown_chunk unknown_chunk;
 #endif
 
 /* New member added in libpng-1.2.26 */
   png_size_t old_big_row_buf_size;
 
+#ifdef PNG_READ_SUPPORTED
 /* New member added in libpng-1.2.30 */
-  png_charp chunkdata;  /* buffer for reading chunk data */
+  png_bytep        read_buffer;      /* buffer for reading chunk data */
+  png_alloc_size_t read_buffer_size; /* current size of the buffer */
+#endif
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+  uInt             IDAT_read_size;   /* limit on read buffer size for IDAT */
+#endif
 
 #ifdef PNG_IO_STATE_SUPPORTED
 /* New member added in libpng-1.4.0 */
@@ -345,9 +474,10 @@ struct png_struct_def
    void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
       png_bytep row, png_const_bytep prev_row);
 
-   /* Options */
-#ifdef PNG_SET_OPTION_SUPPORTED
-   png_byte options;           /* On/off state (up to 4 options) */
+#ifdef PNG_READ_SUPPORTED
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+   png_colorspace   colorspace;
+#endif
 #endif
 };
 #endif /* PNGSTRUCT_H */

+ 121 - 53
drivers/png/pngtrans.c

@@ -1,8 +1,8 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * Last changed in libpng 1.5.19 [August 21, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.18 [July 23, 2015]
+ * Copyright (c) 1998-2002,2004,2006-2015 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.)
  *
@@ -18,7 +18,7 @@
 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
 /* Turn on BGR-to-RGB mapping */
 void PNGAPI
-png_set_bgr(png_structp png_ptr)
+png_set_bgr(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_bgr");
 
@@ -30,9 +30,9 @@ png_set_bgr(png_structp png_ptr)
 #endif
 
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Turn on 16 bit byte swapping */
+/* Turn on 16-bit byte swapping */
 void PNGAPI
-png_set_swap(png_structp png_ptr)
+png_set_swap(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_swap");
 
@@ -47,7 +47,7 @@ png_set_swap(png_structp png_ptr)
 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
 /* Turn on pixel packing */
 void PNGAPI
-png_set_packing(png_structp png_ptr)
+png_set_packing(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_packing");
 
@@ -57,7 +57,9 @@ png_set_packing(png_structp png_ptr)
    if (png_ptr->bit_depth < 8)
    {
       png_ptr->transformations |= PNG_PACK;
-      png_ptr->usr_bit_depth = 8;
+#     ifdef PNG_WRITE_SUPPORTED
+         png_ptr->usr_bit_depth = 8;
+#     endif
    }
 }
 #endif
@@ -65,7 +67,7 @@ png_set_packing(png_structp png_ptr)
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 /* Turn on packed pixel swapping */
 void PNGAPI
-png_set_packswap(png_structp png_ptr)
+png_set_packswap(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_packswap");
 
@@ -79,7 +81,7 @@ png_set_packswap(png_structp png_ptr)
 
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
 void PNGAPI
-png_set_shift(png_structp png_ptr, png_const_color_8p true_bits)
+png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
 {
    png_debug(1, "in png_set_shift");
 
@@ -94,11 +96,11 @@ png_set_shift(png_structp png_ptr, png_const_color_8p true_bits)
 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
     defined(PNG_WRITE_INTERLACING_SUPPORTED)
 int PNGAPI
-png_set_interlace_handling(png_structp png_ptr)
+png_set_interlace_handling(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_interlace handling");
 
-   if (png_ptr && png_ptr->interlaced)
+   if (png_ptr != 0 && png_ptr->interlaced != 0)
    {
       png_ptr->transformations |= PNG_INTERLACE;
       return (7);
@@ -115,44 +117,91 @@ png_set_interlace_handling(png_structp png_ptr)
  * that don't like bytes as parameters.
  */
 void PNGAPI
-png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
 {
    png_debug(1, "in png_set_filler");
 
    if (png_ptr == NULL)
       return;
 
+   /* In libpng 1.6 it is possible to determine whether this is a read or write
+    * operation and therefore to do more checking here for a valid call.
+    */
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+   {
+#     ifdef PNG_READ_FILLER_SUPPORTED
+         /* On read png_set_filler is always valid, regardless of the base PNG
+          * format, because other transformations can give a format where the
+          * filler code can execute (basically an 8 or 16-bit component RGB or G
+          * format.)
+          *
+          * NOTE: usr_channels is not used by the read code!  (This has led to
+          * confusion in the past.)  The filler is only used in the read code.
+          */
+         png_ptr->filler = (png_uint_16)filler;
+#     else
+         png_app_error(png_ptr, "png_set_filler not supported on read");
+         PNG_UNUSED(filler) /* not used in the write case */
+         return;
+#     endif
+   }
+
+   else /* write */
+   {
+#     ifdef PNG_WRITE_FILLER_SUPPORTED
+         /* On write the usr_channels parameter must be set correctly at the
+          * start to record the number of channels in the app-supplied data.
+          */
+         switch (png_ptr->color_type)
+         {
+            case PNG_COLOR_TYPE_RGB:
+               png_ptr->usr_channels = 4;
+               break;
+
+            case PNG_COLOR_TYPE_GRAY:
+               if (png_ptr->bit_depth >= 8)
+               {
+                  png_ptr->usr_channels = 2;
+                  break;
+               }
+
+               else
+               {
+                  /* There simply isn't any code in libpng to strip out bits
+                   * from bytes when the components are less than a byte in
+                   * size!
+                   */
+                  png_app_error(png_ptr,
+                     "png_set_filler is invalid for low bit depth gray output");
+                  return;
+               }
+
+            default:
+               png_app_error(png_ptr,
+                  "png_set_filler: inappropriate color type");
+               return;
+         }
+#     else
+         png_app_error(png_ptr, "png_set_filler not supported on write");
+         return;
+#     endif
+   }
+
+   /* Here on success - libpng supports the operation, set the transformation
+    * and the flag to say where the filler channel is.
+    */
    png_ptr->transformations |= PNG_FILLER;
-   png_ptr->filler = (png_uint_16)filler;
 
    if (filler_loc == PNG_FILLER_AFTER)
       png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
 
    else
       png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
-
-   /* This should probably go in the "do_read_filler" routine.
-    * I attempted to do that in libpng-1.0.1a but that caused problems
-    * so I restored it in libpng-1.0.2a
-   */
-
-   if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
-   {
-      png_ptr->usr_channels = 4;
-   }
-
-   /* Also I added this in libpng-1.0.2a (what happens when we expand
-    * a less-than-8-bit grayscale to GA?) */
-
-   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
-   {
-      png_ptr->usr_channels = 2;
-   }
 }
 
 /* Added to libpng-1.2.7 */
 void PNGAPI
-png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
 {
    png_debug(1, "in png_set_add_alpha");
 
@@ -160,7 +209,9 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
       return;
 
    png_set_filler(png_ptr, filler, filler_loc);
-   png_ptr->transformations |= PNG_ADD_ALPHA;
+   /* The above may fail to do anything. */
+   if ((png_ptr->transformations & PNG_FILLER) != 0)
+      png_ptr->transformations |= PNG_ADD_ALPHA;
 }
 
 #endif
@@ -168,7 +219,7 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
 void PNGAPI
-png_set_swap_alpha(png_structp png_ptr)
+png_set_swap_alpha(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_swap_alpha");
 
@@ -182,7 +233,7 @@ png_set_swap_alpha(png_structp png_ptr)
 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
 void PNGAPI
-png_set_invert_alpha(png_structp png_ptr)
+png_set_invert_alpha(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_invert_alpha");
 
@@ -195,7 +246,7 @@ png_set_invert_alpha(png_structp png_ptr)
 
 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
 void PNGAPI
-png_set_invert_mono(png_structp png_ptr)
+png_set_invert_mono(png_structrp png_ptr)
 {
    png_debug(1, "in png_set_invert_mono");
 
@@ -262,7 +313,7 @@ png_do_invert(png_row_infop row_info, png_bytep row)
 
 #ifdef PNG_16BIT_SUPPORTED
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swaps byte order on 16 bit depth images */
+/* Swaps byte order on 16-bit depth images */
 void /* PRIVATE */
 png_do_swap(png_row_infop row_info, png_bytep row)
 {
@@ -276,9 +327,16 @@ png_do_swap(png_row_infop row_info, png_bytep row)
 
       for (i = 0; i < istop; i++, rp += 2)
       {
+#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
+         /* Feature added to libpng-1.6.11 for testing purposes, not
+          * enabled by default.
+          */
+         *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
+#else
          png_byte t = *rp;
          *rp = *(rp + 1);
          *(rp + 1) = t;
+#endif
       }
    }
 }
@@ -420,7 +478,7 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
          *rp = table[*rp];
    }
 }
-#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+#endif /* PACKSWAP || WRITE_PACKSWAP */
 
 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
@@ -547,7 +605,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_bgr");
 
-   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
+   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
    {
       png_uint_32 row_width = row_info->width;
       if (row_info->bit_depth == 8)
@@ -617,13 +675,13 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
 #endif
    }
 }
-#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+#endif /* READ_BGR || WRITE_BGR */
 
 #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
     defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
 /* Added at libpng-1.5.10 */
 void /* PRIVATE */
-png_do_check_palette_indexes(png_structp png_ptr, png_row_infop row_info)
+png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
 {
    if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
       png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
@@ -646,7 +704,7 @@ png_do_check_palette_indexes(png_structp png_ptr, png_row_infop row_info)
              */
             for (; rp > png_ptr->row_buf; rp--)
             {
-              if (*rp >> padding != 0)
+              if ((*rp >> padding) != 0)
                  png_ptr->num_palette_max = 1;
               padding = 0;
             }
@@ -720,19 +778,30 @@ png_do_check_palette_indexes(png_structp png_ptr, png_row_infop row_info)
       }
    }
 }
-#endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */
+#endif /* CHECK_FOR_INVALID_INDEX */
 
 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
 void PNGAPI
-png_set_user_transform_info(png_structp png_ptr, png_voidp
+png_set_user_transform_info(png_structrp png_ptr, png_voidp
    user_transform_ptr, int user_transform_depth, int user_transform_channels)
 {
    png_debug(1, "in png_set_user_transform_info");
 
    if (png_ptr == NULL)
       return;
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+      (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
+   {
+      png_app_error(png_ptr,
+            "info change after png_start_read_image or png_read_update_info");
+      return;
+   }
+#endif
+
    png_ptr->user_transform_ptr = user_transform_ptr;
    png_ptr->user_transform_depth = (png_byte)user_transform_depth;
    png_ptr->user_transform_channels = (png_byte)user_transform_channels;
@@ -746,20 +815,20 @@ png_set_user_transform_info(png_structp png_ptr, png_voidp
  */
 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
 png_voidp PNGAPI
-png_get_user_transform_ptr(png_const_structp png_ptr)
+png_get_user_transform_ptr(png_const_structrp png_ptr)
 {
    if (png_ptr == NULL)
       return (NULL);
 
-   return ((png_voidp)png_ptr->user_transform_ptr);
+   return png_ptr->user_transform_ptr;
 }
 #endif
 
 #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
 png_uint_32 PNGAPI
-png_get_current_row_number(png_const_structp png_ptr)
+png_get_current_row_number(png_const_structrp png_ptr)
 {
-   /* See the comments in png.h - this is the sub-image row when reading and
+   /* See the comments in png.h - this is the sub-image row when reading an
     * interlaced image.
     */
    if (png_ptr != NULL)
@@ -769,13 +838,12 @@ png_get_current_row_number(png_const_structp png_ptr)
 }
 
 png_byte PNGAPI
-png_get_current_pass_number(png_const_structp png_ptr)
+png_get_current_pass_number(png_const_structrp png_ptr)
 {
    if (png_ptr != NULL)
       return png_ptr->pass;
    return 8; /* invalid */
 }
-#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */
-#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
-          PNG_WRITE_USER_TRANSFORM_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+#endif /* USER_TRANSFORM_INFO */
+#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
+#endif /* READ || WRITE */

+ 12 - 100
drivers/png/pngwio.c

@@ -1,7 +1,7 @@
 
 /* pngwio.c - functions for data output
  *
- * Last changed in libpng 1.5.18 [February 6, 2014]
+ * Last changed in libpng 1.6.15 [November 20, 2014]
  * Copyright (c) 1998-2002,2004,2006-2014 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.)
@@ -26,15 +26,16 @@
  * writes to a file pointer.  Note that this routine sometimes gets called
  * with very small lengths, so you should implement some kind of simple
  * buffering if you are using unbuffered writes.  This should never be asked
- * to write more than 64K on a 16 bit machine.
+ * to write more than 64K on a 16-bit machine.
  */
 
 void /* PRIVATE */
-png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
+png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
 {
    /* NOTE: write_data_fn must not change the buffer! */
    if (png_ptr->write_data_fn != NULL )
-      (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length);
+      (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
+         length);
 
    else
       png_error(png_ptr, "Call to NULL write function");
@@ -46,7 +47,6 @@ png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
  * write_data function and use it at run time with png_set_write_fn(), rather
  * than changing the library.
  */
-#ifndef USE_FAR_KEYWORD
 void PNGCBAPI
 png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
@@ -60,64 +60,6 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
    if (check != length)
       png_error(png_ptr, "Write Error");
 }
-#else
-/* This is the model-independent version. Since the standard I/O library
- * can't handle far buffers in the medium and small models, we have to copy
- * the data.
- */
-
-#define NEAR_BUF_SIZE 1024
-#define MIN(a,b) (a <= b ? a : b)
-
-void PNGCBAPI
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-   png_uint_32 check;
-   png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
-   png_FILE_p io_ptr;
-
-   if (png_ptr == NULL)
-      return;
-
-   /* Check if data really is near. If so, use usual code. */
-   near_data = (png_byte *)CVT_PTR_NOCHECK(data);
-   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
-
-   if ((png_bytep)near_data == data)
-   {
-      check = fwrite(near_data, 1, length, io_ptr);
-   }
-
-   else
-   {
-      png_byte buf[NEAR_BUF_SIZE];
-      png_size_t written, remaining, err;
-      check = 0;
-      remaining = length;
-
-      do
-      {
-         written = MIN(NEAR_BUF_SIZE, remaining);
-         png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
-         err = fwrite(buf, 1, written, io_ptr);
-
-         if (err != written)
-            break;
-
-         else
-            check += err;
-
-         data += written;
-         remaining -= written;
-      }
-      while (remaining != 0);
-   }
-
-   if (check != length)
-      png_error(png_ptr, "Write Error");
-}
-
-#endif
 #endif
 
 /* This function is called to output any data pending writing (normally
@@ -126,7 +68,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  */
 #ifdef PNG_WRITE_FLUSH_SUPPORTED
 void /* PRIVATE */
-png_flush(png_structp png_ptr)
+png_flush(png_structrp png_ptr)
 {
    if (png_ptr->output_flush_fn != NULL)
       (*(png_ptr->output_flush_fn))(png_ptr);
@@ -141,7 +83,7 @@ png_default_flush(png_structp png_ptr)
    if (png_ptr == NULL)
       return;
 
-   io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+   io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
    fflush(io_ptr);
 }
 #  endif
@@ -177,7 +119,7 @@ png_default_flush(png_structp png_ptr)
  *                 *FILE structure.
  */
 void PNGAPI
-png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
+png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
     png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
 {
    if (png_ptr == NULL)
@@ -209,8 +151,9 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
 #  endif
 #else
    PNG_UNUSED(output_flush_fn)
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif /* WRITE_FLUSH */
 
+#ifdef PNG_READ_SUPPORTED
    /* It is an error to read while writing a png file */
    if (png_ptr->read_data_fn != NULL)
    {
@@ -220,37 +163,6 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
           "Can't set both read_data_fn and write_data_fn in the"
           " same structure");
    }
-}
-
-#ifdef USE_FAR_KEYWORD
-#  ifdef _MSC_VER
-void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
-{
-   void *near_ptr;
-   void FAR *far_ptr;
-   FP_OFF(near_ptr) = FP_OFF(ptr);
-   far_ptr = (void FAR *)near_ptr;
-
-   if (check != 0)
-      if (FP_SEG(ptr) != FP_SEG(far_ptr))
-         png_error(png_ptr, "segment lost in conversion");
-
-   return(near_ptr);
-}
-#  else
-void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
-{
-   void *near_ptr;
-   void FAR *far_ptr;
-   near_ptr = (void FAR *)ptr;
-   far_ptr = (void FAR *)near_ptr;
-
-   if (check != 0)
-      if (far_ptr != ptr)
-         png_error(png_ptr, "segment lost in conversion");
-
-   return(near_ptr);
-}
-#  endif
 #endif
-#endif /* PNG_WRITE_SUPPORTED */
+}
+#endif /* WRITE */

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 347 - 370
drivers/png/pngwrite.c


+ 105 - 174
drivers/png/pngwtran.c

@@ -1,8 +1,8 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * Copyright (c) 1998-2002,2004,2006-2012 Glenn Randers-Pehrson
- * Copyright (c) 1998-2012 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.18 [July 23, 2015]
+ * Copyright (c) 1998-2002,2004,2006-2015 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.)
  *
@@ -14,102 +14,14 @@
 #include "pngpriv.h"
 
 #ifdef PNG_WRITE_SUPPORTED
-
 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-/* Transform the data according to the user's wishes.  The order of
- * transformations is significant.
- */
-void /* PRIVATE */
-png_do_write_transformations(png_structp png_ptr, png_row_infop row_info)
-{
-   png_debug(1, "in png_do_write_transformations");
-
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-   if (png_ptr->transformations & PNG_USER_TRANSFORM)
-      if (png_ptr->write_user_transform_fn != NULL)
-         (*(png_ptr->write_user_transform_fn)) /* User write transform
-                                                 function */
-             (png_ptr,  /* png_ptr */
-             row_info,  /* row_info: */
-                /*  png_uint_32 width;       width of row */
-                /*  png_size_t rowbytes;     number of bytes in row */
-                /*  png_byte color_type;     color type of pixels */
-                /*  png_byte bit_depth;      bit depth of samples */
-                /*  png_byte channels;       number of channels (1-4) */
-                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
-             png_ptr->row_buf + 1);      /* start of pixel data for row */
-#endif
-
-#ifdef PNG_WRITE_FILLER_SUPPORTED
-   if (png_ptr->transformations & PNG_FILLER)
-   {
-      if (png_ptr->color_type & (PNG_COLOR_MASK_ALPHA|PNG_COLOR_MASK_PALETTE))
-      {
-         /* GA, RGBA or palette; in any of these cases libpng will not do the
-          * the correct thing (whatever that might be).
-          */
-         png_warning(png_ptr, "incorrect png_set_filler call ignored");
-         png_ptr->transformations &= ~PNG_FILLER;
-      }
-
-      else
-         png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-            !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
-   }
-#endif
-
-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_PACKSWAP)
-      png_do_packswap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_PACK_SUPPORTED
-   if (png_ptr->transformations & PNG_PACK)
-      png_do_pack(row_info, png_ptr->row_buf + 1,
-          (png_uint_32)png_ptr->bit_depth);
-#endif
-
-#ifdef PNG_WRITE_SWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_BYTES)
-      png_do_swap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-   if (png_ptr->transformations & PNG_SHIFT)
-      png_do_shift(row_info, png_ptr->row_buf + 1,
-          &(png_ptr->shift));
-#endif
-
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_ALPHA)
-      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_ALPHA)
-      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_BGR_SUPPORTED
-   if (png_ptr->transformations & PNG_BGR)
-      png_do_bgr(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_INVERT_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_MONO)
-      png_do_invert(row_info, png_ptr->row_buf + 1);
-#endif
-}
 
 #ifdef PNG_WRITE_PACK_SUPPORTED
 /* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
  * row_info bit depth should be 8 (one pixel per byte).  The channels
  * should be 1 (this only happens on grayscale and paletted images).
  */
-void /* PRIVATE */
+static void
 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
 {
    png_debug(1, "in png_do_pack");
@@ -159,7 +71,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
          case 2:
          {
             png_bytep sp, dp;
-            int shift, v;
+            unsigned int shift;
+            int v;
             png_uint_32 i;
             png_uint_32 row_width = row_info->width;
 
@@ -198,7 +111,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
          case 4:
          {
             png_bytep sp, dp;
-            int shift, v;
+            unsigned int shift;
+            int v;
             png_uint_32 i;
             png_uint_32 row_width = row_info->width;
 
@@ -254,7 +168,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
  * would pass 3 as bit_depth, and this routine would translate the
  * data to 0 to 15.
  */
-void /* PRIVATE */
+static void
 png_do_shift(png_row_infop row_info, png_bytep row,
     png_const_color_8p bit_depth)
 {
@@ -265,7 +179,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
       int shift_start[4], shift_dec[4];
       int channels = 0;
 
-      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+      if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
       {
          shift_start[channels] = row_info->bit_depth - bit_depth->red;
          shift_dec[channels] = bit_depth->red;
@@ -287,7 +201,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
          channels++;
       }
 
-      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+      if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
       {
          shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
          shift_dec[channels] = bit_depth->alpha;
@@ -299,7 +213,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
       {
          png_bytep bp = row;
          png_size_t i;
-         png_byte mask;
+         unsigned int mask;
          png_size_t row_bytes = row_info->rowbytes;
 
          if (bit_depth->gray == 1 && row_info->bit_depth == 2)
@@ -313,20 +227,22 @@ png_do_shift(png_row_infop row_info, png_bytep row,
 
          for (i = 0; i < row_bytes; i++, bp++)
          {
-            png_uint_16 v;
             int j;
+            unsigned int v, out;
 
             v = *bp;
-            *bp = 0;
+            out = 0;
 
             for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
             {
                if (j > 0)
-                  *bp |= (png_byte)((v << j) & 0xff);
+                  out |= v << j;
 
                else
-                  *bp |= (png_byte)((v >> (-j)) & mask);
+                  out |= (v >> (-j)) & mask;
             }
+
+            *bp = (png_byte)(out & 0xff);
          }
       }
 
@@ -339,21 +255,23 @@ png_do_shift(png_row_infop row_info, png_bytep row,
          for (i = 0; i < istop; i++, bp++)
          {
 
-            png_uint_16 v;
+            const unsigned int c = i%channels;
             int j;
-            int c = (int)(i%channels);
+            unsigned int v, out;
 
             v = *bp;
-            *bp = 0;
+            out = 0;
 
             for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
             {
                if (j > 0)
-                  *bp |= (png_byte)((v << j) & 0xff);
+                  out |= v << j;
 
                else
-                  *bp |= (png_byte)((v >> (-j)) & 0xff);
+                  out |= v >> (-j);
             }
+
+            *bp = (png_byte)(out & 0xff);
          }
       }
 
@@ -365,22 +283,22 @@ png_do_shift(png_row_infop row_info, png_bytep row,
 
          for (bp = row, i = 0; i < istop; i++)
          {
-            int c = (int)(i%channels);
-            png_uint_16 value, v;
+            const unsigned int c = i%channels;
             int j;
+            unsigned int value, v;
 
-            v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
+            v = png_get_uint_16(bp);
             value = 0;
 
             for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
             {
                if (j > 0)
-                  value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
+                  value |= v << j;
 
                else
-                  value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
+                  value |= v >> (-j);
             }
-            *bp++ = (png_byte)(value >> 8);
+            *bp++ = (png_byte)((value >> 8) & 0xff);
             *bp++ = (png_byte)(value & 0xff);
          }
       }
@@ -389,7 +307,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
 #endif
 
 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-void /* PRIVATE */
+static void
 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_write_swap_alpha");
@@ -437,7 +355,7 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
                *(dp++) = save[1];
             }
          }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
+#endif /* WRITE_16BIT */
       }
 
       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
@@ -476,14 +394,14 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
                *(dp++) = save[1];
             }
          }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
+#endif /* WRITE_16BIT */
       }
    }
 }
 #endif
 
 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-void /* PRIVATE */
+static void
 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_write_invert_alpha");
@@ -506,7 +424,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
                *(dp++) = *(sp++);
                */
                sp+=3; dp = sp;
-               *(dp++) = (png_byte)(255 - *(sp++));
+               *dp = (png_byte)(255 - *(sp++));
             }
          }
 
@@ -530,10 +448,10 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
                */
                sp+=6; dp = sp;
                *(dp++) = (png_byte)(255 - *(sp++));
-               *(dp++) = (png_byte)(255 - *(sp++));
+               *dp     = (png_byte)(255 - *(sp++));
             }
          }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
+#endif /* WRITE_16BIT */
       }
 
       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
@@ -568,78 +486,91 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
                */
                sp+=2; dp = sp;
                *(dp++) = (png_byte)(255 - *(sp++));
-               *(dp++) = (png_byte)(255 - *(sp++));
+               *dp     = (png_byte)(255 - *(sp++));
             }
          }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
+#endif /* WRITE_16BIT */
       }
    }
 }
 #endif
-#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
 
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-/* Undoes intrapixel differencing  */
+/* Transform the data according to the user's wishes.  The order of
+ * transformations is significant.
+ */
 void /* PRIVATE */
-png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
 {
-   png_debug(1, "in png_do_write_intrapixel");
+   png_debug(1, "in png_do_write_transformations");
 
-   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
-   {
-      int bytes_per_pixel;
-      png_uint_32 row_width = row_info->width;
-      if (row_info->bit_depth == 8)
-      {
-         png_bytep rp;
-         png_uint_32 i;
+   if (png_ptr == NULL)
+      return;
 
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 3;
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+      if (png_ptr->write_user_transform_fn != NULL)
+         (*(png_ptr->write_user_transform_fn)) /* User write transform
+                                                 function */
+             (png_ptr,  /* png_ptr */
+             row_info,  /* row_info: */
+                /*  png_uint_32 width;       width of row */
+                /*  png_size_t rowbytes;     number of bytes in row */
+                /*  png_byte color_type;     color type of pixels */
+                /*  png_byte bit_depth;      bit depth of samples */
+                /*  png_byte channels;       number of channels (1-4) */
+                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
+             png_ptr->row_buf + 1);      /* start of pixel data for row */
+#endif
 
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 4;
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+   if ((png_ptr->transformations & PNG_FILLER) != 0)
+      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+         !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+#endif
 
-         else
-            return;
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+      png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
 
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
-            *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
-         }
-      }
+#ifdef PNG_WRITE_PACK_SUPPORTED
+   if ((png_ptr->transformations & PNG_PACK) != 0)
+      png_do_pack(row_info, png_ptr->row_buf + 1,
+          (png_uint_32)png_ptr->bit_depth);
+#endif
 
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-      else if (row_info->bit_depth == 16)
-      {
-         png_bytep rp;
-         png_uint_32 i;
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+#  ifdef PNG_16BIT_SUPPORTED
+   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+      png_do_swap(row_info, png_ptr->row_buf + 1);
+#  endif
+#endif
 
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 6;
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+   if ((png_ptr->transformations & PNG_SHIFT) != 0)
+      png_do_shift(row_info, png_ptr->row_buf + 1,
+          &(png_ptr->shift));
+#endif
 
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 8;
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
+      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
 
-         else
-            return;
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
+      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
 
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
-            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
-            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
-            *(rp    ) = (png_byte)((red >> 8) & 0xff);
-            *(rp + 1) = (png_byte)(red & 0xff);
-            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
-            *(rp + 5) = (png_byte)(blue & 0xff);
-         }
-      }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
-   }
+#ifdef PNG_WRITE_BGR_SUPPORTED
+   if ((png_ptr->transformations & PNG_BGR) != 0)
+      png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+      png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
 }
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
-#endif /* PNG_WRITE_SUPPORTED */
+#endif /* WRITE_TRANSFORMS */
+#endif /* WRITE */

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 392 - 401
drivers/png/pngwutil.c


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä