summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2014-03-06 12:35:04 -0600
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2014-03-06 13:15:45 -0600
commit1cc02f0395aa85e71927c5a45b4bc8091a7d9ef8 (patch)
tree3ca04025157dc47c8f82e90925941e167f7b3519
parenta710317d2f9cb1e154861c000ee1cc1c70794a85 (diff)
downloadlibpng-baserock/mikedrake/update-chunks.tar.gz
-rw-r--r--ANNOUNCE111
-rw-r--r--CHANGES76
-rw-r--r--CMakeLists.txt4
-rw-r--r--LICENSE4
-rw-r--r--Makefile.am9
-rw-r--r--README2
-rw-r--r--TODO1
-rw-r--r--arm/arm_init.c147
-rw-r--r--configure.ac6
-rw-r--r--contrib/arm-neon/README83
-rw-r--r--contrib/arm-neon/android-ndk.c39
-rw-r--r--contrib/arm-neon/linux-auxv.c120
-rw-r--r--contrib/arm-neon/linux.c159
-rw-r--r--contrib/examples/iccfrompng.c4
-rw-r--r--contrib/examples/pngpixel.c6
-rw-r--r--contrib/gregbook/readpng2.c9
-rw-r--r--contrib/libtests/pngimage.c1618
-rw-r--r--contrib/libtests/pngunknown.c10
-rw-r--r--contrib/libtests/pngvalid.c37
-rw-r--r--contrib/pngminim/decoder/pngusr.h1
-rw-r--r--contrib/pngminim/encoder/pngusr.h1
-rw-r--r--contrib/pngminim/preader/pngusr.h1
-rw-r--r--contrib/tools/pngfix.c8
-rw-r--r--libpng-manual.txt260
-rw-r--r--libpng.3273
-rw-r--r--libpngpf.34
-rw-r--r--png.52
-rw-r--r--png.c28
-rw-r--r--png.h139
-rw-r--r--pngconf.h10
-rw-r--r--pngerror.c10
-rw-r--r--pngpread.c5
-rw-r--r--pngpriv.h15
-rw-r--r--pngread.c99
-rw-r--r--pngrtran.c24
-rw-r--r--pngrutil.c48
-rw-r--r--pngtest.c6
-rw-r--r--pngwrite.c78
-rw-r--r--pngwutil.c3
-rw-r--r--projects/vstudio/readme.txt2
-rw-r--r--projects/vstudio/zlib.props2
-rw-r--r--scripts/README.txt12
-rw-r--r--scripts/def.dfn2
-rw-r--r--scripts/dfn.awk20
-rw-r--r--scripts/intprefix.dfn3
-rwxr-xr-xscripts/libpng-config-head.in2
-rw-r--r--scripts/libpng.pc.in2
-rw-r--r--scripts/makefile.cegcc2
-rw-r--r--scripts/makefile.linux2
-rw-r--r--scripts/makefile.msys2
-rw-r--r--scripts/makefile.ne12bsd2
-rw-r--r--scripts/makefile.netbsd2
-rw-r--r--scripts/makefile.openbsd2
-rwxr-xr-xscripts/pnglibconf.dfa7
-rw-r--r--scripts/pnglibconf.h.prebuilt4
-rw-r--r--scripts/symbols.def2
-rwxr-xr-xtests/pngimage-full2
-rwxr-xr-xtests/pngimage-quick2
58 files changed, 2965 insertions, 569 deletions
diff --git a/ANNOUNCE b/ANNOUNCE
index ecc043db1..9f198806f 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
-Libpng 1.6.9 - February 6, 2014
+Libpng 1.6.10 - March 6, 2014
This is a public release of libpng, intended for use in production codes.
@@ -8,56 +8,80 @@ Files available for download:
Source files with LF line endings (for Unix/Linux) and with a
"configure" script
- libpng-1.6.9.tar.xz (LZMA-compressed, recommended)
- libpng-1.6.9.tar.gz
+ libpng-1.6.10.tar.xz (LZMA-compressed, recommended)
+ libpng-1.6.10.tar.gz
Source files with CRLF line endings (for Windows), without the
"configure" script
- lpng169.7z (LZMA-compressed, recommended)
- lpng169.zip
+ lpng1610.7z (LZMA-compressed, recommended)
+ lpng1610.zip
Other information:
- libpng-1.6.9-README.txt
- libpng-1.6.9-LICENSE.txt
- Gnupg/*.asc (PGP armored detached signatures)
+ libpng-1.6.10-README.txt
+ libpng-1.6.10-LICENSE.txt
+ libpng-1.6.10-*.asc (armored detached GPG signatures)
-Changes since the last public release (1.6.8):
- Bookkeeping: Moved functions around (no changes). Moved transform
- function definitions before the place where they are called so that
- they can be masde static. Move the intrapixel functions and the
- grayscale palette builder out of the png?tran.c files. The latter
- isn't a transform function and is no longer used internally, and the
- former MNG specific functions are better placed in pngread/pngwrite.c
- Made transform implementation functions static. This makes the internal
- functions called by png_do_{read|write}_transformations static. On an
- x86-64 DLL build (Gentoo Linux) this reduces the size of the text
- segment of the DLL by 1208 bytes, about 0.6%. It also simplifies
- maintenance by removing the declarations from pngpriv.h and allowing
- easier changes to the internal interfaces.
- Rebuilt configure scripts with automake-1.14.1 and autoconf-2.69
- in the tar distributions.
- Added checks for libpng 1.5 to pngvalid.c. This supports the use of
- this version of pngvalid in libpng 1.5
- Merged with pngvalid.c from libpng-1.7 changes to create a single
- pngvalid.c
- Removed #error macro from contrib/tools/pngfix.c (Thomas Klausner).
- Merged pngrio.c, pngtrans.c, pngwio.c, and pngerror.c with libpng-1.7.0
- Merged libpng-1.7.0 changes to make no-interlace configurations work
- with test programs.
- Revised pngvalid.c to support libpng 1.5, which does not support the
- PNG_MAXIMUM_INFLATE_WINDOW option, so #define it out when appropriate in
- pngvalid.c
- Allow unversioned links created on install to be disabled in configure.
- In configure builds 'make install' changes/adds links like png.h
- and libpng.a to point to the newly installed, versioned, files (e.g.
- libpng17/png.h and libpng17.a). Three new configure options and some
- rearrangement of Makefile.am allow creation of these links to be disabled.
- Removed potentially misleading warning from png_check_IHDR().
- Updated scripts/makefile.* to use CPPFLAGS (Cosmin).
- Added clang attribute support (Cosmin).
- Quiet an uninitialized memory warning from VC2013 in png_get_png().
+Changes since the last public release (1.6.9):
+ Backported changes from libpng-1.7.0beta30 and beta31:
+ Fixed a large number of instances where PNGCBAPI was omitted from
+ function definitions.
+ Added pngimage test program for png_read_png() and png_write_png()
+ with two new test scripts.
+ Removed dependence on !PNG_READ_EXPAND_SUPPORTED for calling
+ png_set_packing() in png_read_png().
+ Fixed combination of ~alpha with shift. On read invert alpha, processing
+ occurred after shift processing, which causes the final values to be
+ outside the range that should be produced by the shift. Reversing the
+ order on read makes the two transforms work together correctly and mirrors
+ the order used on write.
+ Do not read invalid sBIT chunks. Previously libpng only checked sBIT
+ values on write, so a malicious PNG writer could therefore cause
+ the read code to return an invalid sBIT chunk, which might lead to
+ application errors or crashes. Such chunks are now skipped (with
+ chunk_benign_error).
+ Make png_read_png() and png_write_png() prototypes in png.h depend
+ upon PNG_READ_SUPPORTED and PNG_WRITE_SUPPORTED.
+ Support builds with unsupported PNG_TRANSFORM_* values. All of the
+ PNG_TRANSFORM_* values are always defined in png.h and, because they
+ are used for both read and write in some cases, it is not reliable
+ to #if out ones that are totally unsupported. This change adds error
+ detection in png_read_image() and png_write_image() to do a
+ png_app_error() if the app requests something that cannot be done
+ and it adds corresponding code to pngimage.c to handle such options
+ by not attempting to test them.
+ Moved redefines of png_error(), png_warning(), png_chunk_error(),
+ and png_chunk_warning() from pngpriv.h to png.h to make them visible
+ to libpng-calling applications.
+ Moved OS dependent code from arm/arm_init.c, to allow the included
+ implementation of the ARM NEON discovery function to be set at
+ build-time and provide sample implementations from the current code in the
+ contrib/arm-neon subdirectory. The __linux__ code has also been changed to
+ compile and link on Android by using /proc/cpuinfo, and the old linux code
+ is in contrib/arm-neon/linux-auxv.c. The new code avoids POSIX and Linux
+ dependencies apart from opening /proc/cpuinfo and is C90 compliant.
+ Check for info_ptr == NULL early in png_read_end() so we don't need to
+ run all the png_handle_*() and depend on them to return if info_ptr == NULL.
+ This improves the performance of png_read_end(png_ptr, NULL) and makes
+ it more robust against future programming errors.
+ Check for __has_extension before using it in pngconf.h, to
+ support older Clang versions (Jeremy Sequoia).
+ Treat CRC error handling with png_set_crc_action(), instead of with
+ png_set_benign_errors(), which has been the case since libpng-1.6.0beta18.
+ Use a user warning handler in contrib/gregbook/readpng2.c instead of default,
+ so warnings will be put on stderr even if libpng has CONSOLE_IO disabled.
+ Added png_ptr->process_mode = PNG_READ_IDAT_MODE in png_push_read_chunk
+ after recognizing the IDAT chunk, which avoids an infinite loop while
+ reading a datastream whose first IDAT chunk is of zero-length.
+ This fixes CERT VU#684412 and CVE-2014-0333.
+ Don't recognize known sRGB profiles as sRGB if they have been hacked,
+ but don't reject them and don't issue a copyright violation warning.
+ Moved some documentation from png.h to libpng.3 and libpng-manual.txt
+ Minor editing of contrib/arm-neon/README and contrib/examples/*.c
+ Fixed typos in the manual and in scripts/pnglibconf.dfa (CFLAGS -> CPPFLAGS
+ and PNG_USR_CONFIG -> PNG_USER_CONFIG).
+ Un-deprecated png_data_freer().
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
@@ -66,3 +90,4 @@ to subscribe)
or to glennrp at users.sourceforge.net
Glenn R-P
+#endif
diff --git a/CHANGES b/CHANGES
index 99c954d2f..b3e09f857 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4754,7 +4754,7 @@ Version 1.6.8 [December 19, 2013]
Version 1.6.9beta01 [December 26, 2013]
Bookkeeping: Moved functions around (no changes). Moved transform
function definitions before the place where they are called so that
- they can be masde static. Move the intrapixel functions and the
+ they can be made static. Move the intrapixel functions and the
grayscale palette builder out of the png?tran.c files. The latter
isn't a transform function and is no longer used internally, and the
former MNG specific functions are better placed in pngread/pngwrite.c
@@ -4800,6 +4800,80 @@ Version 1.6.9rc02 [January 30, 2014]
Version 1.6.9 [February 6, 2014]
+Version 1.6.10beta01 [February 9, 2014]
+ Backported changes from libpng-1.7.0beta30 and beta31:
+ Fixed a large number of instances where PNGCBAPI was omitted from
+ function definitions.
+ Added pngimage test program for png_read_png() and png_write_png()
+ with two new test scripts.
+ Removed dependence on !PNG_READ_EXPAND_SUPPORTED for calling
+ png_set_packing() in png_read_png().
+ Fixed combination of ~alpha with shift. On read invert alpha, processing
+ occurred after shift processing, which causes the final values to be
+ outside the range that should be produced by the shift. Reversing the
+ order on read makes the two transforms work together correctly and mirrors
+ the order used on write.
+ Do not read invalid sBIT chunks. Previously libpng only checked sBIT
+ values on write, so a malicious PNG writer could therefore cause
+ the read code to return an invalid sBIT chunk, which might lead to
+ application errors or crashes. Such chunks are now skipped (with
+ chunk_benign_error).
+ Make png_read_png() and png_write_png() prototypes in png.h depend
+ upon PNG_READ_SUPPORTED and PNG_WRITE_SUPPORTED.
+ Support builds with unsupported PNG_TRANSFORM_* values. All of the
+ PNG_TRANSFORM_* values are always defined in png.h and, because they
+ are used for both read and write in some cases, it is not reliable
+ to #if out ones that are totally unsupported. This change adds error
+ detection in png_read_image() and png_write_image() to do a
+ png_app_error() if the app requests something that cannot be done
+ and it adds corresponding code to pngimage.c to handle such options
+ by not attempting to test them.
+
+Version 1.6.10beta02 [February 23, 2014]
+ Moved redefines of png_error(), png_warning(), png_chunk_error(),
+ and png_chunk_warning() from pngpriv.h to png.h to make them visible
+ to libpng-calling applications.
+ Moved OS dependent code from arm/arm_init.c, to allow the included
+ implementation of the ARM NEON discovery function to be set at
+ build-time and provide sample implementations from the current code in the
+ contrib/arm-neon subdirectory. The __linux__ code has also been changed to
+ compile and link on Android by using /proc/cpuinfo, and the old linux code
+ is in contrib/arm-neon/linux-auxv.c. The new code avoids POSIX and Linux
+ dependencies apart from opening /proc/cpuinfo and is C90 compliant.
+ Check for info_ptr == NULL early in png_read_end() so we don't need to
+ run all the png_handle_*() and depend on them to return if info_ptr == NULL.
+ This improves the performance of png_read_end(png_ptr, NULL) and makes
+ it more robust against future programming errors.
+ Check for __has_extension before using it in pngconf.h, to
+ support older Clang versions (Jeremy Sequoia).
+ Treat CRC error handling with png_set_crc_action(), instead of with
+ png_set_benign_errors(), which has been the case since libpng-1.6.0beta18.
+ Use a user warning handler in contrib/gregbook/readpng2.c instead of default,
+ so warnings will be put on stderr even if libpng has CONSOLE_IO disabled.
+ Added png_ptr->process_mode = PNG_READ_IDAT_MODE in png_push_read_chunk
+ after recognizing the IDAT chunk, which avoids an infinite loop while
+ reading a datastream whose first IDAT chunk is of zero-length.
+ This fixes CERT VU#684412 and CVE-2014-0333.
+ Don't recognize known sRGB profiles as sRGB if they have been hacked,
+ but don't reject them and don't issue a copyright violation warning.
+
+Version 1.6.10beta03 [February 25, 2014]
+ Moved some documentation from png.h to libpng.3 and libpng-manual.txt
+ Minor editing of contrib/arm-neon/README and contrib/examples/*.c
+
+Version 1.6.10rc01 [February 27, 2014]
+ Fixed typos in the manual and in scripts/pnglibconf.dfa (CFLAGS -> CPPFLAGS
+ and PNG_USR_CONFIG -> PNG_USER_CONFIG).
+
+Version 1.6.10rc02 [February 28, 2014]
+ Removed unreachable return statement after png_chunk_error()
+ in pngrutil.c
+
+Version 1.6.10rc03 [March 4, 2014]
+ Un-deprecated png_data_freer().
+
+Version 1.6.10 [March 6, 2014]
+
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ce5ca6986..34d62b5d1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,7 +16,7 @@ enable_testing()
set(PNGLIB_MAJOR 1)
set(PNGLIB_MINOR 6)
-set(PNGLIB_RELEASE 9)
+set(PNGLIB_RELEASE 10)
set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
@@ -252,7 +252,7 @@ endif(NOT WIN32 OR CYGWIN OR MINGW)
# SET UP LINKS
if(PNG_SHARED)
set_target_properties(${PNG_LIB_NAME} PROPERTIES
-# VERSION 16.${PNGLIB_RELEASE}.1.6.9
+# VERSION 16.${PNGLIB_RELEASE}.1.6.10
VERSION 16.${PNGLIB_RELEASE}.0
SOVERSION 16
CLEAN_DIRECT_OUTPUT 1)
diff --git a/LICENSE b/LICENSE
index cfab9c639..94f5e9500 100644
--- a/LICENSE
+++ b/LICENSE
@@ -10,7 +10,7 @@ this sentence.
This code is released under the libpng license.
-libpng versions 1.2.6, August 15, 2004, through 1.6.9, February 6, 2014, are
+libpng versions 1.2.6, August 15, 2004, through 1.6.10, March 6, 2014, are
Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are
distributed according to the same disclaimer and license as libpng-1.2.5
with the following individual added to the list of Contributing Authors
@@ -108,4 +108,4 @@ certification mark of the Open Source Initiative.
Glenn Randers-Pehrson
glennrp at users.sourceforge.net
-February 6, 2014
+March 6, 2014
diff --git a/Makefile.am b/Makefile.am
index e69519d71..052e596b6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,7 @@ PNGLIB_BASENAME= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
ACLOCAL_AMFLAGS = -I scripts
# test programs - run on make check, make distcheck
-check_PROGRAMS= pngtest pngunknown pngstest pngvalid
+check_PROGRAMS= pngtest pngunknown pngstest pngvalid pngimage
# Utilities - installed
bin_PROGRAMS= pngfix png-fix-itxt
@@ -34,6 +34,9 @@ pngstest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
pngunknown_SOURCES = contrib/libtests/pngunknown.c
pngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
+pngimage_SOURCES = contrib/libtests/pngimage.c
+pngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
+
pngfix_SOURCES = contrib/tools/pngfix.c
pngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
@@ -59,7 +62,8 @@ TESTS =\
tests/pngstest-4a16 tests/pngstest-6a08 tests/pngstest-6a16\
tests/pngstest-error tests/pngunknown-IDAT\
tests/pngunknown-discard tests/pngunknown-if-safe tests/pngunknown-sAPI\
- tests/pngunknown-sTER tests/pngunknown-save tests/pngunknown-vpAg
+ tests/pngunknown-sTER tests/pngunknown-save tests/pngunknown-vpAg\
+ tests/pngimage-quick tests/pngimage-full
# These tests are expected, and required, to fail:
XFAIL_TESTS = tests/pngstest-error
@@ -212,6 +216,7 @@ pngtest.o: pnglibconf.h
contrib/libtests/makepng.o: pnglibconf.h
contrib/libtests/pngstest.o: pnglibconf.h
contrib/libtests/pngunknown.o: pnglibconf.h
+contrib/libtests/pngimage.o: pnglibconf.h
contrib/libtests/pngvalid.o: pnglibconf.h
contrib/libtests/readpng.o: pnglibconf.h
contrib/libtests/tarith.o: pnglibconf.h
diff --git a/README b/README
index 1aefa24de..57f287bf1 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.9 - February 6, 2014 (shared library 16.0)
+README for libpng version 1.6.10 - March 6, 2014 (shared library 16.0)
See the note about version numbers near the top of png.h
See INSTALL for instructions on how to install libpng.
diff --git a/TODO b/TODO
index 6e1f028bd..63613b8dd 100644
--- a/TODO
+++ b/TODO
@@ -10,6 +10,7 @@ Add "grayscale->palette" transformation and "palette->grayscale" detection.
Improved dithering.
Multi-lingual error and warning message support.
Complete sRGB transformation (presently it simply uses gamma=0.45455).
+Make profile checking optional via a png_set_something() call.
Man pages for function calls.
Better documentation.
Better filter selection
diff --git a/arm/arm_init.c b/arm/arm_init.c
index 271c6121d..952b8029f 100644
--- a/arm/arm_init.c
+++ b/arm/arm_init.c
@@ -1,9 +1,9 @@
/* arm_init.c - 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.6.6 [September 16, 2013]
+ * Last changed in libpng 1.6.10 [March 6, 2014]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -19,132 +19,33 @@
#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
+ * presense of the required support, therefore run-time detectioon 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 */
-}
-
-static int
-png_have_neon(png_structp png_ptr)
-{
- int fd = open("/proc/self/auxv", O_RDONLY);
- Elf32_auxv_t aux;
+#ifndef PNG_ARM_NEON_FILE
+# ifdef __linux__
+# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
+# endif
+#endif
- /* Failsafe: failure to open means no NEON */
- if (fd == -1)
- {
- png_warning(png_ptr, "/proc/self/auxv open failed");
- return 0;
- }
+#ifdef PNG_ARM_NEON_FILE
- 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
diff --git a/configure.ac b/configure.ac
index 8061aba60..a1ec12909 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,7 +18,7 @@ AC_PREREQ([2.68])
dnl Version number stuff here:
-AC_INIT([libpng],[1.6.9],[png-mng-implement@lists.sourceforge.net])
+AC_INIT([libpng],[1.6.10],[png-mng-implement@lists.sourceforge.net])
AC_CONFIG_MACRO_DIR([scripts])
# libpng does not follow GNU file name conventions (hence 'foreign')
@@ -39,10 +39,10 @@ dnl automake, so the following is not necessary (and is not defined anyway):
dnl AM_PREREQ([1.11.2])
dnl stop configure from automagically running automake
-PNGLIB_VERSION=1.6.9
+PNGLIB_VERSION=1.6.10
PNGLIB_MAJOR=1
PNGLIB_MINOR=6
-PNGLIB_RELEASE=9
+PNGLIB_RELEASE=10
dnl End of version number stuff
diff --git a/contrib/arm-neon/README b/contrib/arm-neon/README
new file mode 100644
index 000000000..535c8d3f7
--- /dev/null
+++ b/contrib/arm-neon/README
@@ -0,0 +1,83 @@
+OPERATING SYSTEM SPECIFIC ARM NEON DETECTION
+--------------------------------------------
+
+Detection of the ability to exexcute ARM NEON on an ARM processor requires
+operating system support. (The information is not available in user mode.)
+
+HOW TO USE THIS
+---------------
+
+This directory contains C code fragments that can be included in arm/arm_init.c
+by setting the macro PNG_ARM_NEON_FILE to the file name in "" or <> at build
+time. This setting is not recorded in pnglibconf.h and can be changed simply by
+rebuilding arm/arm_init.o with the required macro definition.
+
+For any of this code to be used the ARM NEON code must be enabled and run time
+checks must be supported. I.e.:
+
+#if PNG_ARM_NEON_OPT > 0
+#ifdef PNG_ARM_NEON_CHECK_SUPPORTED
+
+This is done in a 'configure' build by passing configure the argument:
+
+ --enable-arm-neon=check
+
+Apart from the basic Linux implementation in contrib/arm-neon/linux.c this code
+is unsupported. That means that it is not even compiled on a regular basis and
+may be broken in any given minor release.
+
+FILE FORMAT
+-----------
+
+Each file documents its testing status as of the last time it was tested (which
+may have been a long time ago):
+
+STATUS: one of:
+ SUPPORTED: This indicates that the file is included in the regularly
+ performed test builds and bugs are fixed when discovered.
+ COMPILED: This indicates that the code did compile at least once. See the
+ more detailed description for the extent to which the result was
+ successful.
+ TESTED: This means the code was fully compiled into the libpng test programs
+ and these were run at least once.
+
+BUG REPORTS: an email address to which to send reports of problems
+
+The file is a fragment of C code. It should not define any 'extern' symbols;
+everything should be static. It must define the function:
+
+static int png_have_neon(png_structp png_ptr);
+
+That function must return 1 if ARM NEON instructions are supported, 0 if not.
+It must not execute png_error unless it detects a bug. A png_error will prevent
+the reading of the PNG and in the future, writing too.
+
+BUG REPORTS
+-----------
+
+If you mail a bug report for any file that is not SUPPORTED there may only be
+limited response. Consider fixing it and sending a patch to fix the problem -
+this is more likely to result in action.
+
+CONTRIBUTIONS
+-------------
+
+You may send contributions of new implementations to
+png-mng-implement@sourceforge.net. Please write code in strict C90 C where
+possible. Obviously OS dependencies are to be expected. If you submit code you
+must have the authors permission and it must have a license that is acceptable
+to the current maintainer; in particular that license must permit modification
+and redistribution.
+
+Please try to make the contribution a single file and give the file a clear and
+unambiguous name that identifies the target OS. If multiple files really are
+required put them all in a sub-directory.
+
+You must also be prepared to handle bug reports from users of the code, either
+by joining the png-mng-implement mailing list or by providing an email for the
+"BUG REPORTS" entry or both. Please make sure that the header of the file
+contains the STATUS and BUG REPORTS fields as above.
+
+Please list the OS requirements as precisely as possible. Ideally you should
+also list the environment in which the code has been tested and certainly list
+any environments where you suspect it might not work.
diff --git a/contrib/arm-neon/android-ndk.c b/contrib/arm-neon/android-ndk.c
new file mode 100644
index 000000000..724012348
--- /dev/null
+++ b/contrib/arm-neon/android-ndk.c
@@ -0,0 +1,39 @@
+/* contrib/arm-neon/android-ndk.c
+ *
+ * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Written by John Bowler, 2014.
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * SEE contrib/arm-neon/README before reporting bugs
+ *
+ * STATUS: COMPILED, UNTESTED
+ * BUG REPORTS: png-mng-implement@sourceforge.net
+ *
+ * png_have_neon implemented for the Android NDK, see:
+ *
+ * Documentation:
+ * http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
+ * http://code.google.com/p/android/issues/detail?id=49065
+ *
+ * NOTE: this requires that libpng is built against the Android NDK and linked
+ * with an implementation of the Android ARM 'cpu-features' library. The code
+ * has been compiled only, not linked: no version of the library has been found,
+ * only the header files exist in the NDK.
+ */
+#include <cpu-features.h>
+
+static int
+png_have_neon(png_structp png_ptr)
+{
+ /* This is a whole lot easier than the linux code, 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;
+}
diff --git a/contrib/arm-neon/linux-auxv.c b/contrib/arm-neon/linux-auxv.c
new file mode 100644
index 000000000..696e297ef
--- /dev/null
+++ b/contrib/arm-neon/linux-auxv.c
@@ -0,0 +1,120 @@
+/* contrib/arm-neon/linux-auxv.c
+ *
+ * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Written by Mans Rullgard, 2011.
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * SEE contrib/arm-neon/README before reporting bugs
+ *
+ * STATUS: COMPILED, TESTED
+ * BUG REPORTS: png-mng-implement@sourceforge.net
+ *
+ * png_have_neon implemented for Linux versions which allow access to
+ * /proc/self/auxv. This is probably faster, cleaner and safer than the code to
+ * read /proc/cpuinfo in contrib/arm-neon/linux, however it is yet another piece
+ * of potentially untested code and has more complex dependencies than the code
+ * to read cpuinfo.
+ *
+ * This 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.
+ */
+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 */
+}
+
+static int
+png_have_neon(png_structp png_ptr)
+{
+ int fd = open("/proc/self/auxv", O_RDONLY);
+ Elf32_auxv_t aux;
+
+ /* 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;
+ }
+ }
+
+ close(fd);
+ return 0;
+}
diff --git a/contrib/arm-neon/linux.c b/contrib/arm-neon/linux.c
new file mode 100644
index 000000000..182f37605
--- /dev/null
+++ b/contrib/arm-neon/linux.c
@@ -0,0 +1,159 @@
+/* contrib/arm-neon/linux.c
+ *
+ * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Written by John Bowler, 2014.
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * SEE contrib/arm-neon/README before reporting bugs
+ *
+ * STATUS: SUPPORTED
+ * BUG REPORTS: png-mng-implement@sourceforge.net
+ *
+ * png_have_neon implemented for Linux by reading the widely available
+ * pseudo-file /proc/cpuinfo.
+ *
+ * This code is strict ANSI-C and is probably moderately portable, it does
+ * however use <stdio.h> and assumes that /proc/cpuinfo is never localized.
+ */
+#include <stdio.h>
+
+static int
+png_have_neon(png_structp png_ptr)
+{
+ FILE *f = fopen("/proc/cpuinfo", "rb");
+
+ if (f != NULL)
+ {
+ /* This is a simple state machine which reads the input byte-by-byte until
+ * it gets a match on the 'neon' feature or reaches the end of the stream.
+ */
+ static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 };
+ static const char ch_neon[] = { 78, 69, 79, 78 };
+
+ enum
+ {
+ StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine
+ } state;
+ int counter;
+
+ for (state=StartLine, counter=0;;)
+ {
+ int ch = fgetc(f);
+
+ if (ch == EOF)
+ {
+ /* EOF means error or end-of-file, return false; neon at EOF is
+ * assumed to be a mistake.
+ */
+ fclose(f);
+ return 0;
+ }
+
+ switch (state)
+ {
+ case StartLine:
+ /* Match spaces at the start of line */
+ if (ch <= 32) /* skip control characters and space */
+ break;
+
+ counter=0;
+ state = Feature;
+ /* FALL THROUGH */
+
+ case Feature:
+ /* Match 'FEATURE', ASCII case insensitive. */
+ if ((ch & ~0x20) == ch_feature[counter])
+ {
+ if (++counter == (sizeof ch_feature))
+ state = Colon;
+ break;
+ }
+
+ /* did not match 'feature' */
+ state = SkipLine;
+ /* FALL THROUGH */
+
+ case SkipLine:
+ skipLine:
+ /* Skip everything until we see linefeed or carriage return */
+ if (ch != 10 && ch != 13)
+ break;
+
+ state = StartLine;
+ break;
+
+ case Colon:
+ /* Match any number of space or tab followed by ':' */
+ if (ch == 32 || ch == 9)
+ break;
+
+ if (ch == 58) /* i.e. ':' */
+ {
+ state = StartTag;
+ break;
+ }
+
+ /* Either a bad line format or a 'feature' prefix followed by
+ * other characters.
+ */
+ state = SkipLine;
+ goto skipLine;
+
+ case StartTag:
+ /* Skip space characters before a tag */
+ if (ch == 32 || ch == 9)
+ break;
+
+ state = Neon;
+ counter = 0;
+ /* FALL THROUGH */
+
+ case Neon:
+ /* Look for 'neon' tag */
+ if ((ch & ~0x20) == ch_neon[counter])
+ {
+ if (++counter == (sizeof ch_neon))
+ state = HaveNeon;
+ break;
+ }
+
+ state = SkipTag;
+ /* FALL THROUGH */
+
+ case SkipTag:
+ /* Skip non-space characters */
+ if (ch == 10 || ch == 13)
+ state = StartLine;
+
+ else if (ch == 32 || ch == 9)
+ state = StartTag;
+ break;
+
+ case HaveNeon:
+ /* Have seen a 'neon' prefix, but there must be a space or new
+ * line character to terminate it.
+ */
+ if (ch == 10 || ch == 13 || ch == 32 || ch == 9)
+ {
+ fclose(f);
+ return 1;
+ }
+
+ state = SkipTag;
+ break;
+
+ default:
+ png_error(png_ptr, "png_have_neon: internal error (bug)");
+ }
+ }
+ }
+
+ else
+ png_warning(png_ptr, "/proc/cpuinfo open failed");
+
+ return 0;
+}
diff --git a/contrib/examples/iccfrompng.c b/contrib/examples/iccfrompng.c
index 67676219e..386e522a3 100644
--- a/contrib/examples/iccfrompng.c
+++ b/contrib/examples/iccfrompng.c
@@ -6,9 +6,9 @@
* United States.
*
* Extract any icc profiles found in the given PNG files. This is a simple
- * example of a program which extracts information from the header of a PNG file
+ * example of a program that extracts information from the header of a PNG file
* without processing the image. Notice that some header information may occur
- * after the image data, textual data and comments are an example; the approach
+ * after the image data. Textual data and comments are an example; the approach
* in this file won't work reliably for such data because it only looks for the
* information in the section of the file that preceeds the image data.
*
diff --git a/contrib/examples/pngpixel.c b/contrib/examples/pngpixel.c
index 410476031..e0d43e3f0 100644
--- a/contrib/examples/pngpixel.c
+++ b/contrib/examples/pngpixel.c
@@ -8,7 +8,7 @@
* Read a single pixel value from a PNG file.
*
* This code illustrates basic 'by-row' reading of a PNG file using libpng.
- * Rows are read until a particular pixel is found, the value of this pixel is
+ * Rows are read until a particular pixel is found; the value of this pixel is
* then printed on stdout.
*
* The code illustrates how to do this on interlaced as well as non-interlaced
@@ -56,7 +56,7 @@ component(png_const_bytep row, png_uint_32 x, unsigned int c,
case 8: return row[0];
case 16: return (row[0] << 8) + row[1];
default:
- /* This should never happen, it indicates a bug in this program or in
+ /* This should never happen; it indicates a bug in this program or in
* libpng itself:
*/
fprintf(stderr, "pngpixel: invalid bit depth %u\n", bit_depth);
@@ -132,7 +132,7 @@ print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
return;
default:
- png_error(png_ptr, "invalid color type");
+ png_error(png_ptr, "pngpixel: invalid color type");
}
}
diff --git a/contrib/gregbook/readpng2.c b/contrib/gregbook/readpng2.c
index e179db71e..e6a132eca 100644
--- a/contrib/gregbook/readpng2.c
+++ b/contrib/gregbook/readpng2.c
@@ -69,6 +69,7 @@ static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass);
static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
+static void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg);
@@ -104,7 +105,7 @@ int readpng2_init(mainprog_info *mainprog_ptr)
/* could also replace libpng warning-handler (final NULL), but no need: */
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
- readpng2_error_handler, NULL);
+ readpng2_error_handler, readpng2_warning_handler);
if (!png_ptr)
return 4; /* out of memory */
@@ -467,7 +468,11 @@ void readpng2_cleanup(mainprog_info *mainprog_ptr)
}
-
+static void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg)
+{
+ fprintf(stderr, "readpng2 libpng warning: %s\n", msg);
+ fflush(stderr);
+}
static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
diff --git a/contrib/libtests/pngimage.c b/contrib/libtests/pngimage.c
new file mode 100644
index 000000000..372845ead
--- /dev/null
+++ b/contrib/libtests/pngimage.c
@@ -0,0 +1,1618 @@
+/* pngimage.c
+ *
+ * Copyright (c) 2014 John Cunningham Bowler
+ *
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * Test the png_read_png and png_write_png interfaces. Given a PNG file load it
+ * using png_read_png and then write with png_write_png. Test all possible
+ * transforms.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <assert.h>
+
+#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
+# include <config.h>
+#endif
+
+/* Define the following to use this test against your installed libpng, rather
+ * than the one being built here:
+ */
+#ifdef PNG_FREESTANDING_TESTS
+# include <png.h>
+#else
+# include "../../png.h"
+#endif
+
+#ifndef PNG_SETJMP_SUPPORTED
+# include <setjmp.h> /* because png.h did *not* include this */
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)
+/* If a transform is valid on both read and write this implies that if the
+ * transform is applied to read it must also be applied on write to produce
+ * meaningful data. This is because these transforms when performed on read
+ * produce data with a memory format that does not correspond to a PNG format.
+ *
+ * Most of these transforms are invertible; after applying the transform on
+ * write the result is the original PNG data that would have would have been
+ * read if no transform were applied.
+ *
+ * The exception is _SHIFT, which destroys the low order bits marked as not
+ * significant in a PNG with the sBIT chunk.
+ *
+ * The following table lists, for each transform, the conditions under which it
+ * is expected to do anything. Conditions are defined as follows:
+ *
+ * 1) Color mask bits required - simply a mask to AND with color_type; one of
+ * these must be present for the transform to fire, except that 0 means
+ * 'always'.
+ * 2) Color mask bits which must be absent - another mask - none of these must
+ * be present.
+ * 3) Bit depths - a mask of component bit depths for the transform to fire.
+ * 4) 'read' - the transform works in png_read_png.
+ * 5) 'write' - the transform works in png_write_png.
+ * 6) PNG_INFO_chunk; a mask of the chunks that must be present for the
+ * transform to fire. All must be present - the requirement is that
+ * png_get_valid() & mask == mask, so if mask is 0 there is no requirement.
+ *
+ * The condition refers to the original image state - if multiple transforms are
+ * used together it is possible to cause a transform that wouldn't fire on the
+ * original image to fire.
+ */
+static struct transform_info
+{
+ const char *name;
+ int transform;
+ png_uint_32 valid_chunks;
+# define CHUNK_NONE 0
+# define CHUNK_sBIT PNG_INFO_sBIT
+# define CHUNK_tRNS PNG_INFO_tRNS
+ png_byte color_mask_required;
+ png_byte color_mask_absent;
+# define COLOR_MASK_X 0
+# define COLOR_MASK_P PNG_COLOR_MASK_PALETTE
+# define COLOR_MASK_C PNG_COLOR_MASK_COLOR
+# define COLOR_MASK_A PNG_COLOR_MASK_ALPHA
+# define COLOR_MASK_ALL (PALETTE+COLOR+ALPHA) /* absent = gray, no alpha */
+ png_byte bit_depths;
+# define BD_ALL (1 + 2 + 4 + 8 + 16)
+# define BD_PAL (1 + 2 + 4 + 8)
+# define BD_LOW (1 + 2 + 4)
+# define BD_16 16
+# define BD_TRUE (8+16) /* i.e. true-color depths */
+ png_byte when;
+# define TRANSFORM_R 1
+# define TRANSFORM_W 2
+# define TRANSFORM_RW 3
+ png_byte tested; /* the transform was tested somewhere */
+} transform_info[] =
+{
+ /* List ALL the PNG_TRANSFORM_ macros here. Check for support using the READ
+ * macros; even if the transform is supported on write it cannot be tested
+ * without the read support.
+ */
+# define T(name,chunk,cm_required,cm_absent,bd,when)\
+ { #name, PNG_TRANSFORM_ ## name, CHUNK_ ## chunk,\
+ COLOR_MASK_ ## cm_required, COLOR_MASK_ ## cm_absent, BD_ ## bd,\
+ TRANSFORM_ ## when, 0/*!tested*/ }
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ T(STRIP_16, NONE, X, X, 16, R),
+ /* drops the bottom 8 bits when bit depth is 16 */
+#endif
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ T(STRIP_ALPHA, NONE, A, X, ALL, R),
+ /* removes the alpha channel if present */
+#endif
+#ifdef PNG_WRITE_PACK_SUPPORTED
+# define TRANSFORM_RW_PACK TRANSFORM_RW
+#else
+# define TRANSFORM_RW_PACK TRANSFORM_R
+#endif
+#ifdef PNG_READ_PACK_SUPPORTED
+ T(PACKING, NONE, X, X, LOW, RW_PACK),
+ /* unpacks low-bit-depth components into 1 byte per component on read,
+ * reverses this on write.
+ */
+#endif
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+# define TRANSFORM_RW_PACKSWAP TRANSFORM_RW
+#else
+# define TRANSFORM_RW_PACKSWAP TRANSFORM_R
+#endif
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ T(PACKSWAP, NONE, X, X, LOW, RW_PACKSWAP),
+ /* reverses the order of low-bit-depth components packed into a byte */
+#endif
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ T(EXPAND, NONE, P, X, ALL, R),
+ /* expands PLTE PNG files to RGB (no tRNS) or RGBA (tRNS) *
+ * Note that the 'EXPAND' transform does lots of different things: */
+ T(EXPAND, NONE, X, C, ALL, R),
+ /* expands grayscale PNG files to RGB, or RGBA */
+ T(EXPAND, tRNS, X, A, ALL, R),
+ /* expands the tRNS chunk in files without alpha */
+#endif
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+# define TRANSFORM_RW_INVERT TRANSFORM_RW
+#else
+# define TRANSFORM_RW_INVERT TRANSFORM_R
+#endif
+#ifdef PNG_READ_INVERT_SUPPORTED
+ T(INVERT_MONO, NONE, X, C, ALL, RW_INVERT),
+ /* converts gray-scale components to 1..0 from 0..1 */
+#endif
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+# define TRANSFORM_RW_SHIFT TRANSFORM_RW
+#else
+# define TRANSFORM_RW_SHIFT TRANSFORM_R
+#endif
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ T(SHIFT, sBIT, X, X, ALL, RW_SHIFT),
+ /* reduces component values to the original range based on the sBIT chunk,
+ * this is only partially reversible - the low bits are lost and cannot be
+ * recovered on write. In fact write code replicates the bits to generate
+ * new low-order bits.
+ */
+#endif
+#ifdef PNG_WRITE_BGR_SUPPORTED
+# define TRANSFORM_RW_BGR TRANSFORM_RW
+#else
+# define TRANSFORM_RW_BGR TRANSFORM_R
+#endif
+#ifdef PNG_READ_BGR_SUPPORTED
+ T(BGR, NONE, C, P, TRUE, RW_BGR),
+ /* reverses the rgb component values of true-color pixels */
+#endif
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+# define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_RW
+#else
+# define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_R
+#endif
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ T(SWAP_ALPHA, NONE, A, X, TRUE, RW_SWAP_ALPHA),
+ /* swaps the alpha channel of RGBA or GA pixels to the front - ARGB or
+ * AG, on write reverses the process.
+ */
+#endif
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+# define TRANSFORM_RW_SWAP TRANSFORM_RW
+#else
+# define TRANSFORM_RW_SWAP TRANSFORM_R
+#endif
+#ifdef PNG_READ_SWAP_SUPPORTED
+ T(SWAP_ENDIAN, NONE, X, P, 16, RW_SWAP),
+ /* byte-swaps 16-bit component values */
+#endif
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+# define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_RW
+#else
+# define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_R
+#endif
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ T(INVERT_ALPHA, NONE, A, X, TRUE, RW_INVERT_ALPHA),
+ /* converts an alpha channel from 0..1 to 1..0 */
+#endif
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ T(STRIP_FILLER_BEFORE, NONE, A, P, TRUE, W), /* 'A' for a filler! */
+ /* on write skips a leading filler channel; testing requires data with a
+ * filler channel so this is produced from RGBA or GA images by removing
+ * the 'alpha' flag from the color type in place.
+ */
+ T(STRIP_FILLER_AFTER, NONE, A, P, TRUE, W),
+ /* on write strips a trailing filler channel */
+#endif
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ T(GRAY_TO_RGB, NONE, X, C, ALL, R),
+ /* expands grayscale images to RGB, also causes the palette part of
+ * 'EXPAND' to happen. Low bit depth grayscale images are expanded to
+ * 8-bits per component and no attempt is made to convert the image to a
+ * palette image. While this transform is partially reversible
+ * png_write_png does not currently support this.
+ */
+ T(GRAY_TO_RGB, NONE, P, X, ALL, R),
+ /* The 'palette' side effect mentioned above; a bit bogus but this is the
+ * way the libpng code works.
+ */
+#endif
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ T(EXPAND_16, NONE, X, X, PAL, R),
+ /* expands images to 16-bits per component, as a side effect expands
+ * palette images to RGB and expands the tRNS chunk if present, so it can
+ * modify 16-bit per component images as well:
+ */
+ T(EXPAND_16, tRNS, X, A, 16, R),
+ /* side effect of EXPAND_16 - expands the tRNS chunk in an RGB or G 16-bit
+ * image.
+ */
+#endif
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ T(SCALE_16, NONE, X, X, 16, R)
+ /* scales 16-bit components to 8-bits. */
+#endif
+
+#undef T
+};
+
+#define ARRAY_SIZE(a) ((sizeof a)/(sizeof a[0]))
+#define TTABLE_SIZE ARRAY_SIZE(transform_info)
+
+/* Some combinations of options that should be reversible are not; these cases
+ * are bugs.
+ */
+static int known_bad_combos[][2] =
+{
+ /* problem, antidote */
+ { PNG_TRANSFORM_SHIFT | PNG_TRANSFORM_INVERT_ALPHA, 0/*antidote*/ }
+};
+
+static int
+is_combo(int transforms)
+{
+ return transforms & (transforms-1); /* non-zero if more than one set bit */
+}
+
+static int
+first_transform(int transforms)
+{
+ return transforms & -transforms; /* lowest set bit */
+}
+
+static int
+is_bad_combo(int transforms)
+{
+ unsigned int i;
+
+ for (i=0; i<ARRAY_SIZE(known_bad_combos); ++i)
+ {
+ int combo = known_bad_combos[i][0];
+
+ if ((combo & transforms) == combo &&
+ (transforms & known_bad_combos[i][1]) == 0)
+ return 1;
+ }
+
+ return 0; /* combo is ok */
+}
+
+static const char *
+transform_name(int t)
+ /* The name, if 't' has multiple bits set the name of the lowest set bit is
+ * returned.
+ */
+{
+ unsigned int i;
+
+ t &= -t; /* first set bit */
+
+ for (i=0; i<TTABLE_SIZE; ++i)
+ {
+ if ((transform_info[i].transform & t) != 0)
+ return transform_info[i].name;
+ }
+
+ return "invalid transform";
+}
+
+/* Variables calculated by validate_T below and used to record all the supported
+ * transforms. Need (unsigned int) here because of the places where these
+ * values are used (unsigned compares in the 'exhaustive' iterator.)
+ */
+static unsigned int read_transforms, write_transforms, rw_transforms;
+
+static void
+validate_T(void)
+ /* Validate the above table - this just builds the above values */
+{
+ unsigned int i;
+
+ for (i=0; i<TTABLE_SIZE; ++i)
+ {
+ if (transform_info[i].when & TRANSFORM_R)
+ read_transforms |= transform_info[i].transform;
+
+ if (transform_info[i].when & TRANSFORM_W)
+ write_transforms |= transform_info[i].transform;
+ }
+
+ /* Reversible transforms are those which are supported on both read and
+ * write.
+ */
+ rw_transforms = read_transforms & write_transforms;
+}
+
+/* FILE DATA HANDLING
+ * The original file is cached in memory. During write the output file is
+ * written to memory.
+ *
+ * In both cases the file data is held in a linked list of buffers - not all
+ * of these are in use at any time.
+ */
+struct buffer_list
+{
+ struct buffer_list *next; /* next buffer in list */
+ png_byte buffer[1024]; /* the actual buffer */
+};
+
+struct buffer
+{
+ struct buffer_list *last; /* last buffer in use */
+ size_t end_count; /* bytes in the last buffer */
+ struct buffer_list *current; /* current buffer being read */
+ size_t read_count; /* count of bytes read from current */
+ struct buffer_list first; /* the very first buffer */
+};
+
+static void
+buffer_init(struct buffer *buffer)
+ /* Call this only once for a given buffer */
+{
+ buffer->first.next = NULL;
+ buffer->last = NULL;
+ buffer->current = NULL;
+}
+
+#ifdef PNG_WRITE_SUPPORTED
+static void
+buffer_start_write(struct buffer *buffer)
+{
+ buffer->last = &buffer->first;
+ buffer->end_count = 0;
+ buffer->current = NULL;
+}
+#endif
+
+static void
+buffer_start_read(struct buffer *buffer)
+{
+ buffer->current = &buffer->first;
+ buffer->read_count = 0;
+}
+
+#ifdef ENOMEM /* required by POSIX 1003.1 */
+# define MEMORY ENOMEM
+#else
+# define MEMORY ERANGE /* required by ANSI-C */
+#endif
+static struct buffer *
+get_buffer(png_structp pp)
+ /* Used from libpng callbacks to get the current buffer */
+{
+ return (struct buffer*)png_get_io_ptr(pp);
+}
+
+#define NEW(type) ((type *)malloc(sizeof (type)))
+
+static struct buffer_list *
+buffer_extend(struct buffer_list *current)
+{
+ struct buffer_list *add;
+
+ assert(current->next == NULL);
+
+ add = NEW(struct buffer_list);
+ if (add == NULL)
+ return NULL;
+
+ add->next = NULL;
+ current->next = add;
+
+ return add;
+}
+
+/* Load a buffer from a file; does the equivalent of buffer_start_write. On a
+ * read error returns an errno value, else returns 0.
+ */
+static int
+buffer_from_file(struct buffer *buffer, FILE *fp)
+{
+ struct buffer_list *last = &buffer->first;
+ size_t count = 0;
+
+ for (;;)
+ {
+ size_t r = fread(last->buffer+count, 1/*size*/,
+ (sizeof last->buffer)-count, fp);
+
+ if (r > 0)
+ {
+ count += r;
+
+ if (count >= sizeof last->buffer)
+ {
+ assert(count == sizeof last->buffer);
+ count = 0;
+
+ if (last->next == NULL)
+ {
+ last = buffer_extend(last);
+ if (last == NULL)
+ return MEMORY;
+ }
+
+ else
+ last = last->next;
+ }
+ }
+
+ else /* fread failed - probably end of file */
+ {
+ if (feof(fp))
+ {
+ buffer->last = last;
+ buffer->end_count = count;
+ return 0; /* no error */
+ }
+
+ /* Some kind of funky error; errno should be non-zero */
+ return errno == 0 ? ERANGE : errno;
+ }
+ }
+}
+
+/* This structure is used to control the test of a single file. */
+typedef enum
+{
+ VERBOSE, /* switches on all messages */
+ INFORMATION,
+ WARNINGS, /* switches on warnings */
+ LIBPNG_WARNING,
+ APP_WARNING,
+ ERRORS, /* just errors */
+ APP_FAIL, /* continuable error - no need to longjmp */
+ LIBPNG_ERROR, /* this and higher cause a longjmp */
+ LIBPNG_BUG, /* erroneous behavior in libpng */
+ APP_ERROR, /* such as out-of-memory in a callback */
+ QUIET, /* no normal messages */
+ USER_ERROR, /* such as file-not-found */
+ INTERNAL_ERROR
+} error_level;
+#define LEVEL_MASK 0xf /* where the level is in 'options' */
+
+#define EXHAUSTIVE 0x010 /* Test all combinations of active options */
+#define STRICT 0x020 /* Fail on warnings as well as errors */
+#define LOG 0x040 /* Log pass/fail to stdout */
+#define CONTINUE 0x080 /* Continue on APP_FAIL errors */
+#define SKIP_BUGS 0x100 /* Skip over known bugs */
+#define LOG_SKIPPED 0x200 /* Log skipped bugs */
+#define FIND_BAD_COMBOS 0x400 /* Attempt to deduce bad combos */
+
+/* Result masks apply to the result bits in the 'results' field below; these
+ * bits are simple 1U<<error_level. A pass requires either nothing worse than
+ * warnings (--relaxes) or nothing worse than information (--strict)
+ */
+#define RESULT_STRICT(r) (((r) & ~((1U<<WARNINGS)-1)) == 0)
+#define RESULT_RELAXED(r) (((r) & ~((1U<<ERRORS)-1)) == 0)
+
+struct display
+{
+ jmp_buf error_return; /* Where to go to on error */
+
+ const char *filename; /* The name of the original file */
+ const char *operation; /* Operation being performed */
+ int transforms; /* Transform used in operation */
+ png_uint_32 options; /* See display_log below */
+ png_uint_32 results; /* A mask of errors seen */
+
+
+ png_structp original_pp; /* used on the original read */
+ png_infop original_ip; /* set by the original read */
+
+ png_size_t original_rowbytes; /* of the original rows: */
+ png_bytepp original_rows; /* from the original read */
+
+ /* Original chunks valid */
+ png_uint_32 chunks;
+
+ /* Original IHDR information */
+ png_uint_32 width;
+ png_uint_32 height;
+ int bit_depth;
+ int color_type;
+ int interlace_method;
+ int compression_method;
+ int filter_method;
+
+ /* Derived information for the original image. */
+ int active_transforms; /* transforms that do something on read */
+ int ignored_transforms; /* transforms that should do nothing */
+
+ /* Used on a read, both the original read and when validating a written
+ * image.
+ */
+ png_structp read_pp;
+ png_infop read_ip;
+
+# ifdef PNG_WRITE_SUPPORTED
+ /* Used to write a new image (the original info_ptr is used) */
+ png_structp write_pp;
+ struct buffer written_file; /* where the file gets written */
+# endif
+
+ struct buffer original_file; /* Data read from the original file */
+};
+
+static void
+display_init(struct display *dp)
+ /* Call this only once right at the start to initialize the control
+ * structure, the (struct buffer) lists are maintained across calls - the
+ * memory is not freed.
+ */
+{
+ memset(dp, 0, sizeof *dp);
+ dp->options = WARNINGS; /* default to !verbose, !quiet */
+ dp->filename = NULL;
+ dp->operation = NULL;
+ dp->original_pp = NULL;
+ dp->original_ip = NULL;
+ dp->original_rows = NULL;
+ dp->read_pp = NULL;
+ dp->read_ip = NULL;
+ buffer_init(&dp->original_file);
+
+# ifdef PNG_WRITE_SUPPORTED
+ dp->write_pp = NULL;
+ buffer_init(&dp->written_file);
+# endif
+}
+
+static void
+display_clean_read(struct display *dp)
+{
+ if (dp->read_pp != NULL)
+ png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL);
+}
+
+#ifdef PNG_WRITE_SUPPORTED
+static void
+display_clean_write(struct display *dp)
+{
+ if (dp->write_pp != NULL)
+ png_destroy_write_struct(&dp->write_pp, NULL);
+}
+#endif
+
+static void
+display_clean(struct display *dp)
+{
+# ifdef PNG_WRITE_SUPPORTED
+ display_clean_write(dp);
+# endif
+ display_clean_read(dp);
+
+ dp->original_rowbytes = 0;
+ dp->original_rows = NULL;
+ dp->chunks = 0;
+
+ png_destroy_read_struct(&dp->original_pp, &dp->original_ip, NULL);
+ /* leave the filename for error detection */
+ dp->results = 0; /* reset for next time */
+}
+
+static struct display *
+get_dp(png_structp pp)
+ /* The display pointer is always stored in the png_struct error pointer */
+{
+ struct display *dp = (struct display*)png_get_error_ptr(pp);
+
+ if (dp == NULL)
+ {
+ fprintf(stderr, "pngimage: internal error (no display)\n");
+ exit(99); /* prevents a crash */
+ }
+
+ return dp;
+}
+
+/* error handling */
+#ifdef __GNUC__
+# define VGATTR __attribute__((__format__ (__printf__,3,4)))
+ /* Required to quiet GNUC warnings when the compiler sees a stdarg function
+ * that calls one of the stdio v APIs.
+ */
+#else
+# define VGATTR
+#endif
+static void VGATTR
+display_log(struct display *dp, error_level level, const char *fmt, ...)
+ /* 'level' is as above, fmt is a stdio style format string. This routine
+ * does not return if level is above LIBPNG_WARNING
+ */
+{
+ dp->results |= 1U << level;
+
+ if (level > (error_level)(dp->options & LEVEL_MASK))
+ {
+ const char *lp;
+ va_list ap;
+
+ switch (level)
+ {
+ case INFORMATION: lp = "information"; break;
+ case LIBPNG_WARNING: lp = "warning(libpng)"; break;
+ case APP_WARNING: lp = "warning(pngimage)"; break;
+ case APP_FAIL: lp = "error(continuable)"; break;
+ case LIBPNG_ERROR: lp = "error(libpng)"; break;
+ case LIBPNG_BUG: lp = "bug(libpng)"; break;
+ case APP_ERROR: lp = "error(pngimage)"; break;
+ case USER_ERROR: lp = "error(user)"; break;
+
+ case INTERNAL_ERROR: /* anything unexpected is an internal error: */
+ case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
+ default: lp = "bug(pngimage)"; break;
+ }
+
+ fprintf(stderr, "%s: %s: %s",
+ dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);
+
+ if (dp->transforms != 0)
+ {
+ int tr = dp->transforms;
+
+ if (is_combo(tr))
+ fprintf(stderr, "(0x%x)", tr);
+
+ else
+ fprintf(stderr, "(%s)", transform_name(tr));
+ }
+
+ fprintf(stderr, ": ");
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ fputc('\n', stderr);
+ }
+ /* else do not output any message */
+
+ /* Errors cause this routine to exit to the fail code */
+ if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
+ longjmp(dp->error_return, level);
+}
+
+/* error handler callbacks for libpng */
+static void PNGCBAPI
+display_warning(png_structp pp, png_const_charp warning)
+{
+ display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
+}
+
+static void PNGCBAPI
+display_error(png_structp pp, png_const_charp error)
+{
+ struct display *dp = get_dp(pp);
+
+ display_log(dp, LIBPNG_ERROR, "%s", error);
+}
+
+static void
+display_cache_file(struct display *dp, const char *filename)
+ /* Does the initial cache of the file. */
+{
+ FILE *fp;
+ int ret;
+
+ dp->filename = filename;
+
+ if (filename != NULL)
+ {
+ fp = fopen(filename, "rb");
+ if (fp == NULL)
+ display_log(dp, USER_ERROR, "open failed: %s", strerror(errno));
+ }
+
+ else
+ fp = stdin;
+
+ ret = buffer_from_file(&dp->original_file, fp);
+
+ fclose(fp);
+
+ if (ret != 0)
+ display_log(dp, APP_ERROR, "read failed: %s", strerror(ret));
+}
+
+static void
+buffer_read(struct display *dp, struct buffer *bp, png_bytep data,
+ png_size_t size)
+{
+ struct buffer_list *last = bp->current;
+ size_t read_count = bp->read_count;
+
+ while (size > 0)
+ {
+ size_t avail;
+
+ if (last == NULL ||
+ (last == bp->last && read_count >= bp->end_count))
+ {
+ display_log(dp, USER_ERROR, "file truncated (%lu bytes)",
+ (unsigned long)size);
+ /*NOTREACHED*/
+ break;
+ }
+
+ else if (read_count >= sizeof last->buffer)
+ {
+ /* Move to the next buffer: */
+ last = last->next;
+ read_count = 0;
+ bp->current = last; /* Avoid update outside the loop */
+
+ /* And do a sanity check (the EOF case is caught above) */
+ if (last == NULL)
+ {
+ display_log(dp, INTERNAL_ERROR, "damaged buffer list");
+ /*NOTREACHED*/
+ break;
+ }
+ }
+
+ avail = (sizeof last->buffer) - read_count;
+ if (avail > size)
+ avail = size;
+
+ memcpy(data, last->buffer + read_count, avail);
+ read_count += avail;
+ size -= avail;
+ data += avail;
+ }
+
+ bp->read_count = read_count;
+}
+
+static void PNGCBAPI
+read_function(png_structp pp, png_bytep data, png_size_t size)
+{
+ buffer_read(get_dp(pp), get_buffer(pp), data, size);
+}
+
+static void
+read_png(struct display *dp, struct buffer *bp, const char *operation,
+ int transforms)
+{
+ png_structp pp;
+ png_infop ip;
+
+ /* This cleans out any previous read and sets operation and transforms to
+ * empty.
+ */
+ display_clean_read(dp);
+
+ if (operation != NULL) /* else this is a verify and do not overwrite info */
+ {
+ dp->operation = operation;
+ dp->transforms = transforms;
+ }
+
+ dp->read_pp = pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
+ display_error, display_warning);
+ if (pp == NULL)
+ display_log(dp, LIBPNG_ERROR, "failed to create read struct");
+
+ /* The png_read_png API requires us to make the info struct, but it does the
+ * call to png_read_info.
+ */
+ dp->read_ip = ip = png_create_info_struct(pp);
+ if (ip == NULL)
+ display_log(dp, LIBPNG_ERROR, "failed to create info struct");
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ /* Remove the user limits, if any */
+ png_set_user_limits(pp, 0x7fffffff, 0x7fffffff);
+# endif
+
+ /* Set the IO handling */
+ buffer_start_read(bp);
+ png_set_read_fn(pp, bp, read_function);
+
+ png_read_png(pp, ip, transforms, NULL/*params*/);
+
+#if 0 /* crazy debugging */
+ {
+ png_bytep pr = png_get_rows(pp, ip)[0];
+ size_t rb = png_get_rowbytes(pp, ip);
+ size_t cb;
+ char c = ' ';
+
+ fprintf(stderr, "%.4x %2d (%3lu bytes):", transforms, png_get_bit_depth(pp,ip), (unsigned long)rb);
+
+ for (cb=0; cb<rb; ++cb)
+ fputc(c, stderr), fprintf(stderr, "%.2x", pr[cb]), c='.';
+
+ fputc('\n', stderr);
+ }
+#endif
+}
+
+static void
+update_display(struct display *dp)
+ /* called once after the first read to update all the info, original_pp and
+ * original_ip must have been filled in.
+ */
+{
+ png_structp pp;
+ png_infop ip;
+
+ /* Now perform the initial read with a 0 tranform. */
+ read_png(dp, &dp->original_file, "original read", 0/*no transform*/);
+
+ /* Move the result to the 'original' fields */
+ dp->original_pp = pp = dp->read_pp, dp->read_pp = NULL;
+ dp->original_ip = ip = dp->read_ip, dp->read_ip = NULL;
+
+ dp->original_rowbytes = png_get_rowbytes(pp, ip);
+ if (dp->original_rowbytes == 0)
+ display_log(dp, LIBPNG_BUG, "png_get_rowbytes returned 0");
+
+ dp->chunks = png_get_valid(pp, ip, 0xffffffff);
+ if ((dp->chunks & PNG_INFO_IDAT) == 0) /* set by png_read_png */
+ display_log(dp, LIBPNG_BUG, "png_read_png did not set IDAT flag");
+
+ dp->original_rows = png_get_rows(pp, ip);
+ if (dp->original_rows == NULL)
+ display_log(dp, LIBPNG_BUG, "png_read_png did not create row buffers");
+
+ if (!png_get_IHDR(pp, ip,
+ &dp->width, &dp->height, &dp->bit_depth, &dp->color_type,
+ &dp->interlace_method, &dp->compression_method, &dp->filter_method))
+ display_log(dp, LIBPNG_BUG, "png_get_IHDR failed");
+
+ /* 'active' transforms are discovered based on the original image format;
+ * running one active transform can activate others. At present the code
+ * does not attempt to determine the closure.
+ */
+ {
+ png_uint_32 chunks = dp->chunks;
+ int active = 0, inactive = 0;
+ int ct = dp->color_type;
+ int bd = dp->bit_depth;
+ unsigned int i;
+
+ for (i=0; i<TTABLE_SIZE; ++i)
+ {
+ int transform = transform_info[i].transform;
+
+ if ((transform_info[i].valid_chunks == 0 ||
+ (transform_info[i].valid_chunks & chunks) != 0) &&
+ (transform_info[i].color_mask_required & ct) ==
+ transform_info[i].color_mask_required &&
+ (transform_info[i].color_mask_absent & ct) == 0 &&
+ (transform_info[i].bit_depths & bd) != 0 &&
+ (transform_info[i].when & TRANSFORM_R) != 0)
+ active |= transform;
+
+ else if ((transform_info[i].when & TRANSFORM_R) != 0)
+ inactive |= transform;
+ }
+
+ /* Some transforms appear multiple times in the table; the 'active' status
+ * is the logical OR of these and the inactive status must be adjusted to
+ * take this into account.
+ */
+ inactive &= ~active;
+
+ dp->active_transforms = active;
+ dp->ignored_transforms = inactive; /* excluding write-only transforms */
+
+ if (active == 0)
+ display_log(dp, INTERNAL_ERROR, "bad transform table");
+ }
+}
+
+static int
+compare_read(struct display *dp, int applied_transforms)
+{
+ /* Compare the png_info from read_ip with original_info */
+ size_t rowbytes;
+ png_uint_32 width, height;
+ int bit_depth, color_type;
+ int interlace_method, compression_method, filter_method;
+ const char *e = NULL;
+
+ png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth,
+ &color_type, &interlace_method, &compression_method, &filter_method);
+
+# define C(item) if (item != dp->item) \
+ display_log(dp, APP_WARNING, "IHDR " #item "(%lu) changed to %lu",\
+ (unsigned long)dp->item, (unsigned long)item), e = #item
+
+ /* The IHDR should be identical: */
+ C(width);
+ C(height);
+ C(bit_depth);
+ C(color_type);
+ C(interlace_method);
+ C(compression_method);
+ C(filter_method);
+
+ /* 'e' remains set to the name of the last thing changed: */
+ if (e)
+ display_log(dp, APP_ERROR, "IHDR changed (%s)", e);
+
+ /* All the chunks from the original PNG should be preserved in the output PNG
+ * because the PNG format has not been changed.
+ */
+ {
+ unsigned long chunks =
+ png_get_valid(dp->read_pp, dp->read_ip, 0xffffffff);
+
+ if (chunks != dp->chunks)
+ display_log(dp, APP_FAIL, "PNG chunks changed from 0x%lx to 0x%lx",
+ (unsigned long)dp->chunks, chunks);
+ }
+
+ /* rowbytes should be the same */
+ rowbytes = png_get_rowbytes(dp->read_pp, dp->read_ip);
+
+ /* NOTE: on 64-bit systems this may trash the top bits of rowbytes,
+ * which could lead to weird error messages.
+ */
+ if (rowbytes != dp->original_rowbytes)
+ display_log(dp, APP_ERROR, "PNG rowbytes changed from %lu to %lu",
+ (unsigned long)dp->original_rowbytes, (unsigned long)rowbytes);
+
+ /* The rows should be the same too, unless the applied transforms includes
+ * the shift transform, in which case low bits may have been lost.
+ */
+ {
+ png_bytepp rows = png_get_rows(dp->read_pp, dp->read_ip);
+ unsigned int mask; /* mask (if not zero) for the final byte */
+
+ if (bit_depth < 8)
+ {
+ /* Need the stray bits at the end, this depends only on the low bits
+ * of the image width; overflow does not matter. If the width is an
+ * exact multiple of 8 bits this gives a mask of 0, not 0xff.
+ */
+ mask = 0xff & (0xff00 >> ((bit_depth * width) & 7));
+ }
+
+ else
+ mask = 0;
+
+ if (rows == NULL)
+ display_log(dp, LIBPNG_BUG, "png_get_rows returned NULL");
+
+ if ((applied_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
+ (dp->active_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
+ color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ unsigned long y;
+
+ for (y=0; y<height; ++y)
+ {
+ png_bytep row = rows[y];
+ png_bytep orig = dp->original_rows[y];
+
+ if (memcmp(row, orig, rowbytes-(mask != 0)) != 0 || (mask != 0 &&
+ ((row[rowbytes-1] & mask) != (orig[rowbytes-1] & mask))))
+ {
+ size_t x;
+
+ /* Find the first error */
+ for (x=0; x<rowbytes-1; ++x) if (row[x] != orig[x])
+ break;
+
+ display_log(dp, APP_FAIL,
+ "byte(%lu,%lu) changed 0x%.2x -> 0x%.2x",
+ (unsigned long)x, (unsigned long)y, orig[x], row[x]);
+ return 0; /* don't keep reporting failed rows on 'continue' */
+ }
+ }
+ }
+
+ else
+ {
+ unsigned long y;
+ int bpp; /* bits-per-pixel then bytes-per-pixel */
+ /* components are up to 8 bytes in size */
+ png_byte sig_bits[8];
+ png_color_8p sBIT;
+
+ if (png_get_sBIT(dp->read_pp, dp->read_ip, &sBIT) != PNG_INFO_sBIT)
+ display_log(dp, INTERNAL_ERROR,
+ "active shift transform but no sBIT in file");
+
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ sig_bits[0] = sBIT->gray;
+ bpp = bit_depth;
+ break;
+
+ case PNG_COLOR_TYPE_GA:
+ sig_bits[0] = sBIT->gray;
+ sig_bits[1] = sBIT->alpha;
+ bpp = 2 * bit_depth;
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ sig_bits[0] = sBIT->red;
+ sig_bits[1] = sBIT->green;
+ sig_bits[2] = sBIT->blue;
+ bpp = 3 * bit_depth;
+ break;
+
+ case PNG_COLOR_TYPE_RGBA:
+ sig_bits[0] = sBIT->red;
+ sig_bits[1] = sBIT->green;
+ sig_bits[2] = sBIT->blue;
+ sig_bits[3] = sBIT->alpha;
+ bpp = 4 * bit_depth;
+ break;
+
+ default:
+ display_log(dp, LIBPNG_ERROR, "invalid colour type %d",
+ color_type);
+ /*NOTREACHED*/
+ bpp = 0;
+ break;
+ }
+
+ {
+ int b;
+
+ for (b=0; 8*b<bpp; ++b)
+ {
+ /* libpng should catch this; if not there is a security issue
+ * because an app (like this one) may overflow an array. In fact
+ * libpng doesn't catch this at present.
+ */
+ if (sig_bits[b] == 0 || sig_bits[b] > bit_depth/*!palette*/)
+ display_log(dp, LIBPNG_BUG,
+ "invalid sBIT[%u] value %d returned for PNG bit depth %d",
+ b, sig_bits[b], bit_depth);
+ }
+ }
+
+ if (bpp < 8 && bpp != bit_depth)
+ {
+ /* sanity check; this is a grayscale PNG; something is wrong in the
+ * code above.
+ */
+ display_log(dp, INTERNAL_ERROR, "invalid bpp %u for bit_depth %u",
+ bpp, bit_depth);
+ }
+
+ switch (bit_depth)
+ {
+ int b;
+
+ case 16: /* Two bytes per component, bit-endian */
+ for (b = (bpp >> 4); b > 0; )
+ {
+ unsigned int sig = (unsigned int)(0xffff0000 >> sig_bits[b]);
+
+ sig_bits[2*b+1] = (png_byte)sig;
+ sig_bits[2*b+0] = (png_byte)(sig >> 8); /* big-endian */
+ }
+ break;
+
+ case 8: /* One byte per component */
+ for (b=0; b*8 < bpp; ++b)
+ sig_bits[b] = (png_byte)(0xff00 >> sig_bits[b]);
+ break;
+
+ case 1: /* allowed, but dumb */
+ /* Value is 1 */
+ sig_bits[0] = 0xff;
+ break;
+
+ case 2: /* Replicate 4 times */
+ /* Value is 1 or 2 */
+ b = 0x3 & ((0x3<<2) >> sig_bits[0]);
+ b |= b << 2;
+ b |= b << 4;
+ sig_bits[0] = (png_byte)b;
+ break;
+
+ case 4: /* Relicate twice */
+ /* Value is 1, 2, 3 or 4 */
+ b = 0xf & ((0xf << 4) >> sig_bits[0]);
+ b |= b << 4;
+ sig_bits[0] = (png_byte)b;
+ break;
+
+ default:
+ display_log(dp, LIBPNG_BUG, "invalid bit depth %d", bit_depth);
+ break;
+ }
+
+ /* Convert bpp to bytes; this gives '1' for low-bit depth grayscale,
+ * where there are multiple pixels per byte.
+ */
+ bpp = (bpp+7) >> 3;
+
+ /* The mask can be combined with sig_bits[0] */
+ if (mask != 0)
+ {
+ mask &= sig_bits[0];
+
+ if (bpp != 1 || mask == 0)
+ display_log(dp, INTERNAL_ERROR, "mask calculation error %u, %u",
+ bpp, mask);
+ }
+
+ for (y=0; y<height; ++y)
+ {
+ png_bytep row = rows[y];
+ png_bytep orig = dp->original_rows[y];
+ unsigned long x;
+
+ for (x=0; x<(width-(mask!=0)); ++x)
+ {
+ int b;
+
+ for (b=0; b<bpp; ++b)
+ {
+ if ((*row++ & sig_bits[b]) != (*orig++ & sig_bits[b]))
+ {
+ display_log(dp, APP_FAIL,
+ "significant bits at (%lu[%u],%lu) changed %.2x->%.2x",
+ x, b, y, orig[-1], row[-1]);
+ return 0;
+ }
+ }
+ }
+
+ if (mask != 0 && (*row & mask) != (*orig & mask))
+ {
+ display_log(dp, APP_FAIL,
+ "significant bits at (%lu[end],%lu) changed", x, y);
+ return 0;
+ }
+ } /* for y */
+ }
+ }
+
+ return 1; /* compare succeeded */
+}
+
+#ifdef PNG_WRITE_SUPPORTED
+static void
+buffer_write(struct display *dp, struct buffer *buffer, png_bytep data,
+ png_size_t size)
+ /* Generic write function used both from the write callback provided to
+ * libpng and from the generic read code.
+ */
+{
+ /* Write the data into the buffer, adding buffers as required */
+ struct buffer_list *last = buffer->last;
+ size_t end_count = buffer->end_count;
+
+ while (size > 0)
+ {
+ size_t avail;
+
+ if (end_count >= sizeof last->buffer)
+ {
+ if (last->next == NULL)
+ {
+ last = buffer_extend(last);
+
+ if (last == NULL)
+ display_log(dp, APP_ERROR, "out of memory saving file");
+ }
+
+ else
+ last = last->next;
+
+ buffer->last = last; /* avoid the need to rewrite every time */
+ end_count = 0;
+ }
+
+ avail = (sizeof last->buffer) - end_count;
+ if (avail > size)
+ avail = size;
+
+ memcpy(last->buffer + end_count, data, avail);
+ end_count += avail;
+ size -= avail;
+ data += avail;
+ }
+
+ buffer->end_count = end_count;
+}
+
+static void PNGCBAPI
+write_function(png_structp pp, png_bytep data, png_size_t size)
+{
+ buffer_write(get_dp(pp), get_buffer(pp), data, size);
+}
+
+static void
+write_png(struct display *dp, png_infop ip, int transforms)
+{
+ display_clean_write(dp); /* safety */
+
+ buffer_start_write(&dp->written_file);
+ dp->operation = "write";
+ dp->transforms = transforms;
+
+ dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
+ display_error, display_warning);
+
+ if (dp->write_pp == NULL)
+ display_log(dp, APP_ERROR, "failed to create write png_struct");
+
+ png_set_write_fn(dp->write_pp, &dp->written_file, write_function,
+ NULL/*flush*/);
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ /* Remove the user limits, if any */
+ png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
+# endif
+
+ /* Certain transforms require the png_info to be zapped to allow the
+ * transform to work correctly.
+ */
+ if (transforms & (PNG_TRANSFORM_PACKING|
+ PNG_TRANSFORM_STRIP_FILLER|
+ PNG_TRANSFORM_STRIP_FILLER_BEFORE))
+ {
+ int ct = dp->color_type;
+
+ if (transforms & (PNG_TRANSFORM_STRIP_FILLER|
+ PNG_TRANSFORM_STRIP_FILLER_BEFORE))
+ ct &= ~PNG_COLOR_MASK_ALPHA;
+
+ png_set_IHDR(dp->write_pp, ip, dp->width, dp->height, dp->bit_depth, ct,
+ dp->interlace_method, dp->compression_method, dp->filter_method);
+ }
+
+ png_write_png(dp->write_pp, ip, transforms, NULL/*params*/);
+
+ /* Clean it on the way out - if control returns to the caller then the
+ * written_file contains the required data.
+ */
+ display_clean_write(dp);
+}
+#endif /* WRITE_SUPPORTED */
+
+static int
+skip_transform(struct display *dp, int tr)
+ /* Helper to test for a bad combo and log it if it is skipped */
+{
+ if ((dp->options & SKIP_BUGS) != 0 && is_bad_combo(tr))
+ {
+ /* Log this to stdout if logging is on, otherwise just do an information
+ * display_log.
+ */
+ if ((dp->options & LOG_SKIPPED) != 0)
+ {
+ printf("SKIP: %s transforms ", dp->filename);
+
+ while (tr != 0)
+ {
+ int next = first_transform(tr);
+ tr &= ~next;
+
+ printf("%s", transform_name(next));
+ if (tr != 0)
+ putchar('+');
+ }
+
+ putchar('\n');
+ }
+
+ else
+ display_log(dp, INFORMATION, "%s: skipped known bad combo 0x%x",
+ dp->filename, tr);
+
+ return 1; /* skip */
+ }
+
+ return 0; /* don't skip */
+}
+
+static void
+test_one_file(struct display *dp, const char *filename)
+{
+ /* First cache the file and update the display original file
+ * information for the new file.
+ */
+ dp->operation = "cache file";
+ dp->transforms = 0;
+ display_cache_file(dp, filename);
+ update_display(dp);
+
+ /* First test: if there are options that should be ignored for this file
+ * verify that they really are ignored.
+ */
+ if (dp->ignored_transforms != 0)
+ {
+ read_png(dp, &dp->original_file, "ignored transforms",
+ dp->ignored_transforms);
+
+ /* The result should be identical to the original_rows */
+ if (!compare_read(dp, 0/*transforms applied*/))
+ return; /* no point testing more */
+ }
+
+#ifdef PNG_WRITE_SUPPORTED
+ /* Second test: write the original PNG data out to a new file (to test the
+ * write side) then read the result back in and make sure that it hasn't
+ * changed.
+ */
+ dp->operation = "write";
+ write_png(dp, dp->original_ip, 0/*transforms*/);
+ read_png(dp, &dp->written_file, NULL, 0/*transforms*/);
+ if (!compare_read(dp, 0/*transforms applied*/))
+ return;
+#endif
+
+ /* Third test: the active options. Test each in turn, or, with the
+ * EXHAUSTIVE option, test all possible combinations.
+ */
+ {
+ /* Use unsigned int here because the code below to increment through all
+ * the possibilities exhaustively has to use a compare and that must be
+ * unsigned, because some transforms are negative on a 16-bit system.
+ */
+ unsigned int active = dp->active_transforms;
+ const int exhaustive = (dp->options & EXHAUSTIVE) != 0;
+ unsigned int current = first_transform(active);
+ unsigned int bad_transforms = 0;
+ unsigned int bad_combo = ~0U; /* bitwise AND of failing transforms */
+ unsigned int bad_combo_list = 0; /* bitwise OR of failures */
+
+ for (;;)
+ {
+ read_png(dp, &dp->original_file, "active transforms", current);
+
+ /* If this involved any irreversible transformations then if we write
+ * it out with just the reversible transformations and read it in again
+ * with the same transforms we should get the same thing. At present
+ * this isn't done - it just seems like a waste of time and it would
+ * require two sets of read png_struct/png_info.
+ *
+ * If there were no irreversible transformations then if we write it
+ * out and read it back in again (without the reversible transforms)
+ * we should get back to the place where we started.
+ */
+#ifdef PNG_WRITE_SUPPORTED
+ if ((current & write_transforms) == current)
+ {
+ /* All transforms reversible: write the PNG with the transformations
+ * reversed, then read it back in with no transformations. The
+ * result should be the same as the original apart from the loss of
+ * low order bits because of the SHIFT/sBIT transform.
+ */
+ dp->operation = "reversible transforms";
+ write_png(dp, dp->read_ip, current);
+
+ /* And if this is read back in, because all the transformations were
+ * reversible, the result should be the same.
+ */
+ read_png(dp, &dp->written_file, NULL, 0);
+ if (!compare_read(dp, current/*for the SHIFT/sBIT transform*/))
+ {
+ /* This set of transforms failed. If a single bit is set - if
+ * there is just one transform - don't include this in further
+ * 'exhaustive' tests. Notice that each transform is tested on
+ * its own before testing combos in the exhaustive case.
+ */
+ if (is_combo(current))
+ {
+ bad_combo &= current;
+ bad_combo_list |= current;
+ }
+
+ else
+ bad_transforms |= current;
+ }
+ }
+#endif
+
+ /* Now move to the next transform */
+ if (exhaustive) /* all combinations */
+ {
+ unsigned int next = current;
+
+ do
+ {
+ if (next == read_transforms) /* Everything tested */
+ goto combo;
+
+ ++next;
+ } /* skip known bad combos if the relevant option is set; skip
+ * combos involving known bad single transforms in all cases.
+ */
+ while ( (next & read_transforms) <= current
+ || (next & active) == 0 /* skip cases that do nothing */
+ || (next & bad_transforms) != 0
+ || skip_transform(dp, next));
+
+ assert((next & read_transforms) == next);
+ current = next;
+ }
+
+ else /* one at a time */
+ {
+ active &= ~current;
+
+ if (active == 0)
+ goto combo;
+
+ current = first_transform(active);
+ }
+ }
+
+combo:
+ if (dp->options & FIND_BAD_COMBOS)
+ {
+ /* bad_combos identifies the combos that occur in all failing cases;
+ * bad_combo_list identifies transforms that do not prevent the
+ * failure.
+ */
+ if (bad_combo != ~0U)
+ printf("%s[0x%x]: PROBLEM: 0x%x[0x%x] ANTIDOTE: 0x%x\n",
+ dp->filename, active, bad_combo, bad_combo_list,
+ rw_transforms & ~bad_combo_list);
+
+ else
+ printf("%s: no %sbad combos found\n", dp->filename,
+ (dp->options & SKIP_BUGS) ? "additional " : "");
+ }
+ }
+}
+
+static int
+do_test(struct display *dp, const char *file)
+ /* Exists solely to isolate the setjmp clobbers */
+{
+ int ret = setjmp(dp->error_return);
+
+ if (ret == 0)
+ {
+ test_one_file(dp, file);
+ return 0;
+ }
+
+ else if (ret < ERRORS) /* shouldn't longjmp on warnings */
+ display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
+
+ return ret;
+}
+
+int
+main(const int argc, const char * const * const argv)
+{
+ /* For each file on the command line test it with a range of transforms */
+ int option_end, ilog = 0;
+ struct display d;
+
+ validate_T();
+ display_init(&d);
+
+ for (option_end=1; option_end<argc; ++option_end)
+ {
+ const char *name = argv[option_end];
+
+ if (strcmp(name, "--verbose") == 0)
+ d.options = (d.options & ~LEVEL_MASK) | VERBOSE;
+
+ else if (strcmp(name, "--warnings") == 0)
+ d.options = (d.options & ~LEVEL_MASK) | WARNINGS;
+
+ else if (strcmp(name, "--errors") == 0)
+ d.options = (d.options & ~LEVEL_MASK) | ERRORS;
+
+ else if (strcmp(name, "--quiet") == 0)
+ d.options = (d.options & ~LEVEL_MASK) | QUIET;
+
+ else if (strcmp(name, "--exhaustive") == 0)
+ d.options |= EXHAUSTIVE;
+
+ else if (strcmp(name, "--fast") == 0)
+ d.options &= ~EXHAUSTIVE;
+
+ else if (strcmp(name, "--strict") == 0)
+ d.options |= STRICT;
+
+ else if (strcmp(name, "--relaxed") == 0)
+ d.options &= ~STRICT;
+
+ else if (strcmp(name, "--log") == 0)
+ {
+ ilog = option_end; /* prevent display */
+ d.options |= LOG;
+ }
+
+ else if (strcmp(name, "--nolog") == 0)
+ d.options &= ~LOG;
+
+ else if (strcmp(name, "--continue") == 0)
+ d.options |= CONTINUE;
+
+ else if (strcmp(name, "--stop") == 0)
+ d.options &= ~CONTINUE;
+
+ else if (strcmp(name, "--skip-bugs") == 0)
+ d.options |= SKIP_BUGS;
+
+ else if (strcmp(name, "--test-all") == 0)
+ d.options &= ~SKIP_BUGS;
+
+ else if (strcmp(name, "--log-skipped") == 0)
+ d.options |= LOG_SKIPPED;
+
+ else if (strcmp(name, "--nolog-skipped") == 0)
+ d.options &= ~LOG_SKIPPED;
+
+ else if (strcmp(name, "--find-bad-combos") == 0)
+ d.options |= FIND_BAD_COMBOS;
+
+ else if (strcmp(name, "--nofind-bad-combos") == 0)
+ d.options &= ~FIND_BAD_COMBOS;
+
+ else if (name[0] == '-' && name[1] == '-')
+ {
+ fprintf(stderr, "pngimage: %s: unknown option\n", name);
+ return 99;
+ }
+
+ else
+ break; /* Not an option */
+ }
+
+ {
+ int i;
+ int errors = 0;
+
+ for (i=option_end; i<argc; ++i)
+ {
+ {
+ int ret = do_test(&d, argv[i]);
+
+ if (ret > QUIET) /* abort on user or internal error */
+ return 99;
+ }
+
+ /* Here on any return, including failures, except user/internal issues
+ */
+ {
+ const int pass = (d.options & STRICT) ?
+ RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
+
+ if (!pass)
+ ++errors;
+
+ if (d.options & LOG)
+ {
+ int j;
+
+ printf("%s: pngimage ", pass ? "PASS" : "FAIL");
+
+ for (j=1; j<option_end; ++j) if (j != ilog)
+ printf("%s ", argv[j]);
+
+ printf("%s\n", d.filename);
+ }
+ }
+
+ display_clean(&d);
+ }
+
+ return errors != 0;
+ }
+}
+#else /* !PNG_INFO_IMAGE_SUPPORTED || !PNG_READ_SUPPORTED */
+int
+main(void)
+{
+ fprintf(stderr, "pngimage: no support for png_read/write_image\n");
+ return 77;
+}
+#endif
diff --git a/contrib/libtests/pngunknown.c b/contrib/libtests/pngunknown.c
index a21c9d75d..b8c4899de 100644
--- a/contrib/libtests/pngunknown.c
+++ b/contrib/libtests/pngunknown.c
@@ -1,8 +1,8 @@
/* pngunknown.c - test the read side unknown chunk handling
*
- * Last changed in libpng 1.6.0 [February 14, 2013]
- * Copyright (c) 2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ * Copyright (c) 2014 Glenn Randers-Pehrson
* Written by John Cunningham Bowler
*
* This code is released under the libpng license.
@@ -439,7 +439,7 @@ display_rc(const display *d, int strict)
}
/* libpng error and warning callbacks */
-PNG_FUNCTION(void, error, (png_structp png_ptr, const char *message),
+PNG_FUNCTION(void, (PNGCBAPI error), (png_structp png_ptr, const char *message),
static PNG_NORETURN)
{
display *d = (display*)png_get_error_ptr(png_ptr);
@@ -448,7 +448,7 @@ PNG_FUNCTION(void, error, (png_structp png_ptr, const char *message),
display_exit(d);
}
-static void
+static void PNGCBAPI
warning(png_structp png_ptr, const char *message)
{
display *d = (display*)png_get_error_ptr(png_ptr);
@@ -490,7 +490,7 @@ get_valid(display *d, png_infop info_ptr)
}
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
-static int
+static int PNGCBAPI
read_callback(png_structp pp, png_unknown_chunkp pc)
{
/* This function mimics the behavior of png_set_keep_unknown_chunks by
diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c
index 7347c1b5d..788b69327 100644
--- a/contrib/libtests/pngvalid.c
+++ b/contrib/libtests/pngvalid.c
@@ -1,7 +1,7 @@
/* pngvalid.c - validate libpng by constructing then reading png files.
*
- * Last changed in libpng 1.5.18 [February 6, 2014]
+ * Last changed in libpng 1.6.10 [March 6, 2014]
* Copyright (c) 2014 Glenn Randers-Pehrson
* Written by John Cunningham Bowler
*
@@ -122,11 +122,6 @@ typedef png_byte *png_const_bytep;
# endif
#endif
-/* Fixups for various minimal builds */
-#ifndef PNG_ERROR_TEXT_SUPPORTED
-# define png_error(a,b) png_err(a)
-#endif
-
/***************************** EXCEPTION HANDLING *****************************/
#ifdef PNG_FREESTANDING_TESTS
# include <cexcept.h>
@@ -926,7 +921,7 @@ internal_error(png_store *ps, png_const_charp message)
#endif /* PNG_READ_SUPPORTED */
/* Functions to use as PNG callbacks. */
-static void
+static void PNGCBAPI
store_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */
{
png_const_structp pp = ppIn;
@@ -942,7 +937,7 @@ store_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */
}
}
-static void
+static void PNGCBAPI
store_warning(png_structp ppIn, png_const_charp message)
{
png_const_structp pp = ppIn;
@@ -1093,7 +1088,7 @@ store_image_check(PNG_CONST png_store* ps, png_const_structp pp, int iImage)
}
#endif /* PNG_READ_SUPPORTED */
-static void
+static void PNGCBAPI
store_write(png_structp ppIn, png_bytep pb, png_size_t st)
{
png_const_structp pp = ppIn;
@@ -1121,7 +1116,7 @@ store_write(png_structp ppIn, png_bytep pb, png_size_t st)
}
}
-static void
+static void PNGCBAPI
store_flush(png_structp ppIn)
{
UNUSED(ppIn) /*DOES NOTHING*/
@@ -1215,7 +1210,7 @@ store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
}
}
-static void
+static void PNGCBAPI
store_read(png_structp ppIn, png_bytep pb, png_size_t st)
{
png_const_structp pp = ppIn;
@@ -1408,7 +1403,7 @@ store_pool_delete(png_store *ps, store_pool *pool)
}
/* The memory callbacks: */
-static png_voidp
+static png_voidp PNGCBAPI
store_malloc(png_structp ppIn, png_alloc_size_t cb)
{
png_const_structp pp = ppIn;
@@ -1457,7 +1452,7 @@ store_malloc(png_structp ppIn, png_alloc_size_t cb)
return new;
}
-static void
+static void PNGCBAPI
store_free(png_structp ppIn, png_voidp memory)
{
png_const_structp pp = ppIn;
@@ -2676,7 +2671,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
}
/* The callback: */
-static void
+static void PNGCBAPI
modifier_read(png_structp ppIn, png_bytep pb, png_size_t st)
{
png_const_structp pp = ppIn;
@@ -4680,7 +4675,7 @@ standard_info_imp(standard_display *dp, png_structp pp, png_infop pi,
standard_info_part2(dp, pp, pi, nImages);
}
-static void
+static void PNGCBAPI
standard_info(png_structp pp, png_infop pi)
{
standard_display *dp = voidcast(standard_display*,
@@ -4692,7 +4687,7 @@ standard_info(png_structp pp, png_infop pi)
standard_info_imp(dp, pp, pi, 1 /*only one image*/);
}
-static void
+static void PNGCBAPI
progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass)
{
png_const_structp pp = ppIn;
@@ -5006,7 +5001,7 @@ standard_image_validate(standard_display *dp, png_const_structp pp, int iImage,
dp->ps->validated = 1;
}
-static void
+static void PNGCBAPI
standard_end(png_structp ppIn, png_infop pi)
{
png_const_structp pp = ppIn;
@@ -5841,7 +5836,7 @@ transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
}
}
-static void
+static void PNGCBAPI
transform_info(png_structp pp, png_infop pi)
{
transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)),
@@ -6048,7 +6043,7 @@ transform_image_validate(transform_display *dp, png_const_structp pp,
dp->this.ps->validated = 1;
}
-static void
+static void PNGCBAPI
transform_end(png_structp ppIn, png_infop pi)
{
png_const_structp pp = ppIn;
@@ -7865,7 +7860,7 @@ gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
standard_info_part2(&dp->this, pp, pi, 1 /*images*/);
}
-static void
+static void PNGCBAPI
gamma_info(png_structp pp, png_infop pi)
{
gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp,
@@ -8829,7 +8824,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
dp->this.ps->validated = 1;
}
-static void
+static void PNGCBAPI
gamma_end(png_structp ppIn, png_infop pi)
{
png_const_structp pp = ppIn;
diff --git a/contrib/pngminim/decoder/pngusr.h b/contrib/pngminim/decoder/pngusr.h
index 841da0c28..cbd7890c7 100644
--- a/contrib/pngminim/decoder/pngusr.h
+++ b/contrib/pngminim/decoder/pngusr.h
@@ -18,7 +18,6 @@
* affect the API (so are not recorded in pnglibconf.h)
*/
-#define PNG_NO_WARNINGS
#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
#endif /* MINRDPNGCONF_H */
diff --git a/contrib/pngminim/encoder/pngusr.h b/contrib/pngminim/encoder/pngusr.h
index a050ef3eb..997d44fe9 100644
--- a/contrib/pngminim/encoder/pngusr.h
+++ b/contrib/pngminim/encoder/pngusr.h
@@ -18,7 +18,6 @@
* affect the API (so are not recorded in pnglibconf.h)
*/
-#define PNG_NO_WARNINGS
#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
#endif /* MINWRPNGCONF_H */
diff --git a/contrib/pngminim/preader/pngusr.h b/contrib/pngminim/preader/pngusr.h
index d84863472..80db3bb17 100644
--- a/contrib/pngminim/preader/pngusr.h
+++ b/contrib/pngminim/preader/pngusr.h
@@ -18,7 +18,6 @@
* affect the API (so are not recorded in pnglibconf.h)
*/
-#define PNG_NO_WARNINGS
#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
#endif /* MINPRDPNGCONF_H */
diff --git a/contrib/tools/pngfix.c b/contrib/tools/pngfix.c
index 08b23e73b..3b64627c2 100644
--- a/contrib/tools/pngfix.c
+++ b/contrib/tools/pngfix.c
@@ -2,7 +2,7 @@
*
* Copyright (c) 2014 John Cunningham Bowler
*
- * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Last changed in libpng 1.6.10 [March 6, 2014]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -3159,13 +3159,13 @@ read_chunk(struct file *file)
/* This returns a file* from a png_struct in an implementation specific way. */
static struct file *get_control(png_const_structrp png_ptr);
-static void
+static void PNGCBAPI
error_handler(png_structp png_ptr, png_const_charp message)
{
stop(get_control(png_ptr), LIBPNG_ERROR_CODE, message);
}
-static void
+static void PNGCBAPI
warning_handler(png_structp png_ptr, png_const_charp message)
{
struct file *file = get_control(png_ptr);
@@ -3177,7 +3177,7 @@ warning_handler(png_structp png_ptr, png_const_charp message)
/* Read callback - this is where the work gets done to check the stream before
* passing it to libpng
*/
-static void
+static void PNGCBAPI
read_callback(png_structp png_ptr, png_bytep buffer, size_t count)
/* Return 'count' bytes to libpng in 'buffer' */
{
diff --git a/libpng-manual.txt b/libpng-manual.txt
index c854b4c68..73e09abd0 100644
--- a/libpng-manual.txt
+++ b/libpng-manual.txt
@@ -1,6 +1,6 @@
libpng-manual.txt - A description on how to use and modify libpng
- libpng version 1.6.9 - February 6, 2014
+ libpng version 1.6.10 - March 6, 2014
Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net>
Copyright (c) 1998-2014 Glenn Randers-Pehrson
@@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
- libpng versions 0.97, January 1998, through 1.6.9 - February 6, 2014
+ libpng versions 0.97, January 1998, through 1.6.10 - March 6, 2014
Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2014 Glenn Randers-Pehrson
@@ -274,10 +274,10 @@ This method of building a customized pnglibconf.h is illustrated in
contrib/pngminim/*. See the "$(PNGCONF):" target in the makefile and
pngusr.dfa in these directories.
-C. Configuration using PNG_USR_CONFIG
+C. Configuration using PNG_USER_CONFIG
-If -DPNG_USR_CONFIG is added to the CFLAGS when pnglibconf.h is built the file
-pngusr.h will automatically be included before the options in
+If -DPNG_USER_CONFIG is added to the CPPFLAGS when pnglibconf.h is built,
+the file pngusr.h will automatically be included before the options in
scripts/pnglibconf.dfa are processed. Your pngusr.h file should contain only
macro definitions turning features on or off or setting settings.
@@ -712,12 +712,12 @@ value. You can also specify a default encoding for the PNG file in
case the required information is missing from the file. By default libpng
assumes that the PNG data matches your system, to keep this default call:
- png_set_gamma(png_ptr, screen_gamma, 1/screen_gamma/*file gamma*/);
+ png_set_gamma(png_ptr, screen_gamma, output_gamma);
or you can use the fixed point equivalent:
png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma,
- PNG_FP_1/screen_gamma);
+ PNG_FP_1*output_gamma);
If you don't know the gamma for your system it is probably 2.2 - a good
approximation to the IEC standard for display systems (sRGB). If images are
@@ -745,6 +745,70 @@ component value whenever arithmetic is performed. A lot of graphics software
uses linear values for this reason, often with higher precision component values
to preserve overall accuracy.
+
+The output_gamma value expresses how to decode the output values, not how
+they are encoded. The values used correspond to the normal numbers used to
+describe the overall gamma of a computer display system; for example 2.2 for
+an sRGB conformant system. The values are scaled by 100000 in the _fixed
+version of the API (so 220000 for sRGB.)
+
+The inverse of the value is always used to provide a default for the PNG file
+encoding if it has no gAMA chunk and if png_set_gamma() has not been called
+to override the PNG gamma information.
+
+When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
+opaque pixels however pixels with lower alpha values are not encoded,
+regardless of the output gamma setting.
+
+When the standard Porter Duff handling is requested with mode 1 the output
+encoding is set to be linear and the output_gamma value is only relevant
+as a default for input data that has no gamma information. The linear output
+encoding will be overridden if png_set_gamma() is called - the results may be
+highly unexpected!
+
+The following numbers are derived from the sRGB standard and the research
+behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of
+0.45455 (1/2.2) for PNG. The value implicitly includes any viewing
+correction required to take account of any differences in the color
+environment of the original scene and the intended display environment; the
+value expresses how to *decode* the image for display, not how the original
+data was *encoded*.
+
+sRGB provides a peg for the PNG standard by defining a viewing environment.
+sRGB itself, and earlier TV standards, actually use a more complex transform
+(a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is
+limited to simple power laws.) By saying that an image for direct display on
+an sRGB conformant system should be stored with a gAMA chunk value of 45455
+(11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
+makes it possible to derive values for other display systems and
+environments.
+
+The Mac value is deduced from the sRGB based on an assumption that the actual
+extra viewing correction used in early Mac display systems was implemented as
+a power 1.45 lookup table.
+
+Any system where a programmable lookup table is used or where the behavior of
+the final display device characteristics can be changed requires system
+specific code to obtain the current characteristic. However this can be
+difficult and most PNG gamma correction only requires an approximate value.
+
+By default, if png_set_alpha_mode() is not called, libpng assumes that all
+values are unencoded, linear, values and that the output device also has a
+linear characteristic. This is only very rarely correct - it is invariably
+better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
+default if you don't know what the right answer is!
+
+The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
+10.6) which used a correction table to implement a somewhat lower gamma on an
+otherwise sRGB system.
+
+Both these values are reserved (not simple gamma values) in order to allow
+more precise correction internally in the future.
+
+NOTE: the values can be passed to either the fixed or floating
+point APIs, but the floating point API will also accept floating point
+values.
+
The second thing you may need to tell libpng about is how your system handles
alpha channel information. Some, but not all, PNG files contain an alpha
channel. To display these files correctly you need to compose the data onto a
@@ -769,11 +833,11 @@ by png_set_alpha_mode().
The mode is as follows:
- PNG_ALPHA_PNG: The data is encoded according to the PNG specification. Red,
-green and blue, or gray, components are gamma encoded color
-values and are not premultiplied by the alpha value. The
-alpha value is a linear measure of the contribution of the
-pixel to the corresponding final output pixel.
+ PNG_ALPHA_PNG: The data is encoded according to the PNG
+specification. Red, green and blue, or gray, components are
+gamma encoded color values and are not premultiplied by the
+alpha value. The alpha value is a linear measure of the
+contribution of the pixel to the corresponding final output pixel.
You should normally use this format if you intend to perform
color correction on the color values; most, maybe all, color
@@ -790,11 +854,35 @@ be used!
The remaining modes assume you don't need to do any further color correction or
that if you do, your color correction software knows all about alpha (it
-probably doesn't!)
-
- PNG_ALPHA_STANDARD: The data libpng produces
-is encoded in the standard way
-assumed by most correctly written graphics software.
+probably doesn't!). They 'associate' the alpha with the color information by
+storing color channel values that have been scaled by the alpha. The
+advantage is that the color channels can be resampled (the image can be
+scaled) in this form. The disadvantage is that normal practice is to store
+linear, not (gamma) encoded, values and this requires 16-bit channels for
+still images rather than the 8-bit channels that are just about sufficient if
+gamma encoding is used. In addition all non-transparent pixel values,
+including completely opaque ones, must be gamma encoded to produce the final
+image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
+described below (the latter being the two common names for associated alpha
+color channels). Note that PNG files always contain non-associated color
+channels; png_set_alpha_mode() with one of the modes causes the decoder to
+convert the pixels to an associated form before returning them to your
+application.
+
+Since it is not necessary to perform arithmetic on opaque color values so
+long as they are not to be resampled and are in the final color space it is
+possible to optimize the handling of alpha by storing the opaque pixels in
+the PNG format (adjusted for the output color space) while storing partially
+opaque pixels in the standard, linear, format. The accuracy required for
+standard alpha composition is relatively low, because the pixels are
+isolated, therefore typically the accuracy loss in storing 8-bit linear
+values is acceptable. (This is not true if the alpha channel is used to
+simulate transparency over large areas - use 16 bits or the PNG mode in
+this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is
+treated as opaque only if the alpha value is equal to the maximum value.
+
+ PNG_ALPHA_STANDARD: The data libpng produces is encoded in the
+standard way assumed by most correctly written graphics software.
The gamma encoding will be removed by libpng and the
linear component values will be pre-multiplied by the
alpha channel.
@@ -823,9 +911,8 @@ dynamic range. To avoid problems, and if your software
supports it, use png_set_expand_16() to force all
components to 16 bits.
- PNG_ALPHA_OPTIMIZED: This mode is the same
-as PNG_ALPHA_STANDARD except that
-completely opaque pixels are gamma encoded according to
+ PNG_ALPHA_OPTIMIZED: This mode is the same as PNG_ALPHA_STANDARD
+except that completely opaque pixels are gamma encoded according to
the screen_gamma value. Pixels with alpha less than 1.0
will still have linear components.
@@ -844,18 +931,16 @@ representation of non-opaque pixels are irrelevant.
You can also try this format if your software is broken;
it might look better.
- PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD;
-however, all component values,
-including the alpha channel are gamma encoded. This is
-an appropriate format to try if your software, or more
-likely hardware, is totally broken, i.e., if it performs
-linear arithmetic directly on gamma encoded values.
-
-In most cases of broken software or hardware the bug in the final display
-manifests as a subtle halo around composited parts of the image. You may not
-even perceive this as a halo; the composited part of the image may simply appear
-separate from the background, as though it had been cut out of paper and pasted
-on afterward.
+ PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD; however, all component
+values, including the alpha channel are gamma encoded. This is
+broken because, in practice, no implementation that uses this choice
+correctly undoes the encoding before handling alpha composition. Use this
+choice only if other serious errors in the software or hardware you use
+mandate it. In most cases of broken software or hardware the bug in the
+final display manifests as a subtle halo around composited parts of the
+image. You may not even perceive this as a halo; the composited part of
+the image may simply appear separate from the background, as though it had
+been cut out of paper and pasted on afterward.
If you don't have to deal with bugs in software or hardware, or if you can fix
them, there are three recommended ways of using png_set_alpha_mode():
@@ -886,6 +971,89 @@ All you can do is compose the result onto a matching output. Since this
mode is libpng-specific you also need to write your own composition
software.
+The following are examples of calls to png_set_alpha_mode to achieve the
+required overall gamma correction and, where necessary, alpha
+premultiplication.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+
+This is the default libpng handling of the alpha channel - it is not
+pre-multiplied into the color components. In addition the call states
+that the output is for a sRGB system and causes all PNG files without gAMA
+chunks to be assumed to be encoded using sRGB.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+In this case the output is assumed to be something like an sRGB conformant
+display preceeded by a power-law lookup table of power 1.45. This is how
+early Mac systems behaved.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
+
+This is the classic Jim Blinn approach and will work in academic
+environments where everything is done by the book. It has the shortcoming
+of assuming that input PNG data with no gamma information is linear - this
+is unlikely to be correct unless the PNG files where generated locally.
+Most of the time the output precision will be so low as to show
+significant banding in dark areas of the image.
+
+ png_set_expand_16(pp);
+ png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
+
+This is a somewhat more realistic Jim Blinn inspired approach. PNG files
+are assumed to have the sRGB encoding if not marked with a gamma value and
+the output is always 16 bits per component. This permits accurate scaling
+and processing of the data. If you know that your input PNG files were
+generated locally you might need to replace PNG_DEFAULT_sRGB with the
+correct value for your system.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
+
+If you just need to composite the PNG image onto an existing background
+and if you control the code that does this you can use the optimization
+setting. In this case you just copy completely opaque pixels to the
+output. For pixels that are not completely transparent (you just skip
+those) you do the composition math using png_composite or png_composite_16
+below then encode the resultant 8-bit or 16-bit values to match the output
+encoding.
+
+ Other cases
+
+If neither the PNG nor the standard linear encoding work for you because
+of the software or hardware you use then you have a big problem. The PNG
+case will probably result in halos around the image. The linear encoding
+will probably result in a washed out, too bright, image (it's actually too
+contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably
+substantially reduce the halos. Alternatively try:
+
+ png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
+
+This option will also reduce the halos, but there will be slight dark
+halos round the opaque parts of the image where the background is light.
+In the OPTIMIZED mode the halos will be light halos where the background
+is dark. Take your pick - the halos are unavoidable unless you can get
+your hardware/software fixed! (The OPTIMIZED approach is slightly
+faster.)
+
+When the default gamma of PNG files doesn't match the output gamma.
+If you have PNG files with no gamma information png_set_alpha_mode allows
+you to provide a default gamma, but it also sets the ouput gamma to the
+matching value. If you know your PNG files have a gamma that doesn't
+match the output you can take advantage of the fact that
+png_set_alpha_mode always sets the output gamma but only sets the PNG
+default if it is not already set:
+
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+The first call sets both the default and the output gamma values, the
+second call overrides the output gamma without changing the default. This
+is easier than achieving the same effect with png_set_gamma. You must use
+PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
+fire if more than one call to png_set_alpha_mode and png_set_background is
+made in the same read operation, however multiple calls with PNG_ALPHA_PNG
+are ignored.
+
If you don't need, or can't handle, the alpha channel you can call
png_set_background() to remove it by compositing against a fixed color. Don't
call png_set_strip_alpha() to do this - it will leave spurious pixel values in
@@ -1216,7 +1384,7 @@ png_set_rgb_to_gray()).
png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
- file_srgb_intent - the rendering intent (PNG_INFO_sRGB)
+ srgb_intent - the rendering intent (PNG_INFO_sRGB)
The presence of the sRGB chunk
means that the pixel data is in the
sRGB color space. This chunk also
@@ -2166,10 +2334,15 @@ how pngvalid.c does it.
Finishing a sequential read
After you are finished reading the image through the
-low-level interface, you can finish reading the file. If you are
-interested in comments or time, which may be stored either before or
-after the image data, you should pass the separate png_info struct if
-you want to keep the comments from before and after the image
+low-level interface, you can finish reading the file.
+
+If you want to use a different crc action for handling CRC errors in
+chunks after the image data, you can call png_set_crc_action()
+again at this point.
+
+If you are interested in comments or time, which may be stored either
+before or after the image data, you should pass the separate png_info
+struct if you want to keep the comments from before and after the image
separate.
png_infop end_info = png_create_info_struct(png_ptr);
@@ -2185,6 +2358,9 @@ separate.
If you are not interested, you should still call png_read_end()
but you can pass NULL, avoiding the need to create an end_info structure.
+If you do this, libpng will not process any chunks after IDAT other than
+skipping over them and perhaps (depending on whether you have called
+png_set_crc_action) checking their CRCs while looking for the IEND chunk.
png_read_end(png_ptr, (png_infop)NULL);
@@ -4941,7 +5117,7 @@ pngconf.h no longer includes pngusr.h, therefore pngusr.h is ignored after the
build of pnglibconf.h and it is never included in an application build.
The rarely used alternative of adding a list of feature macros to the
-CFLAGS setting in the build also still works; however, the macros will be
+CPPFLAGS setting in the build also still works; however, the macros will be
copied to pnglibconf.h and this may produce macro redefinition warnings
when the individual C files are compiled.
@@ -4998,7 +5174,6 @@ The following API are now DEPRECATED:
png_info_init_3()
png_convert_to_rfc1123() which has been replaced
with png_convert_to_rfc1123_buffer()
- png_data_freer()
png_malloc_default()
png_free_default()
png_reset_zstream()
@@ -5174,6 +5349,9 @@ exported functions are marked with PNGAPI:
body;
}
+The return type and decorations are placed on a separate line
+ahead of the function name, as illustrated above.
+
The prototypes for all exported functions appear in png.h,
above the comment that says
@@ -5238,13 +5416,13 @@ Other rules can be inferred by inspecting the libpng source.
XVI. Y2K Compliance in libpng
-February 6, 2014
+March 6, 2014
Since the PNG Development group is an ad-hoc body, we can't make
an official declaration.
This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.9 are Y2K compliant. It is my belief that earlier
+upward through 1.6.10 are Y2K compliant. It is my belief that earlier
versions were also Y2K compliant.
Libpng only has two year fields. One is a 2-byte unsigned integer
diff --git a/libpng.3 b/libpng.3
index f80ca41da..db4990f33 100644
--- a/libpng.3
+++ b/libpng.3
@@ -1,6 +1,6 @@
-.TH LIBPNG 3 "February 6, 2014"
+.TH LIBPNG 3 "March 6, 2014"
.SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.9
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.10
.SH SYNOPSIS
\fB
#include <png.h>\fP
@@ -504,7 +504,7 @@ Following is a copy of the libpng-manual.txt file that accompanies libpng.
.SH LIBPNG.TXT
libpng-manual.txt - A description on how to use and modify libpng
- libpng version 1.6.9 - February 6, 2014
+ libpng version 1.6.10 - March 6, 2014
Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net>
Copyright (c) 1998-2014 Glenn Randers-Pehrson
@@ -515,7 +515,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
- libpng versions 0.97, January 1998, through 1.6.9 - February 6, 2014
+ libpng versions 0.97, January 1998, through 1.6.10 - March 6, 2014
Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2014 Glenn Randers-Pehrson
@@ -778,10 +778,10 @@ This method of building a customized pnglibconf.h is illustrated in
contrib/pngminim/*. See the "$(PNGCONF):" target in the makefile and
pngusr.dfa in these directories.
-C. Configuration using PNG_USR_CONFIG
+C. Configuration using PNG_USER_CONFIG
-If \-DPNG_USR_CONFIG is added to the CFLAGS when pnglibconf.h is built the file
-pngusr.h will automatically be included before the options in
+If \-DPNG_USER_CONFIG is added to the CPPFLAGS when pnglibconf.h is built,
+the file pngusr.h will automatically be included before the options in
scripts/pnglibconf.dfa are processed. Your pngusr.h file should contain only
macro definitions turning features on or off or setting settings.
@@ -1216,12 +1216,12 @@ value. You can also specify a default encoding for the PNG file in
case the required information is missing from the file. By default libpng
assumes that the PNG data matches your system, to keep this default call:
- png_set_gamma(png_ptr, screen_gamma, 1/screen_gamma/*file gamma*/);
+ png_set_gamma(png_ptr, screen_gamma, output_gamma);
or you can use the fixed point equivalent:
png_set_gamma_fixed(png_ptr, PNG_FP_1*screen_gamma,
- PNG_FP_1/screen_gamma);
+ PNG_FP_1*output_gamma);
If you don't know the gamma for your system it is probably 2.2 - a good
approximation to the IEC standard for display systems (sRGB). If images are
@@ -1249,6 +1249,70 @@ component value whenever arithmetic is performed. A lot of graphics software
uses linear values for this reason, often with higher precision component values
to preserve overall accuracy.
+
+The output_gamma value expresses how to decode the output values, not how
+they are encoded. The values used correspond to the normal numbers used to
+describe the overall gamma of a computer display system; for example 2.2 for
+an sRGB conformant system. The values are scaled by 100000 in the _fixed
+version of the API (so 220000 for sRGB.)
+
+The inverse of the value is always used to provide a default for the PNG file
+encoding if it has no gAMA chunk and if png_set_gamma() has not been called
+to override the PNG gamma information.
+
+When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
+opaque pixels however pixels with lower alpha values are not encoded,
+regardless of the output gamma setting.
+
+When the standard Porter Duff handling is requested with mode 1 the output
+encoding is set to be linear and the output_gamma value is only relevant
+as a default for input data that has no gamma information. The linear output
+encoding will be overridden if png_set_gamma() is called - the results may be
+highly unexpected!
+
+The following numbers are derived from the sRGB standard and the research
+behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of
+0.45455 (1/2.2) for PNG. The value implicitly includes any viewing
+correction required to take account of any differences in the color
+environment of the original scene and the intended display environment; the
+value expresses how to *decode* the image for display, not how the original
+data was *encoded*.
+
+sRGB provides a peg for the PNG standard by defining a viewing environment.
+sRGB itself, and earlier TV standards, actually use a more complex transform
+(a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is
+limited to simple power laws.) By saying that an image for direct display on
+an sRGB conformant system should be stored with a gAMA chunk value of 45455
+(11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
+makes it possible to derive values for other display systems and
+environments.
+
+The Mac value is deduced from the sRGB based on an assumption that the actual
+extra viewing correction used in early Mac display systems was implemented as
+a power 1.45 lookup table.
+
+Any system where a programmable lookup table is used or where the behavior of
+the final display device characteristics can be changed requires system
+specific code to obtain the current characteristic. However this can be
+difficult and most PNG gamma correction only requires an approximate value.
+
+By default, if png_set_alpha_mode() is not called, libpng assumes that all
+values are unencoded, linear, values and that the output device also has a
+linear characteristic. This is only very rarely correct - it is invariably
+better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
+default if you don't know what the right answer is!
+
+The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
+10.6) which used a correction table to implement a somewhat lower gamma on an
+otherwise sRGB system.
+
+Both these values are reserved (not simple gamma values) in order to allow
+more precise correction internally in the future.
+
+NOTE: the values can be passed to either the fixed or floating
+point APIs, but the floating point API will also accept floating point
+values.
+
The second thing you may need to tell libpng about is how your system handles
alpha channel information. Some, but not all, PNG files contain an alpha
channel. To display these files correctly you need to compose the data onto a
@@ -1273,11 +1337,11 @@ by png_set_alpha_mode().
The mode is as follows:
- PNG_ALPHA_PNG: The data is encoded according to the PNG specification. Red,
-green and blue, or gray, components are gamma encoded color
-values and are not premultiplied by the alpha value. The
-alpha value is a linear measure of the contribution of the
-pixel to the corresponding final output pixel.
+ PNG_ALPHA_PNG: The data is encoded according to the PNG
+specification. Red, green and blue, or gray, components are
+gamma encoded color values and are not premultiplied by the
+alpha value. The alpha value is a linear measure of the
+contribution of the pixel to the corresponding final output pixel.
You should normally use this format if you intend to perform
color correction on the color values; most, maybe all, color
@@ -1294,11 +1358,35 @@ be used!
The remaining modes assume you don't need to do any further color correction or
that if you do, your color correction software knows all about alpha (it
-probably doesn't!)
-
- PNG_ALPHA_STANDARD: The data libpng produces
-is encoded in the standard way
-assumed by most correctly written graphics software.
+probably doesn't!). They 'associate' the alpha with the color information by
+storing color channel values that have been scaled by the alpha. The
+advantage is that the color channels can be resampled (the image can be
+scaled) in this form. The disadvantage is that normal practice is to store
+linear, not (gamma) encoded, values and this requires 16-bit channels for
+still images rather than the 8-bit channels that are just about sufficient if
+gamma encoding is used. In addition all non-transparent pixel values,
+including completely opaque ones, must be gamma encoded to produce the final
+image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
+described below (the latter being the two common names for associated alpha
+color channels). Note that PNG files always contain non-associated color
+channels; png_set_alpha_mode() with one of the modes causes the decoder to
+convert the pixels to an associated form before returning them to your
+application.
+
+Since it is not necessary to perform arithmetic on opaque color values so
+long as they are not to be resampled and are in the final color space it is
+possible to optimize the handling of alpha by storing the opaque pixels in
+the PNG format (adjusted for the output color space) while storing partially
+opaque pixels in the standard, linear, format. The accuracy required for
+standard alpha composition is relatively low, because the pixels are
+isolated, therefore typically the accuracy loss in storing 8-bit linear
+values is acceptable. (This is not true if the alpha channel is used to
+simulate transparency over large areas - use 16 bits or the PNG mode in
+this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is
+treated as opaque only if the alpha value is equal to the maximum value.
+
+ PNG_ALPHA_STANDARD: The data libpng produces is encoded in the
+standard way assumed by most correctly written graphics software.
The gamma encoding will be removed by libpng and the
linear component values will be pre-multiplied by the
alpha channel.
@@ -1327,9 +1415,8 @@ dynamic range. To avoid problems, and if your software
supports it, use png_set_expand_16() to force all
components to 16 bits.
- PNG_ALPHA_OPTIMIZED: This mode is the same
-as PNG_ALPHA_STANDARD except that
-completely opaque pixels are gamma encoded according to
+ PNG_ALPHA_OPTIMIZED: This mode is the same as PNG_ALPHA_STANDARD
+except that completely opaque pixels are gamma encoded according to
the screen_gamma value. Pixels with alpha less than 1.0
will still have linear components.
@@ -1348,18 +1435,16 @@ representation of non-opaque pixels are irrelevant.
You can also try this format if your software is broken;
it might look better.
- PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD;
-however, all component values,
-including the alpha channel are gamma encoded. This is
-an appropriate format to try if your software, or more
-likely hardware, is totally broken, i.e., if it performs
-linear arithmetic directly on gamma encoded values.
-
-In most cases of broken software or hardware the bug in the final display
-manifests as a subtle halo around composited parts of the image. You may not
-even perceive this as a halo; the composited part of the image may simply appear
-separate from the background, as though it had been cut out of paper and pasted
-on afterward.
+ PNG_ALPHA_BROKEN: This is PNG_ALPHA_STANDARD; however, all component
+values, including the alpha channel are gamma encoded. This is
+broken because, in practice, no implementation that uses this choice
+correctly undoes the encoding before handling alpha composition. Use this
+choice only if other serious errors in the software or hardware you use
+mandate it. In most cases of broken software or hardware the bug in the
+final display manifests as a subtle halo around composited parts of the
+image. You may not even perceive this as a halo; the composited part of
+the image may simply appear separate from the background, as though it had
+been cut out of paper and pasted on afterward.
If you don't have to deal with bugs in software or hardware, or if you can fix
them, there are three recommended ways of using png_set_alpha_mode():
@@ -1390,6 +1475,89 @@ All you can do is compose the result onto a matching output. Since this
mode is libpng-specific you also need to write your own composition
software.
+The following are examples of calls to png_set_alpha_mode to achieve the
+required overall gamma correction and, where necessary, alpha
+premultiplication.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+
+This is the default libpng handling of the alpha channel - it is not
+pre-multiplied into the color components. In addition the call states
+that the output is for a sRGB system and causes all PNG files without gAMA
+chunks to be assumed to be encoded using sRGB.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+In this case the output is assumed to be something like an sRGB conformant
+display preceeded by a power-law lookup table of power 1.45. This is how
+early Mac systems behaved.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
+
+This is the classic Jim Blinn approach and will work in academic
+environments where everything is done by the book. It has the shortcoming
+of assuming that input PNG data with no gamma information is linear - this
+is unlikely to be correct unless the PNG files where generated locally.
+Most of the time the output precision will be so low as to show
+significant banding in dark areas of the image.
+
+ png_set_expand_16(pp);
+ png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
+
+This is a somewhat more realistic Jim Blinn inspired approach. PNG files
+are assumed to have the sRGB encoding if not marked with a gamma value and
+the output is always 16 bits per component. This permits accurate scaling
+and processing of the data. If you know that your input PNG files were
+generated locally you might need to replace PNG_DEFAULT_sRGB with the
+correct value for your system.
+
+ png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
+
+If you just need to composite the PNG image onto an existing background
+and if you control the code that does this you can use the optimization
+setting. In this case you just copy completely opaque pixels to the
+output. For pixels that are not completely transparent (you just skip
+those) you do the composition math using png_composite or png_composite_16
+below then encode the resultant 8-bit or 16-bit values to match the output
+encoding.
+
+ Other cases
+
+If neither the PNG nor the standard linear encoding work for you because
+of the software or hardware you use then you have a big problem. The PNG
+case will probably result in halos around the image. The linear encoding
+will probably result in a washed out, too bright, image (it's actually too
+contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably
+substantially reduce the halos. Alternatively try:
+
+ png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
+
+This option will also reduce the halos, but there will be slight dark
+halos round the opaque parts of the image where the background is light.
+In the OPTIMIZED mode the halos will be light halos where the background
+is dark. Take your pick - the halos are unavoidable unless you can get
+your hardware/software fixed! (The OPTIMIZED approach is slightly
+faster.)
+
+When the default gamma of PNG files doesn't match the output gamma.
+If you have PNG files with no gamma information png_set_alpha_mode allows
+you to provide a default gamma, but it also sets the ouput gamma to the
+matching value. If you know your PNG files have a gamma that doesn't
+match the output you can take advantage of the fact that
+png_set_alpha_mode always sets the output gamma but only sets the PNG
+default if it is not already set:
+
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+
+The first call sets both the default and the output gamma values, the
+second call overrides the output gamma without changing the default. This
+is easier than achieving the same effect with png_set_gamma. You must use
+PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
+fire if more than one call to png_set_alpha_mode and png_set_background is
+made in the same read operation, however multiple calls with PNG_ALPHA_PNG
+are ignored.
+
If you don't need, or can't handle, the alpha channel you can call
png_set_background() to remove it by compositing against a fixed color. Don't
call png_set_strip_alpha() to do this - it will leave spurious pixel values in
@@ -1720,7 +1888,7 @@ png_set_rgb_to_gray()).
png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
- file_srgb_intent - the rendering intent (PNG_INFO_sRGB)
+ srgb_intent - the rendering intent (PNG_INFO_sRGB)
The presence of the sRGB chunk
means that the pixel data is in the
sRGB color space. This chunk also
@@ -2670,10 +2838,15 @@ how pngvalid.c does it.
.SS Finishing a sequential read
After you are finished reading the image through the
-low-level interface, you can finish reading the file. If you are
-interested in comments or time, which may be stored either before or
-after the image data, you should pass the separate png_info struct if
-you want to keep the comments from before and after the image
+low-level interface, you can finish reading the file.
+
+If you want to use a different crc action for handling CRC errors in
+chunks after the image data, you can call png_set_crc_action()
+again at this point.
+
+If you are interested in comments or time, which may be stored either
+before or after the image data, you should pass the separate png_info
+struct if you want to keep the comments from before and after the image
separate.
png_infop end_info = png_create_info_struct(png_ptr);
@@ -2689,6 +2862,9 @@ separate.
If you are not interested, you should still call png_read_end()
but you can pass NULL, avoiding the need to create an end_info structure.
+If you do this, libpng will not process any chunks after IDAT other than
+skipping over them and perhaps (depending on whether you have called
+png_set_crc_action) checking their CRCs while looking for the IEND chunk.
png_read_end(png_ptr, (png_infop)NULL);
@@ -5446,7 +5622,7 @@ pngconf.h no longer includes pngusr.h, therefore pngusr.h is ignored after the
build of pnglibconf.h and it is never included in an application build.
The rarely used alternative of adding a list of feature macros to the
-CFLAGS setting in the build also still works; however, the macros will be
+CPPFLAGS setting in the build also still works; however, the macros will be
copied to pnglibconf.h and this may produce macro redefinition warnings
when the individual C files are compiled.
@@ -5503,7 +5679,6 @@ The following API are now DEPRECATED:
png_info_init_3()
png_convert_to_rfc1123() which has been replaced
with png_convert_to_rfc1123_buffer()
- png_data_freer()
png_malloc_default()
png_free_default()
png_reset_zstream()
@@ -5679,6 +5854,9 @@ exported functions are marked with PNGAPI:
body;
}
+The return type and decorations are placed on a separate line
+ahead of the function name, as illustrated above.
+
The prototypes for all exported functions appear in png.h,
above the comment that says
@@ -5743,13 +5921,13 @@ Other rules can be inferred by inspecting the libpng source.
.SH XVI. Y2K Compliance in libpng
-February 6, 2014
+March 6, 2014
Since the PNG Development group is an ad-hoc body, we can't make
an official declaration.
This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.9 are Y2K compliant. It is my belief that earlier
+upward through 1.6.10 are Y2K compliant. It is my belief that earlier
versions were also Y2K compliant.
Libpng only has two year fields. One is a 2-byte unsigned integer
@@ -5980,6 +6158,9 @@ the first widely used release:
1.6.9beta01-04 16 10609 16.so.16.9[.0]
1.6.9rc01-02 16 10609 16.so.16.9[.0]
1.6.9 16 10609 16.so.16.9[.0]
+ 1.6.10beta01-03 16 10610 16.so.16.10[.0]
+ 1.6.10rc01-04 16 10610 16.so.16.10[.0]
+ 1.6.10 16 10610 16.so.16.10[.0]
Henceforth the source version will match the shared-library minor
and patch numbers; the shared-library major version number will be
@@ -6036,7 +6217,7 @@ possible without all of you.
Thanks to Frank J. T. Wojcik for helping with the documentation.
-Libpng version 1.6.9 - February 6, 2014:
+Libpng version 1.6.10 - March 6, 2014:
Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
@@ -6059,7 +6240,7 @@ this sentence.
This code is released under the libpng license.
-libpng versions 1.2.6, August 15, 2004, through 1.6.9, February 6, 2014, are
+libpng versions 1.2.6, August 15, 2004, through 1.6.10, March 6, 2014, are
Copyright (c) 2004,2006-2007 Glenn Randers-Pehrson, and are
distributed according to the same disclaimer and license as libpng-1.2.5
with the following individual added to the list of Contributing Authors
@@ -6158,7 +6339,7 @@ certification mark of the Open Source Initiative.
Glenn Randers-Pehrson
glennrp at users.sourceforge.net
-February 6, 2014
+March 6, 2014
.\" end of man page
diff --git a/libpngpf.3 b/libpngpf.3
index ef0fb869b..844a9fcef 100644
--- a/libpngpf.3
+++ b/libpngpf.3
@@ -1,6 +1,6 @@
-.TH LIBPNGPF 3 "February 6, 2014"
+.TH LIBPNGPF 3 "March 6, 2014"
.SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.9
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.10
(private functions)
.SH SYNOPSIS
\fB#include \fI"pngpriv.h"
diff --git a/png.5 b/png.5
index 096ccc221..3beacfae5 100644
--- a/png.5
+++ b/png.5
@@ -1,4 +1,4 @@
-.TH PNG 5 "February 6, 2014"
+.TH PNG 5 "March 6, 2014"
.SH NAME
png \- Portable Network Graphics (PNG) format
.SH DESCRIPTION
diff --git a/png.c b/png.c
index 3db9ad41e..0cb4a1d04 100644
--- a/png.c
+++ b/png.c
@@ -14,7 +14,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_9 Your_png_h_is_not_version_1_6_9;
+typedef png_libpng_version_1_6_10 Your_png_h_is_not_version_1_6_10;
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
@@ -773,13 +773,13 @@ png_get_copyright(png_const_structrp png_ptr)
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
- "libpng version 1.6.9 - February 6, 2014" PNG_STRING_NEWLINE \
+ "libpng version 1.6.10 - March 6, 2014" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# else
- return "libpng version 1.6.9 - February 6, 2014\
+ return "libpng version 1.6.10 - March 6, 2014\
Copyright (c) 1998-2014 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@@ -1742,7 +1742,8 @@ is_ICC_signature_char(png_alloc_size_t it)
(it >= 97 && it <= 122);
}
-static int is_ICC_signature(png_alloc_size_t it)
+static int
+is_ICC_signature(png_alloc_size_t it)
{
return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
is_ICC_signature_char((it >> 16) & 0xff) &&
@@ -2295,15 +2296,16 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
}
}
-# if PNG_sRGB_PROFILE_CHECKS > 0
- /* The signature matched, but the profile had been changed in some
- * way. This is an apparent violation of the ICC terms of use and,
- * anyway, probably indicates a data error or uninformed hacking.
- */
- if (png_sRGB_checks[i].have_md5)
- png_benign_error(png_ptr,
- "copyright violation: edited ICC profile ignored");
-# endif
+# if PNG_sRGB_PROFILE_CHECKS > 0
+ /* The signature matched, but the profile had been changed in some
+ * way. This probably indicates a data error or uninformed hacking.
+ * Fall through to "no match".
+ */
+ png_chunk_report(png_ptr,
+ "Not recognizing known sRGB profile that has been edited",
+ PNG_CHUNK_WARNING);
+ break;
+# endif
}
}
diff --git a/png.h b/png.h
index b572dc732..16d3299aa 100644
--- a/png.h
+++ b/png.h
@@ -1,8 +1,8 @@
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.9 - February 6, 2014
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * libpng version 1.6.10 - March 6, 2014
+ * Copyright (c) 1998-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.)
*
@@ -11,7 +11,7 @@
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- * libpng versions 0.97, January 1998, through 1.6.9 - February 6, 2014: Glenn
+ * libpng versions 0.97, January 1998, through 1.6.10 - March 6, 2014: Glenn
* See also "Contributing Authors", below.
*
* Note about libpng version numbers:
@@ -192,6 +192,9 @@
* 1.6.9beta01-04 16 10609 16.so.16.9[.0]
* 1.6.9rc01-02 16 10609 16.so.16.9[.0]
* 1.6.9 16 10609 16.so.16.9[.0]
+ * 1.6.10beta01-03 16 10610 16.so.16.10[.0]
+ * 1.6.10betarc01-04 16 10610 16.so.16.10[.0]
+ * 1.6.10beta 16 10610 16.so.16.10[.0]
*
* Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be
@@ -223,7 +226,7 @@
*
* This code is released under the libpng license.
*
- * libpng versions 1.2.6, August 15, 2004, through 1.6.9, February 6, 2014, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.10, March 6, 2014, are
* Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors:
@@ -335,13 +338,13 @@
* Y2K compliance in libpng:
* =========================
*
- * February 6, 2014
+ * March 6, 2014
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
*
* This is your unofficial assurance that libpng from version 0.71 and
- * upward through 1.6.9 are Y2K compliant. It is my belief that
+ * upward through 1.6.10 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant.
*
* Libpng only has two year fields. One is a 2-byte unsigned integer
@@ -401,9 +404,9 @@
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.9"
+#define PNG_LIBPNG_VER_STRING "1.6.10"
#define PNG_HEADER_VERSION_STRING \
- " libpng version 1.6.9 - February 6, 2014\n"
+ " libpng version 1.6.10 - March 6, 2014\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
@@ -411,7 +414,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 9
+#define PNG_LIBPNG_VER_RELEASE 10
/* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero:
@@ -442,7 +445,7 @@
* version 1.0.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/
-#define PNG_LIBPNG_VER 10609 /* 1.6.9 */
+#define PNG_LIBPNG_VER 10610 /* 1.6.10 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@@ -547,7 +550,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char* png_libpng_version_1_6_9;
+typedef char* png_libpng_version_1_6_10;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
@@ -1209,9 +1212,9 @@ PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
#endif
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-/* How the alpha channel is interpreted - this affects how the color channels of
- * a PNG file are returned when an alpha channel, or tRNS chunk in a palette
- * file, is present.
+/* How the alpha channel is interpreted - this affects how the color channels
+ * of a PNG file are returned to the calling application when an alpha channel,
+ * or a tRNS chunk in a palette file, is present.
*
* This has no effect on the way pixels are written into a PNG output
* datastream. The color samples in a PNG datastream are never premultiplied
@@ -1219,33 +1222,19 @@ PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
*
* The default is to return data according to the PNG specification: the alpha
* channel is a linear measure of the contribution of the pixel to the
- * corresponding composited pixel. The gamma encoded color channels must be
- * scaled according to the contribution and to do this it is necessary to undo
+ * corresponding composited pixel, and the color channels are unassociated
+ * (not premultiplied). The gamma encoded color channels must be scaled
+ * according to the contribution and to do this it is necessary to undo
* the encoding, scale the color values, perform the composition and reencode
* the values. This is the 'PNG' mode.
*
* The alternative is to 'associate' the alpha with the color information by
- * storing color channel values that have been scaled by the alpha. The
- * advantage is that the color channels can be resampled (the image can be
- * scaled) in this form. The disadvantage is that normal practice is to store
- * linear, not (gamma) encoded, values and this requires 16-bit channels for
- * still images rather than the 8-bit channels that are just about sufficient if
- * gamma encoding is used. In addition all non-transparent pixel values,
- * including completely opaque ones, must be gamma encoded to produce the final
- * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the
- * latter being the two common names for associated alpha color channels.)
- *
- * Since it is not necessary to perform arithmetic on opaque color values so
- * long as they are not to be resampled and are in the final color space it is
- * possible to optimize the handling of alpha by storing the opaque pixels in
- * the PNG format (adjusted for the output color space) while storing partially
- * opaque pixels in the standard, linear, format. The accuracy required for
- * standard alpha composition is relatively low, because the pixels are
- * isolated, therefore typically the accuracy loss in storing 8-bit linear
- * values is acceptable. (This is not true if the alpha channel is used to
- * simulate transparency over large areas - use 16 bits or the PNG mode in
- * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is
- * treated as opaque only if the alpha value is equal to the maximum value.
+ * storing color channel values that have been scaled by the alpha.
+ * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
+ * (the latter being the two common names for associated alpha color channels).
+ *
+ * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha
+ * value is equal to the maximum value.
*
* The final choice is to gamma encode the alpha channel as well. This is
* broken because, in practice, no implementation that uses this choice
@@ -1272,68 +1261,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
/* The output_gamma value is a screen gamma in libpng terminology: it expresses
- * how to decode the output values, not how they are encoded. The values used
- * correspond to the normal numbers used to describe the overall gamma of a
- * computer display system; for example 2.2 for an sRGB conformant system. The
- * values are scaled by 100000 in the _fixed version of the API (so 220000 for
- * sRGB.)
- *
- * The inverse of the value is always used to provide a default for the PNG file
- * encoding if it has no gAMA chunk and if png_set_gamma() has not been called
- * to override the PNG gamma information.
- *
- * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
- * opaque pixels however pixels with lower alpha values are not encoded,
- * regardless of the output gamma setting.
- *
- * When the standard Porter Duff handling is requested with mode 1 the output
- * encoding is set to be linear and the output_gamma value is only relevant
- * as a default for input data that has no gamma information. The linear output
- * encoding will be overridden if png_set_gamma() is called - the results may be
- * highly unexpected!
- *
- * The following numbers are derived from the sRGB standard and the research
- * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of
- * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing
- * correction required to take account of any differences in the color
- * environment of the original scene and the intended display environment; the
- * value expresses how to *decode* the image for display, not how the original
- * data was *encoded*.
- *
- * sRGB provides a peg for the PNG standard by defining a viewing environment.
- * sRGB itself, and earlier TV standards, actually use a more complex transform
- * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is
- * limited to simple power laws.) By saying that an image for direct display on
- * an sRGB conformant system should be stored with a gAMA chunk value of 45455
- * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
- * makes it possible to derive values for other display systems and
- * environments.
- *
- * The Mac value is deduced from the sRGB based on an assumption that the actual
- * extra viewing correction used in early Mac display systems was implemented as
- * a power 1.45 lookup table.
- *
- * Any system where a programmable lookup table is used or where the behavior of
- * the final display device characteristics can be changed requires system
- * specific code to obtain the current characteristic. However this can be
- * difficult and most PNG gamma correction only requires an approximate value.
- *
- * By default, if png_set_alpha_mode() is not called, libpng assumes that all
- * values are unencoded, linear, values and that the output device also has a
- * linear characteristic. This is only very rarely correct - it is invariably
- * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
- * default if you don't know what the right answer is!
- *
- * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
- * 10.6) which used a correction table to implement a somewhat lower gamma on an
- * otherwise sRGB system.
- *
- * Both these values are reserved (not simple gamma values) in order to allow
- * more precise correction internally in the future.
- *
- * NOTE: the following values can be passed to either the fixed or floating
- * point APIs, but the floating point API will also accept floating point
- * values.
+ * how to decode the output values, not how they are encoded.
*/
#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */
#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */
@@ -1956,8 +1884,8 @@ PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
* It is unlikely that this function works correctly as of 1.6.0 and using it
* may result either in memory leaks or double free of allocated data.
*/
-PNG_EXPORTA(99, void, png_data_freer, (png_const_structrp png_ptr,
- png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED);
+PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int freer, png_uint_32 mask));
/* Assignments for png_data_freer */
#define PNG_DESTROY_WILL_FREE_DATA 1
@@ -1999,6 +1927,8 @@ PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,
#else
/* Fatal error in PNG image of libpng - can't continue */
PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);
+# define png_error(s1,s2) png_err(s1)
+# define png_chunk_error(s1,s2) png_err(s1)
#endif
#ifdef PNG_WARNINGS_SUPPORTED
@@ -2009,6 +1939,9 @@ PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,
/* Non-fatal error in libpng, chunk name is prepended to message. */
PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
png_const_charp warning_message));
+#else
+# define png_warning(s1,s2) ((void)(s1))
+# define png_chunk_warning(s1,s2) ((void)(s1))
#endif
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
@@ -2519,11 +2452,15 @@ PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,
#ifdef PNG_INFO_IMAGE_SUPPORTED
/* The "params" pointer is currently not used and is for future expansion. */
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,
int transforms, png_voidp params));
+#endif
+#ifdef PNG_WRITE_SUPPORTED
PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,
int transforms, png_voidp params));
#endif
+#endif
PNG_EXPORT(180, png_const_charp, png_get_copyright,
(png_const_structrp png_ptr));
diff --git a/pngconf.h b/pngconf.h
index 7ce5c65a0..afc0ead2b 100644
--- a/pngconf.h
+++ b/pngconf.h
@@ -1,7 +1,7 @@
/* pngconf.h - machine configurable file for libpng
*
- * libpng version 1.6.9 - February 6, 2014
+ * libpng version 1.6.10 - March 6, 2014
*
* Copyright (c) 1998-2013 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@@ -376,9 +376,11 @@
# define PNG_DEPRECATED __attribute__((__deprecated__))
# endif
# if !defined(PNG_PRIVATE)
-# if __has_extension(attribute_unavailable_with_message)
-# define PNG_PRIVATE __attribute__((__unavailable__(\
- "This function is not exported by libpng.")))
+# 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
diff --git a/pngerror.c b/pngerror.c
index 3faf27319..5876b477c 100644
--- a/pngerror.c
+++ b/pngerror.c
@@ -1,8 +1,8 @@
/* pngerror.c - stub functions for i/o and memory allocation
*
- * Last changed in libpng 1.6.8 [December 19, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ * Copyright (c) 1998-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.)
*
@@ -876,8 +876,8 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
* possible to implement without setjmp support just so long as there is some
* way to handle the error return here:
*/
-PNG_FUNCTION(void /* PRIVATE */,
-png_safe_error,(png_structp png_nonconst_ptr, png_const_charp error_message),
+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;
@@ -912,7 +912,7 @@ png_safe_error,(png_structp png_nonconst_ptr, png_const_charp error_message),
}
#ifdef PNG_WARNINGS_SUPPORTED
-void /* PRIVATE */
+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;
diff --git a/pngpread.c b/pngpread.c
index 94856e90f..6c8404e47 100644
--- a/pngpread.c
+++ b/pngpread.c
@@ -1,8 +1,8 @@
/* pngpread.c - read a png file in push mode
*
- * Last changed in libpng 1.6.8 [December 19, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ * Copyright (c) 1998-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.)
*
@@ -234,6 +234,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_error(png_ptr, "Missing PLTE before IDAT");
png_ptr->mode |= PNG_HAVE_IDAT;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
if (png_ptr->push_length == 0)
diff --git a/pngpriv.h b/pngpriv.h
index a9aa1a2de..a3fd1a46a 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -6,7 +6,7 @@
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
- * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Last changed in libpng 1.6.10 [March 6, 2014]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -254,6 +254,11 @@
extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
#endif
+#ifndef PNG_INTERNAL_CALLBACK
+# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
+ extern PNG_FUNCTION(type, (PNGCBAPI name), args, PNG_EMPTY attributes)
+#endif
+
/* If floating or fixed point APIs are disabled they may still be compiled
* internally. To handle this make sure they are declared as the appropriate
* internal extern function (otherwise the symbol prefixing stuff won't work and
@@ -373,8 +378,6 @@
#ifdef PNG_WARNINGS_SUPPORTED
# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
#else
-# define png_warning(s1,s2) ((void)(s1))
-# define png_chunk_warning(s1,s2) ((void)(s1))
# define png_warning_parameter(p,number,string) ((void)0)
# define png_warning_parameter_unsigned(p,number,format,value) ((void)0)
# define png_warning_parameter_signed(p,number,format,value) ((void)0)
@@ -382,8 +385,6 @@
# define PNG_WARNING_PARAMETERS(p)
#endif
#ifndef PNG_ERROR_TEXT_SUPPORTED
-# define png_error(s1,s2) png_err(s1)
-# define png_chunk_error(s1,s2) png_err(s1)
# define png_fixed_error(s1,s2) png_err(s1)
#endif
@@ -1883,11 +1884,11 @@ typedef struct png_control
* errors that might occur. Returns true on success, false on failure (either
* of the function or as a result of a png_error.)
*/
-PNG_INTERNAL_FUNCTION(void,png_safe_error,(png_structp png_ptr,
+PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr,
png_const_charp error_message),PNG_NORETURN);
#ifdef PNG_WARNINGS_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_safe_warning,(png_structp png_ptr,
+PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr,
png_const_charp warning_message),PNG_EMPTY);
#else
# define png_safe_warning 0/*dummy argument*/
diff --git a/pngread.c b/pngread.c
index 9ff639de2..cd9ab58b4 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1,7 +1,7 @@
/* pngread.c - read a PNG file
*
- * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Last changed in libpng 1.6.10 [March 6, 2014]
* Copyright (c) 1998-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.)
@@ -781,11 +781,14 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
png_uint_32 length = png_read_chunk_header(png_ptr);
png_uint_32 chunk_name = png_ptr->chunk_name;
- if (chunk_name == png_IHDR)
+ if (chunk_name == png_IEND)
+ png_handle_IEND(png_ptr, info_ptr, length);
+
+ else if (chunk_name == png_IHDR)
png_handle_IHDR(png_ptr, info_ptr, length);
- else if (chunk_name == png_IEND)
- png_handle_IEND(png_ptr, info_ptr, length);
+ else if (info_ptr == NULL)
+ png_crc_finish(png_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
@@ -1001,8 +1004,6 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
int transforms,
voidp params)
{
- int row;
-
if (png_ptr == NULL || info_ptr == NULL)
return;
@@ -1014,120 +1015,149 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
png_error(png_ptr, "Image is too high to process with png_read_png()");
/* -------------- image transformations start here ------------------- */
+ /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM
+ * is not implemented. This will only happen in de-configured (non-default)
+ * libpng builds. The results can be unexpected - png_read_png may return
+ * short or mal-formed rows because the transform is skipped.
+ */
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
/* Tell libpng to strip 16-bit/color files down to 8 bits per color.
*/
if (transforms & PNG_TRANSFORM_SCALE_16)
- {
/* Added at libpng-1.5.4. "strip_16" produces the same result that it
* did in earlier versions, while "scale_16" is now more accurate.
*/
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
png_set_scale_16(png_ptr);
- }
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");
#endif
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
/* If both SCALE and STRIP are required pngrtran will effectively cancel the
* latter by doing SCALE first. This is ok and allows apps not to check for
* which is supported to get the right answer.
*/
if (transforms & PNG_TRANSFORM_STRIP_16)
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
png_set_strip_16(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");
#endif
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
/* Strip alpha bytes from the input data without combining with
* the background (not recommended).
*/
if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
png_set_strip_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");
#endif
-#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
/* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
* byte into separate bytes (useful for paletted and grayscale images).
*/
if (transforms & PNG_TRANSFORM_PACKING)
+#ifdef PNG_READ_PACK_SUPPORTED
png_set_packing(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
#endif
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
/* Change the order of packed pixels to least significant bit first
* (not useful if you are using png_set_packing).
*/
if (transforms & PNG_TRANSFORM_PACKSWAP)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
png_set_packswap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
#endif
-#ifdef PNG_READ_EXPAND_SUPPORTED
/* Expand paletted colors into true RGB triplets
* Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
* Expand paletted or RGB images with transparency to full alpha
* channels so the data will be available as RGBA quartets.
*/
if (transforms & PNG_TRANSFORM_EXPAND)
- if ((png_ptr->bit_depth < 8) ||
- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
- (info_ptr->valid & PNG_INFO_tRNS))
- png_set_expand(png_ptr);
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ png_set_expand(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");
#endif
/* We don't handle background color or gamma transformation or quantizing.
*/
-#ifdef PNG_READ_INVERT_SUPPORTED
/* Invert monochrome files to have 0 as white and 1 as black
*/
if (transforms & PNG_TRANSFORM_INVERT_MONO)
+#ifdef PNG_READ_INVERT_SUPPORTED
png_set_invert_mono(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
#endif
-#ifdef PNG_READ_SHIFT_SUPPORTED
/* If you want to shift the pixel values from the range [0,255] or
* [0,65535] to the original [0,7] or [0,31], or whatever range the
* colors were originally in:
*/
- if ((transforms & PNG_TRANSFORM_SHIFT) && (info_ptr->valid & PNG_INFO_sBIT))
- png_set_shift(png_ptr, &info_ptr->sig_bit);
+ if (transforms & PNG_TRANSFORM_SHIFT)
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sBIT)
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
#endif
-#ifdef PNG_READ_BGR_SUPPORTED
/* Flip the RGB pixels to BGR (or RGBA to BGRA) */
if (transforms & PNG_TRANSFORM_BGR)
+#ifdef PNG_READ_BGR_SUPPORTED
png_set_bgr(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
#endif
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
/* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
png_set_swap_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
#endif
-#ifdef PNG_READ_SWAP_SUPPORTED
/* Swap bytes of 16-bit files to least significant byte first */
if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+#ifdef PNG_READ_SWAP_SUPPORTED
png_set_swap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
#endif
/* Added at libpng-1.2.41 */
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
/* Invert the alpha channel from opacity to transparency */
if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
png_set_invert_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
#endif
/* Added at libpng-1.2.41 */
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
/* Expand grayscale image to RGB */
if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
png_set_gray_to_rgb(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");
#endif
/* Added at libpng-1.5.4 */
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
if (transforms & PNG_TRANSFORM_EXPAND_16)
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
png_set_expand_16(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");
#endif
/* We don't handle adding filler bytes */
@@ -1150,16 +1180,17 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
{
png_uint_32 iptr;
- info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
- info_ptr->height * (sizeof (png_bytep)));
+ info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
+ info_ptr->height * (sizeof (png_bytep))));
+
for (iptr=0; iptr<info_ptr->height; iptr++)
info_ptr->row_pointers[iptr] = NULL;
info_ptr->free_me |= PNG_FREE_ROWS;
- for (row = 0; row < (int)info_ptr->height; row++)
- info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
- png_get_rowbytes(png_ptr, info_ptr));
+ for (iptr = 0; iptr < info_ptr->height; iptr++)
+ info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,
+ png_malloc(png_ptr, info_ptr->rowbytes));
}
png_read_image(png_ptr, info_ptr->row_pointers);
@@ -1168,9 +1199,7 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
/* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
png_read_end(png_ptr, info_ptr);
- PNG_UNUSED(transforms) /* Quiet compiler warnings */
PNG_UNUSED(params)
-
}
#endif /* PNG_INFO_IMAGE_SUPPORTED */
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
diff --git a/pngrtran.c b/pngrtran.c
index f0c016478..53953966e 100644
--- a/pngrtran.c
+++ b/pngrtran.c
@@ -1,7 +1,7 @@
/* pngrtran.c - transforms the data in a row for PNG readers
*
- * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Last changed in libpng 1.6.10 [March 6, 2014]
* Copyright (c) 1998-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.)
@@ -1363,12 +1363,12 @@ png_init_read_transformations(png_structrp png_ptr)
* 12) PNG_EXPAND_16
* 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
* 14) PNG_INVERT_MONO
- * 15) PNG_SHIFT
- * 16) PNG_PACK
- * 17) PNG_BGR
- * 18) PNG_PACKSWAP
- * 19) PNG_FILLER (includes PNG_ADD_ALPHA)
- * 20) PNG_INVERT_ALPHA
+ * 15) PNG_INVERT_ALPHA
+ * 16) PNG_SHIFT
+ * 17) PNG_PACK
+ * 18) PNG_BGR
+ * 19) PNG_PACKSWAP
+ * 20) PNG_FILLER (includes PNG_ADD_ALPHA)
* 21) PNG_SWAP_ALPHA
* 22) PNG_SWAP_BYTES
* 23) PNG_USER_TRANSFORM [must be last]
@@ -4907,6 +4907,11 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
png_do_invert(row_info, png_ptr->row_buf + 1);
#endif
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
#ifdef PNG_READ_SHIFT_SUPPORTED
if (png_ptr->transformations & PNG_SHIFT)
png_do_unshift(row_info, png_ptr->row_buf + 1,
@@ -4941,11 +4946,6 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
(png_uint_32)png_ptr->filler, png_ptr->flags);
#endif
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
- if (png_ptr->transformations & PNG_INVERT_ALPHA)
- png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
diff --git a/pngrutil.c b/pngrutil.c
index 062f287ed..98e952406 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -1,8 +1,8 @@
/* pngrutil.c - utilities to read a PNG file
*
- * Last changed in libpng 1.6.8 [December 19, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.10 [March 6, 2014]
+ * Copyright (c) 1998-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.)
*
@@ -227,10 +227,7 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
}
else
- {
- png_chunk_benign_error(png_ptr, "CRC error");
- return (0);
- }
+ png_chunk_error(png_ptr, "CRC error");
return (1);
}
@@ -314,16 +311,11 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
else if (warn < 2) /* else silent */
{
-#ifdef PNG_WARNINGS_SUPPORTED
if (warn)
png_chunk_warning(png_ptr, "insufficient memory to read chunk");
+
else
-#endif
- {
-#ifdef PNG_ERROR_TEXT_SUPPORTED
png_chunk_error(png_ptr, "insufficient memory to read chunk");
-#endif
- }
}
}
@@ -986,22 +978,15 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
{
if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
- {
- png_chunk_benign_error(png_ptr, "CRC error");
- }
+ return;
else
- {
- png_chunk_warning(png_ptr, "CRC error");
- return;
- }
+ png_chunk_error(png_ptr, "CRC error");
}
/* Otherwise, we (optionally) emit a warning and use the chunk. */
else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
- {
png_chunk_warning(png_ptr, "CRC error");
- }
}
#endif
@@ -1112,13 +1097,12 @@ png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
void /* PRIVATE */
png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
- unsigned int truelen;
+ unsigned int truelen, i;
+ png_byte sample_depth;
png_byte buf[4];
png_debug(1, "in png_handle_sBIT");
- buf[0] = buf[1] = buf[2] = buf[3] = 0;
-
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_chunk_error(png_ptr, "missing IHDR");
@@ -1137,10 +1121,16 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
truelen = 3;
+ sample_depth = 8;
+ }
else
+ {
truelen = png_ptr->channels;
+ sample_depth = png_ptr->bit_depth;
+ }
if (length != truelen || length > 4)
{
@@ -1149,11 +1139,19 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
return;
}
+ buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;
png_crc_read(png_ptr, buf, truelen);
if (png_crc_finish(png_ptr, 0))
return;
+ for (i=0; i<truelen; ++i)
+ if (buf[i] == 0 || buf[i] > sample_depth)
+ {
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
{
png_ptr->sig_bit.red = buf[0];
@@ -1423,7 +1421,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
(sizeof local_buffer), &length,
profile + (sizeof profile_header), &size, 0);
- /* Still expect a a buffer error because we expect
+ /* Still expect a buffer error because we expect
* there to be some tag data!
*/
if (size == 0)
diff --git a/pngtest.c b/pngtest.c
index 2c69f33e6..3b1f055db 100644
--- a/pngtest.c
+++ b/pngtest.c
@@ -667,8 +667,8 @@ set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
return 1; /* handled */
}
-static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
- png_unknown_chunkp chunk)
+static int PNGCBAPI
+read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
{
struct user_chunk_data *my_user_chunk_data =
(struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr);
@@ -1991,4 +1991,4 @@ main(void)
#endif
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_9 Your_png_h_is_not_version_1_6_9;
+typedef png_libpng_version_1_6_10 Your_png_h_is_not_version_1_6_10;
diff --git a/pngwrite.c b/pngwrite.c
index c3cb6070d..cff7864cb 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -1,7 +1,7 @@
/* pngwrite.c - general routines to write a PNG file
*
- * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Last changed in libpng 1.6.10 [March 6, 2014]
* Copyright (c) 1998-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.)
@@ -1546,81 +1546,117 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
if (png_ptr == NULL || info_ptr == NULL)
return;
+ if ((info_ptr->valid & PNG_INFO_IDAT) == 0)
+ {
+ png_app_error(png_ptr, "no rows for png_write_image to write");
+ return;
+ }
+
/* Write the file header information. */
png_write_info(png_ptr, info_ptr);
/* ------ these transformations don't touch the info structure ------- */
-#ifdef PNG_WRITE_INVERT_SUPPORTED
/* Invert monochrome pixels */
if (transforms & PNG_TRANSFORM_INVERT_MONO)
+#ifdef PNG_WRITE_INVERT_SUPPORTED
png_set_invert_mono(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
#endif
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
/* Shift the pixels up to a legal bit depth and fill in
* as appropriate to correctly scale the image.
*/
- if ((transforms & PNG_TRANSFORM_SHIFT)
- && (info_ptr->valid & PNG_INFO_sBIT))
- png_set_shift(png_ptr, &info_ptr->sig_bit);
+ if (transforms & PNG_TRANSFORM_SHIFT)
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sBIT)
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
#endif
-#ifdef PNG_WRITE_PACK_SUPPORTED
/* Pack pixels into bytes */
if (transforms & PNG_TRANSFORM_PACKING)
- png_set_packing(png_ptr);
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ png_set_packing(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
#endif
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
/* Swap location of alpha bytes from ARGB to RGBA */
if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
png_set_swap_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
#endif
+ /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into
+ * RGB, note that the code expects the input color type to be G or RGB; no
+ * alpha channel.
+ */
+ if (transforms &
+ (PNG_TRANSFORM_STRIP_FILLER_AFTER|PNG_TRANSFORM_STRIP_FILLER_BEFORE))
+ {
#ifdef PNG_WRITE_FILLER_SUPPORTED
- /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */
- if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
- png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+ if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
+ {
+ if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+ png_app_error(png_ptr,
+ "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
- else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+ /* Continue if ignored - this is the pre-1.6.10 behavior */
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+ }
+
+ else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported");
#endif
+ }
-#ifdef PNG_WRITE_BGR_SUPPORTED
/* Flip BGR pixels to RGB */
if (transforms & PNG_TRANSFORM_BGR)
+#ifdef PNG_WRITE_BGR_SUPPORTED
png_set_bgr(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
#endif
-#ifdef PNG_WRITE_SWAP_SUPPORTED
/* Swap bytes of 16-bit files to most significant byte first */
if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+#ifdef PNG_WRITE_SWAP_SUPPORTED
png_set_swap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
#endif
-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
/* Swap bits of 1, 2, 4 bit packed pixel formats */
if (transforms & PNG_TRANSFORM_PACKSWAP)
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
png_set_packswap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
#endif
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
/* Invert the alpha channel from opacity to transparency */
if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
png_set_invert_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
#endif
/* ----------------------- end of transformations ------------------- */
/* Write the bits */
- if (info_ptr->valid & PNG_INFO_IDAT)
- png_write_image(png_ptr, info_ptr->row_pointers);
+ png_write_image(png_ptr, info_ptr->row_pointers);
/* It is REQUIRED to call this to finish writing the rest of the file */
png_write_end(png_ptr, info_ptr);
- PNG_UNUSED(transforms) /* Quiet compiler warnings */
PNG_UNUSED(params)
}
#endif
diff --git a/pngwutil.c b/pngwutil.c
index 49e6a2d21..755bbdb28 100644
--- a/pngwutil.c
+++ b/pngwutil.c
@@ -2309,7 +2309,8 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
* been specified by the application, and then writes the row out with the
* chosen filter.
*/
-static void png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+static void
+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_size_t row_bytes);
#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
diff --git a/projects/vstudio/readme.txt b/projects/vstudio/readme.txt
index d88d98c38..2ee18ff2a 100644
--- a/projects/vstudio/readme.txt
+++ b/projects/vstudio/readme.txt
@@ -1,7 +1,7 @@
VisualStudio instructions
-libpng version 1.6.9 - February 6, 2014
+libpng version 1.6.10 - March 6, 2014
Copyright (c) 1998-2010 Glenn Randers-Pehrson
diff --git a/projects/vstudio/zlib.props b/projects/vstudio/zlib.props
index 9d894dd1a..8438f36fe 100644
--- a/projects/vstudio/zlib.props
+++ b/projects/vstudio/zlib.props
@@ -2,7 +2,7 @@
<!--
* zlib.props - location of zlib source
*
- * libpng version 1.6.9 - February 6, 2014
+ * libpng version 1.6.10 - March 6, 2014
*
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
*
diff --git a/scripts/README.txt b/scripts/README.txt
index f0b726788..c468d975c 100644
--- a/scripts/README.txt
+++ b/scripts/README.txt
@@ -1,9 +1,9 @@
-Makefiles for libpng version 1.6.9 - February 6, 2014
+Makefiles for libpng version 1.6.10 - March 6, 2014
pnglibconf.h.prebuilt => Stores configuration settings
makefile.linux => Linux/ELF makefile
- (gcc, creates libpng16.so.16.1.6.9)
+ (gcc, creates libpng16.so.16.1.6.10)
makefile.gcc => Generic makefile (gcc, creates static libpng.a)
makefile.knr => Archaic UNIX Makefile that converts files with
ansi2knr (Requires ansi2knr.c from
@@ -20,7 +20,7 @@ pnglibconf.h.prebuilt => Stores configuration settings
makefile.dec => DEC Alpha UNIX makefile
makefile.dj2 => DJGPP 2 makefile
makefile.elf => Linux/ELF makefile symbol versioning,
- (gcc, creates libpng16.so.16.1.6.9)
+ (gcc, creates libpng16.so.16.1.6.10)
makefile.freebsd => FreeBSD makefile
makefile.gcc => Generic gcc makefile
makefile.hpgcc => HPUX makefile using gcc
@@ -35,12 +35,12 @@ pnglibconf.h.prebuilt => Stores configuration settings
makefile.os2 => OS/2 Makefile (gcc and emx, requires libpng.def)
makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc
makefile.sggcc => Silicon Graphics (gcc,
- creates libpng16.so.16.1.6.9)
+ creates libpng16.so.16.1.6.10)
makefile.sgi => Silicon Graphics IRIX makefile (cc, creates static lib)
makefile.solaris => Solaris 2.X makefile (gcc,
- creates libpng16.so.16.1.6.9)
+ creates libpng16.so.16.1.6.10)
makefile.so9 => Solaris 9 makefile (gcc,
- creates libpng16.so.16.1.6.9)
+ creates libpng16.so.16.1.6.10)
makefile.std => Generic UNIX makefile (cc, creates static libpng.a)
makefile.sunos => Sun makefile
makefile.32sunu => Sun Ultra 32-bit makefile
diff --git a/scripts/def.dfn b/scripts/def.dfn
index 40f765430..c4b5a3818 100644
--- a/scripts/def.dfn
+++ b/scripts/def.dfn
@@ -21,7 +21,7 @@ PNG_DFN "OS2 DESCRIPTION "PNG image compression library""
PNG_DFN "OS2 CODE PRELOAD MOVEABLE DISCARDABLE"
PNG_DFN ""
PNG_DFN "EXPORTS"
-PNG_DFN ";Version 1.6.9"
+PNG_DFN ";Version 1.6.10"
#define PNG_EXPORTA(ordinal, type, name, args, attributes)\
PNG_DFN "@" SYMBOL_PREFIX "@@" name "@"
diff --git a/scripts/dfn.awk b/scripts/dfn.awk
index 89b92d5d9..afa498cb5 100644
--- a/scripts/dfn.awk
+++ b/scripts/dfn.awk
@@ -1,9 +1,9 @@
#!/bin/awk -f
# scripts/dfn.awk - process a .dfn file
#
-# last changed in libpng version 1.5.14 - February 4, 2013
+# last changed in libpng version 1.5.19 - $RDATE%
#
-# Copyright (c) 2013-2013 Glenn Randers-Pehrson
+# Copyright (c) 2013-2014 Glenn Randers-Pehrson
#
# This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer
@@ -25,7 +25,7 @@ BEGIN{
# The output file must be specified before any input:
NR==1 && out == "/dev/null" {
print "out=output.file must be given on the command line"
- # but continue without setting the error code, this allows the
+ # but continue without setting the error code; this allows the
# script to be checked easily
}
@@ -61,14 +61,14 @@ $1 ~ /^PNG_DFN_END_SORT/{
}
/^[^"]*PNG_DFN *".*"[^"]*$/{
- # A definition line, apparently correctly formated, extract the
+ # A definition line, apparently correctly formatted; extract the
# definition then replace any doubled "" that remain with a single
# double quote. Notice that the original doubled double quotes
# may have been split by tokenization
#
- # Sometimes GCC splits the PNG_DFN lines, we know this has happened
+ # Sometimes GCC splits the PNG_DFN lines; we know this has happened
# if the quotes aren't closed and must read another line. In this
- # case it is essential to reject lines that start '#' because those
+ # case it is essential to reject lines that start with '#' because those
# are introduced #line directives.
orig=$0
line=$0
@@ -126,13 +126,13 @@ $1 ~ /^PNG_DFN_END_SORT/{
else while (1) {
if (getline nextline) {
# If the line starts with '#' it is a preprocesor line directive
- # from cc -E, skip it:
+ # from cc -E; skip it:
if (nextline !~ /^#/) {
line = line " " nextline
break
}
} else {
- # This is end-of-input - probably a missig "@ on the first line:
+ # This is end-of-input - probably a missing "@ on the first line:
print "line", lineno ": unbalanced @\" ... \"@ pair"
err=1
next
@@ -144,7 +144,7 @@ $1 ~ /^PNG_DFN_END_SORT/{
}
# Attempt to remove a trailing " (not preceded by '@') - if this can
- # be done stop now, if not assume a split line again
+ # be done, stop now; if not assume a split line again
if (sub(/"[^"]*$/, "", line))
break
@@ -189,7 +189,7 @@ $1 ~ /^PNG_DFN_END_SORT/{
}
/PNG_DFN/{
- print "line", NR, "incorrectly formated PNG_DFN line:"
+ print "line", NR, "incorrectly formatted PNG_DFN line:"
print $0
err = 1
}
diff --git a/scripts/intprefix.dfn b/scripts/intprefix.dfn
index 790bdfee9..fa59f88e9 100644
--- a/scripts/intprefix.dfn
+++ b/scripts/intprefix.dfn
@@ -15,5 +15,8 @@
#define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
PNG_DFN "@" name "@"
+#define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
+ PNG_DFN "@" name "@"
+
#define PNGPREFIX_H /* self generation */
#include "../pngpriv.h"
diff --git a/scripts/libpng-config-head.in b/scripts/libpng-config-head.in
index 51b861e63..462de7479 100755
--- a/scripts/libpng-config-head.in
+++ b/scripts/libpng-config-head.in
@@ -11,7 +11,7 @@
# Modeled after libxml-config.
-version=1.6.9
+version=1.6.10
prefix=""
libdir=""
libs=""
diff --git a/scripts/libpng.pc.in b/scripts/libpng.pc.in
index 9395df482..1ae258b56 100644
--- a/scripts/libpng.pc.in
+++ b/scripts/libpng.pc.in
@@ -5,6 +5,6 @@ includedir=@includedir@/libpng16
Name: libpng
Description: Loads and saves PNG files
-Version: 1.6.9
+Version: 1.6.10
Libs: -L${libdir} -lpng16
Cflags: -I${includedir}
diff --git a/scripts/makefile.cegcc b/scripts/makefile.cegcc
index f2179b76f..e2ff2739b 100644
--- a/scripts/makefile.cegcc
+++ b/scripts/makefile.cegcc
@@ -23,7 +23,7 @@
VERMAJ = 1
VERMIN = 6
-VERMIC = 9
+VERMIC = 10
VER = $(VERMAJ).$(VERMIN).$(VERMIC)
NAME = libpng
PACKAGE = $(NAME)-$(VER)
diff --git a/scripts/makefile.linux b/scripts/makefile.linux
index 57272498f..73a30c873 100644
--- a/scripts/makefile.linux
+++ b/scripts/makefile.linux
@@ -10,7 +10,7 @@
# Library name:
LIBNAME = libpng16
PNGMAJ = 16
-RELEASE = 9
+RELEASE = 10
# Shared library names:
LIBSO=$(LIBNAME).so
diff --git a/scripts/makefile.msys b/scripts/makefile.msys
index 0a5727f14..69fbb4d68 100644
--- a/scripts/makefile.msys
+++ b/scripts/makefile.msys
@@ -18,7 +18,7 @@ exec_prefix=$(prefix)
# Library name:
LIBNAME = libpng16
PNGMAJ = 16
-RELEASE = 9
+RELEASE = 10
# Shared library names:
LIBSO=$(LIBNAME).dll
diff --git a/scripts/makefile.ne12bsd b/scripts/makefile.ne12bsd
index 649acdde4..783e5d53d 100644
--- a/scripts/makefile.ne12bsd
+++ b/scripts/makefile.ne12bsd
@@ -17,7 +17,7 @@ INCSDIR=${LOCALBASE}/include/libpng16
LIB= png16
SHLIB_MAJOR= 0
-SHLIB_MINOR= 1.6.9
+SHLIB_MINOR= 1.6.10
SRCS= png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
pngwtran.c pngmem.c pngerror.c pngpread.c
diff --git a/scripts/makefile.netbsd b/scripts/makefile.netbsd
index a16dae816..af4eb934e 100644
--- a/scripts/makefile.netbsd
+++ b/scripts/makefile.netbsd
@@ -17,7 +17,7 @@ INCSDIR=${LOCALBASE}/include
LIB= png
SHLIB_MAJOR= 16
-SHLIB_MINOR= 1.6.9
+SHLIB_MINOR= 1.6.10
SRCS= png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
pngwtran.c pngmem.c pngerror.c pngpread.c
diff --git a/scripts/makefile.openbsd b/scripts/makefile.openbsd
index 69b1ecc50..c61fa2ef7 100644
--- a/scripts/makefile.openbsd
+++ b/scripts/makefile.openbsd
@@ -11,7 +11,7 @@ LIBDIR= ${PREFIX}/lib
MANDIR= ${PREFIX}/man/cat
SHLIB_MAJOR= 16
-SHLIB_MINOR= 1.6.9
+SHLIB_MINOR= 1.6.10
LIB= png
SRCS= png.c pngerror.c pngget.c pngmem.c pngpread.c \
diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa
index b173bb19c..4d4ea8a3b 100755
--- a/scripts/pnglibconf.dfa
+++ b/scripts/pnglibconf.dfa
@@ -164,7 +164,7 @@ logunsupported = 1
# NONE
-# Note that PNG_USR_CONFIG only has an effect when building
+# Note that PNG_USER_CONFIG only has an effect when building
# pnglibconf.h
setting USER_CONFIG
@@ -578,8 +578,9 @@ option GAMMA disabled
option COLORSPACE enables GAMMA disabled
# When an ICC profile is read, or png_set, it will be checked for a match
-# against known sRGB profiles if the sRGB handling is enabled. This
-# setting controls how much work is done during the check:
+# against known sRGB profiles if the sRGB handling is enabled. The
+# PNG_sRGB_PROFILE_CHECKS setting controls how much work is done during the
+# check:
#
# 0: Just validate the profile MD5 signature if present, otherwise use
# the checks in option 1.
diff --git a/scripts/pnglibconf.h.prebuilt b/scripts/pnglibconf.h.prebuilt
index 8ad56dbb5..9d4ef5a16 100644
--- a/scripts/pnglibconf.h.prebuilt
+++ b/scripts/pnglibconf.h.prebuilt
@@ -1,8 +1,8 @@
-/* libpng 1.6.9 STANDARD API DEFINITION */
+/* libpng 1.6.10 STANDARD API DEFINITION */
/* pnglibconf.h - library build configuration */
-/* Libpng version 1.6.9 - February 6, 2014 */
+/* Libpng version 1.6.10 - March 6, 2014 */
/* Copyright (c) 1998-2013 Glenn Randers-Pehrson */
diff --git a/scripts/symbols.def b/scripts/symbols.def
index 61e47698b..f509932ff 100644
--- a/scripts/symbols.def
+++ b/scripts/symbols.def
@@ -1,4 +1,4 @@
-;Version 1.6.9
+;Version 1.6.10
;--------------------------------------------------------------
; LIBPNG symbol list as a Win32 DEF file
; Contains all the symbols that can be exported from libpng
diff --git a/tests/pngimage-full b/tests/pngimage-full
new file mode 100755
index 000000000..f5eb9895e
--- /dev/null
+++ b/tests/pngimage-full
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec ./pngimage --exhaustive --log "${srcdir}/contrib/pngsuite/"*.png
diff --git a/tests/pngimage-quick b/tests/pngimage-quick
new file mode 100755
index 000000000..2d4b5db22
--- /dev/null
+++ b/tests/pngimage-quick
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec ./pngimage --log "${srcdir}/contrib/pngsuite/"*.png