diff --git a/ANNOUNCE b/ANNOUNCE index 179b6010c..7c684d27e 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.5.6beta01 - September 22, 2011 +Libpng 1.5.6beta02 - September 22, 2011 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -9,99 +9,36 @@ Files available for download: Source files with LF line endings (for Unix/Linux) and with a "configure" script - 1.5.6beta01.tar.xz (LZMA-compressed, recommended) - 1.5.6beta01.tar.gz - 1.5.6beta01.tar.bz2 + 1.5.6beta02.tar.xz (LZMA-compressed, recommended) + 1.5.6beta02.tar.gz + 1.5.6beta02.tar.bz2 Source files with CRLF line endings (for Windows), without the "configure" script - lp156b01.7z (LZMA-compressed, recommended) - lp156b01.zip + lp156b02.7z (LZMA-compressed, recommended) + lp156b02.zip Other information: - 1.5.6beta01-README.txt - 1.5.6beta01-LICENSE.txt + 1.5.6beta02-README.txt + 1.5.6beta02-LICENSE.txt -Changes since the last public release (1.5.4): +Changes since the last public release (1.5.5): -Version 1.5.5beta01 [July 13, 2011] - Fixed some typos and made other minor changes in the manual. - Updated contrib/pngminus/makefile.std (Samuli Souminen) - -Version 1.5.5beta02 [July 14, 2011] - Revised Makefile.am and Makefile.in to look in the right directory for - pnglibconf.h.prebuilt - -Version 1.5.5beta03 [July 27, 2011] - Enabled compilation with g++ compiler. This compiler does not recognize - the file extension, so it always compiles with C++ rules. Made minor - changes to pngrutil.c to cast results where C++ expects it but C does not. - Minor editing of libpng.3 and libpng-manual.txt. - -Version 1.5.5beta04 [July 29, 2011] - Revised CMakeLists.txt (Clifford Yapp) - Updated commentary about the png_rgb_to_gray() default coefficients - in the manual and in pngrtran.c - -Version 1.5.5beta05 [August 17, 2011] - Prevent unexpected API exports from non-libpng DLLs on Windows. The "_DLL" - is removed from the test of whether a DLL is being built (this erroneously - caused the libpng APIs to be marked as DLL exports in static builds under - Microsoft Visual Studio). Almost all of the libpng building configuration - is moved from pngconf.h to pngpriv.h, but PNG_DLL_EXPORT remains in - pngconf.h, though, so that it is colocated with the import definition (it - is no longer used anywhere in the installed headers). The VStudio project - definitions have been cleaned up: "_USRDLL" has been removed from the - static library builds (this was incorrect), and PNG_USE_DLL has been added - to pngvalid to test the functionality (pngtest does not supply it, - deliberately). The spurious "_EXPORTS" has been removed from the - libpng build (all these errors were a result of copy/paste between project - configurations.) - Added new types and internal functions for CIE RGB end point handling to - pngpriv.h (functions yet to be implemented). - -Version 1.5.5beta06 [August 26, 2011] - Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt - (Clifford Yap) - Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler): - The rgb_to_gray code had errors when combined with gamma correction. - Some pixels were treated as true grey when they weren't and such pixels - and true grey ones were not gamma corrected (the original value of the - red component was used instead). APIs to get and set cHRM using color - space end points have been added and the rgb_to_gray code that defaults - based on cHRM, and the divide-by-zero bug in png_handle_cHRM (CERT - VU#477046, CVE-2011-3328, introduced in 1.5.4) have been corrected. - A considerable number of tests has been added to pngvalid for the - rgb_to_gray transform. - Arithmetic errors in rgb_to_gray whereby the calculated gray value was - truncated to the bit depth rather than rounded have been fixed except in - the 8-bit non-gamma-corrected case (where consistency seems more important - than correctness.) The code still has considerable inaccuracies in the - 8-bit case because 8-bit linear arithmetic is used. - -Version 1.5.5beta07 [September 7, 2011] - Added "$(ARCH)" option to makefile.darwin - Added SunOS support to configure.ac and Makefile.am - Changed png_chunk_benign_error() to png_warning() in png.c, in - png_XYZ_from_xy_checked(). - -Version 1.5.5beta08 [September 10, 2011] - Fixed 64-bit compilation errors (gcc). The errors fixed relate - to conditions where types that are 32 bits in the GCC 32-bit - world (uLong and png_size_t) become 64 bits in the 64-bit - world. This produces potential truncation errors that the - compiler correctly flags. - Relocated new HAVE_SOLARIS_LD definition in configure.ac - Constant changes for 64-bit compatibility (removal of L suffixes). The - 16-bit cases still use "L" as we don't have a 16-bit test system. - -Version 1.5.5rc01 [September 17, 2011] - Removed "L" suffixes from constants in pngpriv.h - -Version 1.5.5 [September 22, 2011] - No changes. +Version 1.5.6beta01 [September 22, 2011] + Fixed some 64-bit type conversion warnings in pngrtran.c + Moved row_info from png_struct to a local variable. + The various interlace mask arrays have been made into arrays of + bytes and made PNG_CONST and static (previously some arrays were + marked PNG_CONST and some weren't). + Additional checks have been added to the transform code to validate the + pixel depths after the transforms on both read and write. + Removed some redundant code from pngwrite.c, in png_desgtroy_write_struct(). + Changed chunk reading/writing code to use png_uint_32 instead of png_byte[4]. + This removes the need to allocate temporary strings for chunk names on + the stack in the read/write code. Unknown chunk handling still uses the + string form because this is exposed in the API. Send comments/corrections/commendations to png-mng-implement at lists.sf.net: (subscription required; visit diff --git a/CHANGES b/CHANGES index dd31a96ae..6556584ee 100644 --- a/CHANGES +++ b/CHANGES @@ -3575,18 +3575,34 @@ Version 1.5.5beta08 [September 10, 2011] Fixed 64-bit compilation errors (gcc). The errors fixed relate to conditions where types that are 32 bits in the GCC 32-bit world (uLong and png_size_t) become 64 bits in the 64-bit - world. This produces potential truncation errors that the + world. This produces potential truncation errors which the compiler correctly flags. Relocated new HAVE_SOLARIS_LD definition in configure.ac Constant changes for 64-bit compatibility (removal of L suffixes). The 16-bit cases still use "L" as we don't have a 16-bit test system. -Version 1.5.5rc01 [September 17, 2011] - Removed "L" suffixes from constants in pngpriv.h +Version 1.5.5rc01 [September 15, 2011] + Removed "L" suffixes in pngpriv.h Version 1.5.5 [September 22, 2011] No changes. +Version 1.5.6beta01 [September 22, 2011] + Fixed some 64-bit type conversion warnings in pngrtran.c + Moved row_info from png_struct to a local variable. + The various interlace mask arrays have been made into arrays of + bytes and made PNG_CONST and static (previously some arrays were + marked PNG_CONST and some weren't). + Additional checks have been added to the transform code to validate the + pixel depths after the transforms on both read and write. + Removed some redundant code from pngwrite.c, in png_destroy_write_struct(). + Changed chunk reading/writing code to use png_uint_32 instead of png_byte[4]. + This removes the need to allocate temporary strings for chunk names on + the stack in the read/write code. Unknown chunk handling still uses the + string form because this is exposed in the API. + +Version 1.5.6beta02 [September 22, 2011] + 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 4bcd79428..9b828dd95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -262,7 +262,7 @@ CREATE_SYMLINK(${PNGLIB_NAME}-config libpng-config) # SET UP LINKS if(PNG_SHARED) set_target_properties(${PNG_LIB_NAME} PROPERTIES -# VERSION 15.${PNGLIB_RELEASE}.1.5.6beta01 +# VERSION 15.${PNGLIB_RELEASE}.1.5.6beta02 VERSION 15.${PNGLIB_RELEASE}.0 SOVERSION 15 CLEAN_DIRECT_OUTPUT 1) diff --git a/LICENSE b/LICENSE index 586268af9..f5664ea9f 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.5.6beta01, September 22, 2011, are +libpng versions 1.2.6, August 15, 2004, through 1.5.6beta02, September 22, 2011, are Copyright (c) 2004, 2006-2011 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 diff --git a/README b/README index 31398bded..25d884417 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -README for libpng version 1.5.6beta01 - September 22, 2011 (shared library 15.0) +README for libpng version 1.5.6beta02 - September 22, 2011 (shared library 15.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/configure b/configure index e22b3fc84..a1ac4f89a 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for libpng 1.5.6beta01. +# Generated by GNU Autoconf 2.68 for libpng 1.5.6beta02. # # Report bugs to . # @@ -570,8 +570,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libpng' PACKAGE_TARNAME='libpng' -PACKAGE_VERSION='1.5.6beta01' -PACKAGE_STRING='libpng 1.5.6beta01' +PACKAGE_VERSION='1.5.6beta02' +PACKAGE_STRING='libpng 1.5.6beta02' PACKAGE_BUGREPORT='png-mng-implement@lists.sourceforge.net' PACKAGE_URL='' @@ -1308,7 +1308,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libpng 1.5.6beta01 to adapt to many kinds of systems. +\`configure' configures libpng 1.5.6beta02 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1378,7 +1378,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libpng 1.5.6beta01:";; + short | recursive ) echo "Configuration of libpng 1.5.6beta02:";; esac cat <<\_ACEOF @@ -1486,7 +1486,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libpng configure 1.5.6beta01 +libpng configure 1.5.6beta02 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1909,7 +1909,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libpng $as_me 1.5.6beta01, which was +It was created by libpng $as_me 1.5.6beta02, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2724,7 +2724,7 @@ fi # Define the identity of the package. PACKAGE='libpng' - VERSION='1.5.6beta01' + VERSION='1.5.6beta02' cat >>confdefs.h <<_ACEOF @@ -2788,7 +2788,7 @@ fi -PNGLIB_VERSION=1.5.6beta01 +PNGLIB_VERSION=1.5.6beta02 PNGLIB_MAJOR=1 PNGLIB_MINOR=5 PNGLIB_RELEASE=6 @@ -13073,7 +13073,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libpng $as_me 1.5.6beta01, which was +This file was extended by libpng $as_me 1.5.6beta02, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13139,7 +13139,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libpng config.status 1.5.6beta01 +libpng config.status 1.5.6beta02 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 3a9376341..144181d98 100644 --- a/configure.ac +++ b/configure.ac @@ -18,12 +18,12 @@ AC_PREREQ(2.59) dnl Version number stuff here: -AC_INIT([libpng], [1.5.6beta01], [png-mng-implement@lists.sourceforge.net]) +AC_INIT([libpng], [1.5.6beta02], [png-mng-implement@lists.sourceforge.net]) AM_INIT_AUTOMAKE dnl stop configure from automagically running automake AM_MAINTAINER_MODE -PNGLIB_VERSION=1.5.6beta01 +PNGLIB_VERSION=1.5.6beta02 PNGLIB_MAJOR=1 PNGLIB_MINOR=5 PNGLIB_RELEASE=6 diff --git a/libpng-manual.txt b/libpng-manual.txt index b17753f4e..a80d7eb45 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.5.6beta01 - September 22, 2011 + libpng version 1.5.6beta02 - September 22, 2011 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2011 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.5.6beta01 - September 22, 2011 + libpng versions 0.97, January 1998, through 1.5.6beta02 - September 22, 2011 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2011 Glenn Randers-Pehrson @@ -4566,7 +4566,7 @@ 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.5.6beta01 are Y2K compliant. It is my belief that earlier +upward through 1.5.6beta02 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has three year fields. One is a 2-byte unsigned integer that diff --git a/libpng.3 b/libpng.3 index c9ad0dd05..f02668db0 100644 --- a/libpng.3 +++ b/libpng.3 @@ -1,6 +1,6 @@ .TH LIBPNG 3 "September 22, 2011" .SH NAME -libpng \- Portable Network Graphics (PNG) Reference Library 1.5.6beta01 +libpng \- Portable Network Graphics (PNG) Reference Library 1.5.6beta02 .SH SYNOPSIS \fI\fB @@ -977,7 +977,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.5.6beta01 - September 22, 2011 + libpng version 1.5.6beta02 - September 22, 2011 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2011 Glenn Randers-Pehrson @@ -988,7 +988,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.5.6beta01 - September 22, 2011 + libpng versions 0.97, January 1998, through 1.5.6beta02 - September 22, 2011 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2011 Glenn Randers-Pehrson @@ -5544,7 +5544,7 @@ 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.5.6beta01 are Y2K compliant. It is my belief that earlier +upward through 1.5.6beta02 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has three year fields. One is a 2-byte unsigned integer that @@ -5743,6 +5743,7 @@ the first widely used release: 1.5.5beta01-08 15 10505 15.so.15.5[.0] 1.5.5rc01 15 10505 15.so.15.5[.0] 1.5.5 15 10505 15.so.15.5[.0] + 1.5.6beta01-02 15 10506 15.so.15.6[.0] Henceforth the source version will match the shared-library minor and patch numbers; the shared-library major version number will be @@ -5799,7 +5800,7 @@ possible without all of you. Thanks to Frank J. T. Wojcik for helping with the documentation. -Libpng version 1.5.6beta01 - September 22, 2011: +Libpng version 1.5.6beta02 - September 22, 2011: Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc. Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). @@ -5822,7 +5823,7 @@ this sentence. This code is released under the libpng license. -libpng versions 1.2.6, August 15, 2004, through 1.5.6beta01, September 22, 2011, are +libpng versions 1.2.6, August 15, 2004, through 1.5.6beta02, September 22, 2011, 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 diff --git a/libpngpf.3 b/libpngpf.3 index 68f3b4fa9..6c9ccd5fa 100644 --- a/libpngpf.3 +++ b/libpngpf.3 @@ -1,6 +1,6 @@ .TH LIBPNGPF 3 "September 22, 2011" .SH NAME -libpng \- Portable Network Graphics (PNG) Reference Library 1.5.6beta01 +libpng \- Portable Network Graphics (PNG) Reference Library 1.5.6beta02 (private functions) .SH SYNOPSIS \fB#include \fI"pngpriv.h" diff --git a/png.c b/png.c index 6d073c633..4f8071063 100644 --- a/png.c +++ b/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.5.5 [(PENDING RELEASE)] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -14,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_5_6beta01 Your_png_h_is_not_version_1_5_6beta01; +typedef png_libpng_version_1_5_6beta02 Your_png_h_is_not_version_1_5_6beta02; /* 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 @@ -121,14 +121,14 @@ png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length) { int need_crc = 1; - if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ + if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) { if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) need_crc = 0; } - else /* critical */ + else /* critical */ { if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) need_crc = 0; @@ -645,13 +645,13 @@ png_get_copyright(png_const_structp png_ptr) #else # ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.5.6beta01 - September 22, 2011" PNG_STRING_NEWLINE \ + "libpng version 1.5.6beta02 - September 22, 2011" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2011 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.5.6beta01 - September 22, 2011\ + return "libpng version 1.5.6beta02 - September 22, 2011\ Copyright (c) 1998-2011 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; @@ -698,25 +698,43 @@ png_get_header_version(png_const_structp png_ptr) #endif } -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED int PNGAPI png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) { /* Check chunk_name and return "keep" value if it's on the list, else 0 */ - int i; - png_bytep p; - if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0) - return 0; + png_const_bytep p, p_end; - p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5; - for (i = png_ptr->num_chunk_list; i; i--, p -= 5) + if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list <= 0) + return PNG_HANDLE_CHUNK_AS_DEFAULT; + + p_end = png_ptr->chunk_list; + p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ + + /* The code is the fifth byte after each four byte string. Historically this + * code was always searched from the end of the list, so it should continue + * to do so in case there are duplicated entries. + */ + do /* num_chunk_list > 0, so at least one */ + { + p -= 5; if (!png_memcmp(chunk_name, p, 4)) - return ((int)*(p + 4)); - return 0; + return p[4]; + } + while (p > p_end); + + return PNG_HANDLE_CHUNK_AS_DEFAULT; } -# endif -#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +int /* PRIVATE */ +png_chunk_unknown_handling(png_structp png_ptr, png_uint_32 chunk_name) +{ + png_byte chunk_string[5]; + + PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); + return png_handle_as_unknown(png_ptr, chunk_string); +} +#endif #ifdef PNG_READ_SUPPORTED /* This function, added to libpng-1.0.6g, is untested. */ diff --git a/png.h b/png.h index bb551d6df..b2ab3c9be 100644 --- a/png.h +++ b/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.5.6beta01 - September 22, 2011 + * libpng version 1.5.6beta02 - September 22, 2011 * Copyright (c) 1998-2011 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.5.6beta01 - September 22, 2011: Glenn + * libpng versions 0.97, January 1998, through 1.5.6beta02 - September 22, 2011: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: @@ -160,6 +160,7 @@ * 1.5.5beta01-08 15 10505 15.so.15.5[.0] * 1.5.5rc01 15 10505 15.so.15.5[.0] * 1.5.5 15 10505 15.so.15.5[.0] + * 1.5.6beta01-02 15 10506 15.so.15.6[.0] * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be @@ -191,7 +192,7 @@ * * This code is released under the libpng license. * - * libpng versions 1.2.6, August 15, 2004, through 1.5.6beta01, September 22, 2011, are + * libpng versions 1.2.6, August 15, 2004, through 1.5.6beta02, September 22, 2011, are * Copyright (c) 2004, 2006-2011 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: @@ -309,7 +310,7 @@ * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.5.6beta01 are Y2K compliant. It is my belief that + * upward through 1.5.6beta02 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 @@ -364,9 +365,9 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.5.6beta01" +#define PNG_LIBPNG_VER_STRING "1.5.6beta02" #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.5.6beta01 - September 22, 2011\n" + " libpng version 1.5.6beta02 - September 22, 2011\n" #define PNG_LIBPNG_VER_SONUM 15 #define PNG_LIBPNG_VER_DLLNUM 15 @@ -379,7 +380,7 @@ * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ -#define PNG_LIBPNG_VER_BUILD 01 +#define PNG_LIBPNG_VER_BUILD 02 /* Release Status */ #define PNG_LIBPNG_BUILD_ALPHA 1 @@ -526,7 +527,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_5_6beta01; +typedef char* png_libpng_version_1_5_6beta02; /* Three color definitions. The order of the red, green, and blue, (and the * exact size) is not important, although the size of the fields need to @@ -2305,15 +2306,21 @@ PNG_EXPORT(171, void, png_set_sCAL_s, /* Provide a list of chunks and how they are to be handled, if the built-in handling or default unknown chunk handling is not desired. Any chunks not listed will be handled in the default manner. The IHDR and IEND chunks - must not be listed. - keep = 0: follow default behavior - = 1: do not keep - = 2: keep only if safe-to-copy - = 3: keep even if unsafe-to-copy + must not be listed. Because this turns off the default handling for chunks + that would otherwise be recognized the behavior of libpng transformations may + well become incorrect! + keep = 0: PNG_HANDLE_CHUNK_AS_DEFAULT: follow default behavior + = 1: PNG_HANDLE_CHUNK_NEVER: do not keep + = 2: PNG_HANDLE_CHUNK_IF_SAFE: keep only if safe-to-copy + = 3: PNG_HANDLE_CHUNK_ALWAYS: keep even if unsafe-to-copy */ PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structp png_ptr, int keep, png_const_bytep chunk_list, int num_chunks)); + +/* The handling code is returned; the result is therefore true (non-zero) if + * special handling is required, false for the default handling. + */ PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, png_const_bytep chunk_name)); #endif diff --git a/pngconf.h b/pngconf.h index 851a6e5c3..e24a2f9c3 100644 --- a/pngconf.h +++ b/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.5.6beta01 - September 22, 2011 + * libpng version 1.5.6beta02 - September 22, 2011 * * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) diff --git a/pngerror.c b/pngerror.c index 4d4cebafa..e77c1e645 100644 --- a/pngerror.c +++ b/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.5.4 [July 7, 2011] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -374,11 +374,14 @@ static void /* PRIVATE */ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp error_message) { - int iout = 0, iin = 0; + png_uint_32 chunk_name = png_ptr->chunk_name; + int iout = 0, ishift = 24; - while (iin < 4) + while (ishift >= 0) { - int c = png_ptr->chunk_name[iin++]; + int c = (int)(chunk_name >> ishift) & 0xff; + + ishift -= 8; if (isnonalpha(c)) { buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; @@ -389,7 +392,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp else { - buffer[iout++] = (png_byte)c; + buffer[iout++] = (char)c; } } @@ -398,10 +401,11 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp else { + int iin = 0; + buffer[iout++] = ':'; buffer[iout++] = ' '; - iin = 0; while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') buffer[iout++] = error_message[iin++]; diff --git a/pngget.c b/pngget.c index 770c123e7..433092190 100644 --- a/pngget.c +++ b/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.5.5 [(PENDING RELEASE)] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -950,9 +950,8 @@ png_get_text(png_const_structp png_ptr, png_const_infop info_ptr, { if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) { - png_debug1(1, "in %s retrieval function", - (png_ptr->chunk_name[0] == '\0' ? "text" : - (png_const_charp)png_ptr->chunk_name)); + png_debug1(1, "in 0x%lx retrieval function", + (unsigned long)png_ptr->chunk_name); if (text_ptr != NULL) *text_ptr = info_ptr->text; @@ -1111,16 +1110,14 @@ png_get_io_state (png_structp png_ptr) png_uint_32 PNGAPI png_get_io_chunk_type (png_const_structp png_ptr) { - return ((png_ptr->chunk_name[0] << 24) + - (png_ptr->chunk_name[1] << 16) + - (png_ptr->chunk_name[2] << 8) + - (png_ptr->chunk_name[3])); + return png_ptr->chunk_name; } png_const_bytep PNGAPI png_get_io_chunk_name (png_structp png_ptr) { - return png_ptr->chunk_name; + PNG_CSTRING_FROM_CHUNK(png_ptr->io_chunk_string, png_ptr->chunk_name); + return png_ptr->io_chunk_string; } #endif /* ?PNG_IO_STATE_SUPPORTED */ diff --git a/pngpread.c b/pngpread.c index a50292a76..3c666dcbe 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,7 +1,7 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.5.2 [March 31, 2011] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -208,61 +208,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) void /* PRIVATE */ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) { - PNG_IHDR; - PNG_IDAT; - PNG_IEND; - PNG_PLTE; -#ifdef PNG_READ_bKGD_SUPPORTED - PNG_bKGD; -#endif -#ifdef PNG_READ_cHRM_SUPPORTED - PNG_cHRM; -#endif -#ifdef PNG_READ_gAMA_SUPPORTED - PNG_gAMA; -#endif -#ifdef PNG_READ_hIST_SUPPORTED - PNG_hIST; -#endif -#ifdef PNG_READ_iCCP_SUPPORTED - PNG_iCCP; -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - PNG_iTXt; -#endif -#ifdef PNG_READ_oFFs_SUPPORTED - PNG_oFFs; -#endif -#ifdef PNG_READ_pCAL_SUPPORTED - PNG_pCAL; -#endif -#ifdef PNG_READ_pHYs_SUPPORTED - PNG_pHYs; -#endif -#ifdef PNG_READ_sBIT_SUPPORTED - PNG_sBIT; -#endif -#ifdef PNG_READ_sCAL_SUPPORTED - PNG_sCAL; -#endif -#ifdef PNG_READ_sRGB_SUPPORTED - PNG_sRGB; -#endif -#ifdef PNG_READ_sPLT_SUPPORTED - PNG_sPLT; -#endif -#ifdef PNG_READ_tEXt_SUPPORTED - PNG_tEXt; -#endif -#ifdef PNG_READ_tIME_SUPPORTED - PNG_tIME; -#endif -#ifdef PNG_READ_tRNS_SUPPORTED - PNG_tRNS; -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - PNG_zTXt; -#endif + png_uint_32 chunk_name; /* First we make sure we have enough data for the 4 byte chunk name * and the 4 byte chunk length before proceeding with decoding the @@ -273,6 +219,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; + png_byte chunk_tag[4]; if (png_ptr->buffer_size < 8) { @@ -283,16 +230,19 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_fill_buffer(png_ptr, chunk_length, 4); png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); png_reset_crc(png_ptr); - png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_crc_read(png_ptr, chunk_tag, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); png_check_chunk_name(png_ptr, png_ptr->chunk_name); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } - if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + chunk_name = png_ptr->chunk_name; + + if (chunk_name == png_IDAT) if (png_ptr->mode & PNG_AFTER_IDAT) png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + if (chunk_name == png_IHDR) { if (png_ptr->push_length != 13) png_error(png_ptr, "Invalid IHDR length"); @@ -306,7 +256,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); } - else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + else if (chunk_name == png_IEND) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -321,7 +271,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) + else if (png_chunk_unknown_handling(png_ptr, chunk_name)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -329,15 +279,15 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) return; } - if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + if (chunk_name == png_IDAT) png_ptr->mode |= PNG_HAVE_IDAT; png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); - if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + if (chunk_name == png_PLTE) png_ptr->mode |= PNG_HAVE_PLTE; - else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + else if (chunk_name == png_IDAT) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); @@ -349,7 +299,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif - else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + else if (chunk_name == png_PLTE) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -359,7 +309,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); } - else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + else if (chunk_name == png_IDAT) { /* If we reach an IDAT chunk, this means we have read all of the * header chunks, and we can start reading the image (or if this @@ -395,7 +345,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #ifdef PNG_READ_gAMA_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + else if (png_ptr->chunk_name == png_gAMA) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -408,7 +358,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_sBIT_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + else if (png_ptr->chunk_name == png_sBIT) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -421,7 +371,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_cHRM_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + else if (png_ptr->chunk_name == png_cHRM) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -434,7 +384,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_sRGB_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + else if (chunk_name == png_sRGB) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -447,7 +397,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_iCCP_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + else if (png_ptr->chunk_name == png_iCCP) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -460,7 +410,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_sPLT_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + else if (chunk_name == png_sPLT) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -473,7 +423,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_tRNS_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + else if (chunk_name == png_tRNS) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -486,7 +436,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_bKGD_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + else if (chunk_name == png_bKGD) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -499,7 +449,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_hIST_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + else if (chunk_name == png_hIST) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -512,7 +462,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_pHYs_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + else if (chunk_name == png_pHYs) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -525,7 +475,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_oFFs_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + else if (chunk_name == png_oFFs) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -538,7 +488,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_pCAL_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + else if (chunk_name == png_pCAL) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -551,7 +501,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_sCAL_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + else if (chunk_name == png_sCAL) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -564,7 +514,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_tIME_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + else if (chunk_name == png_tIME) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -577,7 +527,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_tEXt_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + else if (chunk_name == png_tEXt) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -590,7 +540,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_zTXt_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + else if (chunk_name == png_zTXt) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -603,7 +553,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_iTXt_SUPPORTED - else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + else if (chunk_name == png_iTXt) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { @@ -809,11 +759,12 @@ png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, void /* PRIVATE */ png_push_read_IDAT(png_structp png_ptr) { - PNG_IDAT; if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; + png_byte chunk_tag[4]; + /* TODO: this code can be commoned up with the same code in push_read */ if (png_ptr->buffer_size < 8) { png_push_save_buffer(png_ptr); @@ -823,10 +774,11 @@ png_push_read_IDAT(png_structp png_ptr) png_push_fill_buffer(png_ptr, chunk_length, 4); png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); png_reset_crc(png_ptr); - png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_crc_read(png_ptr, chunk_tag, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + if (png_ptr->chunk_name != png_IDAT) { png_ptr->process_mode = PNG_READ_CHUNK_MODE; @@ -838,6 +790,7 @@ png_push_read_IDAT(png_structp png_ptr) png_ptr->idat_size = png_ptr->push_length; } + if (png_ptr->idat_size && png_ptr->save_buffer_size) { png_size_t save_size = png_ptr->save_buffer_size; @@ -1011,36 +964,56 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, void /* PRIVATE */ png_push_process_row(png_structp png_ptr) { - png_ptr->row_info.color_type = png_ptr->color_type; - png_ptr->row_info.width = png_ptr->iwidth; - png_ptr->row_info.channels = png_ptr->channels; - png_ptr->row_info.bit_depth = png_ptr->bit_depth; - png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; + /* 1.5.6: row_info moved out of png_struct to a local here. */ + png_row_info row_info; - png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->row_info.width); + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - png_read_filter_row(png_ptr, &(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->prev_row + 1, - (int)(png_ptr->row_buf[0])); + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(&row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } - png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced row count: + */ + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); #ifdef PNG_READ_TRANSFORMS_SUPPORTED if (png_ptr->transformations) - png_do_read_transformations(png_ptr); + png_do_read_transformations(png_ptr, &row_info); #endif + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "progressive row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal progressive row size calculation error"); + + #ifdef PNG_READ_INTERLACING_SUPPORTED /* Blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) -/* old interface (pre-1.0.9): - png_do_read_interlace(&(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); - */ - png_do_read_interlace(png_ptr); + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); switch (png_ptr->pass) { @@ -1223,20 +1196,20 @@ png_read_push_finish_row(png_structp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* Height of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h - PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ png_ptr->row_number++; @@ -1714,11 +1687,12 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_uint_32 skip = 0; + png_uint_32 chunk_name = png_ptr->chunk_name; - if (!(png_ptr->chunk_name[0] & 0x20)) + if (PNG_CHUNK_CRITICAL(chunk_name)) { #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + if (png_chunk_unknown_handling(png_ptr, chunk_name) != PNG_HANDLE_CHUNK_ALWAYS #ifdef PNG_READ_USER_CHUNKS_SUPPORTED && png_ptr->read_user_chunk_fn == NULL @@ -1731,22 +1705,26 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 } #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* TODO: the code below is apparently just using the + * png_struct::unknown_chunk member as a temporarily variable, it should be + * possible to eliminate both it and the temporary buffer. + */ if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) { #ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) + if (length > 65535) { png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; + skip = length - 65535; + length = 65535; } #endif - png_memcpy((png_charp)png_ptr->unknown_chunk.name, - (png_charp)png_ptr->chunk_name, - png_sizeof(png_ptr->unknown_chunk.name)); - png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] - = '\0'; + /* This is just a record for the user; libpng doesn't use the character + * form of the name. + */ + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); + /* The following cast should be safe because of the check above. */ png_ptr->unknown_chunk.size = (png_size_t)length; if (length == 0) @@ -1755,8 +1733,9 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 else { png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, - (png_size_t)length); - png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); + png_ptr->unknown_chunk.size); + png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, + png_ptr->unknown_chunk.size); } #ifdef PNG_READ_USER_CHUNKS_SUPPORTED @@ -1772,8 +1751,8 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 if (ret == 0) { - if (!(png_ptr->chunk_name[0] & 0x20)) - if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + if (png_chunk_unknown_handling(png_ptr, chunk_name) != PNG_HANDLE_CHUNK_ALWAYS) png_chunk_error(png_ptr, "unknown critical chunk"); png_set_unknown_chunks(png_ptr, info_ptr, @@ -1820,7 +1799,7 @@ void PNGAPI png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, png_const_bytep new_row) { - PNG_CONST int FARDATA png_pass_dsp_mask[7] = + static PNG_CONST png_byte FARDATA png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; if (png_ptr == NULL) diff --git a/pngpriv.h b/pngpriv.h index 8ca5d1a37..4a73b66df 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -502,32 +502,70 @@ PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, #endif #endif -/* Constant strings for known chunk types. If you need to add a chunk, - * define the name here, and add an invocation of the macro wherever it's - * needed. +/* Constants for known chunk types. If you need to add a chunk, define the name + * here. For historical reasons these constants have the form png_; i.e. + * the prefix is lower case. Please use decimal values as the parameters to + * match the ISO PNG specification and to avoid relying on the C locale + * interpretation of character values. + * + * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values + * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string + * to be generated if required. + * + * PNG_32b correctly produces a value shifted by up to 24 bits, even on + * architectures where (int) is only 16 bits. */ -#define PNG_IHDR PNG_CONST png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} -#define PNG_IDAT PNG_CONST png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} -#define PNG_IEND PNG_CONST png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} -#define PNG_PLTE PNG_CONST png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} -#define PNG_bKGD PNG_CONST png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} -#define PNG_cHRM PNG_CONST png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} -#define PNG_gAMA PNG_CONST png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} -#define PNG_hIST PNG_CONST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} -#define PNG_iCCP PNG_CONST png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} -#define PNG_iTXt PNG_CONST png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} -#define PNG_oFFs PNG_CONST png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} -#define PNG_pCAL PNG_CONST png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} -#define PNG_sCAL PNG_CONST png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} -#define PNG_pHYs PNG_CONST png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} -#define PNG_sBIT PNG_CONST png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} -#define PNG_sPLT PNG_CONST png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} -#define PNG_sRGB PNG_CONST png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} -#define PNG_sTER PNG_CONST png_byte png_sTER[5] = {115, 84, 69, 82, '\0'} -#define PNG_tEXt PNG_CONST png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} -#define PNG_tIME PNG_CONST png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} -#define PNG_tRNS PNG_CONST png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} -#define PNG_zTXt PNG_CONST png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} +#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) +#define PNG_CHUNK(b1,b2,b3,b4) \ + (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) + +#define png_IHDR PNG_CHUNK( 73, 72, 68, 82) +#define png_IDAT PNG_CHUNK( 73, 68, 65, 84) +#define png_IEND PNG_CHUNK( 73, 69, 78, 68) +#define png_PLTE PNG_CHUNK( 80, 76, 84, 69) +#define png_bKGD PNG_CHUNK( 98, 75, 71, 68) +#define png_cHRM PNG_CHUNK( 99, 72, 82, 77) +#define png_gAMA PNG_CHUNK(103, 65, 77, 65) +#define png_hIST PNG_CHUNK(104, 73, 83, 84) +#define png_iCCP PNG_CHUNK(105, 67, 67, 80) +#define png_iTXt PNG_CHUNK(105, 84, 88, 116) +#define png_oFFs PNG_CHUNK(111, 70, 70, 115) +#define png_pCAL PNG_CHUNK(112, 67, 65, 76) +#define png_sCAL PNG_CHUNK(115, 67, 65, 76) +#define png_pHYs PNG_CHUNK(112, 72, 89, 115) +#define png_sBIT PNG_CHUNK(115, 66, 73, 84) +#define png_sPLT PNG_CHUNK(115, 80, 76, 84) +#define png_sRGB PNG_CHUNK(115, 82, 71, 66) +#define png_sTER PNG_CHUNK(115, 84, 69, 82) +#define png_tEXt PNG_CHUNK(116, 69, 88, 116) +#define png_tIME PNG_CHUNK(116, 73, 77, 69) +#define png_tRNS PNG_CHUNK(116, 82, 78, 83) +#define png_zTXt PNG_CHUNK(122, 84, 88, 116) + +/* The following will work on (signed char*) strings, whereas the get_uint_32 + * macro will fail on top-bit-set values because of the sign extension. + */ +#define PNG_CHUNK_FROM_STRING(s)\ + PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3]) + +/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is + * signed and the argument is a (char[]) This macro will fail miserably on + * systems where (char) is more than 8 bits. + */ +#define PNG_STRING_FROM_CHUNK(s,c)\ + (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\ + ((char*)(s))[3]=(char)((c)>>8), ((char*)(s))[3]=(char)((c))) + +/* Do the same but terminate with a null character. */ +#define PNG_CSTRING_FROM_CHUNK(s,c)\ + (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) + +/* Test on flag values as defined in the spec (section 5.4): */ +#define PNG_CHUNK_ANCILLIARY(c) (1 & ((c) >> 29)) +#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLIARY(c)) +#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) +#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) +#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) /* Gamma values (new at libpng-1.5.4): */ #define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ @@ -784,17 +822,20 @@ PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); /* Internal use only. Called before first row of data */ PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); -/* Combine a row of data, dealing with alpha, etc. if requested */ +/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an + * array of png_ptr->width pixels, 'mask' is a mask of the pixels to copy from + * png_ptr->row_buf+1. 'mask' describes each block of 8 pixels - only the low 8 + * bits are used. This function is only ever used to write to row buffers + * provided by the caller of the relevant libpng API and the row must have + * already been transformed by the read transformations. + */ PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, int mask)); #ifdef PNG_READ_INTERLACING_SUPPORTED /* Expand an interlaced row */ -/* OLD pre-1.0.9 interface: PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, png_bytep row, int pass, png_uint_32 transformations)); - */ -PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); #endif /* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ @@ -805,10 +846,11 @@ PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, png_bytep row, int pass)); #endif -/* Unfilter a row */ -PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, - png_row_infop row_info, png_bytep row, png_const_bytep prev_row, - int filter)); +/* Unfilter a row: check the filter value before calling this, there is no point + * calling it for PNG_FILTER_VALUE_NONE. + */ +PNG_EXTERN void png_read_filter_row PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep prev_row, int filter)); /* Choose the best filter to use and filter the row data */ PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, @@ -1058,18 +1100,30 @@ PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); +#endif PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, - png_const_bytep chunk_name)); + png_uint_32 chunk_name)); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +/* Exactly as png_handle_as_unknown() except that the argument is a 32-bit chunk + * name, not a string. + */ +PNG_EXTERN int png_chunk_unknown_handling PNGARG((png_structp png_ptr, + png_uint_32 chunk_name)); +#endif /* Handle the transformations for reading and writing */ #ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr, + png_row_infop row_info)); #endif #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr, + png_row_infop row_info)); #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED diff --git a/pngread.c b/pngread.c index be3df4769..3747ebe9e 100644 --- a/pngread.c +++ b/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.5.4 [July 7, 2011] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -190,89 +190,35 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) for (;;) { - PNG_IHDR; - PNG_IDAT; - PNG_IEND; - PNG_PLTE; -#ifdef PNG_READ_bKGD_SUPPORTED - PNG_bKGD; -#endif -#ifdef PNG_READ_cHRM_SUPPORTED - PNG_cHRM; -#endif -#ifdef PNG_READ_gAMA_SUPPORTED - PNG_gAMA; -#endif -#ifdef PNG_READ_hIST_SUPPORTED - PNG_hIST; -#endif -#ifdef PNG_READ_iCCP_SUPPORTED - PNG_iCCP; -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - PNG_iTXt; -#endif -#ifdef PNG_READ_oFFs_SUPPORTED - PNG_oFFs; -#endif -#ifdef PNG_READ_pCAL_SUPPORTED - PNG_pCAL; -#endif -#ifdef PNG_READ_pHYs_SUPPORTED - PNG_pHYs; -#endif -#ifdef PNG_READ_sBIT_SUPPORTED - PNG_sBIT; -#endif -#ifdef PNG_READ_sCAL_SUPPORTED - PNG_sCAL; -#endif -#ifdef PNG_READ_sPLT_SUPPORTED - PNG_sPLT; -#endif -#ifdef PNG_READ_sRGB_SUPPORTED - PNG_sRGB; -#endif -#ifdef PNG_READ_tEXt_SUPPORTED - PNG_tEXt; -#endif -#ifdef PNG_READ_tIME_SUPPORTED - PNG_tIME; -#endif -#ifdef PNG_READ_tRNS_SUPPORTED - PNG_tRNS; -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - PNG_zTXt; -#endif png_uint_32 length = png_read_chunk_header(png_ptr); - PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; + png_uint_32 chunk_name = png_ptr->chunk_name; /* This should be a binary subdivision search or a hash for * matching the chunk name rather than a linear search. */ - if (!png_memcmp(chunk_name, png_IDAT, 4)) + if (chunk_name == png_IDAT) if (png_ptr->mode & PNG_AFTER_IDAT) png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - if (!png_memcmp(chunk_name, png_IHDR, 4)) + if (chunk_name == png_IHDR) png_handle_IHDR(png_ptr, info_ptr, length); - else if (!png_memcmp(chunk_name, png_IEND, 4)) + else if (chunk_name == png_IEND) png_handle_IEND(png_ptr, info_ptr, length); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if (png_handle_as_unknown(png_ptr, chunk_name)) + else if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_AS_DEFAULT) { - if (!png_memcmp(chunk_name, png_IDAT, 4)) + if (chunk_name == png_IDAT) png_ptr->mode |= PNG_HAVE_IDAT; png_handle_unknown(png_ptr, info_ptr, length); - if (!png_memcmp(chunk_name, png_PLTE, 4)) + if (chunk_name == png_PLTE) png_ptr->mode |= PNG_HAVE_PLTE; - else if (!png_memcmp(chunk_name, png_IDAT, 4)) + else if (chunk_name == png_IDAT) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); @@ -285,10 +231,10 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) } } #endif - else if (!png_memcmp(chunk_name, png_PLTE, 4)) + else if (chunk_name == png_PLTE) png_handle_PLTE(png_ptr, info_ptr, length); - else if (!png_memcmp(chunk_name, png_IDAT, 4)) + else if (chunk_name == png_IDAT) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); @@ -303,87 +249,87 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) } #ifdef PNG_READ_bKGD_SUPPORTED - else if (!png_memcmp(chunk_name, png_bKGD, 4)) + else if (chunk_name == png_bKGD) png_handle_bKGD(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_cHRM_SUPPORTED - else if (!png_memcmp(chunk_name, png_cHRM, 4)) + else if (chunk_name == png_cHRM) png_handle_cHRM(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_gAMA_SUPPORTED - else if (!png_memcmp(chunk_name, png_gAMA, 4)) + else if (chunk_name == png_gAMA) png_handle_gAMA(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_hIST_SUPPORTED - else if (!png_memcmp(chunk_name, png_hIST, 4)) + else if (chunk_name == png_hIST) png_handle_hIST(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_oFFs_SUPPORTED - else if (!png_memcmp(chunk_name, png_oFFs, 4)) + else if (chunk_name == png_oFFs) png_handle_oFFs(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_pCAL_SUPPORTED - else if (!png_memcmp(chunk_name, png_pCAL, 4)) + else if (chunk_name == png_pCAL) png_handle_pCAL(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sCAL_SUPPORTED - else if (!png_memcmp(chunk_name, png_sCAL, 4)) + else if (chunk_name == png_sCAL) png_handle_sCAL(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_pHYs_SUPPORTED - else if (!png_memcmp(chunk_name, png_pHYs, 4)) + else if (chunk_name == png_pHYs) png_handle_pHYs(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sBIT_SUPPORTED - else if (!png_memcmp(chunk_name, png_sBIT, 4)) + else if (chunk_name == png_sBIT) png_handle_sBIT(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sRGB_SUPPORTED - else if (!png_memcmp(chunk_name, png_sRGB, 4)) + else if (chunk_name == png_sRGB) png_handle_sRGB(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_iCCP_SUPPORTED - else if (!png_memcmp(chunk_name, png_iCCP, 4)) + else if (chunk_name == png_iCCP) png_handle_iCCP(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sPLT_SUPPORTED - else if (!png_memcmp(chunk_name, png_sPLT, 4)) + else if (chunk_name == png_sPLT) png_handle_sPLT(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_tEXt_SUPPORTED - else if (!png_memcmp(chunk_name, png_tEXt, 4)) + else if (chunk_name == png_tEXt) png_handle_tEXt(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_tIME_SUPPORTED - else if (!png_memcmp(chunk_name, png_tIME, 4)) + else if (chunk_name == png_tIME) png_handle_tIME(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_tRNS_SUPPORTED - else if (!png_memcmp(chunk_name, png_tRNS, 4)) + else if (chunk_name == png_tRNS) png_handle_tRNS(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_zTXt_SUPPORTED - else if (!png_memcmp(chunk_name, png_zTXt, 4)) + else if (chunk_name == png_zTXt) png_handle_zTXt(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_iTXt_SUPPORTED - else if (!png_memcmp(chunk_name, png_iTXt, 4)) + else if (chunk_name == png_iTXt) png_handle_iTXt(png_ptr, info_ptr, length); #endif @@ -444,7 +390,6 @@ png_start_read_image(png_structp png_ptr) void PNGAPI png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { - PNG_IDAT; #ifdef PNG_READ_INTERLACING_SUPPORTED PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; @@ -452,15 +397,28 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) #endif int ret; + png_row_info row_info; + if (png_ptr == NULL) return; png_debug2(1, "in png_read_row (row %lu, pass %d)", (unsigned long)png_ptr->row_number, png_ptr->pass); + /* png_read_start_row sets the information (in particular iwidth) for this + * interlace pass. + */ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); + /* 1.5.6: row_info moved out of png_struct to a local here. */ + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + if (png_ptr->row_number == 0 && png_ptr->pass == 0) { /* Check for transforms that have been set but were defined out */ @@ -502,7 +460,12 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) } #ifdef PNG_READ_INTERLACING_SUPPORTED - /* If interlaced and we do not need a new row, combine row and return */ + /* If interlaced and we do not need a new row, combine row and return. + * Notice that the pixels we have from previous rows have been transformed + * already; we can only combine like with like (transformed or + * untransformed) and, because of the libpng API for interlaced images, this + * means we must transform before de-interlacing. + */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { switch (png_ptr->pass) @@ -606,7 +569,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_crc_finish(png_ptr, 0); png_ptr->idat_size = png_read_chunk_header(png_ptr); - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + if (png_ptr->chunk_name != png_IDAT) png_error(png_ptr, "Not enough image data"); } png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; @@ -636,47 +599,56 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) } while (png_ptr->zstream.avail_out); - png_ptr->row_info.color_type = png_ptr->color_type; - png_ptr->row_info.width = png_ptr->iwidth; - png_ptr->row_info.channels = png_ptr->channels; - png_ptr->row_info.bit_depth = png_ptr->bit_depth; - png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; - png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->row_info.width); + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(&row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } - if (png_ptr->row_buf[0]) - png_read_filter_row(png_ptr, &(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->prev_row + 1, - (int)(png_ptr->row_buf[0])); - - png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced count: + */ + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); #ifdef PNG_MNG_FEATURES_SUPPORTED if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ - png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); } #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED if (png_ptr->transformations) - png_do_read_transformations(png_ptr); + png_do_read_transformations(png_ptr, &row_info); #endif + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "sequential row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal sequential row size calculation error"); + #ifdef PNG_READ_INTERLACING_SUPPORTED /* Blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) - /* Old interface (pre-1.0.9): - * png_do_read_interlace(&(png_ptr->row_info), - * png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); - */ - png_do_read_interlace(png_ptr); + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); @@ -858,85 +830,31 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) do { - PNG_IHDR; - PNG_IDAT; - PNG_IEND; - PNG_PLTE; -#ifdef PNG_READ_bKGD_SUPPORTED - PNG_bKGD; -#endif -#ifdef PNG_READ_cHRM_SUPPORTED - PNG_cHRM; -#endif -#ifdef PNG_READ_gAMA_SUPPORTED - PNG_gAMA; -#endif -#ifdef PNG_READ_hIST_SUPPORTED - PNG_hIST; -#endif -#ifdef PNG_READ_iCCP_SUPPORTED - PNG_iCCP; -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - PNG_iTXt; -#endif -#ifdef PNG_READ_oFFs_SUPPORTED - PNG_oFFs; -#endif -#ifdef PNG_READ_pCAL_SUPPORTED - PNG_pCAL; -#endif -#ifdef PNG_READ_pHYs_SUPPORTED - PNG_pHYs; -#endif -#ifdef PNG_READ_sBIT_SUPPORTED - PNG_sBIT; -#endif -#ifdef PNG_READ_sCAL_SUPPORTED - PNG_sCAL; -#endif -#ifdef PNG_READ_sPLT_SUPPORTED - PNG_sPLT; -#endif -#ifdef PNG_READ_sRGB_SUPPORTED - PNG_sRGB; -#endif -#ifdef PNG_READ_tEXt_SUPPORTED - PNG_tEXt; -#endif -#ifdef PNG_READ_tIME_SUPPORTED - PNG_tIME; -#endif -#ifdef PNG_READ_tRNS_SUPPORTED - PNG_tRNS; -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - PNG_zTXt; -#endif png_uint_32 length = png_read_chunk_header(png_ptr); - PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; + png_uint_32 chunk_name = png_ptr->chunk_name; - if (!png_memcmp(chunk_name, png_IHDR, 4)) + if (chunk_name == png_IHDR) png_handle_IHDR(png_ptr, info_ptr, length); - else if (!png_memcmp(chunk_name, png_IEND, 4)) + else if (chunk_name == png_IEND) png_handle_IEND(png_ptr, info_ptr, length); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if (png_handle_as_unknown(png_ptr, chunk_name)) + else if (png_chunk_unknown_handling(png_ptr, chunk_name) != + PNG_HANDLE_CHUNK_AS_DEFAULT) { - if (!png_memcmp(chunk_name, png_IDAT, 4)) + if (chunk_name == png_IDAT) { if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) png_benign_error(png_ptr, "Too many IDATs found"); } png_handle_unknown(png_ptr, info_ptr, length); - if (!png_memcmp(chunk_name, png_PLTE, 4)) + if (chunk_name == png_PLTE) png_ptr->mode |= PNG_HAVE_PLTE; } #endif - else if (!png_memcmp(chunk_name, png_IDAT, 4)) + else if (chunk_name == png_IDAT) { /* Zero length IDATs are legal after the last IDAT has been * read, but not after other chunks have been read. @@ -946,91 +864,91 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) png_crc_finish(png_ptr, length); } - else if (!png_memcmp(chunk_name, png_PLTE, 4)) + else if (chunk_name == png_PLTE) png_handle_PLTE(png_ptr, info_ptr, length); #ifdef PNG_READ_bKGD_SUPPORTED - else if (!png_memcmp(chunk_name, png_bKGD, 4)) + else if (chunk_name == png_bKGD) png_handle_bKGD(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_cHRM_SUPPORTED - else if (!png_memcmp(chunk_name, png_cHRM, 4)) + else if (chunk_name == png_cHRM) png_handle_cHRM(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_gAMA_SUPPORTED - else if (!png_memcmp(chunk_name, png_gAMA, 4)) + else if (chunk_name == png_gAMA) png_handle_gAMA(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_hIST_SUPPORTED - else if (!png_memcmp(chunk_name, png_hIST, 4)) + else if (chunk_name == png_hIST) png_handle_hIST(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_oFFs_SUPPORTED - else if (!png_memcmp(chunk_name, png_oFFs, 4)) + else if (chunk_name == png_oFFs) png_handle_oFFs(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_pCAL_SUPPORTED - else if (!png_memcmp(chunk_name, png_pCAL, 4)) + else if (chunk_name == png_pCAL) png_handle_pCAL(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sCAL_SUPPORTED - else if (!png_memcmp(chunk_name, png_sCAL, 4)) + else if (chunk_name == png_sCAL) png_handle_sCAL(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_pHYs_SUPPORTED - else if (!png_memcmp(chunk_name, png_pHYs, 4)) + else if (chunk_name == png_pHYs) png_handle_pHYs(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sBIT_SUPPORTED - else if (!png_memcmp(chunk_name, png_sBIT, 4)) + else if (chunk_name == png_sBIT) png_handle_sBIT(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sRGB_SUPPORTED - else if (!png_memcmp(chunk_name, png_sRGB, 4)) + else if (chunk_name == png_sRGB) png_handle_sRGB(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_iCCP_SUPPORTED - else if (!png_memcmp(chunk_name, png_iCCP, 4)) + else if (chunk_name == png_iCCP) png_handle_iCCP(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_sPLT_SUPPORTED - else if (!png_memcmp(chunk_name, png_sPLT, 4)) + else if (chunk_name == png_sPLT) png_handle_sPLT(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_tEXt_SUPPORTED - else if (!png_memcmp(chunk_name, png_tEXt, 4)) + else if (chunk_name == png_tEXt) png_handle_tEXt(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_tIME_SUPPORTED - else if (!png_memcmp(chunk_name, png_tIME, 4)) + else if (chunk_name == png_tIME) png_handle_tIME(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_tRNS_SUPPORTED - else if (!png_memcmp(chunk_name, png_tRNS, 4)) + else if (chunk_name == png_tRNS) png_handle_tRNS(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_zTXt_SUPPORTED - else if (!png_memcmp(chunk_name, png_zTXt, 4)) + else if (chunk_name == png_zTXt) png_handle_zTXt(png_ptr, info_ptr, length); #endif #ifdef PNG_READ_iTXt_SUPPORTED - else if (!png_memcmp(chunk_name, png_iTXt, 4)) + else if (chunk_name == png_iTXt) png_handle_iTXt(png_ptr, info_ptr, length); #endif diff --git a/pngrtran.c b/pngrtran.c index c6dd28808..737970011 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.5.5 [(PENDING RELEASE)] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -1198,53 +1198,44 @@ png_init_rgb_transformations(png_structp png_ptr) { { /* Expand background and tRNS chunks */ + int gray = png_ptr->background.gray; + int trans_gray = png_ptr->trans_color.gray; + switch (png_ptr->bit_depth) { case 1: - png_ptr->background.gray *= (png_uint_16)0xff; - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) - { - png_ptr->trans_color.gray *= (png_uint_16)0xff; - png_ptr->trans_color.red = png_ptr->trans_color.green - = png_ptr->trans_color.blue = png_ptr->trans_color.gray; - } + gray *= 0xff; + trans_gray *= 0xff; break; case 2: - png_ptr->background.gray *= (png_uint_16)0x55; - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) - { - png_ptr->trans_color.gray *= (png_uint_16)0x55; - png_ptr->trans_color.red = png_ptr->trans_color.green - = png_ptr->trans_color.blue = png_ptr->trans_color.gray; - } + gray *= 0x55; + trans_gray *= 0x55; break; case 4: - png_ptr->background.gray *= (png_uint_16)0x11; - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) - { - png_ptr->trans_color.gray *= (png_uint_16)0x11; - png_ptr->trans_color.red = png_ptr->trans_color.green - = png_ptr->trans_color.blue = png_ptr->trans_color.gray; - } + gray *= 0x11; + trans_gray *= 0x11; break; default: case 8: + /* Already 8 bits, fall through */ case 16: - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; + /* Already a full 16 bits */ break; } + + png_ptr->background.red = png_ptr->background.green = + png_ptr->background.blue = (png_uint_16)gray; + + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_color.red = png_ptr->trans_color.green = + png_ptr->trans_color.blue = (png_uint_16)trans_gray; + } } } /* background expand and (therefore) no alpha association. */ #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ @@ -1788,26 +1779,38 @@ png_init_read_transformations(png_structp png_ptr) if ((png_ptr->transformations & PNG_SHIFT) && (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) { - png_uint_16 i; - png_uint_16 istop = png_ptr->num_palette; - int sr = 8 - png_ptr->sig_bit.red; - int sg = 8 - png_ptr->sig_bit.green; - int sb = 8 - png_ptr->sig_bit.blue; + int i; + int istop = png_ptr->num_palette; + int shift = 8 - png_ptr->sig_bit.red; - if (sr < 0 || sr > 8) - sr = 0; - - if (sg < 0 || sg > 8) - sg = 0; - - if (sb < 0 || sb > 8) - sb = 0; - - for (i = 0; i < istop; i++) + /* significant bits can be in the range 1 to 7 for a meaninful result, if + * the number of significant bits is 0 then no shift is done (this is an + * error condition which is silently ignored.) + */ + if (shift > 0 && shift < 8) for (i=0; ipalette[i].red >>= sr; - png_ptr->palette[i].green >>= sg; - png_ptr->palette[i].blue >>= sb; + int component = png_ptr->palette[i].red; + + component >>= shift; + png_ptr->palette[i].red = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.green; + if (shift > 0 && shift < 8) for (i=0; ipalette[i].green; + + component >>= shift; + png_ptr->palette[i].green = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.blue; + if (shift > 0 && shift < 8) for (i=0; ipalette[i].blue; + + component >>= shift; + png_ptr->palette[i].blue = (png_byte)component; } } #endif /* PNG_READ_SHIFT_SUPPORTED */ @@ -1913,12 +1916,14 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED if (png_ptr->transformations & PNG_GRAY_TO_RGB) - info_ptr->color_type |= PNG_COLOR_MASK_COLOR; + info_ptr->color_type = (png_byte)(info_ptr->color_type | + PNG_COLOR_MASK_COLOR); #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED if (png_ptr->transformations & PNG_RGB_TO_GRAY) - info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_COLOR); #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED @@ -1958,7 +1963,8 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED if (png_ptr->transformations & PNG_STRIP_ALPHA) { - info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_ALPHA); info_ptr->num_trans = 0; } #endif @@ -2015,7 +2021,7 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) * decide how it fits in with the other transformations here. */ void /* PRIVATE */ -png_do_read_transformations(png_structp png_ptr) +png_do_read_transformations(png_structp png_ptr, png_row_infop row_info) { png_debug(1, "in png_do_read_transformations"); @@ -2046,9 +2052,9 @@ png_do_read_transformations(png_structp png_ptr) #ifdef PNG_READ_EXPAND_SUPPORTED if (png_ptr->transformations & PNG_EXPAND) { - if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) { - png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_expand_palette(row_info, png_ptr->row_buf + 1, png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); } @@ -2056,11 +2062,11 @@ png_do_read_transformations(png_structp png_ptr) { if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS)) - png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_expand(row_info, png_ptr->row_buf + 1, &(png_ptr->trans_color)); else - png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_expand(row_info, png_ptr->row_buf + 1, NULL); } } @@ -2069,9 +2075,9 @@ png_do_read_transformations(png_structp png_ptr) #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED if ((png_ptr->transformations & PNG_STRIP_ALPHA) && !(png_ptr->transformations & PNG_COMPOSE) && - (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, 0 /* at_start == false, because SWAP_ALPHA happens later */); #endif @@ -2079,7 +2085,7 @@ png_do_read_transformations(png_structp png_ptr) if (png_ptr->transformations & PNG_RGB_TO_GRAY) { int rgb_error = - png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), + png_do_rgb_to_gray(png_ptr, row_info, png_ptr->row_buf + 1); if (rgb_error) @@ -2133,13 +2139,13 @@ png_do_read_transformations(png_structp png_ptr) */ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); #endif #if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ (defined PNG_READ_ALPHA_MODE_SUPPORTED) if (png_ptr->transformations & PNG_COMPOSE) - png_do_compose(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); + png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); #endif #ifdef PNG_READ_GAMMA_SUPPORTED @@ -2151,27 +2157,27 @@ png_do_read_transformations(png_structp png_ptr) (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && #endif (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) - png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); + png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); #endif #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED if ((png_ptr->transformations & PNG_STRIP_ALPHA) && (png_ptr->transformations & PNG_COMPOSE) && - (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, 0 /* at_start == false, because SWAP_ALPHA happens later */); #endif #ifdef PNG_READ_ALPHA_MODE_SUPPORTED if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && - (png_ptr->row_info.color_type & PNG_COLOR_MASK_ALPHA)) - png_do_encode_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); + (row_info->color_type & PNG_COLOR_MASK_ALPHA)) + png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); #endif #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED if (png_ptr->transformations & PNG_SCALE_16_TO_8) - png_do_scale_16_to_8(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED @@ -2180,16 +2186,16 @@ png_do_read_transformations(png_structp png_ptr) * calling the API or in a TRANSFORM flag) this is what happens. */ if (png_ptr->transformations & PNG_16_TO_8) - png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_chop(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED if (png_ptr->transformations & PNG_QUANTIZE) { - png_do_quantize(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_quantize(row_info, png_ptr->row_buf + 1, png_ptr->palette_lookup, png_ptr->quantize_index); - if (png_ptr->row_info.rowbytes == 0) + if (row_info->rowbytes == 0) png_error(png_ptr, "png_do_quantize returned rowbytes=0"); } #endif /* PNG_READ_QUANTIZE_SUPPORTED */ @@ -2201,62 +2207,62 @@ png_do_read_transformations(png_structp png_ptr) * better accuracy results faster!) */ if (png_ptr->transformations & PNG_EXPAND_16) - png_do_expand_16(&png_ptr->row_info, png_ptr->row_buf + 1); + png_do_expand_16(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED /*NOTE: moved here in 1.5.4 (from much later in this list.) */ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_INVERT_SUPPORTED if (png_ptr->transformations & PNG_INVERT_MONO) - png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_invert(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_SHIFT_SUPPORTED if (png_ptr->transformations & PNG_SHIFT) - png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_unshift(row_info, png_ptr->row_buf + 1, &(png_ptr->shift)); #endif #ifdef PNG_READ_PACK_SUPPORTED if (png_ptr->transformations & PNG_PACK) - png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_unpack(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_BGR_SUPPORTED if (png_ptr->transformations & PNG_BGR) - png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_bgr(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_PACKSWAP_SUPPORTED if (png_ptr->transformations & PNG_PACKSWAP) - png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_packswap(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_FILLER_SUPPORTED if (png_ptr->transformations & PNG_FILLER) - png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_read_filler(row_info, png_ptr->row_buf + 1, (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(&(png_ptr->row_info), png_ptr->row_buf + 1); + 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(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_16BIT_SUPPORTED #ifdef PNG_READ_SWAP_SUPPORTED if (png_ptr->transformations & PNG_SWAP_BYTES) - png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_swap(row_info, png_ptr->row_buf + 1); #endif #endif @@ -2265,8 +2271,8 @@ png_do_read_transformations(png_structp png_ptr) { if (png_ptr->read_user_transform_fn != NULL) (*(png_ptr->read_user_transform_fn)) /* User read transform function */ - (png_ptr, /* png_ptr */ - &(png_ptr->row_info), /* row_info: */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ /* png_uint_32 width; width of row */ /* png_size_t rowbytes; number of bytes in row */ /* png_byte color_type; color type of pixels */ @@ -2276,16 +2282,15 @@ png_do_read_transformations(png_structp png_ptr) png_ptr->row_buf + 1); /* start of pixel data for row */ #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED if (png_ptr->user_transform_depth) - png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; + row_info->bit_depth = png_ptr->user_transform_depth; if (png_ptr->user_transform_channels) - png_ptr->row_info.channels = png_ptr->user_transform_channels; + row_info->channels = png_ptr->user_transform_channels; #endif - png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * - png_ptr->row_info.channels); + row_info->pixel_depth = (png_byte)(row_info->bit_depth * + row_info->channels); - png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->row_info.width); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); } #endif } @@ -2399,105 +2404,128 @@ void /* PRIVATE */ png_do_unshift(png_row_infop row_info, png_bytep row, png_const_color_8p sig_bits) { + int color_type; + png_debug(1, "in png_do_unshift"); - if ( - row_info->color_type != PNG_COLOR_TYPE_PALETTE) + /* The palette case has already been handled in the _init routine. */ + color_type = row_info->color_type; + + if (color_type != PNG_COLOR_TYPE_PALETTE) { int shift[4]; int channels = 0; - int c; - png_uint_16 value = 0; - png_uint_32 row_width = row_info->width; + int bit_depth = row_info->bit_depth; - if (row_info->color_type & PNG_COLOR_MASK_COLOR) + if (color_type & PNG_COLOR_MASK_COLOR) { - shift[channels++] = row_info->bit_depth - sig_bits->red; - shift[channels++] = row_info->bit_depth - sig_bits->green; - shift[channels++] = row_info->bit_depth - sig_bits->blue; + shift[channels++] = bit_depth - sig_bits->red; + shift[channels++] = bit_depth - sig_bits->green; + shift[channels++] = bit_depth - sig_bits->blue; } else { - shift[channels++] = row_info->bit_depth - sig_bits->gray; + shift[channels++] = bit_depth - sig_bits->gray; } - if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + if (color_type & PNG_COLOR_MASK_ALPHA) { - shift[channels++] = row_info->bit_depth - sig_bits->alpha; + shift[channels++] = bit_depth - sig_bits->alpha; } - for (c = 0; c < channels; c++) { - if (shift[c] <= 0) - shift[c] = 0; + int c, have_shift; - else - value = 1; + for (c = have_shift = 0; c < channels; ++c) + { + /* A shift of more than the bit depth is an error condition but it + * gets ignored here. + */ + if (shift[c] <= 0 || shift[c] >= bit_depth) + shift[c] = 0; + + else + have_shift = 1; + } + + if (!have_shift) + return; } - if (!value) - return; - - switch (row_info->bit_depth) + switch (bit_depth) { default: + /* Must be 1bpp gray: should not be here! */ + /* NOTREACHED */ break; case 2: + /* Must be 2bpp gray */ + /* assert(channels == 1 && shift[0] == 1) */ { - png_bytep bp; - png_size_t i; - png_size_t istop = row_info->rowbytes; + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; - for (bp = row, i = 0; i < istop; i++) + while (bp < bp_end) { - *bp >>= 1; - *bp++ &= 0x55; + int byte = (*bp >> 1) & 0x55; + *bp++ = (png_byte)byte; } break; } case 4: + /* Must be 4bpp gray */ + /* assert(channels == 1) */ { png_bytep bp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; - png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | - (png_byte)((int)0xf >> shift[0])); + png_bytep bp_end = bp + row_info->rowbytes; + int gray_shift = shift[0]; + int mask = 0xf >> gray_shift; - for (i = 0; i < istop; i++) + mask |= mask << 4; + + while (bp < bp_end) { - *bp >>= shift[0]; - *bp++ &= mask; + int byte = (*bp >> gray_shift) & mask; + *bp++ = (png_byte)byte; } break; } case 8: + /* Single byte components, G, GA, RGB, RGBA */ { png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = row_width * channels; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; - for (i = 0; i < istop; i++) + while (bp < bp_end) { - *bp++ >>= shift[i%channels]; + int byte = *bp >> shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)byte; } break; } #ifdef PNG_READ_16BIT_SUPPORTED case 16: + /* Double byte components, G, GA, RGB, RGBA */ { png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = channels * row_width; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; - for (i = 0; i < istop; i++) + while (bp < bp_end) { - value = (png_uint_16)((*bp << 8) + *(bp + 1)); - value >>= shift[i%channels]; + int value = (bp[0] << 8) + bp[1]; + + value >>= shift[channel]; + if (++channel >= channels) + channel = 0; *bp++ = (png_byte)(value >> 8); *bp++ = (png_byte)(value & 0xff); } @@ -3060,7 +3088,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) } } } - row_info->channels += (png_byte)2; + row_info->channels = (png_byte)(row_info->channels + 2); row_info->color_type |= PNG_COLOR_MASK_COLOR; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); @@ -3306,7 +3334,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) } } - row_info->channels -= 2; + row_info->channels = (png_byte)(row_info->channels - 2); row_info->color_type = (png_byte)(row_info->color_type & ~PNG_COLOR_MASK_COLOR); row_info->pixel_depth = (png_byte)(row_info->channels * diff --git a/pngrutil.c b/pngrutil.c index a74353de1..62b3afc9b 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.5.5 [(PENDING RELEASE)] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -165,14 +165,14 @@ png_read_chunk_header(png_structp png_ptr) length = png_get_uint_31(png_ptr, buf); /* Put the chunk name into png_ptr->chunk_name. */ - png_memcpy(png_ptr->chunk_name, buf + 4, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - png_debug2(0, "Reading %s chunk, length = %u", - png_ptr->chunk_name, length); + png_debug2(0, "Reading %lx chunk, length = %lu", + (unsigned long)png_ptr->chunk_name, (unsigned long)length); /* Reset the crc and run it over the chunk name. */ png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); + png_calculate_crc(png_ptr, buf + 4, 4); /* Check to see if chunk name is valid. */ png_check_chunk_name(png_ptr, png_ptr->chunk_name); @@ -218,10 +218,9 @@ png_crc_finish(png_structp png_ptr, png_uint_32 skip) if (png_crc_error(png_ptr)) { - if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ - !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || - (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ - (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) + if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ? + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) : + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)) { png_chunk_warning(png_ptr, "CRC error"); } @@ -248,14 +247,14 @@ png_crc_error(png_structp png_ptr) png_uint_32 crc; int need_crc = 1; - if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ + if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) { if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) need_crc = 0; } - else /* critical */ + else /* critical */ { if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) need_crc = 0; @@ -2641,16 +2640,14 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_ptr->mode & PNG_HAVE_IDAT) { - PNG_IDAT; - - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ + if (png_ptr->chunk_name != png_IDAT) png_ptr->mode |= PNG_AFTER_IDAT; } - if (!(png_ptr->chunk_name[0] & 0x20)) + if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) { #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS #ifdef PNG_READ_USER_CHUNKS_SUPPORTED && png_ptr->read_user_chunk_fn == NULL @@ -2668,21 +2665,20 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ) { #ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) + if (length > 65535) { png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; + skip = length - 65535; + length = 65535; } #endif - png_memcpy((png_charp)png_ptr->unknown_chunk.name, - (png_charp)png_ptr->chunk_name, - png_sizeof(png_ptr->unknown_chunk.name)); - - png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] - = '\0'; - + /* TODO: this code is very close to the unknown handling in pngpread.c, + * maybe it can be put into a common utility routine? + * png_struct::unknown_chunk is just used as a temporary variable, along + * with the data into which the chunk is read. These can be eliminated. + */ + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); png_ptr->unknown_chunk.size = (png_size_t)length; if (length == 0) @@ -2691,7 +2687,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) else { png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); - png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); + png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); } #ifdef PNG_READ_USER_CHUNKS_SUPPORTED @@ -2708,10 +2704,10 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (ret == 0) { - if (!(png_ptr->chunk_name[0] & 0x20)) + if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) { #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS) #endif png_chunk_error(png_ptr, "unknown critical chunk"); @@ -2748,16 +2744,26 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) * the chunk name itself is valid. */ -#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) +/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: + * + * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) + */ void /* PRIVATE */ -png_check_chunk_name(png_structp png_ptr, png_const_bytep chunk_name) +png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name) { + int i; + png_debug(1, "in png_check_chunk_name"); - if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || - isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) + + for (i=1; i<=4; ++i) { - png_chunk_error(png_ptr, "invalid chunk type"); + int c = chunk_name & 0xff; + + if (c < 65 || c > 122 || (c > 90 && c < 97)) + png_chunk_error(png_ptr, "invalid chunk type"); + + chunk_name >>= 8; } } @@ -2776,25 +2782,33 @@ png_check_chunk_name(png_structp png_ptr, png_const_bytep chunk_name) void /* PRIVATE */ png_combine_row(png_structp png_ptr, png_bytep row, int mask) { + int pixel_depth = png_ptr->transformed_pixel_depth; + png_debug(1, "in png_combine_row"); - /* Added in 1.5.4: the row_info should match the information returned by any - * call to png_read_update_info at this point. Do not continue if we got + /* Added in 1.5.6: it should not be possible to enter this routine until at + * least one row has been read from the PNG data and transformed. + */ + if (pixel_depth == 0) + png_error(png_ptr, "internal row logic error"); + + /* Added in 1.5.4: the pixel depth should match the information returned by + * any call to png_read_update_info at this point. Do not continue if we got * this wrong. */ if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != - PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)) + PNG_ROWBYTES(pixel_depth, png_ptr->width)) png_error(png_ptr, "internal row size calculation error"); if (mask == 0xff) { png_memcpy(row, png_ptr->row_buf + 1, - PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); + PNG_ROWBYTES(pixel_depth, png_ptr->width)); } else { - switch (png_ptr->row_info.pixel_depth) + switch (pixel_depth) { case 1: { @@ -2971,7 +2985,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) { png_bytep sp = png_ptr->row_buf + 1; png_bytep dp = row; - png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); + png_size_t pixel_bytes = pixel_depth >> 3; png_uint_32 i; png_uint_32 row_width = png_ptr->width; png_byte m = 0x80; @@ -3000,15 +3014,12 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) #ifdef PNG_READ_INTERLACING_SUPPORTED void /* PRIVATE */ -png_do_read_interlace(png_structp png_ptr) +png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, + png_uint_32 transformations /* Because these may affect the byte layout */) { - png_row_infop row_info = &(png_ptr->row_info); - png_bytep row = png_ptr->row_buf + 1; - int pass = png_ptr->pass; - png_uint_32 transformations = png_ptr->transformations; /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Offset to next interlace block */ - PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_read_interlace"); if (row != NULL && row_info != NULL) @@ -3241,12 +3252,13 @@ png_do_read_interlace(png_structp png_ptr) } #endif /* PNG_READ_INTERLACING_SUPPORTED */ +/* 1.5.6: Changed to just take a png_row_info (not png_ptr) and to ignore bad + * adaptive filter bytes. + */ void /* PRIVATE */ -png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, - png_const_bytep prev_row, int filter) +png_read_filter_row(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row, int filter) { - png_debug(1, "in png_read_filter_row"); - png_debug2(2, "row = %u, filter = %d", png_ptr->row_number, filter); switch (filter) { case PNG_FILTER_VALUE_NONE: @@ -3363,8 +3375,7 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, break; } default: - png_error(png_ptr, "Ignoring bad adaptive filter type"); - /*NOT REACHED */ + /* NOT REACHED */ break; } } @@ -3377,16 +3388,16 @@ png_read_finish_row(png_structp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif /* PNG_READ_INTERLACING_SUPPORTED */ png_debug(1, "in png_read_finish_row"); @@ -3433,7 +3444,6 @@ png_read_finish_row(png_structp png_ptr) if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) { - PNG_IDAT; char extra; int ret; @@ -3448,7 +3458,7 @@ png_read_finish_row(png_structp png_ptr) { png_crc_finish(png_ptr, 0); png_ptr->idat_size = png_read_chunk_header(png_ptr); - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + if (png_ptr->chunk_name != png_IDAT) png_error(png_ptr, "Not enough image data"); } @@ -3507,16 +3517,16 @@ png_read_start_row(png_structp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif int max_pixel_depth; @@ -3676,14 +3686,20 @@ png_read_start_row(png_structp png_ptr) defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) { - int user_pixel_depth = png_ptr->user_transform_depth* + int user_pixel_depth = png_ptr->user_transform_depth * png_ptr->user_transform_channels; if (user_pixel_depth > max_pixel_depth) - max_pixel_depth=user_pixel_depth; + max_pixel_depth = user_pixel_depth; } #endif + /* This value is stored in png_struct and double checked in the row read + * code. + */ + png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; + png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ + /* Align the width on the next larger 8 pixels. Mainly used * for interlacing */ diff --git a/pngset.c b/pngset.c index 373d21b28..b6437217e 100644 --- a/pngset.c +++ b/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.5.5 [(PENDING RELEASE)] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -681,9 +681,8 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, { int i; - png_debug1(1, "in %s storage function", ((png_ptr == NULL || - png_ptr->chunk_name[0] == '\0') ? - "text" : (png_const_charp)png_ptr->chunk_name)); + png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : + (unsigned long)png_ptr->chunk_name); if (png_ptr == NULL || info_ptr == NULL || num_text == 0) return(0); diff --git a/pngstruct.h b/pngstruct.h index b4e5f3b60..f4dbc61f5 100644 --- a/pngstruct.h +++ b/pngstruct.h @@ -104,13 +104,13 @@ struct png_struct_def png_size_t rowbytes; /* size of row in bytes */ png_uint_32 iwidth; /* width of current interlaced row in pixels */ png_uint_32 row_number; /* current row in interlace pass */ + png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ png_bytep prev_row; /* buffer to save previous (unfiltered) row */ png_bytep row_buf; /* buffer to save current (unfiltered) row */ png_bytep sub_row; /* buffer to save "sub" row when filtering */ png_bytep up_row; /* buffer to save "up" row when filtering */ png_bytep avg_row; /* buffer to save "avg" row when filtering */ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ - png_row_info row_info; /* used for transformation routines */ png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ png_uint_32 idat_size; /* current IDAT size for read */ @@ -118,7 +118,6 @@ struct png_struct_def png_colorp palette; /* palette from the input file */ png_uint_16 num_palette; /* number of color entries in palette */ png_uint_16 num_trans; /* number of transparency values */ - png_byte chunk_name[5]; /* null-terminated name of current chunk */ png_byte compression; /* file compression type (always 0) */ png_byte filter; /* file filter type (always 0) */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ @@ -126,11 +125,17 @@ struct png_struct_def png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ png_byte color_type; /* color type of file */ png_byte bit_depth; /* bit depth of file */ - png_byte usr_bit_depth; /* bit depth of users row */ + png_byte usr_bit_depth; /* bit depth of users row: write only */ png_byte pixel_depth; /* number of bits per pixel */ png_byte channels; /* number of channels in file */ - png_byte usr_channels; /* channels at start of write */ + png_byte usr_channels; /* channels at start of write: write only */ png_byte sig_bytes; /* magic bytes read/written from start of file */ + png_byte maximum_pixel_depth; + /* pixel depth used for the row buffers */ + png_byte transformed_pixel_depth; + /* pixel depth after read/write transforms */ + png_byte io_chunk_string[5]; + /* string name of chunk */ #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) png_uint_16 filler; /* filler bytes for pixel expansion */ diff --git a/pngtest.c b/pngtest.c index 9c4615d37..18ed38ce2 100644 --- a/pngtest.c +++ b/pngtest.c @@ -1794,4 +1794,4 @@ main(int argc, char *argv[]) } /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_5_6beta01 Your_png_h_is_not_version_1_5_6beta01; +typedef png_libpng_version_1_5_6beta02 Your_png_h_is_not_version_1_5_6beta02; diff --git a/pngvalid.c b/pngvalid.c index 9d1ce798c..ef915c567 100644 --- a/pngvalid.c +++ b/pngvalid.c @@ -1,7 +1,7 @@ /* pngvalid.c - validate libpng by constructing then reading png files. * - * Last changed in libpng 1.5.5 [(PENDING RELEASE)] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 2011 Glenn Randers-Pehrson * Written by John Cunningham Bowler * diff --git a/pngwrite.c b/pngwrite.c index d1af9e899..b120df983 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.5.4 [July 7, 2011] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -608,6 +608,9 @@ png_write_image(png_structp png_ptr, png_bytepp image) void PNGAPI png_write_row(png_structp png_ptr, png_const_bytep row) { + /* 1.5.6: moved from png_struct to be a local structure: */ + png_row_info row_info; + if (png_ptr == NULL) return; @@ -731,36 +734,31 @@ png_write_row(png_structp png_ptr, png_const_bytep row) #endif /* Set up row info for transformations */ - png_ptr->row_info.color_type = png_ptr->color_type; - png_ptr->row_info.width = png_ptr->usr_width; - png_ptr->row_info.channels = png_ptr->usr_channels; - png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; - png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * - png_ptr->row_info.channels); + row_info.color_type = png_ptr->color_type; + row_info.width = png_ptr->usr_width; + row_info.channels = png_ptr->usr_channels; + row_info.bit_depth = png_ptr->usr_bit_depth; + row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->row_info.width); - - png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); - png_debug1(3, "row_info->width = %u", png_ptr->row_info.width); - png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); - png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth); - png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth); - png_debug1(3, "row_info->rowbytes = %lu", - (unsigned long)png_ptr->row_info.rowbytes); + png_debug1(3, "row_info->color_type = %d", row_info.color_type); + png_debug1(3, "row_info->width = %u", row_info.width); + png_debug1(3, "row_info->channels = %d", row_info.channels); + png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); + png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); + png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); /* Copy user's row into buffer, leaving room for filter byte. */ - png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); + png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Handle interlacing */ if (png_ptr->interlaced && png_ptr->pass < 6 && (png_ptr->transformations & PNG_INTERLACE)) { - png_do_write_interlace(&(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->pass); + png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); /* This should always get caught above, but still ... */ - if (!(png_ptr->row_info.width)) + if (!(row_info.width)) { png_write_finish_row(png_ptr); return; @@ -771,9 +769,16 @@ png_write_row(png_structp png_ptr, png_const_bytep row) #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED /* Handle other transformations */ if (png_ptr->transformations) - png_do_write_transformations(png_ptr); + png_do_write_transformations(png_ptr, &row_info); #endif + /* At this point the row_info pixel depth must match the 'transformed' depth, + * which is also the output depth. + */ + if (row_info.pixel_depth != png_ptr->pixel_depth || + row_info.pixel_depth != png_ptr->transformed_pixel_depth) + png_error(png_ptr, "internal write transform logic error"); + #ifdef PNG_MNG_FEATURES_SUPPORTED /* Write filter_method 64 (intrapixel differencing) only if * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and @@ -788,12 +793,12 @@ png_write_row(png_structp png_ptr, png_const_bytep row) (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ - png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); } #endif /* Find a filter if necessary, filter the row and write it out. */ - png_write_find_filter(png_ptr, &(png_ptr->row_info)); + png_write_find_filter(png_ptr, &row_info); if (png_ptr->write_row_fn != NULL) (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); @@ -879,13 +884,7 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) png_debug(1, "in png_destroy_write_struct"); if (png_ptr_ptr != NULL) - { png_ptr = *png_ptr_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - free_fn = png_ptr->free_fn; - mem_ptr = png_ptr->mem_ptr; -#endif - } #ifdef PNG_USER_MEM_SUPPORTED if (png_ptr != NULL) diff --git a/pngwtran.c b/pngwtran.c index 124d708c4..fc9fa16d2 100644 --- a/pngwtran.c +++ b/pngwtran.c @@ -1,7 +1,7 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * Last changed in libpng 1.5.4 [July 7, 2011] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -20,7 +20,7 @@ * transformations is significant. */ void /* PRIVATE */ -png_do_write_transformations(png_structp png_ptr) +png_do_write_transformations(png_structp png_ptr, png_row_infop row_info) { png_debug(1, "in png_do_write_transformations"); @@ -32,8 +32,8 @@ png_do_write_transformations(png_structp png_ptr) if (png_ptr->write_user_transform_fn != NULL) (*(png_ptr->write_user_transform_fn)) /* User write transform function */ - (png_ptr, /* png_ptr */ - &(png_ptr->row_info), /* row_info: */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ /* png_uint_32 width; width of row */ /* png_size_t rowbytes; number of bytes in row */ /* png_byte color_type; color type of pixels */ @@ -45,50 +45,50 @@ png_do_write_transformations(png_structp png_ptr) #ifdef PNG_WRITE_FILLER_SUPPORTED if (png_ptr->transformations & PNG_FILLER) - png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_strip_channel(row_info, png_ptr->row_buf + 1, !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); #endif #ifdef PNG_WRITE_PACKSWAP_SUPPORTED if (png_ptr->transformations & PNG_PACKSWAP) - png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_packswap(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_WRITE_PACK_SUPPORTED if (png_ptr->transformations & PNG_PACK) - png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_pack(row_info, png_ptr->row_buf + 1, (png_uint_32)png_ptr->bit_depth); #endif #ifdef PNG_WRITE_SWAP_SUPPORTED if (png_ptr->transformations & PNG_SWAP_BYTES) - png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_swap(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_WRITE_SHIFT_SUPPORTED if (png_ptr->transformations & PNG_SHIFT) - png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_do_shift(row_info, png_ptr->row_buf + 1, &(png_ptr->shift)); #endif #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED if (png_ptr->transformations & PNG_SWAP_ALPHA) - png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED if (png_ptr->transformations & PNG_INVERT_ALPHA) - png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_WRITE_BGR_SUPPORTED if (png_ptr->transformations & PNG_BGR) - png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_bgr(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_WRITE_INVERT_SUPPORTED if (png_ptr->transformations & PNG_INVERT_MONO) - png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); + png_do_invert(row_info, png_ptr->row_buf + 1); #endif } diff --git a/pngwutil.c b/pngwutil.c index bafa4067d..a9ebbce36 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1,7 +1,7 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.5.5 [(PENDING RELEASE)] + * Last changed in libpng 1.5.6 [(PENDING RELEASE)] * Copyright (c) 1998-2011 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.) @@ -82,38 +82,17 @@ png_write_sig(png_structp png_ptr) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; } -/* Write a PNG chunk all at once. The type is an array of ASCII characters - * representing the chunk name. The array must be at least 4 bytes in - * length, and does not need to be null terminated. To be safe, pass the - * pre-defined chunk names here, and if you need a new one, define it - * where the others are defined. The length is the length of the data. - * All the data must be present. If that is not possible, use the - * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() - * functions instead. - */ -void PNGAPI -png_write_chunk(png_structp png_ptr, png_const_bytep chunk_name, - png_const_bytep data, png_size_t length) -{ - if (png_ptr == NULL) - return; - - png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); - png_write_chunk_data(png_ptr, data, (png_size_t)length); - png_write_chunk_end(png_ptr); -} - /* Write the start of a PNG chunk. The type is the chunk type. * The total_length is the sum of the lengths of all the data you will be * passing in png_write_chunk_data(). */ -void PNGAPI -png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, +static void +png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name, png_uint_32 length) { png_byte buf[8]; - png_debug2(0, "Writing %s chunk, length = %lu", chunk_name, + png_debug2(0, "Writing %s chunk, length = %lu", chunk_string, (unsigned long)length); if (png_ptr == NULL) @@ -128,16 +107,16 @@ png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, /* Write the length and the chunk name */ png_save_uint_32(buf, length); - png_memcpy(buf + 4, chunk_name, 4); - png_write_data(png_ptr, buf, (png_size_t)8); + png_save_uint_32(buf + 4, chunk_name); + png_write_data(png_ptr, buf, 8); /* Put the chunk name into png_ptr->chunk_name */ - png_memcpy(png_ptr->chunk_name, chunk_name, 4); + png_ptr->chunk_name = chunk_name; /* Reset the crc and run it over the chunk name */ png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, chunk_name, 4); + png_calculate_crc(png_ptr, buf + 4, 4); #ifdef PNG_IO_STATE_SUPPORTED /* Inform the I/O callback that chunk data will (possibly) be written. @@ -147,10 +126,17 @@ png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, #endif } -/* Write the data of a PNG chunk started with png_write_chunk_start(). +void PNGAPI +png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string, + png_uint_32 length) +{ + png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); +} + +/* Write the data of a PNG chunk started with png_write_chunk_header(). * Note that multiple calls to this function are allowed, and that the * sum of the lengths from these calls *must* add up to the total_length - * given to png_write_chunk_start(). + * given to png_write_chunk_header(). */ void PNGAPI png_write_chunk_data(png_structp png_ptr, png_const_bytep data, @@ -171,7 +157,7 @@ png_write_chunk_data(png_structp png_ptr, png_const_bytep data, } } -/* Finish a chunk started with png_write_chunk_start(). */ +/* Finish a chunk started with png_write_chunk_header(). */ void PNGAPI png_write_chunk_end(png_structp png_ptr) { @@ -192,6 +178,40 @@ png_write_chunk_end(png_structp png_ptr) png_write_data(png_ptr, buf, (png_size_t)4); } +/* Write a PNG chunk all at once. The type is an array of ASCII characters + * representing the chunk name. The array must be at least 4 bytes in + * length, and does not need to be null terminated. To be safe, pass the + * pre-defined chunk names here, and if you need a new one, define it + * where the others are defined. The length is the length of the data. + * All the data must be present. If that is not possible, use the + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() + * functions instead. + */ +static void +png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name, + png_const_bytep data, png_size_t length) +{ + if (png_ptr == NULL) + return; + + /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ + if (length > PNG_UINT_32_MAX) + png_error(png_ptr, "length exceeds PNG maxima"); + + png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); + png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); +} + +/* This is the API that calls the internal function above. */ +void PNGAPI +png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string, + png_const_bytep data, png_size_t length) +{ + png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, + length); +} + /* Initialize the compressor for the appropriate type of compression. */ static void png_zlib_claim(png_structp png_ptr, png_uint_32 state) @@ -652,8 +672,6 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int compression_type, int filter_type, int interlace_type) { - PNG_IHDR; - png_byte buf[13]; /* Buffer to store the IHDR info */ png_debug(1, "in png_write_IHDR"); @@ -795,7 +813,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, buf[12] = (png_byte)interlace_type; /* Write the chunk */ - png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); + png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); /* Initialize zlib with PNG info */ png_ptr->zstream.zalloc = png_zalloc; @@ -872,7 +890,6 @@ void /* PRIVATE */ png_write_PLTE(png_structp png_ptr, png_const_colorp palette, png_uint_32 num_pal) { - PNG_PLTE; png_uint_32 i; png_const_colorp pal_ptr; png_byte buf[3]; @@ -908,7 +925,7 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette, png_ptr->num_palette = (png_uint_16)num_pal; png_debug1(3, "num_palette = %d", png_ptr->num_palette); - png_write_chunk_start(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); + png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); #ifdef PNG_POINTER_INDEXING_SUPPORTED for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) @@ -942,8 +959,6 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette, void /* PRIVATE */ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) { - PNG_IDAT; - png_debug(1, "in png_write_IDAT"); #ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED @@ -1014,7 +1029,7 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) } #endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ - png_write_chunk(png_ptr, png_IDAT, data, length); + png_write_complete_chunk(png_ptr, png_IDAT, data, length); png_ptr->mode |= PNG_HAVE_IDAT; /* Prior to 1.5.4 this code was replicated in every caller (except at the @@ -1029,11 +1044,9 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) void /* PRIVATE */ png_write_IEND(png_structp png_ptr) { - PNG_IEND; - png_debug(1, "in png_write_IEND"); - png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); + png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); png_ptr->mode |= PNG_HAVE_IEND; } @@ -1042,14 +1055,13 @@ png_write_IEND(png_structp png_ptr) void /* PRIVATE */ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) { - PNG_gAMA; png_byte buf[4]; png_debug(1, "in png_write_gAMA"); /* file_gamma is saved in 1/100,000ths */ png_save_uint_32(buf, (png_uint_32)file_gamma); - png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); + png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); } #endif @@ -1058,7 +1070,6 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) void /* PRIVATE */ png_write_sRGB(png_structp png_ptr, int srgb_intent) { - PNG_sRGB; png_byte buf[1]; png_debug(1, "in png_write_sRGB"); @@ -1068,7 +1079,7 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) "Invalid sRGB rendering intent specified"); buf[0]=(png_byte)srgb_intent; - png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); + png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); } #endif @@ -1078,7 +1089,6 @@ void /* PRIVATE */ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, png_const_charp profile, int profile_len) { - PNG_iCCP; png_size_t name_len; png_charp new_name; compression_state comp; @@ -1139,7 +1149,7 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); /* Make sure we include the NULL after the name and the compression type */ - png_write_chunk_start(png_ptr, png_iCCP, + png_write_chunk_header(png_ptr, png_iCCP, (png_uint_32)(name_len + profile_len + 2)); new_name[name_len + 1] = 0x00; @@ -1163,7 +1173,6 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, void /* PRIVATE */ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) { - PNG_sPLT; png_size_t name_len; png_charp new_name; png_byte entrybuf[10]; @@ -1180,7 +1189,7 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) return; /* Make sure we include the NULL after the name */ - png_write_chunk_start(png_ptr, png_sPLT, + png_write_chunk_header(png_ptr, png_sPLT, (png_uint_32)(name_len + 2 + palette_size)); png_write_chunk_data(png_ptr, (png_bytep)new_name, @@ -1248,7 +1257,6 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) void /* PRIVATE */ png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) { - PNG_sBIT; png_byte buf[4]; png_size_t size; @@ -1299,7 +1307,7 @@ png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) buf[size++] = sbit->alpha; } - png_write_chunk(png_ptr, png_sBIT, buf, size); + png_write_complete_chunk(png_ptr, png_sBIT, buf, size); } #endif @@ -1311,7 +1319,6 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, png_fixed_point blue_y) { - PNG_cHRM; png_byte buf[32]; png_debug(1, "in png_write_cHRM"); @@ -1334,7 +1341,7 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, png_save_uint_32(buf + 24, (png_uint_32)blue_x); png_save_uint_32(buf + 28, (png_uint_32)blue_y); - png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); + png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); } } #endif @@ -1345,7 +1352,6 @@ void /* PRIVATE */ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, png_const_color_16p tran, int num_trans, int color_type) { - PNG_tRNS; png_byte buf[6]; png_debug(1, "in png_write_tRNS"); @@ -1359,7 +1365,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, } /* Write the chunk out as it is */ - png_write_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); + png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); } else if (color_type == PNG_COLOR_TYPE_GRAY) @@ -1374,7 +1380,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, } png_save_uint_16(buf, tran->gray); - png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); + png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); } else if (color_type == PNG_COLOR_TYPE_RGB) @@ -1394,7 +1400,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, return; } - png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); + png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); } else @@ -1409,7 +1415,6 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, void /* PRIVATE */ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) { - PNG_bKGD; png_byte buf[6]; png_debug(1, "in png_write_bKGD"); @@ -1428,7 +1433,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) } buf[0] = back->index; - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); } else if (color_type & PNG_COLOR_MASK_COLOR) @@ -1448,7 +1453,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) return; } - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); } else @@ -1462,7 +1467,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) } png_save_uint_16(buf, back->gray); - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); + png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); } } #endif @@ -1472,7 +1477,6 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) void /* PRIVATE */ png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) { - PNG_hIST; int i; png_byte buf[3]; @@ -1487,7 +1491,7 @@ png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) return; } - png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); + png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); for (i = 0; i < num_hist; i++) { @@ -1637,7 +1641,6 @@ void /* PRIVATE */ png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, png_size_t text_len) { - PNG_tEXt; png_size_t key_len; png_charp new_key; @@ -1653,7 +1656,7 @@ png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, text_len = png_strlen(text); /* Make sure we include the 0 after the key */ - png_write_chunk_start(png_ptr, png_tEXt, + png_write_chunk_header(png_ptr, png_tEXt, (png_uint_32)(key_len + text_len + 1)); /* * We leave it to the application to meet PNG-1.0 requirements on the @@ -1679,7 +1682,6 @@ void /* PRIVATE */ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, png_size_t text_len, int compression) { - PNG_zTXt; png_size_t key_len; png_byte buf; png_charp new_key; @@ -1713,7 +1715,7 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, &comp); /* Write start of chunk */ - png_write_chunk_start(png_ptr, png_zTXt, + png_write_chunk_header(png_ptr, png_zTXt, (png_uint_32)(key_len+text_len + 2)); /* Write key */ @@ -1742,7 +1744,6 @@ void /* PRIVATE */ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, png_const_charp lang, png_const_charp lang_key, png_const_charp text) { - PNG_iTXt; png_size_t lang_len, key_len, lang_key_len, text_len; png_charp new_lang; png_charp new_key = NULL; @@ -1787,7 +1788,7 @@ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, * and the NULs after the key, lang, and lang_key parts */ - png_write_chunk_start(png_ptr, png_iTXt, (png_uint_32)( + png_write_chunk_header(png_ptr, png_iTXt, (png_uint_32)( 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ + key_len + lang_len @@ -1836,7 +1837,6 @@ void /* PRIVATE */ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type) { - PNG_oFFs; png_byte buf[9]; png_debug(1, "in png_write_oFFs"); @@ -1848,7 +1848,7 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_save_int_32(buf + 4, y_offset); buf[8] = (png_byte)unit_type; - png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); + png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); } #endif #ifdef PNG_WRITE_pCAL_SUPPORTED @@ -1858,7 +1858,6 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_const_charp units, png_charpp params) { - PNG_pCAL; png_size_t purpose_len, units_len, total_len; png_size_tp params_len; png_byte buf[10]; @@ -1891,7 +1890,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, } png_debug1(3, "pCAL total length = %d", (int)total_len); - png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); + png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len); png_save_int_32(buf, X0); png_save_int_32(buf + 4, X1); @@ -1918,7 +1917,6 @@ void /* PRIVATE */ png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, png_const_charp height) { - PNG_sCAL; png_byte buf[64]; png_size_t wlen, hlen, total_len; @@ -1939,7 +1937,7 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_chunk(png_ptr, png_sCAL, buf, total_len); + png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); } #endif @@ -1950,7 +1948,6 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int unit_type) { - PNG_pHYs; png_byte buf[9]; png_debug(1, "in png_write_pHYs"); @@ -1962,7 +1959,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_save_uint_32(buf + 4, y_pixels_per_unit); buf[8] = (png_byte)unit_type; - png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); + png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); } #endif @@ -1973,7 +1970,6 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, void /* PRIVATE */ png_write_tIME(png_structp png_ptr, png_const_timep mod_time) { - PNG_tIME; png_byte buf[7]; png_debug(1, "in png_write_tIME"); @@ -1993,7 +1989,7 @@ png_write_tIME(png_structp png_ptr, png_const_timep mod_time) buf[5] = mod_time->minute; buf[6] = mod_time->second; - png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); + png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); } #endif @@ -2005,28 +2001,32 @@ png_write_start_row(png_structp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif - png_size_t buf_size; + png_alloc_size_t buf_size; + int usr_pixel_depth; png_debug(1, "in png_write_start_row"); - buf_size = (png_size_t)(PNG_ROWBYTES( - png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); + usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; + buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; + + /* 1.5.6: added to allow checking in the row write code. */ + png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; + png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; /* Set up row buffer */ - png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)buf_size); + png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; @@ -2043,8 +2043,7 @@ png_write_start_row(png_structp png_ptr) if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) { /* Set up previous row buffer */ - png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)buf_size); + png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); if (png_ptr->do_filter & PNG_FILTER_UP) { @@ -2112,16 +2111,16 @@ png_write_finish_row(png_structp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif int ret; @@ -2239,10 +2238,10 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_write_interlace"); @@ -2410,7 +2409,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_structp png_ptr, png_bytep filtered_row); +static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, + png_size_t row_bytes); #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) #define PNG_HISHIFT 10 @@ -2426,7 +2426,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_byte filter_to_do = png_ptr->do_filter; png_size_t row_bytes = row_info->rowbytes; #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - int num_p_filters = (int)png_ptr->num_prev_filters; + int num_p_filters = png_ptr->num_prev_filters; #endif png_debug(1, "in png_write_find_filter"); @@ -3063,9 +3063,9 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) } } #endif /* PNG_WRITE_FILTER_SUPPORTED */ - /* Do the actual writing of the filtered row data from the chosen filter. */ - png_write_filtered_row(png_ptr, best_row); + /* Do the actual writing of the filtered row data from the chosen filter. */ + png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); #ifdef PNG_WRITE_FILTER_SUPPORTED #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED @@ -3088,10 +3088,9 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) /* Do the actual writing of a previously filtered row. */ static void -png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) +png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, + png_size_t avail/*includes filter byte*/) { - png_size_t avail; - png_debug(1, "in png_write_filtered_row"); png_debug1(2, "filter = %d", filtered_row[0]); @@ -3099,7 +3098,6 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) png_ptr->zstream.next_in = filtered_row; png_ptr->zstream.avail_in = 0; - avail = png_ptr->row_info.rowbytes + 1; /* Repeat until we have compressed all the data */ do { diff --git a/projects/vstudio/readme.txt b/projects/vstudio/readme.txt index 1e2a261f4..0d22d43c9 100644 --- a/projects/vstudio/readme.txt +++ b/projects/vstudio/readme.txt @@ -1,7 +1,7 @@ VisualStudio instructions -libpng version 1.5.6beta01 - September 22, 2011 +libpng version 1.5.6beta02 - September 22, 2011 Copyright (c) 1998-2010 Glenn Randers-Pehrson diff --git a/projects/vstudio/zlib.props b/projects/vstudio/zlib.props index 10d9442fe..3810da7b6 100644 --- a/projects/vstudio/zlib.props +++ b/projects/vstudio/zlib.props @@ -2,7 +2,7 @@