diff -ru4NwbB libpng-1.6.0beta34/Makefile.am libpng-1.7.0alpha04/Makefile.am --- libpng-1.6.0beta34/Makefile.am 2012-12-19 16:07:03.696288086 -0600 +++ libpng-1.7.0alpha04/Makefile.am 2012-12-22 18:00:54.243987855 -0600 @@ -119,8 +119,10 @@ scripts/sym.out scripts/vers.out: png.h pngconf.h pnglibconf.h scripts/prefix.out: png.h pngconf.h pnglibconf.out scripts/symbols.out: png.h pngconf.h $(srcdir)/scripts/pnglibconf.h.prebuilt +pnglibconf.out: config.h + libpng.sym: scripts/sym.out rm -f $@ cp $? $@ libpng.vers: scripts/vers.out @@ -130,9 +132,9 @@ if DO_PNG_PREFIX # Rename functions in scripts/prefix.out with a PNG_PREFIX prefix. # Rename macros in scripts/macro.lst from PNG_PREFIXpng_ to PNG_ (the actual # implementation of the macro). -pnglibconf.h: pnglibconf.out scripts/prefix.out scripts/macro.lst +pnglibconf.h: pnglibconf.out scripts/prefix.out scripts/macro.lst config.h rm -f $@ $(AWK) 's==0 && NR>1{print prev}\ s==0{prev=$$0}\ s==1{print "#define", $$1, "@PNG_PREFIX@" $$1}\ diff -ru4NwbB libpng-1.6.0beta34/arm/arm_init.c libpng-1.7.0alpha04/arm/arm_init.c --- libpng-1.6.0beta34/arm/arm_init.c 2012-12-15 07:25:15.067576000 -0600 +++ libpng-1.7.0alpha04/arm/arm_init.c 2012-12-15 20:42:25.000000000 -0600 @@ -2,9 +2,9 @@ /* arm_init.c - NEON optimised filter functions * * Copyright (c) 2012 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.5.14 [(PENDING RELEASE)] + * Last changed in libpng 1.6.0 [(PENDING RELEASE)] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h @@ -42,9 +42,9 @@ } #endif /* __linux__ && __arm__ */ void -png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +png_init_filter_functions_neon(png_structrp pp, unsigned int bpp) { #ifdef __arm__ #ifdef __linux__ if (!png_have_hwcap(HWCAP_NEON)) diff -ru4NwbB libpng-1.6.0beta34/configure.ac libpng-1.7.0alpha04/configure.ac --- libpng-1.6.0beta34/configure.ac 2012-12-19 16:07:03.703840684 -0600 +++ libpng-1.7.0alpha04/configure.ac 2012-12-22 18:00:54.251043343 -0600 @@ -38,9 +38,9 @@ dnl stop configure from automagically running automake PNGLIB_VERSION=1.7.0alpha04 PNGLIB_MAJOR=1 -PNGLIB_MINOR=6 +PNGLIB_MINOR=7 PNGLIB_RELEASE=%RELEASE% dnl End of version number stuff @@ -114,33 +114,142 @@ fi],) # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([malloc.h stdlib.h string.h strings.h]) +# Headers used in pngpriv.h: +AC_CHECK_HEADERS([stdlib.h string.h float.h fp.h math.h m68881.h]) +# Additional headers used in pngconf.h: +AC_CHECK_HEADERS([limits.h stddef.h stdio.h setjmp.h time.h]) +# Used by pngread.c (for the simplified API): +AC_CHECK_HEADERS([errno.h]) +# The following are not required for the standard 'make' build of libpng: +# Additional requirements of contrib/libtests/makepng.c: +AC_CHECK_HEADERS([ctype.h]) +# Additional requirements of contrib/libtests/pngvalid.c: +AC_CHECK_HEADERS([fenv.h]) +# Additional requirements of contrib/libtests/tarith.c: +AC_CHECK_HEADERS([assert.h]) # Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_TYPE_SIZE_T -AC_STRUCT_TM +# Most of these have been removed from 1.7.0 because they checked for non-ANSI-C +# behaviors and the result were, anyway, not used by earlier versions of libpng. AC_C_RESTRICT -# Checks for library functions. -AC_FUNC_STRTOD -AC_CHECK_FUNCS([memset], , AC_MSG_ERROR(memset not found in libc)) -AC_CHECK_FUNCS([pow], , AC_CHECK_LIB(m, pow, , AC_MSG_ERROR(cannot find pow)) ) -AC_ARG_WITH(zlib-prefix, - AS_HELP_STRING([[[--with-zlib-prefix]]], - [prefix that may have been used in installed zlib]), - [ZPREFIX=${withval}], - [ZPREFIX='z_']) -AC_CHECK_LIB(z, zlibVersion, , - AC_CHECK_LIB(z, ${ZPREFIX}zlibVersion, , AC_MSG_ERROR(zlib not installed))) +# Checks for library functions; these need to be in order, least demanding to +# most because the -l directives are added to the head of the list at each +# check. +# ANSI-C functions: all are required but they don't have to be implemented in +# libc, it is perfectly ok to configure with an extra, wrapper, library preset +# in LIBS. NOTE: this list may not be complete +AC_CHECK_FUNCS([memset memcpy strncpy],, + AC_MSG_FAILURE([missing ANSI-C functions])) + +# floor and ceil are required for FLOATING_POINT, but they can be turned off on +# the configure command line (and they are independent.) Default is to 'on' +AC_ARG_ENABLE([floating-point],[Enable floating point APIs],, + [enable_floating_point=yes]) +AC_ARG_ENABLE([fixed-point],[Enable fixed point APIs],, + [enable_fixed_point=yes]) +AC_ARG_ENABLE([floating-arithmetic],[Use floating point arithmetic internally],, + [enable_floating_arithmetic=yes]) + +# Check for a requirement for math library support +if test "$enable_floating_arithmetic" = yes +then + AC_SEARCH_LIBS([floor],[m],, + [AC_MSG_WARN([not found]) + enable_floating_arithmetic=no]) + AC_SEARCH_LIBS([frexp],[m],, + [AC_MSG_WARN([not found]) + enable_floating_arithmetic=no]) + AC_SEARCH_LIBS([modf],[m],, + [AC_MSG_WARN([not found]) + enable_floating_arithmetic=no]) + AC_SEARCH_LIBS([atof],[m],, + [AC_MSG_WARN([not found]) + enable_floating_arithmetic=no]) + AC_SEARCH_LIBS([pow],[m],, + [AC_MSG_WARN([not found]) + enable_floating_arithmetic=no]) +fi + +# Set the relevant defines if required (only if required), this will override +# anything on the command line. +if test "$enable_floating_point" != yes +then + AC_MSG_NOTICE([Floating point APIs disabled]) + AC_DEFINE([PNG_NO_FLOATING_POINT],[1], + [No support for floating point APIs]) +fi +if test "$enable_fixed_point" != yes +then + AC_MSG_NOTICE([Fixed point APIs disabled]) + AC_DEFINE([PNG_NO_FIXED_POINT],[1], + [No support for fixed point APIs]) +fi +if test "$enable_floating_arithmetic" != yes +then + AC_MSG_NOTICE([Fixed point arithmetic will be used]) + AC_DEFINE([PNG_NO_FLOATING_ARITHMETIC],[1], + [No support for floating point arithmetic]) +fi # The following is for pngvalid, to ensure it catches FP errors even on # platforms that don't enable FP exceptions, the function appears in the math # library (typically), it's not an error if it is not found. -AC_CHECK_LIB([m], [feenableexcept]) -AC_CHECK_FUNCS([feenableexcept]) +AC_SEARCH_LIBS([feenableexcept],[m],AC_DEFINE([HAVE_FEENABLEEXCEPT],[1], + [Define to 1 if the feenableexcept function is available])) +# Required by pngvalid: +AC_SEARCH_LIBS([ceil],[m]) + +# zlib checks and arguments; +# package zlib: argument is the name of the library +# zlib-header: the name of the header file +# zlib-prefix: the prefix for library functions, if any +AC_ARG_WITH([zlib], + AS_HELP_STRING([[[--with-zlib=]]], + [base name of the zlib implementation (e.g. 'z')]),, + [with_zlib='z']) + +z_prefix= +AC_ARG_WITH([zlib-prefix], + AS_HELP_STRING([[[--with-zlib-prefix=]]], + [prefix for zlib API functions]), + [if test "$withval" = "" -o "$withval" = yes; then + with_zlib_prefix='z_' + AC_DEFINE([PNG_ZLIB_PREFIX],[z_],[Standard zlib prefix]) + elif test "${withval}" != "no"; then + AC_DEFINE_UNQUOTED([PNG_ZLIB_PREFIX],[${withval}], + [User defined zlib prefix]) + else + with_zlib_prefix= + fi + if test "$with_zlib_prefix" != ""; then + AC_DEFINE([Z_PREFIX],[1],[Tell zlib.h to prefix function names]) + z_prefix="#define Z_PREFIX 1" + fi]) + +AC_ARG_WITH([zlib-header], + AS_HELP_STRING([[[--with-zlib-header='' or '"file"']]], + [C include argument to locate zlib header file, e.g. , take + care to put single quotes round this on the command line]), + [AC_DEFINE_UNQUOTED([PNG_ZLIB_HEADER],[${withval}],[Zlib header file])], + with_zlib_header='') + +# AC_CHECK_LIB isn't quite enough for this because we need the special header +# file too. +LIBS="-l${with_zlib} $LIBS" +AC_MSG_CHECKING( + [[Library '${with_zlib}' and #include ${with_zlib_header} for symbol '${with_zlib_prefix}zlibVersion']]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +${z_prefix} +#include ${with_zlib_header} + ]], + [[(void)${with_zlib_prefix}zlibVersion();]])], + AC_MSG_RESULT([ok]), + AC_MSG_FAILURE([not found])) AC_MSG_CHECKING([if using Solaris linker]) SLD=`$LD --version 2>&1 | grep Solaris` if test "$SLD"; then @@ -251,9 +360,8 @@ AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]]) # Config files, substituting as above -AC_CONFIG_FILES([Makefile libpng.pc:libpng.pc.in]) -AC_CONFIG_FILES([libpng-config:libpng-config.in], - [chmod +x libpng-config]) +AC_CONFIG_FILES([Makefile libpng.pc]) +AC_CONFIG_FILES([libpng-config], [chmod +x libpng-config]) AC_OUTPUT diff -ru4NwbB libpng-1.6.0beta34/contrib/gregbook/Makefile.sgi libpng-1.7.0alpha04/contrib/gregbook/Makefile.sgi --- libpng-1.6.0beta34/contrib/gregbook/Makefile.sgi 2012-12-19 16:06:53.240743423 -0600 +++ libpng-1.7.0alpha04/contrib/gregbook/Makefile.sgi 2012-12-22 18:00:42.667294623 -0600 @@ -22,11 +22,11 @@ # macros -------------------------------------------------------------------- -PNGINC = -I/usr/local/include/libpng16 -PNGLIB = -L/usr/local/lib -lpng16 # dynamically linked against libpng -#PNGLIB = /usr/local/lib/libpng16.a # statically linked against libpng +PNGINC = -I/usr/local/include/libpng17 +PNGLIB = -L/usr/local/lib -lpng17 # dynamically linked against libpng +#PNGLIB = /usr/local/lib/libpng17.a # statically linked against libpng # or: #PNGINC = -I../.. #PNGLIB = -L../.. -lpng #PNGLIB = ../../libpng.a diff -ru4NwbB libpng-1.6.0beta34/contrib/gregbook/Makefile.unx libpng-1.7.0alpha04/contrib/gregbook/Makefile.unx --- libpng-1.6.0beta34/contrib/gregbook/Makefile.unx 2012-12-19 16:06:53.250672055 -0600 +++ libpng-1.7.0alpha04/contrib/gregbook/Makefile.unx 2012-12-22 18:00:42.676978753 -0600 @@ -25,16 +25,16 @@ # macros -------------------------------------------------------------------- #PNGDIR = /usr/local/lib -#PNGINC = -I/usr/local/include/libpng16 -#PNGLIBd = -L$(PNGDIR) -lpng16 # dynamically linked, installed libpng -#PNGLIBs = $(PNGDIR)/libpng16.a # statically linked, installed libpng +#PNGINC = -I/usr/local/include/libpng17 +#PNGLIBd = -L$(PNGDIR) -lpng17 # dynamically linked, installed libpng +#PNGLIBs = $(PNGDIR)/libpng17.a # statically linked, installed libpng # or: PNGDIR = ../..# this one is for libpng-x.y.z/contrib/gregbook builds #PNGDIR = ../libpng PNGINC = -I$(PNGDIR) -PNGLIBd = -Wl,-rpath,$(PNGDIR) -L$(PNGDIR) -lpng16 # dynamically linked +PNGLIBd = -Wl,-rpath,$(PNGDIR) -L$(PNGDIR) -lpng17 # dynamically linked PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng ZDIR = /usr/local/lib #ZDIR = /usr/lib64 diff -ru4NwbB libpng-1.6.0beta34/contrib/libtests/pngvalid.c libpng-1.7.0alpha04/contrib/libtests/pngvalid.c --- libpng-1.6.0beta34/contrib/libtests/pngvalid.c 2012-12-19 16:06:55.809323029 -0600 +++ libpng-1.7.0alpha04/contrib/libtests/pngvalid.c 2012-12-22 18:00:45.300575955 -0600 @@ -38,10 +38,12 @@ * than the one being built here: */ #ifdef PNG_FREESTANDING_TESTS # include +# include /* For crc32 */ #else # include "../../png.h" +# include PNG_ZLIB_HEADER #endif #ifdef PNG_WRITE_SUPPORTED /* else pngvalid can do nothing */ @@ -87,10 +89,8 @@ */ # define png_const_structp png_structp #endif -#include /* For crc32 */ - #include /* For floating point constants */ #include /* For malloc */ #include /* For memcpy, memset */ #include /* For floor */ @@ -343,13 +343,18 @@ #define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1U : 16U) static int next_format(png_bytep colour_type, png_bytep bit_depth, - unsigned int* palette_number) + unsigned int* palette_number, int no_low_depth_gray) { if (*bit_depth == 0) { - *colour_type = 0, *bit_depth = 1, *palette_number = 0; + *colour_type = 0; + if (no_low_depth_gray) + *bit_depth = 8; + else + *bit_depth = 1; + *palette_number = 0; return 1; } if (*colour_type == 3) @@ -1827,8 +1832,9 @@ double maxpc8; /* Percentage sample error 0..100% */ double maxout16; /* Maximum output value error */ double maxabs16; /* Absolute sample error 0..1 */ double maxcalc16;/* Absolute sample error 0..1 */ + double maxcalcG; /* Absolute sample error 0..1 */ double maxpc16; /* Percentage sample error 0..100% */ /* This is set by transforms that need to allow a higher limit, it is an * internal check on pngvalid to ensure that the calculated error limits are @@ -1866,12 +1872,17 @@ /* Run the odd-sized image and interlace read/write tests? */ unsigned int test_size :1; - /* Run tests on reading with a combiniation of transforms, */ + /* Run tests on reading with a combination of transforms, */ unsigned int test_transform :1; - /* When to use the use_input_precision option: */ + /* When to use the use_input_precision option, this controls the gamma + * validation code checks. If set any value that is within the transformed + * range input-.5 to input+.5 will be accepted, otherwise the value must be + * within the normal limits. It should not be necessary to set this; the + * result should always be exact within the permitted error limits. + */ unsigned int use_input_precision :1; unsigned int use_input_precision_sbit :1; unsigned int use_input_precision_16to8 :1; @@ -1879,10 +1890,10 @@ * precision, not the output precision. */ unsigned int calculations_use_input_precision :1; - /* If set assume that the calculations are done in 16 bits even if both input - * and output are 8 bit or less. + /* If set assume that the calculations are done in 16 bits even if the sample + * depth is 8 bits. */ unsigned int assume_16_bit_calculations :1; /* Which gamma tests to run: */ @@ -1935,8 +1946,9 @@ pm->repeat = 0; pm->test_uses_encoding = 0; pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0; pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0; + pm->maxcalcG = 0; pm->limit = 4E-3; pm->log8 = pm->log16 = 0; /* Means 'off' */ pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0; pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0; @@ -1949,8 +1961,9 @@ pm->use_input_precision = 0; pm->use_input_precision_sbit = 0; pm->use_input_precision_16to8 = 0; pm->calculations_use_input_precision = 0; + pm->assume_16_bit_calculations = 0; pm->test_gamma_threshold = 0; pm->test_gamma_transform = 0; pm->test_gamma_sbit = 0; pm->test_gamma_scale16 = 0; @@ -1963,28 +1976,35 @@ /* Rely on the memset for all the other fields - there are no pointers */ } #ifdef PNG_READ_TRANSFORMS_SUPPORTED + +/* This controls use of checks that explicitly know how libpng digitizes the + * samples in calculations; setting this circumvents simple error limit checking + * in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5 + * algorithm. + */ +#define DIGITIZE PNG_LIBPNG_VER < 10700 + /* If pm->calculations_use_input_precision is set then operations will happen - * with only 8 bit precision unless both the input and output bit depth are 16. + * with the precision of the input, not the precision of the output depth. * * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16 * bit precision. This only affects those of the following limits that pertain * to a calculation - not a digitization operation - unless the following API is * called directly. */ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -static double digitize(PNG_CONST png_modifier *pm, double value, - int sample_depth, int do_round) +#if DIGITIZE +static double digitize(double value, int depth, int do_round) { /* 'value' is in the range 0 to 1, the result is the same value rounded to a * multiple of the digitization factor - 8 or 16 bits depending on both the * sample depth and the 'assume' setting. Digitization is normally by * rounding and 'do_round' should be 1, if it is 0 the digitized value will * be truncated. */ - PNG_CONST unsigned int digitization_factor = - (pm->assume_16_bit_calculations || sample_depth == 16) ? 65535 : 255; + PNG_CONST unsigned int digitization_factor = (1U << depth) -1; /* Limiting the range is done as a convenience to the caller - it's easier to * do it once here than every time at the call site. */ @@ -1997,33 +2018,32 @@ if (do_round) value += .5; return floor(value)/digitization_factor; } #endif +#endif /* RGB_TO_GRAY */ -#if (defined PNG_READ_GAMMA_SUPPORTED) ||\ - (defined PNG_READ_RGB_TO_GRAY_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED static double abserr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) { /* Absolute error permitted in linear values - affected by the bit depth of * the calculations. */ - if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 || - !pm->calculations_use_input_precision))) + if (pm->assume_16_bit_calculations || + (pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxabs16; else return pm->maxabs8; } -#endif -#ifdef PNG_READ_GAMMA_SUPPORTED static double calcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) { /* Error in the linear composition arithmetic - only relevant when * composition actually happens (0 < alpha < 1). */ - if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 || - !pm->calculations_use_input_precision))) + if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxcalc16; + else if (pm->assume_16_bit_calculations) + return pm->maxcalcG; else return pm->maxcalc8; } @@ -2031,10 +2051,10 @@ { /* Percentage error permitted in the linear values. Note that the specified * value is a percentage but this routine returns a simple number. */ - if (pm->assume_16_bit_calculations || (out_depth == 16 && (in_depth == 16 || - !pm->calculations_use_input_precision))) + if (pm->assume_16_bit_calculations || + (pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxpc16 * .01; else return pm->maxpc8 * .01; } @@ -2064,10 +2084,9 @@ if (out_depth == 4) return .90644-.5; - if (out_depth == 16 && (in_depth == 16 || - !pm->calculations_use_input_precision)) + if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxout16; /* This is the case where the value was calculated at 8-bit precision then * scaled to 16 bits. @@ -2098,10 +2117,9 @@ return pm->log8; } - if (out_depth == 16 && (in_depth == 16 || - !pm->calculations_use_input_precision)) + if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) { if (pm->log16 == 0) return 65536; @@ -2124,10 +2142,10 @@ */ static int output_quantization_factor(PNG_CONST png_modifier *pm, int in_depth, int out_depth) { - if (out_depth == 16 && in_depth != 16 - && pm->calculations_use_input_precision) + if (out_depth == 16 && in_depth != 16 && + pm->calculations_use_input_precision) return 257; else return 1; } @@ -3472,9 +3490,9 @@ /* Use next_format to enumerate all the combinations we test, including * generating multiple low bit depth palette images. */ - while (next_format(&colour_type, &bit_depth, &palette_number)) + while (next_format(&colour_type, &bit_depth, &palette_number, 0)) { int interlace_type; for (interlace_type = PNG_INTERLACE_NONE; @@ -5783,14 +5801,11 @@ png_byte in_sample_depth; memset(out_palette, 0x5e, sizeof out_palette); - /* assume-8-bit-calculations means assume that if the input has 8 bit - * (or less) samples and the output has 16 bit samples the calculations - * will be done with 8 bit precision, not 16. - * - * TODO: fix this in libpng; png_set_expand_16 should cause 16 bit - * calculations to be used throughout. + /* use-input-precision means assume that if the input has 8 bit (or less) + * samples and the output has 16 bit samples the calculations will be done + * with 8 bit precision, not 16. */ if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16) in_sample_depth = 8; else @@ -5799,9 +5814,10 @@ if (sample_depth != 16 || in_sample_depth > 8 || !dp->pm->calculations_use_input_precision) digitization_error = .5; - /* Else errors are at 8 bit precision, scale .5 in 8 bits to the 16 bits: + /* Else calculations are at 8 bit precision, and the output actually + * consists of scaled 8-bit values, so scale .5 in 8 bits to the 16 bits: */ else digitization_error = .5 * 257; } @@ -6615,12 +6631,25 @@ if (data.gamma != 1) /* Use gamma tables */ { if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations) { - /* The 16 bit case ends up producing a maximum error of about - * +/-5 in 65535, allow for +/-8 with the given gamma. - */ - that->pm->limit += pow(8./65535, data.gamma); + /* The computations have the form: + * + * r * rc + g * gc + b * bc + * + * Each component of which is +/-1/65535 from the gamma_to_1 table + * lookup, resulting in a base error of +/-6. The gamma_from_1 + * conversion adds another +/-2 in the 16-bit case and + * +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case. + */ + that->pm->limit += pow( +# if PNG_MAX_GAMMA_8 < 14 + (that->this.bit_depth == 16 ? 8. : + 6. + (1<<(15-PNG_MAX_GAMMA_8))) +# else + 8. +# endif + /65535, data.gamma); } else { @@ -6636,9 +6665,9 @@ { /* With no gamma correction a large error comes from the truncation of the * calculation in the 8 bit case, allow for that here. */ - if (that->this.bit_depth != 16) + if (that->this.bit_depth != 16 && !pm->assume_16_bit_calculations) that->pm->limit += 4E-3; } } @@ -6781,11 +6810,16 @@ if (that->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(that); /* Image now has RGB channels... */ +# if DIGITIZE { PNG_CONST png_modifier *pm = display->pm; - PNG_CONST unsigned int sample_depth = that->sample_depth; + const unsigned int sample_depth = that->sample_depth; + const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 : + sample_depth); + const unsigned int gamma_depth = (sample_depth == 16 ? 16 : + (pm->assume_16_bit_calculations ? PNG_MAX_GAMMA_8 : sample_depth)); int isgray; double r, g, b; double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi; @@ -6799,48 +6833,48 @@ * the future (this is just me trying to ensure it works!) */ r = rlo = rhi = that->redf; rlo -= that->rede; - rlo = digitize(pm, rlo, sample_depth, 1/*round*/); + rlo = digitize(rlo, calc_depth, 1/*round*/); rhi += that->rede; - rhi = digitize(pm, rhi, sample_depth, 1/*round*/); + rhi = digitize(rhi, calc_depth, 1/*round*/); g = glo = ghi = that->greenf; glo -= that->greene; - glo = digitize(pm, glo, sample_depth, 1/*round*/); + glo = digitize(glo, calc_depth, 1/*round*/); ghi += that->greene; - ghi = digitize(pm, ghi, sample_depth, 1/*round*/); + ghi = digitize(ghi, calc_depth, 1/*round*/); b = blo = bhi = that->bluef; blo -= that->bluee; - blo = digitize(pm, blo, sample_depth, 1/*round*/); + blo = digitize(blo, calc_depth, 1/*round*/); bhi += that->greene; - bhi = digitize(pm, bhi, sample_depth, 1/*round*/); + bhi = digitize(bhi, calc_depth, 1/*round*/); isgray = r==g && g==b; if (data.gamma != 1) { PNG_CONST double power = 1/data.gamma; - PNG_CONST double abse = abserr(pm, sample_depth, sample_depth); + PNG_CONST double abse = calc_depth == 16 ? .5/65535 : .5/255; /* 'abse' is the absolute error permitted in linear calculations. It * is used here to capture the error permitted in the handling * (undoing) of the gamma encoding. Once again digitization occurs * to handle the upper and lower bounds of the values. This is * where the real errors are introduced. */ r = pow(r, power); - rlo = digitize(pm, pow(rlo, power)-abse, sample_depth, 1); - rhi = digitize(pm, pow(rhi, power)+abse, sample_depth, 1); + rlo = digitize(pow(rlo, power)-abse, calc_depth, 1); + rhi = digitize(pow(rhi, power)+abse, calc_depth, 1); g = pow(g, power); - glo = digitize(pm, pow(glo, power)-abse, sample_depth, 1); - ghi = digitize(pm, pow(ghi, power)+abse, sample_depth, 1); + glo = digitize(pow(glo, power)-abse, calc_depth, 1); + ghi = digitize(pow(ghi, power)+abse, calc_depth, 1); b = pow(b, power); - blo = digitize(pm, pow(blo, power)-abse, sample_depth, 1); - bhi = digitize(pm, pow(bhi, power)+abse, sample_depth, 1); + blo = digitize(pow(blo, power)-abse, calc_depth, 1); + bhi = digitize(pow(bhi, power)+abse, calc_depth, 1); } /* Now calculate the actual gray values. Although the error in the * coefficients depends on whether they were specified on the command @@ -6855,20 +6889,20 @@ gray = r * data.red_coefficient + g * data.green_coefficient + b * data.blue_coefficient; { - PNG_CONST int do_round = data.gamma != 1 || sample_depth == 16; + PNG_CONST int do_round = data.gamma != 1 || calc_depth == 16; PNG_CONST double ce = 1. / 32768; - graylo = digitize(pm, rlo * (data.red_coefficient-ce) + + graylo = digitize(rlo * (data.red_coefficient-ce) + glo * (data.green_coefficient-ce) + - blo * (data.blue_coefficient-ce), sample_depth, do_round); + blo * (data.blue_coefficient-ce), gamma_depth, do_round); if (graylo <= 0) graylo = 0; - grayhi = digitize(pm, rhi * (data.red_coefficient+ce) + + grayhi = digitize(rhi * (data.red_coefficient+ce) + ghi * (data.green_coefficient+ce) + - bhi * (data.blue_coefficient+ce), sample_depth, do_round); + bhi * (data.blue_coefficient+ce), gamma_depth, do_round); if (grayhi >= 1) grayhi = 1; } @@ -6877,10 +6911,10 @@ { PNG_CONST double power = data.gamma; gray = pow(gray, power); - graylo = digitize(pm, pow(graylo, power), sample_depth, 1); - grayhi = digitize(pm, pow(grayhi, power), sample_depth, 1); + graylo = digitize(pow(graylo, power), sample_depth, 1); + grayhi = digitize(pow(grayhi, power), sample_depth, 1); } /* Now the error can be calculated. * @@ -6896,22 +6930,130 @@ if (fabs(gray - graylo) > err) err = fabs(graylo-gray); /* Check that this worked: */ - if (err > display->pm->limit) + if (err > pm->limit) + { + size_t pos = 0; + char buffer[128]; + + pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error "); + pos = safecatd(buffer, sizeof buffer, pos, err, 6); + pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); + pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); + png_error(pp, buffer); + } + } + } +# else /* DIGITIZE */ + { + double r = that->redf; + double re = that->rede; + double g = that->greenf; + double ge = that->greene; + double b = that->bluef; + double be = that->bluee; + + /* The true gray case involves no math. */ + if (r == g && r == b) + { + gray = r; + err = re; + if (err < ge) err = ge; + if (err < be) err = be; + } + + else if (data.gamma == 1) + { + /* There is no need to do the conversions to and from linear space, + * so the calculation should be a lot more accurate. There is a + * built in 1/32768 error in the coefficients because they only have + * 15 bits and are adjusted to make sure they add up to 32768, so + * the result may have an additional error up to 1/32768. (Note + * that adding the 1/32768 here avoids needing to increase the + * global error limits to take this into account.) + */ + gray = r * data.red_coefficient + g * data.green_coefficient + + b * data.blue_coefficient; + err = re * data.red_coefficient + ge * data.green_coefficient + + be * data.blue_coefficient + 1./32768 + gray * 5 * DBL_EPSILON; + } + + else + { + /* The calculation happens in linear space, and this produces much + * wider errors in the encoded space. These are handled here by + * factoring the errors in to the calculation. There are two table + * lookups in the calculation and each introduces a quantization + * error defined by the table size. + */ + PNG_CONST png_modifier *pm = display->pm; + double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255); + double out_qe = (that->sample_depth > 8 ? .5/65535 : + (pm->assume_16_bit_calculations ? .5/(1< 1) rhi = 1; + r -= re + in_qe; if (r < 0) r = 0; + ghi = g + ge + in_qe; if (ghi > 1) ghi = 1; + g -= ge + in_qe; if (g < 0) g = 0; + bhi = b + be + in_qe; if (bhi > 1) bhi = 1; + b -= be + in_qe; if (b < 0) b = 0; + + r = pow(r, g1)*(1-DBL_EPSILON); rhi = pow(rhi, g1)*(1+DBL_EPSILON); + g = pow(g, g1)*(1-DBL_EPSILON); ghi = pow(ghi, g1)*(1+DBL_EPSILON); + b = pow(b, g1)*(1-DBL_EPSILON); bhi = pow(bhi, g1)*(1+DBL_EPSILON); + + /* Work out the lower and upper bounds for the gray value in the + * encoded space, then work out an average and error. Remove the + * previously added input quantization error at this point. + */ + gray = r * data.red_coefficient + g * data.green_coefficient + + b * data.blue_coefficient - 1./32768 - out_qe; + if (gray <= 0) + gray = 0; + else + { + gray *= (1 - 6 * DBL_EPSILON); + gray = pow(gray, data.gamma) * (1-DBL_EPSILON); + } + + grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient + + bhi * data.blue_coefficient + 1./32768 + out_qe; + grayhi *= (1 + 6 * DBL_EPSILON); + if (grayhi >= 1) + grayhi = 1; + else + grayhi = pow(grayhi, data.gamma) * (1+DBL_EPSILON); + + err = (grayhi - gray) / 2; + gray = (grayhi + gray) / 2; + + if (err <= in_qe) + err = gray * DBL_EPSILON; + + else + err -= in_qe; + + /* Validate that the error is within limits (this has caused + * problems before, it's much easier to detect them here.) + */ + if (err > pm->limit) { size_t pos = 0; char buffer[128]; pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error "); pos = safecatd(buffer, sizeof buffer, pos, err, 6); pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); - pos = safecatd(buffer, sizeof buffer, pos, - display->pm->limit, 6); + pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); png_error(pp, buffer); } } } +# endif /* !DIGITIZE */ that->bluef = that->greenf = that->redf = gray; that->bluee = that->greene = that->rede = err; @@ -6958,9 +7100,9 @@ * png_set_background_fixed(png_structp, png_const_color_16p background_color, * int background_gamma_code, int need_expand, * png_fixed_point background_gamma) * - * As with rgb_to_gray this ignores the gamma (at present.) + * This ignores the gamma (at present.) */ #define data ITDATA(background) static image_pixel data; @@ -6969,8 +7111,9 @@ transform_display *that, png_structp pp, png_infop pi) { png_byte colour_type, bit_depth; png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */ + int expand; png_color_16 back; /* We need a background colour, because we don't know exactly what transforms * have been set we have to supply the colour in the original file format and @@ -6986,12 +7129,16 @@ if (colour_type == 3) { colour_type = PNG_COLOR_TYPE_RGB; bit_depth = 8; + expand = 0; /* passing in an RGB not a pixel index */ } else + { bit_depth = that->this.bit_depth; + expand = 1; + } image_pixel_init(&data, random_bytes, colour_type, bit_depth, 0/*x*/, 0/*unused: palette*/); @@ -7010,13 +7157,11 @@ else back.gray = (png_uint_16)data.red; # ifdef PNG_FLOATING_POINT_SUPPORTED - png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1/*need expand*/, - 0); + png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0); # else - png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, - 1/*need expand*/, 0); + png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0); # endif this->next->set(this->next, that, pp, pi); } @@ -7346,9 +7491,9 @@ png_byte colour_type = 0; png_byte bit_depth = 0; unsigned int palette_number = 0; - while (next_format(&colour_type, &bit_depth, &palette_number)) + while (next_format(&colour_type, &bit_depth, &palette_number, 0)) { png_uint_32 counter = 0; size_t base_pos; char name[64]; @@ -8031,16 +8176,27 @@ /* pass is set at this point if either of the tests above would have * passed. Don't do these additional tests here - just log the * original [es_lo..es_hi] values. */ - if (pass == 0 && vi->use_input_precision) + if (pass == 0 && vi->use_input_precision && vi->dp->sbit) { /* Ok, something is wrong - this actually happens in current libpng * 16-to-8 processing. Assume that the input value (id, adjusted * for sbit) can be anywhere between value-.5 and value+.5 - quite a * large range if sbit is low. + * + * NOTE: at present because the libpng gamma table stuff has been + * changed to use a rounding algorithm to correct errors in 8-bit + * calculations the precise sbit calculation (a shift) has been + * lost. This can result in up to a +/-1 error in the presence of + * an sbit less than the bit depth. */ - double tmp = (isbit - .5)/sbit_max; +# if PNG_LIBPNG_VER < 10700 +# define SBIT_ERROR .5 +# else +# define SBIT_ERROR 1. +# endif + double tmp = (isbit - SBIT_ERROR)/sbit_max; if (tmp <= 0) tmp = 0; @@ -8057,12 +8213,12 @@ if (is_lo < 0) is_lo = 0; - tmp = (isbit + .5)/sbit_max; + tmp = (isbit + SBIT_ERROR)/sbit_max; - if (tmp <= 0) - tmp = 0; + if (tmp >= 1) + tmp = 1; else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1) tmp = pow(tmp, vi->file_inverse); @@ -8377,9 +8533,9 @@ * * Because there is limited precision in the input it is arguable that * an acceptable result is any valid result from input-.5 to input+.5. * The basic tests below do not do this, however if 'use_input_precision' - * is set a subsequent test is performed below. + * is set a subsequent test is performed above. */ PNG_CONST unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U; int processing; png_uint_32 y; @@ -8719,9 +8875,9 @@ /* Don't test more than one instance of each palette - it's pointless, in * fact this test is somewhat excessive since libpng doesn't make this * decision based on colour type or bit depth! */ - while (next_format(&colour_type, &bit_depth, &palette_number)) + while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/)) if (palette_number == 0) { double test_gamma = 1.0; while (test_gamma >= .4) @@ -8780,9 +8936,9 @@ png_byte colour_type = 0; png_byte bit_depth = 0; unsigned int palette_number = 0; - while (next_format(&colour_type, &bit_depth, &palette_number)) + while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/)) { unsigned int i, j; for (i=0; ingamma_tests; ++i) for (j=0; jngamma_tests; ++j) @@ -8810,9 +8966,9 @@ { png_byte colour_type = 0, bit_depth = 0; unsigned int npalette = 0; - while (next_format(&colour_type, &bit_depth, &npalette)) + while (next_format(&colour_type, &bit_depth, &npalette, 1/*gamma*/)) if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 && ((colour_type == 3 && sbit < 8) || (colour_type != 3 && sbit < bit_depth))) { @@ -8845,8 +9001,9 @@ { # ifndef PNG_MAX_GAMMA_8 # define PNG_MAX_GAMMA_8 11 # endif +# define SBIT_16_TO_8 PNG_MAX_GAMMA_8 /* Include the alpha cases here. Note that sbit matches the internal value * used by the library - otherwise we will get spurious errors from the * internal sbit style approximation. * @@ -8862,30 +9019,30 @@ if (i != j && fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD) { gamma_transform_test(pm, 0, 16, 0, pm->interlace_type, - 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, + 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; gamma_transform_test(pm, 2, 16, 0, pm->interlace_type, - 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, + 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; gamma_transform_test(pm, 4, 16, 0, pm->interlace_type, - 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, + 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; gamma_transform_test(pm, 6, 16, 0, pm->interlace_type, - 1/pm->gammas[i], pm->gammas[j], PNG_MAX_GAMMA_8, + 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; @@ -9029,9 +9186,9 @@ /* Skip the non-alpha cases - there is no setting of a transparency colour at * present. */ - while (next_format(&colour_type, &bit_depth, &palette_number)) + while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/)) if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0) { unsigned int i, j; @@ -9051,33 +9208,48 @@ static void init_gamma_errors(png_modifier *pm) { - pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0; - pm->error_color_8 = 0; - pm->error_indexed = 0; - pm->error_gray_16 = pm->error_color_16 = 0; + /* Use -1 to catch tests that were not actually run */ + pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = -1.; + pm->error_color_8 = -1.; + pm->error_indexed = -1.; + pm->error_gray_16 = pm->error_color_16 = -1.; +} + +static void +print_one(const char *leader, double err) +{ + if (err != -1.) + printf(" %s %.5f\n", leader, err); } static void -summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth) +summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth, + int indexed) { + fflush(stderr); + if (who) - printf("Gamma correction with %s:\n", who); + printf("\nGamma correction with %s:\n", who); + + else + printf("\nBasic gamma correction:\n"); if (low_bit_depth) { - printf(" 2 bit gray: %.5f\n", pm->error_gray_2); - printf(" 4 bit gray: %.5f\n", pm->error_gray_4); - printf(" 8 bit gray: %.5f\n", pm->error_gray_8); - printf(" 8 bit color: %.5f\n", pm->error_color_8); - printf(" indexed: %.5f\n", pm->error_indexed); + print_one(" 2 bit gray: ", pm->error_gray_2); + print_one(" 4 bit gray: ", pm->error_gray_4); + print_one(" 8 bit gray: ", pm->error_gray_8); + print_one(" 8 bit color:", pm->error_color_8); + if (indexed) + print_one(" indexed: ", pm->error_indexed); } -#ifdef DO_16BIT - printf(" 16 bit gray: %.5f\n", pm->error_gray_16); - printf(" 16 bit color: %.5f\n", pm->error_color_16); -#endif + print_one("16 bit gray: ", pm->error_gray_16); + print_one("16 bit color:", pm->error_color_16); + + fflush(stdout); } static void perform_gamma_test(png_modifier *pm, int summary) @@ -9101,20 +9273,11 @@ /* Now some real transforms. */ if (pm->test_gamma_transform) { - init_gamma_errors(pm); - /*TODO: remove this. Necessary because the current libpng - * implementation works in 8 bits: - */ - if (pm->test_gamma_expand16) - pm->calculations_use_input_precision = 1; - perform_gamma_transform_tests(pm); - if (!calculations_use_input_precision) - pm->calculations_use_input_precision = 0; - if (summary) { + fflush(stderr); printf("Gamma correction error summary\n\n"); printf("The printed value is the maximum error in the pixel values\n"); printf("calculated by the libpng gamma correction code. The error\n"); printf("is calculated as the difference between the output pixel\n"); @@ -9124,12 +9287,27 @@ printf("Expect this value to be less than .5 for 8 bit formats,\n"); printf("less than 1 for formats with fewer than 8 bits and a small\n"); printf("number (typically less than 5) for the 16 bit formats.\n"); printf("For performance reasons the value for 16 bit formats\n"); - printf("increases when the image file includes an sBIT chunk.\n\n"); - - summarize_gamma_errors(pm, 0/*who*/, 1); + printf("increases when the image file includes an sBIT chunk.\n"); + fflush(stdout); } + + init_gamma_errors(pm); + /*TODO: remove this. Necessary because the current libpng + * implementation works in 8 bits: + */ + if (pm->test_gamma_expand16) + pm->calculations_use_input_precision = 1; + perform_gamma_transform_tests(pm); + if (!calculations_use_input_precision) + pm->calculations_use_input_precision = 0; + + if (summary) + summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/); + + if (fail(pm)) + return; } /* The sbit tests produce much larger errors: */ if (pm->test_gamma_sbit) @@ -9137,9 +9315,12 @@ init_gamma_errors(pm); perform_gamma_sbit_tests(pm); if (summary) - summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U); + summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U, 1/*indexed*/); + + if (fail(pm)) + return; } #ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */ if (pm->test_gamma_scale16) @@ -9149,12 +9330,17 @@ perform_gamma_scale16_tests(pm); if (summary) { - printf("Gamma correction with 16 to 8 bit reduction:\n"); + fflush(stderr); + printf("\nGamma correction with 16 to 8 bit reduction:\n"); printf(" 16 bit gray: %.5f\n", pm->error_gray_16); printf(" 16 bit color: %.5f\n", pm->error_color_16); + fflush(stdout); } + + if (fail(pm)) + return; } #endif #ifdef PNG_READ_BACKGROUND_SUPPORTED @@ -9176,9 +9362,12 @@ pm->calculations_use_input_precision = 0; pm->maxout8 = maxout8; if (summary) - summarize_gamma_errors(pm, "background", 1); + summarize_gamma_errors(pm, "background", 1, 0/*indexed*/); + + if (fail(pm)) + return; } #endif #ifdef PNG_READ_ALPHA_MODE_SUPPORTED @@ -9201,9 +9390,12 @@ if (!calculations_use_input_precision) pm->calculations_use_input_precision = 0; if (summary) - summarize_gamma_errors(pm, "alpha mode", 1); + summarize_gamma_errors(pm, "alpha mode", 1, 0/*indexed*/); + + if (fail(pm)) + return; } #endif } #endif /* PNG_READ_GAMMA_SUPPORTED */ @@ -9709,8 +9901,21 @@ /* Default to error on warning: */ pm.this.treat_warnings_as_errors = 1; + /* Default assume_16_bit_calculations appropriately; this tells the checking + * code that 16-bit arithmetic is used for 8-bit samples when it would make a + * difference. + */ + pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700; + + /* Currently 16 bit expansion happens at the end of the pipeline, so the + * calculations are done in the input bit depth not the output. + * + * TODO: fix this + */ + pm.calculations_use_input_precision = 1U; + /* Store the test gammas */ pm.gammas = gammas; pm.ngammas = (sizeof gammas) / (sizeof gammas[0]); pm.ngamma_tests = 0; /* default to off */ @@ -9719,15 +9924,18 @@ pm.encodings = test_encodings; pm.nencodings = (sizeof test_encodings) / (sizeof test_encodings[0]); pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */ + /* The following allows results to pass if they correspond to anything in the * transformed range [input-.5,input+.5]; this is is required because of the - * way libpng treates the 16_TO_8 flag when building the gamma tables. + * way libpng treates the 16_TO_8 flag when building the gamma tables in + * releases up to 1.6.0. * * TODO: review this */ pm.use_input_precision_16to8 = 1U; + pm.use_input_precision_sbit = 1U; /* because libpng now rounds sBIT */ /* Some default values (set the behavior for 'make check' here). * These values simply control the maximum error permitted in the gamma * transformations. The practial limits for human perception are described @@ -9736,13 +9944,14 @@ * images can never be good enough, regardless of encoding. */ pm.maxout8 = .1; /* Arithmetic error in *encoded* value */ pm.maxabs8 = .00005; /* 1/20000 */ - pm.maxcalc8 = .004; /* +/-1 in 8 bits for compose errors */ + pm.maxcalc8 = 1./255; /* +/-1 in 8 bits for compose errors */ pm.maxpc8 = .499; /* I.e., .499% fractional error */ pm.maxout16 = .499; /* Error in *encoded* value */ pm.maxabs16 = .00005;/* 1/20000 */ - pm.maxcalc16 =.000015;/* +/-1 in 16 bits for compose errors */ + pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */ + pm.maxcalcG = 1./((1<>16 + * + * The command arguments are: + * + * scale target source + * + * and the program works out a pair of numbers, mult and add, that evaluate: + * + * number * target + * round( --------------- ) + * source + * + * exactly for number in the range 0..source + */ +#define _ISOC99_SOURCE 1 + +#include +#include +#include +#include + +static double minerr; +static unsigned long minmult, minadd, minshift; +static long mindelta; + +static int +test(unsigned long target, unsigned long source, unsigned long mult, + long add, unsigned long shift, long delta) +{ + unsigned long i; + double maxerr = 0; + double rs = (double)target/source; + + for (i=0; i<=source; ++i) + { + unsigned long t = i*mult+add; + double err = fabs((t >> shift) - i*rs); + + if (err > minerr) + return 0; + + if (err > maxerr) + maxerr = err; + } + + if (maxerr < minerr) + { + minerr = maxerr; + minmult = mult; + minadd = add; + minshift = shift; + mindelta = delta; + } + + return maxerr < .5; +} + +static int +dotest(unsigned long target, unsigned long source, unsigned long mult, + long add, unsigned long shift, long delta, int print) +{ + if (test(target, source, mult, add, shift, delta)) + { + if (print & 4) + printf(" {%11lu,%6ld /* >>%lu */ }, /* %lu/%lu */\n", + mult, add, shift, target, source); + + else if (print & 2) + printf(" {%11lu,%6ld,%3lu }, /* %lu/%lu */\n", + mult, add, shift, target, source); + + else if (print) + printf("number * %lu/%lu = (number * %lu + %ld) >> %lu [delta %ld]\n", + target, source, mult, add, shift, delta); + + return 1; + } + + return 0; +} + +static int +find(unsigned long target, unsigned long source, int print, int fixshift) +{ + unsigned long shift = 0; + unsigned long shiftlim = 0; + + /* In the final math the sum is at most (source*mult+add) >> shift, so: + * + * source*mult+add < 1<<32 + * mult < (1<<32)/source + * + * but: + * + * mult = (target<>1)) / source; + long delta; + long limit = 1; /* seems to be sufficient */ + long add, start, end; + + end = 1<>%lu */ }, /* %lu/%lu ERROR: .5+%g*/\n", + minmult, minadd, minshift, target, source, minerr-.5); + + else if (print & 2) + printf(" {%11lu,%6ld,%3lu }, /* %lu/%lu ERROR: .5+%g*/\n", + minmult, minadd, minshift, target, source, minerr-.5); + + else if (print) + printf( + "number * %lu/%lu ~= (number * %lu + %ld) >> %lu +/-.5+%g [delta %ld]\n", + target, source, minmult, minadd, minshift, minerr-.5, mindelta); + + return 0; +} + +static void +usage(const char *prog) +{ + fprintf(stderr, + "usage: %s {--denominator|--maxshift|--code} target {source}\n" + " For each 'source' prints 'mult' and 'add' such that:\n\n" + " (number * mult + add) >> 16 = round(number*target/source)\n\n" + " for all integer values of number in the range 0..source.\n\n" + " --denominator: swap target and source (specify a single source first\n" + " and follow with multiple targets.)\n" + " --maxshift: find the lowest shift value that works for all the\n" + " repeated 'source' values\n" + " --code: output C code for array/structure initialization\n", + prog); + exit(1); +} + +int +main(int argc, const char **argv) +{ + int i, err = 0, maxshift = 0, firstsrc = 1, code = 0, denominator = 0; + unsigned long target, shift = 0; + + while (argc > 1) + { + if (strcmp(argv[firstsrc], "--maxshift") == 0) + { + maxshift = 1; + ++firstsrc; + } + + else if (strcmp(argv[firstsrc], "--code") == 0) + { + code = 1; + ++firstsrc; + } + + else if (strcmp(argv[firstsrc], "--denominator") == 0) + { + denominator = 1; + ++firstsrc; + } + + else + break; + } + + + if (argc < 2+firstsrc) + usage(argv[0]); + + target = strtoul(argv[firstsrc++], 0, 0); + if (target == 0) usage(argv[0]); + + for (i=firstsrc; i shift) shift = minshift; + } + + if (maxshift) for (i=firstsrc; i #include #include #include -#include +#include PNG_ZLIB_HEADER /* this is the header libpng was built with */ int main(int argc, const char **argv) { if (argc == 3) diff -ru4NwbB libpng-1.6.0beta34/png.c libpng-1.7.0alpha04/png.c --- libpng-1.6.0beta34/png.c 2012-12-19 16:06:52.968635172 -0600 +++ libpng-1.7.0alpha04/png.c 2012-12-22 18:00:42.401024627 -0600 @@ -1,8 +1,8 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -235,24 +235,23 @@ * to be called. */ memset(&create_struct, 0, (sizeof create_struct)); - /* Added at libpng-1.2.6 */ -# ifdef PNG_USER_LIMITS_SUPPORTED + /* These limits are only used on read at present, and if READ is not turned + * on neither will USER_LIMITS be. The width/height and chunk malloc limits + * are constants, so if they cannot be set they don't get defined in + * png_struct, the user_chunk_cache limits is a down-counter, when it reaches + * 1 no more chunks will be handled. 0 means unlimited, consequently the + * limit is 1 more than the number of chunks that will be handled. + */ +# ifdef PNG_SET_USER_LIMITS_SUPPORTED create_struct.user_width_max = PNG_USER_WIDTH_MAX; create_struct.user_height_max = PNG_USER_HEIGHT_MAX; - -# ifdef PNG_USER_CHUNK_CACHE_MAX - /* Added at libpng-1.2.43 and 1.4.0 */ - create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; -# endif - -# ifdef PNG_USER_CHUNK_MALLOC_MAX - /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists - * in png_struct regardless. - */ create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; # endif +# ifdef PNG_USER_LIMITS_SUPPORTED + /* Must exist even if the initial value is constant */ + create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; # endif /* The following two API calls simply set fields in png_struct, so it is safe * to do them now even though error handling is not yet set up. @@ -380,62 +379,8 @@ png_free(png_ptr, info_ptr); } } -/* Initialize the info structure. This is now an internal function (0.89) - * and applications using it are urged to use png_create_info_struct() - * instead. Use deprecated in 1.6.0, internal use removed (used internally it - * is just a memset). - * - * NOTE: it is almost inconceivable that this API is used because it bypasses - * the user-memory mechanism and the user error handling/warning mechanisms in - * those cases where it does anything other than a memset. - */ -PNG_FUNCTION(void,PNGAPI -png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), - PNG_DEPRECATED) -{ - png_inforp info_ptr = *ptr_ptr; - - png_debug(1, "in png_info_init_3"); - - if (info_ptr == NULL) - return; - - if ((sizeof (png_info)) > png_info_struct_size) - { - *ptr_ptr = NULL; - /* The following line is why this API should not be used: */ - free(info_ptr); - info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, - (sizeof *info_ptr))); - *ptr_ptr = info_ptr; - } - - /* Set everything to 0 */ - memset(info_ptr, 0, (sizeof *info_ptr)); -} - -/* The following API is not called internally */ -void PNGAPI -png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, - int freer, png_uint_32 mask) -{ - png_debug(1, "in png_data_freer"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (freer == PNG_DESTROY_WILL_FREE_DATA) - info_ptr->free_me |= mask; - - else if (freer == PNG_USER_WILL_FREE_DATA) - info_ptr->free_me &= ~mask; - - else - png_error(png_ptr, "Unknown freer parameter in png_data_freer"); -} - void PNGAPI png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, int num) { @@ -472,11 +417,12 @@ #ifdef PNG_tRNS_SUPPORTED /* Free any tRNS entry */ if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) { + info_ptr->valid &= ~PNG_INFO_tRNS; png_free(png_ptr, info_ptr->trans_alpha); info_ptr->trans_alpha = NULL; - info_ptr->valid &= ~PNG_INFO_tRNS; + info_ptr->num_trans = 0; } #endif #ifdef PNG_sCAL_SUPPORTED @@ -731,31 +677,8 @@ } return 1; } - -# if PNG_LIBPNG_VER < 10700 -/* To do: remove the following from libpng-1.7 */ -/* Original API that uses a private buffer in png_struct. - * Deprecated because it causes png_struct to carry a spurious temporary - * buffer (png_struct::time_buffer), better to have the caller pass this in. - */ -png_const_charp PNGAPI -png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime) -{ - if (png_ptr != NULL) - { - /* The only failure above if png_ptr != NULL is from an invalid ptime */ - if (!png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime)) - png_warning(png_ptr, "Ignoring invalid time value"); - - else - return png_ptr->time_buffer; - } - - return NULL; -} -# endif # endif /* PNG_TIME_RFC1123_SUPPORTED */ #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ @@ -866,21 +789,8 @@ } #endif /* READ_UNKNOWN_CHUNKS */ #endif /* SET_UNKNOWN_CHUNKS */ -#ifdef PNG_READ_SUPPORTED -/* This function, added to libpng-1.0.6g, is untested. */ -int PNGAPI -png_reset_zstream(png_structrp png_ptr) -{ - if (png_ptr == NULL) - return Z_STREAM_ERROR; - - /* WARNING: this resets the window bits to the maximum! */ - return (inflateReset(&png_ptr->zstream)); -} -#endif /* PNG_READ_SUPPORTED */ - /* This function was added to libpng-1.0.7 */ png_uint_32 PNGAPI png_access_version_number(void) { @@ -2286,9 +2194,9 @@ void /* PRIVATE */ png_colorspace_set_rgb_coefficients(png_structrp png_ptr) { /* Set the rgb_to_gray coefficients from the colorspace. */ - if (!png_ptr->rgb_to_gray_coefficients_set && + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_RGB_TO_GRAY_SET) == 0 && (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { /* png_set_background has not been called, get the coefficients from the Y * values of the colorspace colorants. @@ -3067,26 +2975,34 @@ /* Here on buffer too small. */ png_error(png_ptr, "ASCII conversion buffer too small"); } # endif /* FIXED_POINT */ -#endif /* READ_SCAL */ +#endif /* SCAL */ -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ +#if !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && (\ + defined(PNG_FLOATING_POINT_SUPPORTED) && \ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_sCAL_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) + (defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) &&\ + defined(PNG_sCAL_SUPPORTED))) png_fixed_point png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) { - double r = floor(100000 * fp + .5); + if (fp < 0) + { + if (fp > -21474.836485) + return (png_fixed_point)(100000*fp - .5); + } + + else + { + if (fp < 21474.836475) + return (png_fixed_point)(100000*fp + .5); + } - if (r > 2147483647. || r < -2147483648.) + /* Overflow */ png_fixed_error(png_ptr, text); - - return (png_fixed_point)r; } #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || \ @@ -3262,8 +3178,9 @@ #endif #ifdef PNG_READ_GAMMA_SUPPORTED /* A local convenience routine. */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED static png_fixed_point png_product2(png_fixed_point a, png_fixed_point b) { /* The required result is 1/a * 1/b; the following preserves accuracy. */ @@ -3282,8 +3199,9 @@ #endif return 0; /* overflow */ } +#endif /* The inverse of the above. */ png_fixed_point png_reciprocal2(png_fixed_point a, png_fixed_point b) @@ -3660,163 +3578,334 @@ else return png_gamma_16bit_correct(value, gamma_val); } -/* Internal function to build a single 16-bit table - the table consists of - * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount - * to shift the input values right (or 16-number_of_signifiant_bits). - * - * The caller is responsible for ensuring that the table gets cleaned up on - * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument - * should be somewhere that will be cleaned. - */ -static void -png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) -{ - /* Various values derived from 'shift': */ - PNG_CONST unsigned int num = 1U << (8U - shift); - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; - PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); - unsigned int i; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); +#define PNG_GAMMA_TABLE_8 0 /* 8-bit entries in png_byte */ +#define PNG_GAMMA_TABLE_8_IN_16 1 /* 8-bit entries * 257 in png_uint_16 */ +#define PNG_GAMMA_TABLE_16 2 /* 16-bit entries in png_uint_16 */ - for (i = 0; i < num; i++) +typedef struct { - png_uint_16p sub_table = table[i] = - (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); + png_fixed_point gamma; + png_uint_32 mult; + unsigned int add; + unsigned int shift; /* input value is (i * mult + add) >> shift */ + int output; /* One of the above values */ + int adjust; /* Divide or multiple output by 257 */ + png_voidp table; /* Lookup table */ +} gamma_table_data; - /* The 'threshold' test is repeated here because it can arise for one of - * the 16-bit tables even if the others don't hit it. +static unsigned int +write_gamma_table_entry(const gamma_table_data *data, png_uint_32 i) + /* Calculate and write a single entry into table[i], the value of the entry + * written is returned. */ - if (png_gamma_significant(gamma_val)) { - /* The old code would overflow at the end and this would cause the - * 'pow' function to return a result >1, resulting in an - * arithmetic error. This code follows the spec exactly; ig is - * the recovered input sample, it always has 8-16 bits. - * - * We want input * 65535/max, rounded, the arithmetic fits in 32 - * bits (unsigned) so long as max <= 32767. + png_uint_32 in = (i * data->mult + data->add) >> data->shift; + unsigned int out; + + /* If the output is TABLE_8 with no adjust, or the output is not with an + * adjust, use 8-bit correction. */ - unsigned int j; - for (j = 0; j < 256; j++) + if ((data->output == PNG_GAMMA_TABLE_8) != (data->adjust != 0)) { - png_uint_32 ig = (j << (8-shift)) + i; -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* Inline the 'max' scaling operation: */ - double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); - sub_table[j] = (png_uint_16)d; -# else - if (shift) - ig = (ig * 65535U + max_by_2)/max; + out = png_gamma_8bit_correct((unsigned int)in, data->gamma); - sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); -# endif + if (data->adjust != 0) + out *= 257U; } + + else /* 16-bit correction */ + { + out = png_gamma_16bit_correct((unsigned int)in, data->gamma); + + if (data->adjust != 0) + out = PNG_DIV257(out); } + + if (data->output == PNG_GAMMA_TABLE_8) + ((png_bytep)data->table)[i] = (png_byte)out; + else - { - /* We must still build a table, but do it the fast way. */ - unsigned int j; + ((png_uint_16p)data->table)[i] = (png_uint_16)out; - for (j = 0; j < 256; j++) + return out; +} + +static void +write_gamma_table(const gamma_table_data *data, png_uint_32 lo, + unsigned int loval, png_uint_32 hi, unsigned int hival) + /* Fill in gamma table entries between lo and hi, exclusive. The entries at + * table[lo] and table[hi] have already been written, the intervening entries + * are written. + */ +{ + if (hi > lo+1) /* Else nothing to fill in */ + { + if (hival == loval) + { + /* All intervening entries must be the same. */ + if (data->output == PNG_GAMMA_TABLE_8) { - png_uint_32 ig = (j << (8-shift)) + i; + png_bytep table8 = ((png_bytep)data->table); - if (shift) - ig = (ig * 65535U + max_by_2)/max; + while (++lo < hi) + table8[lo] = (png_byte)loval; + } + + else + { + png_uint_16p table16 = ((png_uint_16p)data->table); - sub_table[j] = (png_uint_16)ig; + while (++lo < hi) + table16[lo] = (png_uint_16)loval; + } } + + else + { + png_uint_32 mid = (lo+hi) >> 1; + unsigned int midval = write_gamma_table_entry(data, mid); + + /* The algorithm used is to divide the entries to be written in half + * and fill in the middle. For all practical tables with significant + * gamma this will result in a performance gain because the expensive + * gamma correction arithmetic is avoided for some entries. + */ + write_gamma_table(data, lo, loval, mid, midval); + write_gamma_table(data, mid, midval, hi, hival); } } } -/* NOTE: this function expects the *inverse* of the overall gamma transformation - * required. +static void * +png_build_gamma_table(png_structrp png_ptr, png_fixed_point gamma_val, + int output/*as above*/, int input_depth, int use_shift) + /* Build a gamma lookup table to encode input_depth bit input values. + * The table will have 2^input_depth entries plus an extra one if use_shift + * is specified. With shift the table is accessed: + * + * table[(original-value + rounding) >> shift] + * + * And an extra entry exists to accomodate overflow of original-value on + * rounding. If use_shift is not specified the table is accessed with an + * input_depth bit value and the original values must have been correctly + * scaled to this range (not using a shift!) + * + * Each table entry contains input-value^gamma_val rounded to the output + * precision. This is 8 bit precision unless output is specified as + * PNG_GAMMA_TABLE_16, in which case it is 16-bit precision. For + * PNG_GAMMA_TABLE_8_IN_16 the 8-bit value is scaled to 16-bits by + * multiplying by 257. */ -static void -png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) { - PNG_CONST unsigned int num = 1U << (8U - shift); - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; - unsigned int i; - png_uint_32 last; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); + png_uint_32 size; + unsigned int hival; + gamma_table_data data; - /* 'num' is the number of tables and also the number of low bits of low - * bits of the input 16-bit value used to select a table. Each table is - * itself index by the high 8 bits of the value. - */ - for (i = 0; i < num; i++) - table[i] = (png_uint_16p)png_malloc(png_ptr, - 256 * (sizeof (png_uint_16))); - - /* 'gamma_val' is set to the reciprocal of the value calculated above, so - * pow(out,g) is an *input* value. 'last' is the last input value set. - * - * In the loop 'i' is used to find output values. Since the output is - * 8-bit there are only 256 possible values. The tables are set up to - * select the closest possible output value for each input by finding - * the input value at the boundary between each pair of output values - * and filling the table up to that boundary with the lower output - * value. + /* If use_shift is true or if the input or output is not 8-bit the gamma + * correction will use the 16-bit correction code. This requires a value in + * the range 0..65535. For use_shift the value is simply: + * + * input << shift + * + * For the scaling case the value is: * - * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit - * values the code below uses a 16-bit value in i; the values start at - * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last - * entries are filled with 255). Start i at 128 and fill all 'last' - * table entries <= 'max' + * round(input * 65535 / ((1<> shift; + * + * With 'mult' and 'add' chosen to minimize the error for all input values + * in the range 0..((1<> shift)][last >> (8U - shift)] = out; - last++; - } + /* The 8-bit correction can only be used if both input and output have no + * more than 8 bits of precision. + */ + data.adjust = output > PNG_GAMMA_TABLE_8; + + if (use_shift) + { + /* The multiplier does the shift: */ + data.mult = 1U << (8-input_depth); + data.add = 0; + data.shift = 0; + if (input_depth < 8) ++size; } - /* And fill in the final entries. */ - while (last < (num << 8)) + else { - table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; - last++; + data.mult = multadd255[input_depth-1].mult; + data.add = multadd255[input_depth-1].add; + data.shift = multadd255[input_depth-1].shift; } } -/* Build a single 8-bit table: same as the 16-bit case but much simpler (and - * typically much faster). Note that libpng currently does no sBIT processing - * (apparently contrary to the spec) so a 256 entry table is always generated. + else + { + /* 16-bit correction is used for cases where input or output require more + * than 8 bits. */ -static void -png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, - PNG_CONST png_fixed_point gamma_val) + data.adjust = output == PNG_GAMMA_TABLE_8; + + if (use_shift) { - unsigned int i; - png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); + data.mult = 1U << (16-input_depth); + data.add = 0; + data.shift = 0; + if (input_depth < 16) ++size; + } + + else + { + data.mult = multadd65535[input_depth-1].mult; + data.add = multadd65535[input_depth-1].add; + data.shift = multadd65535[input_depth-1].shift; + } + } + + if (output == PNG_GAMMA_TABLE_8) + { + data.table = png_malloc(png_ptr, size * sizeof (png_byte)); + ((png_bytep)data.table)[0] = 0; + hival = ((png_bytep)data.table)[size-1] = 255; + } + + else + { + /* Output is 16 bits, although it may only have 8 bits of precision */ + data.table = png_malloc(png_ptr, size * sizeof (png_uint_16)); + ((png_uint_16p)data.table)[0] = 0; + hival = ((png_uint_16p)data.table)[size-1] = 65535; + } + + if (png_gamma_significant(gamma_val)) + write_gamma_table(&data, 0, 0, size-1, hival); - if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++) - table[i] = png_gamma_8bit_correct(i, gamma_val); + else /* gamma_val not significant */ + { + if (output == PNG_GAMMA_TABLE_8) + { + png_uint_32 i; + png_bytep table8 = ((png_bytep)data.table); + + if (data.adjust) + for (i=1; i> + data.shift); + + else + for (i=1; i> data.shift); + } + + else + { + png_uint_32 i; + png_uint_16p table16 = ((png_uint_16p)data.table); + + if (data.adjust) + for (i=1; i> + data.shift) * 257U); + + else + for (i=1; i> + data.shift); + } + } - else for (i=0; i<256; ++i) - table[i] = (png_byte)i; + return data.table; } /* Used from png_read_destroy and below to release the memory used by the gamma * tables. @@ -3826,19 +3915,10 @@ { png_free(png_ptr, png_ptr->gamma_table); png_ptr->gamma_table = NULL; - if (png_ptr->gamma_16_table != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_table[i]); - } png_free(png_ptr, png_ptr->gamma_16_table); png_ptr->gamma_16_table = NULL; - } #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) @@ -3846,30 +3926,12 @@ png_ptr->gamma_from_1 = NULL; png_free(png_ptr, png_ptr->gamma_to_1); png_ptr->gamma_to_1 = NULL; - if (png_ptr->gamma_16_from_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_from_1[i]); - } png_free(png_ptr, png_ptr->gamma_16_from_1); png_ptr->gamma_16_from_1 = NULL; - } - if (png_ptr->gamma_16_to_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_to_1[i]); - } png_free(png_ptr, png_ptr->gamma_16_to_1); png_ptr->gamma_16_to_1 = NULL; - } #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ } /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit @@ -3877,9 +3939,9 @@ * the future. Note also how the gamma_16 tables are segmented so that * we don't need to allocate > 64K chunks for a full 16-bit table. */ void /* PRIVATE */ -png_build_gamma_table(png_structrp png_ptr, int bit_depth) +png_build_gamma_tables(png_structrp png_ptr, int bit_depth) { png_debug(1, "in png_build_gamma_table"); /* Remove any existing table; this copes with multiple calls to @@ -3895,29 +3957,46 @@ } if (bit_depth <= 8) { - png_build_8bit_table(png_ptr, &png_ptr->gamma_table, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); + png_ptr->gamma_table = png_voidcast(png_bytep, png_build_gamma_table( + png_ptr, png_ptr->screen_gamma > 0 ? + png_reciprocal2(png_ptr->colorspace.gamma, png_ptr->screen_gamma) : + PNG_FP_1, PNG_GAMMA_TABLE_8, 8/*input depth*/, 0/*scale*/)); #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) { - png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, - png_reciprocal(png_ptr->colorspace.gamma)); + /* This sets the accuracy of 8-bit composition and the 8-bit RGB to gray + * conversion - PNG_MAX_GAMMA_8 (the number of bits in the sixteen bit + * value that are considered significant.) + */ + png_ptr->gamma_to_1 = png_voidcast(png_uint_16p, png_build_gamma_table( + png_ptr, png_reciprocal(png_ptr->colorspace.gamma), + PNG_GAMMA_TABLE_16, 8/*input depth*/, 0/*scale*/)); + + png_ptr->gamma_from_1 = png_voidcast(png_bytep, png_build_gamma_table( + png_ptr, png_ptr->screen_gamma > 0 ? + png_reciprocal(png_ptr->screen_gamma) : + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */, + PNG_GAMMA_TABLE_8, PNG_MAX_GAMMA_8/*input depth*/, 1/*shift*/)); - png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + png_ptr->gamma_shift = 16-PNG_MAX_GAMMA_8; } #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ } else { png_byte shift, sig_bit; + int table_type; + +# ifdef PNG_16BIT_SUPPORTED + table_type = PNG_GAMMA_TABLE_16; +# else + table_type = PNG_GAMMA_TABLE_8_IN_16; +# endif if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) { sig_bit = png_ptr->sig_bit.red; @@ -3930,26 +4009,8 @@ } else sig_bit = png_ptr->sig_bit.gray; - /* 16-bit gamma code uses this equation: - * - * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] - * - * Where 'iv' is the input color value and 'ov' is the output value - - * pow(iv, gamma). - * - * Thus the gamma table consists of up to 256 256 entry tables. The table - * is selected by the (8-gamma_shift) most significant of the low 8 bits of - * the color value then indexed by the upper 8 bits: - * - * table[low bits][high 8 bits] - * - * So the table 'n' corresponds to all those 'iv' of: - * - * ..<(n+1 << gamma_shift)-1> - * - */ if (sig_bit > 0 && sig_bit < 16U) shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ else @@ -3958,53 +4019,42 @@ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) { /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively * the significant bits in the *input* when the output will - * eventually be 8 bits. By default it is 11. + * eventually be 8 bits. */ if (shift < (16U - PNG_MAX_GAMMA_8)) shift = (16U - PNG_MAX_GAMMA_8); - } - if (shift > 8U) - shift = 8U; /* Guarantees at least one table! */ + table_type = PNG_GAMMA_TABLE_8_IN_16; + } png_ptr->gamma_shift = shift; -#ifdef PNG_16BIT_SUPPORTED - /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now - * PNG_COMPOSE). This effectively smashed the background calculation for - * 16-bit output because the 8-bit table assumes the result will be reduced - * to 8 bits. - */ - if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) -#endif - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - -#ifdef PNG_16BIT_SUPPORTED - else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); -#endif + png_ptr->gamma_16_table = png_voidcast(png_uint_16p, png_build_gamma_table( + png_ptr, png_ptr->screen_gamma > 0 ? png_reciprocal2( + png_ptr->colorspace.gamma, png_ptr->screen_gamma) : PNG_FP_1, + table_type, (16-shift)/*input depth*/, 1/*shift*/)); #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) { - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, - png_reciprocal(png_ptr->colorspace.gamma)); + png_ptr->gamma_16_to_1 = png_voidcast(png_uint_16p, + png_build_gamma_table(png_ptr, + png_reciprocal(png_ptr->colorspace.gamma), PNG_GAMMA_TABLE_16, + (16-shift)/*input depth*/, 1/*shift*/)); /* Notice that the '16 from 1' table should be full precision, however * the lookup on this table still uses gamma_shift, so it can't be. * TODO: fix this. */ - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + png_ptr->gamma_16_from_1 = png_voidcast(png_uint_16p, + png_build_gamma_table(png_ptr, png_ptr->screen_gamma > 0 ? + png_reciprocal(png_ptr->screen_gamma) : + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */, + PNG_GAMMA_TABLE_16, (16-shift)/*input depth*/, 1/*shift*/)); } #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ } } diff -ru4NwbB libpng-1.6.0beta34/png.h libpng-1.7.0alpha04/png.h --- libpng-1.6.0beta34/png.h 2012-12-19 16:06:52.907055036 -0600 +++ libpng-1.7.0alpha04/png.h 2012-12-22 18:00:42.339680981 -0600 @@ -165,9 +165,10 @@ * 1.5.6 15 10506 15.so.15.6[.0] * 1.5.7beta01-05 15 10507 15.so.15.7[.0] * 1.5.7rc01-03 15 10507 15.so.15.7[.0] * 1.5.7 15 10507 15.so.15.7[.0] - * 1.6.0beta01-34 16 10600 16.so.16.0[.0] + * 1.6.0beta01-33 16 10600 16.so.16.0[.0] + * 1.7.0alpha01-04 17 10700 17.so.17.0[.0] * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be * used for changes in backward compatibility, as it is intended. The @@ -1053,10 +1054,10 @@ PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), PNG_NORETURN); #ifdef PNG_READ_SUPPORTED -/* Reset the compression stream */ -PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); +/* Reset the compression stream -- Removed from libpng-1.7.0 */ +PNG_REMOVED(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED) #endif /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ #ifdef PNG_USER_MEM_SUPPORTED @@ -1093,14 +1094,11 @@ /* Allocate and initialize the info structure */ PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), PNG_ALLOCATED); -/* DEPRECATED: this function allowed init structures to be created using the - * default allocation method (typically malloc). Use is deprecated in 1.6.0 and - * the API will be removed in the future. - */ -PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, - png_size_t png_info_struct_size), PNG_DEPRECATED); +/* Removed from libpng-1.7.0 */ +PNG_REMOVED(19, void, png_info_init_3, (png_infopp info_ptr, + png_size_t png_info_struct_size), PNG_DEPRECATED) /* Writes all the PNG information before the image. */ PNG_EXPORT(20, void, png_write_info_before_PLTE, (png_structrp png_ptr, png_const_inforp info_ptr)); @@ -1115,15 +1113,12 @@ #ifdef PNG_TIME_RFC1123_SUPPORTED /* Convert to a US string format: there is no localization support in this * routine. The original implementation used a 29 character buffer in - * png_struct, this will be removed in future versions. + * png_struct, this has been removed (in libpng 1.7.0). */ -#if PNG_LIBPNG_VER < 10700 -/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ -PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, - png_const_timep ptime),PNG_DEPRECATED); -#endif +PNG_REMOVED(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, + png_const_timep ptime),PNG_DEPRECATED) PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], png_const_timep ptime)); #endif @@ -1618,32 +1613,38 @@ */ PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, int filters)); -/* Flags for png_set_filter() to say which filters to use. The flags - * are chosen so that they don't conflict with real filter types - * below, in case they are supplied instead of the #defined constants. - * These values should NOT be changed. - */ -#define PNG_NO_FILTERS 0x00 -#define PNG_FILTER_NONE 0x08 -#define PNG_FILTER_SUB 0x10 -#define PNG_FILTER_UP 0x20 -#define PNG_FILTER_AVG 0x40 -#define PNG_FILTER_PAETH 0x80 -#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ - PNG_FILTER_AVG | PNG_FILTER_PAETH) - /* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. - * These defines should NOT be changed. + * These defines match the values in the PNG specification. */ #define PNG_FILTER_VALUE_NONE 0 #define PNG_FILTER_VALUE_SUB 1 #define PNG_FILTER_VALUE_UP 2 #define PNG_FILTER_VALUE_AVG 3 #define PNG_FILTER_VALUE_PAETH 4 #define PNG_FILTER_VALUE_LAST 5 +/* The above values are valid arguments to png_set_filter() if only a single + * filter is to be used. If multiple filters are to be allowed (the default is + * to allow any of them) then a combination of the following masks must be used + * and the low three bits of the argument to png_set_filter must be 0. + * + * The resultant argument fits in a single byte. + */ +#define PNG_FILTER_NONE (0x08 << PNG_FILTER_VALUE_NONE) +#define PNG_FILTER_SUB (0x08 << PNG_FILTER_VALUE_SUB) +#define PNG_FILTER_UP (0x08 << PNG_FILTER_VALUE_UP) +#define PNG_FILTER_AVG (0x08 << PNG_FILTER_VALUE_AVG) +#define PNG_FILTER_PAETH (0x08 << PNG_FILTER_VALUE_PAETH) + +/* Then two convenience values. PNG_NO_FILTERS is the same as + * PNG_FILTER_VALUE_NONE, but this is harmless because they mean the same thing. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ /* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ * defines, either the default (minimum-sum-of-absolute-differences), or * the experimental method (weighted-minimum-sum-of-absolute-differences). @@ -1927,18 +1928,15 @@ * by libpng or by the application; this works on the png_info structure passed * in, it does not change the state for other png_info structures. * * It is unlikely that this function works correctly as of 1.6.0 and using it - * may result either in memory leaks or double free of allocated data. + * may result either in memory leaks or double free of allocated data. It was + * removed in libpng 1.7.0. */ -PNG_EXPORTA(99, void, png_data_freer, (png_const_structrp png_ptr, - png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED); +PNG_REMOVED(99, void, png_data_freer, (png_const_structrp png_ptr, + png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED) -/* Assignments for png_data_freer */ -#define PNG_DESTROY_WILL_FREE_DATA 1 -#define PNG_SET_WILL_FREE_DATA 1 -#define PNG_USER_WILL_FREE_DATA 2 -/* Flags for png_ptr->free_me and info_ptr->free_me */ +/* Flags for png_free_data */ #define PNG_FREE_HIST 0x0008 #define PNG_FREE_ICCP 0x0010 #define PNG_FREE_SPLT 0x0020 #define PNG_FREE_ROWS 0x0040 @@ -1954,12 +1952,16 @@ #define PNG_FREE_ALL 0x7fff #define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ #ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); -PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, - png_voidp ptr), PNG_DEPRECATED); + /* These were deprecated in libpng 1.6.0 and have been removed from libpng + * 1.7.0; the functionality should be accessed by calling malloc or free + * directly or, if png_error handling is required, calling png_malloc. + */ +PNG_REMOVED(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED) +PNG_REMOVED(101, void, png_free_default, (png_const_structrp png_ptr, + png_voidp ptr), PNG_DEPRECATED) #endif #ifdef PNG_ERROR_TEXT_SUPPORTED /* Fatal error in PNG image of libpng - can't continue */ @@ -2326,27 +2328,31 @@ png_const_color_16p trans_color)); #endif #ifdef PNG_sCAL_SUPPORTED -PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, - png_const_inforp info_ptr, int *unit, double *width, double *height)) -#if (defined PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ - (defined PNG_FLOATING_POINT_SUPPORTED) -/* NOTE: this API is currently implemented using floating point arithmetic, - * consequently it can only be used on systems with floating point support. +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* NOTE: these API are currently implemented using floating point arithmetic, + * consequently they can only be used on systems with floating point support. * In any case the range of values supported by png_fixed_point is small and it * is highly recommended that png_get_sCAL_s be used instead. */ +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, + png_const_inforp info_ptr, int *unit, double *width, double *height)) PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_fixed_point *width, png_fixed_point *height)) #endif PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* This also requires internal floating point arithmetic support - i.e. it + * requires a full math library, not just floating point handling. + */ PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, png_inforp info_ptr, int unit, double width, double height)) +#endif PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, png_inforp info_ptr, int unit, png_fixed_point width, png_fixed_point height)) PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, diff -ru4NwbB libpng-1.6.0beta34/pngconf.h libpng-1.7.0alpha04/pngconf.h --- libpng-1.6.0beta34/pngconf.h 2012-12-19 16:06:52.914509739 -0600 +++ libpng-1.7.0alpha04/pngconf.h 2012-12-22 18:00:42.347387936 -0600 @@ -197,20 +197,18 @@ /* System specific discovery. * ========================== * This code is used at build time to find PNG_IMPEXP, the API settings * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL - * import processing is possible. On Windows/x86 systems it also sets + * import processing is possible. On Windows systems it also sets * compiler-specific macros to the values required to change the calling * conventions of the various functions. */ -#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ - defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\ - ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\ - defined(_M_X64) || defined(_M_IA64) ) - /* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes - * builds under Cygwin or MinGW. Also includes Watcom builds but these need - * special treatment because they are not compatible with GCC or Visual C - * because of different calling conventions. +#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ + defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) + /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or + * MinGW on any architecture currently supported by Windows. Also includes + * Watcom builds but these need special treatment because they are not + * compatible with GCC or Visual C because of different calling conventions. */ # if PNG_API_RULE == 2 /* If this line results in an error, either because __watcall is not * understood or because of a redefine just below you cannot use *this* @@ -222,8 +220,11 @@ # if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) # define PNGCAPI __cdecl # if PNG_API_RULE == 1 + /* If this line results in an error __stdcall is not understood and + * PNG_API_RULE should not have been set to '1'. + */ # define PNGAPI __stdcall # endif # else /* An older compiler, or one not detected (erroneously) above, @@ -259,9 +260,9 @@ # define PNG_DLL_IMPORT __declspec(dllimport) # endif # endif /* compiler */ -#else /* !Windows/x86 */ +#else /* !Windows */ # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) # define PNGAPI _System # else /* !Windows/x86 && !OS/2 */ /* Use the defaults, or define PNG*API on the command line (but diff -ru4NwbB libpng-1.6.0beta34/pngerror.c libpng-1.7.0alpha04/pngerror.c --- libpng-1.6.0beta34/pngerror.c 2012-12-19 16:06:52.976775480 -0600 +++ libpng-1.7.0alpha04/pngerror.c 2012-12-22 18:00:42.409192319 -0600 @@ -1,8 +1,8 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -162,9 +162,9 @@ case PNG_NUMBER_FORMAT_02u: /* Expects at least 2 digits. */ mincount = 2; - /* FALL THROUGH */ + /* fall through */ case PNG_NUMBER_FORMAT_u: *--end = digits[number % 10]; number /= 10; @@ -172,9 +172,9 @@ case PNG_NUMBER_FORMAT_02x: /* This format expects at least two digits */ mincount = 2; - /* FALL THROUGH */ + /* fall through */ case PNG_NUMBER_FORMAT_x: *--end = digits[number & 0xf]; number >>= 4; @@ -545,9 +545,15 @@ # endif } #ifdef PNG_ERROR_TEXT_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ + defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ + (defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) &&\ + defined(PNG_sCAL_SUPPORTED)) PNG_FUNCTION(void, png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) { # define fixed_message "fixed point overflow in " @@ -739,10 +745,19 @@ if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr) png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); #endif - /* Here if not setjmp support or if png_ptr is null. */ - PNG_ABORT(); + /* If control reaches this point, png_longjmp() must not return. The only + * choice is to terminate the whole process (or maybe the thread); to do + * this the ANSI-C abort() function is used unless a different method is + * implemented by overriding the default configuration setting for + * PNG_ABORT (see scripts/pnglibconf.dfa). + * + * API change: prior to 1.7.0 PNG_ABORT was invoked as a function type macro + * with no arguments 'PNG_ABORT();', in 1.7.0 this is changed to a simple + * macro that is defined in the configuration. + */ + PNG_ABORT } #ifdef PNG_WARNINGS_SUPPORTED /* This function is called when there is a warning, but the library thinks diff -ru4NwbB libpng-1.6.0beta34/pngget.c libpng-1.7.0alpha04/pngget.c --- libpng-1.6.0beta34/pngget.c 2012-12-19 16:06:52.985498980 -0600 +++ libpng-1.7.0alpha04/pngget.c 2012-12-22 18:00:42.417664315 -0600 @@ -1,8 +1,8 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -842,11 +842,10 @@ } #endif #ifdef PNG_sCAL_SUPPORTED +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED # ifdef PNG_FIXED_POINT_SUPPORTED -# if (defined PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ - (defined PNG_FLOATING_POINT_SUPPORTED) png_uint_32 PNGAPI png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_fixed_point *width, png_fixed_point *height) { @@ -865,9 +864,8 @@ } return(0); } -# endif /* FLOATING_ARITHMETIC */ # endif /* FIXED_POINT */ # ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, @@ -884,8 +882,10 @@ return(0); } # endif /* FLOATING POINT */ +# endif /* FLOATING_ARITHMETIC */ + png_uint_32 PNGAPI png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_charpp width, png_charpp height) { diff -ru4NwbB libpng-1.6.0beta34/pngmem.c libpng-1.7.0alpha04/pngmem.c --- libpng-1.6.0beta34/pngmem.c 2012-12-19 16:06:52.991179873 -0600 +++ libpng-1.7.0alpha04/pngmem.c 2012-12-22 18:00:42.423195284 -0600 @@ -109,33 +109,13 @@ ret = png_malloc_base(png_ptr, size); if (ret == NULL) - png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */ + png_error(png_ptr, "Out of memory"); return ret; } -#ifdef PNG_USER_MEM_SUPPORTED -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED PNG_DEPRECATED) -{ - png_voidp ret; - - if (png_ptr == NULL) - return NULL; - - /* Passing 'NULL' here bypasses the application provided memory handler. */ - ret = png_malloc_base(NULL/*use malloc*/, size); - - if (ret == NULL) - png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */ - - return ret; -} -#endif /* PNG_USER_MEM_SUPPORTED */ - /* This function was added at libpng version 1.2.3. The png_malloc_warn() * function will issue a png_warning and return NULL instead of issuing a * png_error, if it fails to allocate the requested memory. */ @@ -169,18 +149,9 @@ if (png_ptr->free_fn != NULL) png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); else - png_free_default(png_ptr, ptr); -} - -PNG_FUNCTION(void,PNGAPI -png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED) -{ - if (png_ptr == NULL || ptr == NULL) - return; #endif /* PNG_USER_MEM_SUPPORTED */ - free(ptr); } #ifdef PNG_USER_MEM_SUPPORTED diff -ru4NwbB libpng-1.6.0beta34/pngpriv.h libpng-1.7.0alpha04/pngpriv.h --- libpng-1.6.0beta34/pngpriv.h 2012-12-19 16:06:52.925230613 -0600 +++ libpng-1.7.0alpha04/pngpriv.h 2012-12-22 18:00:42.357852670 -0600 @@ -5,9 +5,9 @@ * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h @@ -333,19 +333,27 @@ /* Other defines specific to compilers can go here. Try to keep * them inside an appropriate ifdef/endif pair for portability. */ -#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) +#if defined PNG_sCAL_SUPPORTED && defined PNG_FLOATING_POINT_SUPPORTED /* png.c requires the following ANSI-C constants if the conversion of * floating point to ASCII is implemented therein: * + * DBL_MIN_10_EXP Minimum negative integer such that 10^integer is a + * normalized (double) value. * DBL_DIG Maximum number of decimal digits (can be set to any constant) * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) * DBL_MAX Maximum floating point number (can be set to an arbitrary value) */ # include +#endif /* sCAL && FLOATING_POINT */ +#if defined PNG_FLOATING_ARITHMETIC_SUPPORTED ||\ + defined PNG_FLOATING_POINT_SUPPORTED + /* Certain floating point functions are used internally; only floor and ceil + * if FLOATING_POINT is supported, but if FLOATING_ARITHMETIC is used then + * pow and exp are needed too. + */ # if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) /* We need to check that hasn't already been included earlier * as it seems it doesn't agree with , yet we should really use @@ -362,34 +370,9 @@ * MATH=68881 */ # include # endif -#endif - -/* This provides the non-ANSI (far) memory allocation routines. */ -#if defined(__TURBOC__) && defined(__MSDOS__) -# include -# include -#endif - -#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \ - defined(_WIN32) || defined(__WIN32__) -# include /* defines _WINDOWS_ macro */ -#endif - -/* Moved here around 1.5.0beta36 from pngconf.h */ -/* Users may want to use these so they are not private. Any library - * functions that are passed far data must be model-independent. - */ - -/* Memory model/platform independent fns */ -#ifndef PNG_ABORT -# ifdef _WINDOWS_ -# define PNG_ABORT() ExitProcess(0) -# else -# define PNG_ABORT() abort() -# endif -#endif +#endif /* FLOATING_ARITHMETIC || FLOATING_POINT */ /* These macros may need to be architecture dependent. */ #define PNG_ALIGN_NONE 0 /* do not use data alignment */ #define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ @@ -457,9 +440,9 @@ /* 0x80 (unused) */ #define PNG_HAVE_CHUNK_HEADER 0x100 #define PNG_WROTE_tIME 0x200 #define PNG_WROTE_INFO_BEFORE_PLTE 0x400 -#define PNG_BACKGROUND_IS_GRAY 0x800 + /* 0x800 (unused) */ #define PNG_HAVE_PNG_SIGNATURE 0x1000 #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ /* 0x4000 (unused) */ #define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */ @@ -472,9 +455,9 @@ #define PNG_SWAP_BYTES 0x0010 #define PNG_INVERT_MONO 0x0020 #define PNG_QUANTIZE 0x0040 #define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */ -#define PNG_BACKGROUND_EXPAND 0x0100 + /* 0x0100 unused */ #define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */ #define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */ #define PNG_RGBA 0x0800 #define PNG_EXPAND 0x1000 @@ -528,10 +511,10 @@ #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 #define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */ #define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */ #define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */ - /* 0x800000 unused */ - /* 0x1000000 unused */ +#define PNG_FLAG_BACKGROUND_IS_GRAY 0x800000 +#define PNG_FLAG_BACKGROUND_EXPAND 0x1000000 /* 0x2000000 unused */ /* 0x4000000 unused */ /* 0x8000000 unused */ /* 0x10000000 unused */ @@ -732,8 +715,18 @@ png_compression_bufferp *list),PNG_EMPTY); /* Free the buffer list used by the compressed write code. */ #endif +#ifdef PNG_WRITE_FILTER_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_alloc_filter_row_buffers, + (png_structrp png_ptr, int filters),PNG_EMPTY); + /* Allocate pixel row buffers to cache filtered rows while testing candidate + * filters. + * TODO: avoid this, only one spare row buffer (at most) is required, this + * wastes a lot of memory for large images. + */ +#endif + #if defined(PNG_FLOATING_POINT_SUPPORTED) && \ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ @@ -1801,9 +1794,9 @@ PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value, png_fixed_point gamma_value),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr), PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr, +PNG_INTERNAL_FUNCTION(void,png_build_gamma_tables,(png_structrp png_ptr, int bit_depth),PNG_EMPTY); #endif /* SIMPLIFIED READ/WRITE SUPPORT */ @@ -1862,9 +1855,10 @@ #endif /* SIMPLIFIED READ/WRITE */ #ifdef PNG_FILTER_OPTIMIZATIONS -PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structrp png_ptr, + unsigned int bpp), PNG_EMPTY); /* This is the initialization function for hardware specific optimizations, * one implementation (for ARM NEON machines) is contained in * arm/filter_neon.c. It need not be defined - the generic code will be used * if not. diff -ru4NwbB libpng-1.6.0beta34/pngrio.c libpng-1.7.0alpha04/pngrio.c --- libpng-1.6.0beta34/pngrio.c 2012-12-19 16:06:53.022502717 -0600 +++ libpng-1.7.0alpha04/pngrio.c 2012-12-22 18:00:42.454081462 -0600 @@ -1,8 +1,8 @@ /* pngrio.c - functions for data input * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -101,16 +101,18 @@ #else png_ptr->read_data_fn = read_data_fn; #endif +#ifdef PNG_WRITE_SUPPORTED /* It is an error to write to a read device */ if (png_ptr->write_data_fn != NULL) { png_ptr->write_data_fn = NULL; png_warning(png_ptr, "Can't set both read_data_fn and write_data_fn in the" " same structure"); } +#endif #ifdef PNG_WRITE_FLUSH_SUPPORTED png_ptr->output_flush_fn = NULL; #endif diff -ru4NwbB libpng-1.6.0beta34/pngrtran.c libpng-1.7.0alpha04/pngrtran.c --- libpng-1.6.0beta34/pngrtran.c 2012-12-19 16:06:53.040672853 -0600 +++ libpng-1.7.0alpha04/pngrtran.c 2012-12-22 18:00:42.472012999 -0600 @@ -1,8 +1,8 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -129,11 +129,13 @@ if (!png_rtran_ok(png_ptr, 0) || background_color == NULL) return; - if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) + if (background_gamma_code != PNG_BACKGROUND_GAMMA_SCREEN && + background_gamma_code != PNG_BACKGROUND_GAMMA_FILE && + background_gamma_code != PNG_BACKGROUND_GAMMA_UNIQUE) { - png_warning(png_ptr, "Application must supply a known background gamma"); + png_app_error(png_ptr, "invalid gamma type"); return; } png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; @@ -142,12 +144,14 @@ png_ptr->background = *background_color; png_ptr->background_gamma = background_gamma; png_ptr->background_gamma_type = (png_byte)(background_gamma_code); + if (need_expand) - png_ptr->transformations |= PNG_BACKGROUND_EXPAND; + png_ptr->flags |= PNG_FLAG_BACKGROUND_EXPAND; + else - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; + png_ptr->flags &= ~PNG_FLAG_BACKGROUND_EXPAND; } # ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI @@ -252,18 +256,12 @@ * API. The alternative would just lead to undetected errors and spurious * bug reports. Negative values fail inside the _fixed API unless they * correspond to the flag values. */ - if (output_gamma > 0 && output_gamma < 128) - output_gamma *= PNG_FP_1; - - /* This preserves -1 and -2 exactly: */ - output_gamma = floor(output_gamma + .5); - - if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) - png_fixed_error(png_ptr, "gamma value"); + if (output_gamma < 0 || output_gamma > 128) + output_gamma *= .00001; - return (png_fixed_point)output_gamma; + return png_fixed(png_ptr, output_gamma, "gamma value"); } # endif #endif /* READ_ALPHA_MODE || READ_GAMMA */ @@ -366,9 +364,9 @@ /* And obtain alpha pre-multiplication by composing on black: */ memset(&png_ptr->background, 0, (sizeof png_ptr->background)); png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; + png_ptr->flags &= ~PNG_FLAG_BACKGROUND_EXPAND; if (png_ptr->transformations & PNG_COMPOSE) png_error(png_ptr, "conflicting calls to set alpha mode and background"); @@ -1004,9 +1002,11 @@ green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); png_ptr->rgb_to_gray_red_coeff = red_int; png_ptr->rgb_to_gray_green_coeff = green_int; - png_ptr->rgb_to_gray_coefficients_set = 1; +# if defined PNG_COLORS_SPACE_SUPPORTED || defined PNG_GAMMA_SUPPORTED + png_ptr->colorspace.flags |= PNG_COLORSPACE_RGB_TO_GRAY_SET; +# endif } else { @@ -1090,25 +1090,266 @@ /* Initialize everything needed for the read. This includes modifying * the palette. */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) +static void +gamma_correct_background(unsigned int value, unsigned int depth, + png_uint_16p backgroundp, png_uint_16p background_1p, + png_fixed_point gamma_correct, png_fixed_point gamma_to_1) +{ + switch (depth) + { + case 8: + if (gamma_correct != PNG_FP_1) + *backgroundp = png_gamma_8bit_correct(value, gamma_correct); + + else + *backgroundp = (png_uint_16)value; + + if (gamma_to_1 != PNG_FP_1) + *background_1p = png_gamma_16bit_correct(value*257, gamma_to_1); + + else + *background_1p = (png_uint_16)(value*257); + + return; + + case 16: + if (gamma_correct != PNG_FP_1) + *backgroundp = png_gamma_16bit_correct(value, gamma_correct); + + else + *backgroundp = (png_uint_16)value; + + if (gamma_to_1 != PNG_FP_1) + *background_1p = png_gamma_16bit_correct(value, gamma_to_1); + + else + *background_1p = (png_uint_16)value; + + return; + + default: + /* Low bit depth gray levels; do no harm. */ + break; + } + + *backgroundp = (png_uint_16)value; + *background_1p = 0; /* should not be used */ +} -/*For the moment 'png_init_palette_transformations' and - * 'png_init_rgb_transformations' only do some flag canceling optimizations. - * The intent is that these two routines should have palette or rgb operations - * extracted from 'png_init_read_transformations'. - */ static void /* PRIVATE */ -png_init_palette_transformations(png_structrp png_ptr) +png_init_background_transformations(png_structrp png_ptr) + /* Set the png_ptr->background and png_ptr->background_1 members correctly + * for the bit depth and format. + */ { - /* Called to handle the (input) palette case. In png_do_read_transformations - * the first step is to expand the palette if requested, so this code must - * take care to only make changes that are invariant with respect to the - * palette expansion, or only do them if there is no expansion. + /* png_ptr->background is only assigned by png_set_background and + * png_set_alpha_mode (which just zeros out the fields.) png_set_background + * can set the PNG_FLAG_BACKGROUND_EXPAND flag if the input value is in the + * file format, for example if it comes from a bKGD chunk. * - * STRIP_ALPHA has already been handled in the caller (by setting num_trans - * to 0.) + * Under some circumstances deficiencies in the current libpng code mean that + * the bit depth of the values must differ from the final bit depth; the bit + * depth has to match that at which the processing of the image pixels + * happens and this is not always the final bit depth. This is fixed up + * here. + * + * First find the required depth. */ + unsigned int bit_depth, required_bit_depth; + unsigned int color_type = png_ptr->color_type; + const png_uint_32 transform = png_ptr->transformations; + const int expand = (png_ptr->flags & PNG_FLAG_BACKGROUND_EXPAND) != 0; + + if (color_type & PNG_COLOR_MASK_PALETTE) + required_bit_depth = bit_depth = 8; + + else + { + required_bit_depth = bit_depth = png_ptr->bit_depth; + + /* But not PNG_EXPAND_16 at present because it happens after the compose + * operation where the background is used! + */ + if (bit_depth < 8 && (transform & PNG_EXPAND) != 0) + required_bit_depth = 8; + } + + /* bit_depth and color_type now refer to the original file data and + * required_bit_depth is correct for the processing libpng does, however it + * does not necessarily match the output the application gets, fix that and + * the color type here: + */ + if (!expand) + { + /* The background bit_depth and color_type need correcting */ + if ((transform & PNG_EXPAND) != 0) + color_type &= ~PNG_COLOR_MASK_PALETTE; + + /* The RGB<->gray transformations do the to gray operation first, then the + * from gray. + */ + if ((transform & PNG_RGB_TO_GRAY) != 0) + color_type &= ~PNG_COLOR_MASK_COLOR; + + if ((transform & PNG_GRAY_TO_RGB) != 0) + color_type |= PNG_COLOR_MASK_COLOR; + + bit_depth = required_bit_depth; + + /* The expansion to 16 bits and the scaling back from 16 bits per + * component to only 8 happens after the background processing (at + * present) so these transforms only affect the screen value, not the + * required value. Note that the 16_TO_8 conversions happen before the 8 + * to 16 one, so in theory both could occur - the order of the tests below + * must be correct! + * + * TODO: Note that the second of these changes cause an input 16-bit + * background value to be temporarily crushed to 8-bits per component, + * losing precision. This is a bug and should be fixed. + */ + if (bit_depth == 16 && + (transform & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0) + bit_depth = 8; + + if (bit_depth == 8 && (color_type & PNG_COLOR_MASK_PALETTE) == 0 && + (transform & PNG_EXPAND_16) != 0) + bit_depth = 16; + } + + /* Now make the background have the correct format. This involves reading the + * correct fields from png_ptr->background, adjusting the bit depth of the + * result and potentially gamma correcting the value then calculating the + * png_ptr->background_1 values too. + */ + { + unsigned int mult = 1; + png_fixed_point gamma_to_1, gamma_correct; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + gamma_to_1 = png_ptr->screen_gamma; + gamma_correct = PNG_FP_1; + break; + + case PNG_BACKGROUND_GAMMA_FILE: + gamma_to_1 = png_reciprocal(png_ptr->colorspace.gamma); + gamma_correct = png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + gamma_to_1 = png_reciprocal(png_ptr->background_gamma); + gamma_correct = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + + default: + gamma_to_1 = PNG_FP_1; + gamma_correct = PNG_FP_1; + break; + } + +# define CORRECT(v, c)\ + gamma_correct_background((v)*mult, bit_depth,\ + &png_ptr->background.c, &png_ptr->background_1.c,\ + gamma_correct, gamma_to_1);\ + if (bit_depth > required_bit_depth)\ + png_ptr->background.c =\ + (png_uint_16)PNG_DIV257(png_ptr->background.c) + + /* The multiplier 'mult' scales the values to 'required_depth', + * 'bit_depth' is the depth of the resultant values. + */ + while (bit_depth < required_bit_depth) + mult += mult << bit_depth, bit_depth <<= 1; + + /* In the event that this still leaves the background bit depth greater + * than the libpng required depth scale the values back to the 8-bit + * range, the test below verifies that this is correct. + */ + if (bit_depth > required_bit_depth) + { + if (bit_depth != 16 || required_bit_depth != 8) + png_error(png_ptr, "internal error handling background depth"); + } + + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_ptr->flags &= ~PNG_FLAG_BACKGROUND_IS_GRAY; /* checked below */ + + /* If need_expand was passed to png_set_background the background value + * was in the file format, therefore if the file is a palette file the + * background will have been an index into the palette. Notice that if + * need_expand was false then the color is RGB even if the output still + * has a palette. + */ + if (expand && (color_type & PNG_COLOR_MASK_PALETTE) != 0) + { + unsigned int background_index = png_ptr->background.index; + + if (background_index < png_ptr->num_palette && + png_ptr->palette != NULL) + { + /* In fact 'mult' is always 1 at present in this case */ + CORRECT(png_ptr->palette[background_index].red, red); + CORRECT(png_ptr->palette[background_index].green, green); + CORRECT(png_ptr->palette[background_index].blue, blue); + } + + else + { + png_app_error(png_ptr, "out of range background index"); + memset(&png_ptr->background, 0, sizeof png_ptr->background); + memset(&png_ptr->background_1, 0, sizeof png_ptr->background_1); + } + } + + else + { + CORRECT(png_ptr->background.red, red); + CORRECT(png_ptr->background.green, green); + CORRECT(png_ptr->background.blue, blue); + } + + if (png_ptr->background.red == png_ptr->background.blue && + png_ptr->background.red == png_ptr->background.green) + { + png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY; + png_ptr->background.gray = png_ptr->background.red; + png_ptr->background_1.gray = png_ptr->background_1.red; + } + + else + png_ptr->background.gray = png_ptr->background_1.gray = 0; + } + + else + { + png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY; + + CORRECT(png_ptr->background.gray, gray); + + png_ptr->background.red = + png_ptr->background.green = + png_ptr->background.blue = png_ptr->background.gray; + + png_ptr->background_1.red = + png_ptr->background_1.green = + png_ptr->background_1.blue = png_ptr->background_1.gray; + } +# undef CORRECT + } +} +#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ + +static void /* PRIVATE */ +png_init_palette_transformations(png_structrp png_ptr) +{ int input_has_alpha = 0; int input_has_transparency = 0; if (png_ptr->num_trans > 0) @@ -1128,57 +1369,17 @@ /* If no alpha we can optimize. */ if (!input_has_alpha) { /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA + * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA * and ENCODE_ALPHA are irrelevant. */ png_ptr->transformations &= ~PNG_ENCODE_ALPHA; png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; if (!input_has_transparency) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - (png_ptr->transformations & PNG_EXPAND)) - { - { - png_ptr->background.red = - png_ptr->palette[png_ptr->background.index].red; - png_ptr->background.green = - png_ptr->palette[png_ptr->background.index].green; - png_ptr->background.blue = - png_ptr->palette[png_ptr->background.index].blue; - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) - { - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) - { - /* Invert the alpha channel (in tRNS) unless the pixels are - * going to be expanded, in which case leave it for later - */ - int i, istop = png_ptr->num_trans; - - for (i=0; itrans_alpha[i] = (png_byte)(255 - - png_ptr->trans_alpha[i]); - } - } -#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ + png_ptr->transformations &= ~PNG_COMPOSE; } - } /* background expand and (therefore) no alpha association. */ -#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ } static void /* PRIVATE */ png_init_rgb_transformations(png_structrp png_ptr) @@ -1202,68 +1403,10 @@ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; # endif if (!input_has_transparency) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - (png_ptr->transformations & PNG_EXPAND) && - !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) - /* i.e., GRAY or GRAY_ALPHA */ - { - { - /* 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: - gray *= 0xff; - trans_gray *= 0xff; - break; - - case 2: - gray *= 0x55; - trans_gray *= 0x55; - break; - - case 4: - gray *= 0x11; - trans_gray *= 0x11; - break; - - default: - - case 8: - /* FALL THROUGH (Already 8 bits) */ - - case 16: - /* 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; - } + png_ptr->transformations &= ~PNG_COMPOSE; } - } /* background expand and (therefore) no alpha association. */ -#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ } void /* PRIVATE */ png_init_read_transformations(png_structrp png_ptr) @@ -1346,18 +1489,18 @@ * * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) * 2) PNG_STRIP_ALPHA (if no compose) * 3) PNG_RGB_TO_GRAY - * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY + * 4) PNG_GRAY_TO_RGB iff !PNG_FLAG_BACKGROUND_IS_GRAY * 5) PNG_COMPOSE * 6) PNG_GAMMA * 7) PNG_STRIP_ALPHA (if compose) * 8) PNG_ENCODE_ALPHA * 9) PNG_SCALE_16_TO_8 * 10) PNG_16_TO_8 * 11) PNG_QUANTIZE (converts to palette) * 12) PNG_EXPAND_16 - * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY + * 13) PNG_GRAY_TO_RGB iff PNG_FLAG_BACKGROUND_IS_GRAY * 14) PNG_INVERT_MONO * 15) PNG_SHIFT * 16) PNG_PACK * 17) PNG_BGR @@ -1368,18 +1511,21 @@ * 22) PNG_SWAP_BYTES * 23) PNG_USER_TRANSFORM [must be last] */ #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - !(png_ptr->transformations & PNG_COMPOSE)) + if (png_ptr->transformations & PNG_STRIP_ALPHA) + { + if (!(png_ptr->transformations & PNG_FILLER)) + png_ptr->transformations &= ~(PNG_INVERT_ALPHA|PNG_SWAP_ALPHA); + + if (!(png_ptr->transformations & PNG_COMPOSE)) { /* Stripping the alpha channel happens immediately after the 'expand' - * transformations, before all other transformation, so it cancels out + * transformations, before all other transformations, so it cancels out * the alpha handling. It has the side effect negating the effect of * PNG_EXPAND_tRNS too: */ - png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | - PNG_EXPAND_tRNS); + png_ptr->transformations &= ~(PNG_ENCODE_ALPHA | PNG_EXPAND_tRNS); png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen * so transparency information would remain just so long as it wasn't @@ -1389,8 +1535,9 @@ * get.) This makes the behavior consistent from 1.5.4: */ png_ptr->num_trans = 0; } + } #endif /* STRIP_ALPHA supported, no COMPOSE */ #ifdef PNG_READ_ALPHA_MODE_SUPPORTED /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA @@ -1410,53 +1557,21 @@ if (png_ptr->transformations & PNG_RGB_TO_GRAY) png_colorspace_set_rgb_coefficients(png_ptr); #endif -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -#if defined PNG_READ_EXPAND_SUPPORTED && defined PNG_READ_BACKGROUND_SUPPORTED - /* Detect gray background and attempt to enable optimization for - * gray --> RGB case. - * - * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or - * RGB_ALPHA (in which case need_expand is superfluous anyway), the - * background color might actually be gray yet not be flagged as such. - * This is not a problem for the current code, which uses - * PNG_BACKGROUND_IS_GRAY only to decide when to do the - * png_do_gray_to_rgb() transformation. - * - * TODO: this code needs to be revised to avoid the complexity and - * interdependencies. The color type of the background should be recorded in - * png_set_background, along with the bit depth, then the code has a record - * of exactly what color space the background is currently in. - */ - if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) - { - /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if - * the file was grayscale the background value is gray. - */ - if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - } + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_init_palette_transformations(png_ptr); - else if (png_ptr->transformations & PNG_COMPOSE) - { - /* PNG_COMPOSE: png_set_background was called with need_expand false, - * so the color is in the color space of the output or png_set_alpha_mode - * was called and the color is black. Ignore RGB_TO_GRAY because that - * happens before GRAY_TO_RGB. + else + png_init_rgb_transformations(png_ptr); + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + /* Set up the background information if required. It is only used if + * PNG_COMPOSE is specified. */ - if (png_ptr->transformations & PNG_GRAY_TO_RGB) - { - if (png_ptr->background.red == png_ptr->background.green && - png_ptr->background.red == png_ptr->background.blue) - { - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - png_ptr->background.gray = png_ptr->background.red; - } - } - } -#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ -#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ + if (png_ptr->transformations & PNG_COMPOSE) + png_init_background_transformations(png_ptr); +#endif /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations * can be performed directly on the palette, and some (such as rgb to gray) * can be optimized inside the palette. This is particularly true of the @@ -1467,76 +1582,13 @@ * earlier and the palette stuff is actually handled on the first row. This * leads to the reported bug that the palette returned by png_get_PLTE is not * updated. */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_init_palette_transformations(png_ptr); - - else - png_init_rgb_transformations(png_ptr); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_READ_EXPAND_16_SUPPORTED) - if ((png_ptr->transformations & PNG_EXPAND_16) && - (png_ptr->transformations & PNG_COMPOSE) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - png_ptr->bit_depth != 16) - { - /* TODO: fix this. Because the expand_16 operation is after the compose - * handling the background color must be 8, not 16, bits deep, but the - * application will supply a 16-bit value so reduce it here. - * - * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at - * present, so that case is ok (until do_expand_16 is moved.) - * - * NOTE: this discards the low 16 bits of the user supplied background - * color, but until expand_16 works properly there is no choice! - */ -# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) - CHOP(png_ptr->background.red); - CHOP(png_ptr->background.green); - CHOP(png_ptr->background.blue); - CHOP(png_ptr->background.gray); -# undef CHOP - } -#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ - defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) - if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && - (png_ptr->transformations & PNG_COMPOSE) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - png_ptr->bit_depth == 16) - { - /* On the other hand, if a 16-bit file is to be reduced to 8-bits per - * component this will also happen after PNG_COMPOSE and so the background - * color must be pre-expanded here. - * - * TODO: fix this too. - */ - png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); - png_ptr->background.green = - (png_uint_16)(png_ptr->background.green * 257); - png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); - png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); - } +#if 0 /* NYI */ + png_do_palette_transformations(png_ptr); #endif - /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the - * background support (see the comments in scripts/pnglibconf.dfa), this - * allows pre-multiplication of the alpha channel to be implemented as - * compositing on black. This is probably sub-optimal and has been done in - * 1.5.4 betas simply to enable external critique and testing (i.e. to - * implement the new API quickly, without lots of internal changes.) - */ - #ifdef PNG_READ_GAMMA_SUPPORTED -# ifdef PNG_READ_BACKGROUND_SUPPORTED - /* Includes ALPHA_MODE */ - png_ptr->background_1 = png_ptr->background; -# endif - /* This needs to change - in the palette image case a whole set of tables are * built when it would be quicker to just calculate the correct value for * each palette entry directly. Also, the test is too tricky - why check * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that @@ -1563,9 +1615,9 @@ )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) && png_gamma_significant(png_ptr->screen_gamma)) ) { - png_build_gamma_table(png_ptr, png_ptr->bit_depth); + png_build_gamma_tables(png_ptr, png_ptr->bit_depth); #ifdef PNG_READ_BACKGROUND_SUPPORTED if (png_ptr->transformations & PNG_COMPOSE) { @@ -1580,113 +1632,43 @@ "libpng does not support gamma+background+rgb_to_gray"); if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - /* We don't get to here unless there is a tRNS chunk with non-opaque - * entries - see the checking code at the start of this function. - */ - png_color back, back_1; + unsigned int i, num_palette = png_ptr->num_palette; + png_color back; + png_color_16 back_1 = png_ptr->background_1; png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) - { - - back.red = png_ptr->gamma_table[png_ptr->background.red]; - back.green = png_ptr->gamma_table[png_ptr->background.green]; - back.blue = png_ptr->gamma_table[png_ptr->background.blue]; - - back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; - back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; - back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; - } - else - { - png_fixed_point g, gs; - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = (png_ptr->screen_gamma); - gs = PNG_FP_1; - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - default: - g = PNG_FP_1; /* back_1 */ - gs = PNG_FP_1; /* back */ - break; - } - - if (png_gamma_significant(gs)) - { - back.red = png_gamma_8bit_correct(png_ptr->background.red, - gs); - back.green = png_gamma_8bit_correct(png_ptr->background.green, - gs); - back.blue = png_gamma_8bit_correct(png_ptr->background.blue, - gs); - } - else - { back.red = (png_byte)png_ptr->background.red; back.green = (png_byte)png_ptr->background.green; back.blue = (png_byte)png_ptr->background.blue; - } - - if (png_gamma_significant(g)) - { - back_1.red = png_gamma_8bit_correct(png_ptr->background.red, - g); - back_1.green = png_gamma_8bit_correct( - png_ptr->background.green, g); - back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, - g); - } - - else - { - back_1.red = (png_byte)png_ptr->background.red; - back_1.green = (png_byte)png_ptr->background.green; - back_1.blue = (png_byte)png_ptr->background.blue; - } - } for (i = 0; i < num_palette; i++) { - if (i < (int)png_ptr->num_trans && - png_ptr->trans_alpha[i] != 0xff) + if (i < png_ptr->num_trans && png_ptr->trans_alpha[i] != 0xff) { if (png_ptr->trans_alpha[i] == 0) { palette[i] = back; } else /* if (png_ptr->trans_alpha[i] != 0xff) */ { - png_byte v, w; + png_uint_16 v, w; + unsigned int alpha = png_ptr->trans_alpha[i] * 257U; + unsigned int shift = png_ptr->gamma_shift; + unsigned int add = (shift > 0 ? 1U<<(shift-1) : 0); v = png_ptr->gamma_to_1[palette[i].red]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); - palette[i].red = png_ptr->gamma_from_1[w]; + png_composite_16(w, v, alpha, back_1.red); + palette[i].red = png_ptr->gamma_from_1[(w+add)>>shift]; v = png_ptr->gamma_to_1[palette[i].green]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); - palette[i].green = png_ptr->gamma_from_1[w]; + png_composite_16(w, v, alpha, back_1.green); + palette[i].green = png_ptr->gamma_from_1[(w+add)>>shift]; v = png_ptr->gamma_to_1[palette[i].blue]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); - palette[i].blue = png_ptr->gamma_from_1[w]; + png_composite_16(w, v, alpha, back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[(w+add)>>shift]; } } else { @@ -1703,93 +1685,8 @@ * transformations elsewhere. */ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); } /* color_type == PNG_COLOR_TYPE_PALETTE */ - - /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ - else /* color_type != PNG_COLOR_TYPE_PALETTE */ - { - int gs_sig, g_sig; - png_fixed_point g = PNG_FP_1; /* Correction to linear */ - png_fixed_point gs = PNG_FP_1; /* Correction to screen */ - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = png_ptr->screen_gamma; - /* gs = PNG_FP_1; */ - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - - default: - png_error(png_ptr, "invalid background gamma type"); - } - - g_sig = png_gamma_significant(g); - gs_sig = png_gamma_significant(gs); - - if (g_sig) - png_ptr->background_1.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, g); - - if (gs_sig) - png_ptr->background.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, gs); - - if ((png_ptr->background.red != png_ptr->background.green) || - (png_ptr->background.red != png_ptr->background.blue) || - (png_ptr->background.red != png_ptr->background.gray)) - { - /* RGB or RGBA with color background */ - if (g_sig) - { - png_ptr->background_1.red = png_gamma_correct(png_ptr, - png_ptr->background.red, g); - - png_ptr->background_1.green = png_gamma_correct(png_ptr, - png_ptr->background.green, g); - - png_ptr->background_1.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, g); - } - - if (gs_sig) - { - png_ptr->background.red = png_gamma_correct(png_ptr, - png_ptr->background.red, gs); - - png_ptr->background.green = png_gamma_correct(png_ptr, - png_ptr->background.green, gs); - - png_ptr->background.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, gs); - } - } - - else - { - /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ - png_ptr->background_1.red = png_ptr->background_1.green - = png_ptr->background_1.blue = png_ptr->background_1.gray; - - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - } - - /* The background is now in screen gamma: */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; - } /* color_type != PNG_COLOR_TYPE_PALETTE */ }/* png_ptr->transformations & PNG_BACKGROUND */ else /* Transformation does not include PNG_BACKGROUND */ @@ -2234,9 +2131,9 @@ /* If gray -> RGB, do so now only if background is non-gray; else do later * for performance reasons */ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && - !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) + !(png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); #endif #if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ @@ -2319,9 +2216,9 @@ #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_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_INVERT_SUPPORTED @@ -3283,25 +3180,26 @@ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; if (row_info->bit_depth == 8) { -#ifdef PNG_READ_GAMMA_SUPPORTED /* Notice that gamma to/from 1 are not necessarily inverses (if * there is an overall gamma correction). Prior to 1.5.5 this code * checked the linearized values for equality; this doesn't match * the documentation, the original values must be checked. */ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) { + PNG_CONST unsigned int shift = 15 + png_ptr->gamma_shift; + PNG_CONST png_uint_32 add = 1U << (shift-1); png_bytep sp = row; png_bytep dp = row; png_uint_32 i; for (i = 0; i < row_width; i++) { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); + unsigned int red = *(sp++); + unsigned int green = *(sp++); + unsigned int blue = *(sp++); if (red != green || red != blue) { red = png_ptr->gamma_to_1[red]; @@ -3309,9 +3207,9 @@ blue = png_ptr->gamma_to_1[blue]; rgb_error |= 1; *(dp++) = png_ptr->gamma_from_1[ - (rc*red + gc*green + bc*blue + 16384)>>15]; + (rc*red + gc*green + bc*blue + add)>>shift]; } else { @@ -3320,9 +3218,9 @@ */ if (png_ptr->gamma_table != NULL) red = png_ptr->gamma_table[red]; - *(dp++) = red; + *(dp++) = (png_byte)red; } if (have_alpha) *(dp++) = *(sp++); @@ -3327,10 +3225,10 @@ if (have_alpha) *(dp++) = *(sp++); } } + else -#endif { png_bytep sp = row; png_bytep dp = row; png_uint_32 i; @@ -3343,12 +3241,9 @@ if (red != green || red != blue) { rgb_error |= 1; - /* NOTE: this is the historical approach which simply - * truncates the results. - */ - *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); + *(dp++) = (png_byte)((rc*red+gc*green+bc*blue+16384)>>15); } else *(dp++) = red; @@ -3360,11 +3255,12 @@ } else /* RGB bit_depth == 16 */ { -#ifdef PNG_READ_GAMMA_SUPPORTED if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) { + unsigned int shift = png_ptr->gamma_shift; + unsigned int add = (shift > 0 ? (1U << (shift-1)) : 0); png_bytep sp = row; png_bytep dp = row; png_uint_32 i; @@ -3378,28 +3274,25 @@ if (red == green && red == blue) { if (png_ptr->gamma_16_table != NULL) - w = png_ptr->gamma_16_table[(red&0xff) - >> png_ptr->gamma_shift][red>>8]; + w = png_ptr->gamma_16_table[(red+add) >> shift]; else w = red; } else { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) - >> png_ptr->gamma_shift][red>>8]; - png_uint_16 green_1 = - png_ptr->gamma_16_to_1[(green&0xff) >> - png_ptr->gamma_shift][green>>8]; - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) - >> png_ptr->gamma_shift][blue>>8]; + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red+add) + >> shift]; + png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green+add) + >> shift]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue+add) + >> shift]; png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + bc*blue_1 + 16384)>>15); - w = png_ptr->gamma_16_from_1[(gray16&0xff) >> - png_ptr->gamma_shift][gray16 >> 8]; + w = png_ptr->gamma_16_from_1[(gray16+add) >> shift]; rgb_error |= 1; } *(dp++) = (png_byte)((w>>8) & 0xff); @@ -3411,10 +3304,10 @@ *(dp++) = *(sp++); } } } + else -#endif { png_bytep sp = row; png_bytep dp = row; png_uint_32 i; @@ -3433,10 +3326,9 @@ /* From 1.5.5 in the 16 bit case do the accurate conversion even * in the 'fast' case - this is because this is where the code * ends up when handling linear 16 bit data. */ - gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> - 15); + gray16 = (png_uint_16)((rc*red+gc*green+bc*blue+16384) >> 15); *(dp++) = (png_byte)((gray16>>8) & 0xff); *(dp++) = (png_byte)(gray16 & 0xff); if (have_alpha) @@ -3526,23 +3418,21 @@ */ void /* PRIVATE */ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { -#ifdef PNG_READ_GAMMA_SUPPORTED png_const_bytep gamma_table = png_ptr->gamma_table; png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; - png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; - png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; - png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; - png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; - int gamma_shift = png_ptr->gamma_shift; - int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; -#endif + png_const_uint_16p gamma_to_1 = png_ptr->gamma_to_1; + png_const_uint_16p gamma_16 = png_ptr->gamma_16_table; + png_const_uint_16p gamma_16_from_1 = png_ptr->gamma_16_from_1; + png_const_uint_16p gamma_16_to_1 = png_ptr->gamma_16_to_1; + PNG_CONST unsigned int shift = png_ptr->gamma_shift; + PNG_CONST unsigned int add = (shift > 0 ? 1U<<(shift-1) : 0); + PNG_CONST int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; png_bytep sp; png_uint_32 i; png_uint_32 row_width = row_info->width; - int shift; png_debug(1, "in png_do_compose"); { @@ -3553,167 +3443,166 @@ switch (row_info->bit_depth) { case 1: { + int bit_shift = 7; sp = row; - shift = 7; for (i = 0; i < row_width; i++) { - if ((png_uint_16)((*sp >> shift) & 0x01) + if ((png_uint_16)((*sp >> bit_shift) & 0x01) == png_ptr->trans_color.gray) { - unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); - tmp |= png_ptr->background.gray << shift; + unsigned int tmp = *sp & (0x7f7f >> (7 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (!bit_shift) { - shift = 7; + bit_shift = 7; sp++; } else - shift--; + bit_shift--; } break; } case 2: { -#ifdef PNG_READ_GAMMA_SUPPORTED +#if 0 if (gamma_table != NULL) { + int bit_shift = 6; sp = row; - shift = 6; for (i = 0; i < row_width; i++) { - if ((png_uint_16)((*sp >> shift) & 0x03) + if ((png_uint_16)((*sp >> bit_shift) & 0x03) == png_ptr->trans_color.gray) { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= png_ptr->background.gray << shift; + unsigned int tmp = *sp & (0x3f3f >> (6 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; *sp = (png_byte)(tmp & 0xff); } else { - unsigned int p = (*sp >> shift) & 0x03; + unsigned int p = (*sp >> bit_shift) & 0x03; unsigned int g = (gamma_table [p | (p << 2) | (p << 4) | (p << 6)] >> 6) & 0x03; - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= g << shift; + unsigned int tmp = *sp & (0x3f3f >> (6 - bit_shift)); + tmp |= g << bit_shift; *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (!bit_shift) { - shift = 6; + bit_shift = 6; sp++; } else - shift -= 2; + bit_shift -= 2; } } else #endif { + int bit_shift = 6; sp = row; - shift = 6; for (i = 0; i < row_width; i++) { - if ((png_uint_16)((*sp >> shift) & 0x03) + if ((png_uint_16)((*sp >> bit_shift) & 0x03) == png_ptr->trans_color.gray) { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= png_ptr->background.gray << shift; + unsigned int tmp = *sp & (0x3f3f >> (6 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (!bit_shift) { - shift = 6; + bit_shift = 6; sp++; } else - shift -= 2; + bit_shift -= 2; } } break; } case 4: { -#ifdef PNG_READ_GAMMA_SUPPORTED +#if 0 if (gamma_table != NULL) { + int bit_shift = 4; sp = row; - shift = 4; for (i = 0; i < row_width; i++) { - if ((png_uint_16)((*sp >> shift) & 0x0f) + if ((png_uint_16)((*sp >> bit_shift) & 0x0f) == png_ptr->trans_color.gray) { - unsigned int tmp = *sp & (0xf0f >> (4 - shift)); - tmp |= png_ptr->background.gray << shift; + unsigned int tmp = *sp & (0xf0f >> (4 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; *sp = (png_byte)(tmp & 0xff); } else { - unsigned int p = (*sp >> shift) & 0x0f; + unsigned int p = (*sp >> bit_shift) & 0x0f; unsigned int g = (gamma_table[p | (p << 4)] >> 4) & 0x0f; - unsigned int tmp = *sp & (0xf0f >> (4 - shift)); - tmp |= g << shift; + unsigned int tmp = *sp & (0xf0f >> (4 - bit_shift)); + tmp |= g << bit_shift; *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (!bit_shift) { - shift = 4; + bit_shift = 4; sp++; } else - shift -= 4; + bit_shift -= 4; } } else #endif { + int bit_shift = 4; sp = row; - shift = 4; for (i = 0; i < row_width; i++) { - if ((png_uint_16)((*sp >> shift) & 0x0f) + if ((png_uint_16)((*sp >> bit_shift) & 0x0f) == png_ptr->trans_color.gray) { - unsigned int tmp = *sp & (0xf0f >> (4 - shift)); - tmp |= png_ptr->background.gray << shift; + unsigned int tmp = *sp & (0xf0f >> (4 - bit_shift)); + tmp |= png_ptr->background.gray << bit_shift; *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (!bit_shift) { - shift = 4; + bit_shift = 4; sp++; } else - shift -= 4; + bit_shift -= 4; } } break; } case 8: { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_table != NULL) { sp = row; for (i = 0; i < row_width; i++, sp++) @@ -3724,10 +3613,10 @@ else *sp = gamma_table[*sp]; } } + else -#endif { sp = row; for (i = 0; i < row_width; i++, sp++) { @@ -3739,9 +3628,8 @@ } case 16: { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_16 != NULL) { sp = row; for (i = 0; i < row_width; i++, sp += 2) @@ -3760,9 +3648,9 @@ } else { - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16[(v+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); } } @@ -3766,10 +3654,10 @@ *(sp + 1) = (png_byte)(v & 0xff); } } } + else -#endif { sp = row; for (i = 0; i < row_width; i++, sp += 2) { @@ -3798,9 +3686,8 @@ case PNG_COLOR_TYPE_RGB: { if (row_info->bit_depth == 8) { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_table != NULL) { sp = row; for (i = 0; i < row_width; i++, sp += 3) @@ -3821,10 +3708,10 @@ *(sp + 2) = gamma_table[*(sp + 2)]; } } } + else -#endif { sp = row; for (i = 0; i < row_width; i++, sp += 3) { @@ -3840,9 +3727,8 @@ } } else /* if (row_info->bit_depth == 16) */ { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_16 != NULL) { sp = row; for (i = 0; i < row_width; i++, sp += 6) @@ -3872,25 +3758,24 @@ } else { - png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + png_uint_16 v = gamma_16[(r+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + v = gamma_16[(g+add) >> shift]; *(sp + 2) = (png_byte)((v >> 8) & 0xff); *(sp + 3) = (png_byte)(v & 0xff); - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + v = gamma_16[(b+add) >> shift]; *(sp + 4) = (png_byte)((v >> 8) & 0xff); *(sp + 5) = (png_byte)(v & 0xff); } } } else -#endif { sp = row; for (i = 0; i < row_width; i++, sp += 6) { @@ -3925,9 +3810,8 @@ case PNG_COLOR_TYPE_GRAY_ALPHA: { if (row_info->bit_depth == 8) { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_to_1 != NULL && gamma_from_1 != NULL && gamma_table != NULL) { sp = row; @@ -3945,20 +3829,26 @@ } else { - png_byte v, w; + unsigned int v, w; v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.gray); + png_composite_16(w, v, 257*a, + png_ptr->background_1.gray); + if (!optimize) - w = gamma_from_1[w]; - *sp = w; + w = gamma_from_1[(w+add)>>shift]; + + else /* alpha pixels linear and approximate */ + w = PNG_DIV257(w); + + *sp = (png_byte)w; } } } + else -#endif { sp = row; for (i = 0; i < row_width; i++, sp += 2) { @@ -3971,11 +3861,11 @@ png_composite(*sp, *sp, a, png_ptr->background.gray); } } } + else /* if (png_ptr->bit_depth == 16) */ { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_16 != NULL && gamma_16_from_1 != NULL && gamma_16_to_1 != NULL) { sp = row; @@ -3987,9 +3877,9 @@ if (a == (png_uint_16)0xffff) { png_uint_16 v; - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); } @@ -4004,14 +3894,17 @@ else { png_uint_16 g, v, w; - g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + g = gamma_16_to_1[((sp[0]<<8)+sp[1]+add) >> shift]; png_composite_16(v, g, a, png_ptr->background_1.gray); - if (optimize) - w = v; + + if (!optimize) + w = gamma_16_from_1[(v+add) >> shift]; + else - w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; + w = v; + *sp = (png_byte)((w >> 8) & 0xff); *(sp + 1) = (png_byte)(w & 0xff); } } @@ -4015,10 +3908,10 @@ *(sp + 1) = (png_byte)(w & 0xff); } } } + else -#endif { sp = row; for (i = 0; i < row_width; i++, sp += 4) { @@ -4050,9 +3943,8 @@ case PNG_COLOR_TYPE_RGB_ALPHA: { if (row_info->bit_depth == 8) { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_to_1 != NULL && gamma_from_1 != NULL && gamma_table != NULL) { sp = row; @@ -4076,29 +3968,51 @@ } else { - png_byte v, w; + unsigned int v, w; + unsigned int alpha = a * 257U; v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.red); - if (!optimize) w = gamma_from_1[w]; - *sp = w; + png_composite_16(w, v, alpha, + png_ptr->background_1.red); + + if (!optimize) + w = gamma_from_1[(w+add)>>shift]; + + else + w = PNG_DIV257(w); + + *sp = (png_byte)w; v = gamma_to_1[*(sp + 1)]; - png_composite(w, v, a, png_ptr->background_1.green); - if (!optimize) w = gamma_from_1[w]; - *(sp + 1) = w; + png_composite_16(w, v, alpha, + png_ptr->background_1.green); + + if (!optimize) + w = gamma_from_1[(w+add)>>shift]; + + else + w = PNG_DIV257(w); + + *(sp + 1) = (png_byte)w; v = gamma_to_1[*(sp + 2)]; - png_composite(w, v, a, png_ptr->background_1.blue); - if (!optimize) w = gamma_from_1[w]; - *(sp + 2) = w; + png_composite_16(w, v, alpha, + png_ptr->background_1.blue); + + if (!optimize) + w = gamma_from_1[(w+add)>>shift]; + + else + w = PNG_DIV257(w); + + *(sp + 2) = (png_byte)w; } } } + else -#endif { sp = row; for (i = 0; i < row_width; i++, sp += 4) { @@ -4123,11 +4037,11 @@ } } } } + else /* if (row_info->bit_depth == 16) */ { -#ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_16 != NULL && gamma_16_from_1 != NULL && gamma_16_to_1 != NULL) { sp = row; @@ -4139,17 +4053,17 @@ if (a == (png_uint_16)0xffff) { png_uint_16 v; - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + v = gamma_16[((sp[2]<<8)+sp[3]+add) >> shift]; *(sp + 2) = (png_byte)((v >> 8) & 0xff); *(sp + 3) = (png_byte)(v & 0xff); - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + v = gamma_16[((sp[4]<<8)+sp[5]+add) >> shift]; *(sp + 4) = (png_byte)((v >> 8) & 0xff); *(sp + 5) = (png_byte)(v & 0xff); } @@ -4170,39 +4084,39 @@ else { png_uint_16 v, w; - v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16_to_1[((sp[0]<<8)+sp[1]+add) >> shift]; png_composite_16(w, v, a, png_ptr->background_1.red); + if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> - 8]; + w = gamma_16_from_1[(w+add) >> shift]; + *sp = (png_byte)((w >> 8) & 0xff); *(sp + 1) = (png_byte)(w & 0xff); - v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + v = gamma_16_to_1[((sp[2]<<8)+sp[3]+add) >> shift]; png_composite_16(w, v, a, png_ptr->background_1.green); + if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> - 8]; + w = gamma_16_from_1[(w+add) >> shift]; *(sp + 2) = (png_byte)((w >> 8) & 0xff); *(sp + 3) = (png_byte)(w & 0xff); - v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + v = gamma_16_to_1[((sp[4]<<8)+sp[5]+add) >> shift]; png_composite_16(w, v, a, png_ptr->background_1.blue); + if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> - 8]; + w = gamma_16_from_1[(w+add) >> shift]; *(sp + 4) = (png_byte)((w >> 8) & 0xff); *(sp + 5) = (png_byte)(w & 0xff); } } } else -#endif { sp = row; for (i = 0; i < row_width; i++, sp += 8) { @@ -4267,18 +4181,24 @@ void /* PRIVATE */ png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; - int gamma_shift = png_ptr->gamma_shift; + png_const_uint_16p gamma_16_table = png_ptr->gamma_16_table; + int shift = png_ptr->gamma_shift; + int add = (shift > 0 ? 1U << (shift-1) : 0); png_bytep sp; png_uint_32 i; png_uint_32 row_width=row_info->width; png_debug(1, "in png_do_gamma"); - if (((row_info->bit_depth <= 8 && gamma_table != NULL) || + /* Prior to libpng 1.7.0 this code would attempt to gamma correct 2 and 4 bit + * gray level values, the results are ridiculously inaccurate. In 1.7.0 the + * code is removed and a warning is introduced to catch cases where an + * application might actually try it. + */ + if (((row_info->bit_depth == 8 && gamma_table != NULL) || (row_info->bit_depth == 16 && gamma_16_table != NULL))) { switch (row_info->color_type) { @@ -4304,19 +4224,19 @@ for (i = 0; i < row_width; i++) { png_uint_16 v; - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; } @@ -4348,19 +4268,21 @@ { sp = row; for (i = 0; i < row_width; i++) { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + png_uint_16 v; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 4; } @@ -4384,9 +4306,11 @@ { sp = row; for (i = 0; i < row_width; i++) { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + png_uint_16 v; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 4; } @@ -4395,42 +4319,9 @@ } case PNG_COLOR_TYPE_GRAY: { - if (row_info->bit_depth == 2) - { - sp = row; - for (i = 0; i < row_width; i += 4) - { - int a = *sp & 0xc0; - int b = *sp & 0x30; - int c = *sp & 0x0c; - int d = *sp & 0x03; - - *sp = (png_byte)( - ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| - ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| - ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| - ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); - sp++; - } - } - - if (row_info->bit_depth == 4) - { - sp = row; - for (i = 0; i < row_width; i += 2) - { - int msb = *sp & 0xf0; - int lsb = *sp & 0x0f; - - *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) - | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); - sp++; - } - } - - else if (row_info->bit_depth == 8) + if (row_info->bit_depth == 8) { sp = row; for (i = 0; i < row_width; i++) { @@ -4438,14 +4329,16 @@ sp++; } } - else if (row_info->bit_depth == 16) + else /*row_info->bit_depth == 16 */ { sp = row; for (i = 0; i < row_width; i++) { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + png_uint_16 v; + + v = gamma_16_table[((sp[0]<<8)+sp[1]+add) >> shift]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; } @@ -4473,33 +4366,35 @@ png_debug(1, "in png_do_encode_alpha"); if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { + PNG_CONST unsigned int shift = png_ptr->gamma_shift; + PNG_CONST unsigned int add = (shift > 0 ? 1U<<(shift-1) : 0); + if (row_info->bit_depth == 8) { - PNG_CONST png_bytep table = png_ptr->gamma_from_1; + PNG_CONST png_bytep gamma_from_1 = png_ptr->gamma_from_1; - if (table != NULL) + if (gamma_from_1 != NULL) { PNG_CONST int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; /* The alpha channel is the last component: */ row += step - 1; for (; row_width > 0; --row_width, row += step) - *row = table[*row]; + *row = gamma_from_1[(257U**row+add)>>shift]; return; } } else if (row_info->bit_depth == 16) { - PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; - PNG_CONST int gamma_shift = png_ptr->gamma_shift; + PNG_CONST png_uint_16p gamma_16_from_1 = png_ptr->gamma_16_from_1; - if (table != NULL) + if (gamma_16_from_1 != NULL) { PNG_CONST int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; @@ -4509,9 +4404,9 @@ for (; row_width > 0; --row_width, row += step) { png_uint_16 v; - v = table[*(row + 1) >> gamma_shift][*row]; + v = gamma_16_from_1[((row[0]<<8)+row[1]+add) >> shift]; *row = (png_byte)((v >> 8) & 0xff); *(row + 1) = (png_byte)(v & 0xff); } diff -ru4NwbB libpng-1.6.0beta34/pngrutil.c libpng-1.7.0alpha04/pngrutil.c --- libpng-1.6.0beta34/pngrutil.c 2012-12-19 16:06:53.057448506 -0600 +++ libpng-1.7.0alpha04/pngrutil.c 2012-12-22 18:00:42.488601172 -0600 @@ -1,8 +1,8 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -17,10 +17,8 @@ #include "pngpriv.h" #ifdef PNG_READ_SUPPORTED -#define png_strtod(p,a,b) strtod(a,b) - png_uint_32 PNGAPI png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) { png_uint_32 uval = png_get_uint_32(buf); @@ -561,9 +559,9 @@ * limited only by the maximum chunk size. */ png_alloc_size_t limit = PNG_SIZE_MAX; -# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +# ifdef PNG_SET_USER_LIMITS_SUPPOPRTED if (png_ptr->user_chunk_malloc_max > 0 && png_ptr->user_chunk_malloc_max < limit) limit = png_ptr->user_chunk_malloc_max; # elif PNG_USER_CHUNK_MALLOC_MAX > 0 @@ -1581,9 +1579,10 @@ } if (--png_ptr->user_chunk_cache_max == 1) { - png_warning(png_ptr, "No space in chunk cache for sPLT"); + /* Warn the first time */ + png_chunk_benign_error(png_ptr, "chunk cache full"); png_crc_finish(png_ptr, length); return; } } @@ -1831,8 +1830,10 @@ * png_info. Fix this. */ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, &(png_ptr->trans_color)); + + png_ptr->trans_alpha = info_ptr->trans_alpha; } #endif #ifdef PNG_READ_bKGD_SUPPORTED @@ -2369,9 +2370,9 @@ if (--png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); + png_chunk_benign_error(png_ptr, "chunk cache full"); return; } } #endif @@ -2448,9 +2449,9 @@ if (--png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); + png_chunk_benign_error(png_ptr, "chunk cache full"); return; } } #endif @@ -2557,9 +2558,9 @@ if (--png_ptr->user_chunk_cache_max == 1) { png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); + png_chunk_benign_error(png_ptr, "chunk cache full"); return; } } #endif @@ -2697,9 +2698,9 @@ png_free(png_ptr, png_ptr->unknown_chunk.data); png_ptr->unknown_chunk.data = NULL; } -# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +# ifdef PNG_SET_USER_LIMITS_SUPPOPRTED if (png_ptr->user_chunk_malloc_max > 0 && png_ptr->user_chunk_malloc_max < limit) limit = png_ptr->user_chunk_malloc_max; @@ -2892,9 +2893,9 @@ switch (png_ptr->user_chunk_cache_max) { case 2: png_ptr->user_chunk_cache_max = 1; - png_chunk_benign_error(png_ptr, "no space in chunk cache"); + png_chunk_benign_error(png_ptr, "chunk cache full"); /* FALL THROUGH */ case 1: /* NOTE: prior to 1.6.0 this case resulted in an unknown critical * chunk being skipped, now there will be a hard error below. @@ -3869,9 +3870,9 @@ * implementations required to reverse the filtering of PNG rows. Reversing * the filter is the first transformation performed on the row data. It is * performed in place, therefore an implementation can be selected based on * the image pixel format. If the implementation depends on image width then - * take care to ensure that it works corretly if the image is interlaced - + * take care to ensure that it works correctly if the image is interlaced - * interlacing causes the actual row width to vary. */ { unsigned int bpp = (pp->pixel_depth + 7) >> 3; @@ -4369,9 +4370,9 @@ if (row_bytes > (png_uint_32)65536L) png_error(png_ptr, "This image requires a row greater than 64KB"); #endif - if (row_bytes + 48 > png_ptr->old_big_row_buf_size) + if (row_bytes + 48 > png_ptr->big_row_buf_size) { png_free(png_ptr, png_ptr->big_row_buf); png_free(png_ptr, png_ptr->big_prev_row); @@ -4406,9 +4407,9 @@ /* Use 31 bytes of padding before and 17 bytes after row_buf. */ png_ptr->row_buf = png_ptr->big_row_buf + 31; png_ptr->prev_row = png_ptr->big_prev_row + 31; #endif - png_ptr->old_big_row_buf_size = row_bytes + 48; + png_ptr->big_row_buf_size = row_bytes + 48; } #ifdef PNG_MAX_MALLOC_64K if (png_ptr->rowbytes > 65535) diff -ru4NwbB libpng-1.6.0beta34/pngset.c libpng-1.7.0alpha04/pngset.c --- libpng-1.6.0beta34/pngset.c 2012-12-19 16:06:53.066531855 -0600 +++ libpng-1.7.0alpha04/pngset.c 2012-12-22 18:00:42.497834933 -0600 @@ -1,8 +1,8 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -430,9 +430,10 @@ info_ptr->valid |= PNG_INFO_sCAL; info_ptr->free_me |= PNG_FREE_SCAL; } -# ifdef PNG_FLOATING_POINT_SUPPORTED +# if defined PNG_FLOATING_POINT_SUPPORTED &&\ + defined PNG_FLOATING_ARITHMETIC_SUPPORTED void PNGAPI png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, double width, double height) { @@ -909,54 +910,92 @@ if (png_ptr == NULL || info_ptr == NULL) return; - if (trans_alpha != NULL) + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + png_chunk_report(png_ptr, + "png_set_tRNS: invalid on PNG with alpha channel", PNG_CHUNK_ERROR); + + else if (info_ptr->color_type & PNG_COLOR_MASK_PALETTE) { - /* It may not actually be necessary to set png_ptr->trans_alpha here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - * - * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively - * relies on png_set_tRNS storing the information in png_struct - * (otherwise it won't be there for the code in pngrtran.c). - */ + int max_num; + /* Free the old data; num_trans 0 can be used to kill the tRNS */ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep, - png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); + /* Do this just in case the old data was not owned by libpng: */ + info_ptr->valid &= ~PNG_INFO_tRNS; + info_ptr->trans_alpha = NULL; + info_ptr->num_trans = 0; + + /* Expect png_set_PLTE to happen before png_set_tRNS, so num_palette will + * be set, but this is not a requirement of the API. + */ + if (png_ptr->num_palette) + max_num = png_ptr->num_palette; + + else + max_num = 1 << png_ptr->bit_depth; - if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) - memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + if (num_trans > max_num) + { + png_chunk_report(png_ptr, "png_set_tRNS: num_trans too large", + PNG_CHUNK_ERROR); + /* If control returns simply limit it; the behavior prior to 1.7 was to + * issue a warning and skip the palette in png_write_tRNS. + */ + num_trans = max_num; } + /* But only attempt a malloc if there is something to do; so the app can + * set a tRNS array then later delete it. + */ + if (num_trans > 0 && trans_alpha != NULL) + { + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1, + * this avoids issues where a palette image contains out of range + * indices. + */ + info_ptr->trans_alpha = png_voidcast(png_bytep, png_malloc(png_ptr, + PNG_MAX_PALETTE_LENGTH)); + info_ptr->free_me |= PNG_FREE_TRNS; + + memcpy(info_ptr->trans_alpha, trans_alpha, + (unsigned)/*SAFE*/num_trans); + info_ptr->valid |= PNG_INFO_tRNS; + info_ptr->num_trans = (png_uint_16)num_trans; /* SAFE */ + } + } + + else /* not a PALETTE image */ + { + /* Invalidate any prior transparent color, set num_trans too, it is not + * used internally in this case but png_get_tRNS still returns it. + */ + info_ptr->valid &= ~PNG_INFO_tRNS; + info_ptr->num_trans = 0; /* for png_get_tRNS */ + if (trans_color != NULL) { int sample_max = (1 << info_ptr->bit_depth); if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && - trans_color->gray > sample_max) || + trans_color->gray <= sample_max) || (info_ptr->color_type == PNG_COLOR_TYPE_RGB && - (trans_color->red > sample_max || - trans_color->green > sample_max || - trans_color->blue > sample_max))) - png_warning(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth"); - + trans_color->red <= sample_max && + trans_color->green <= sample_max && + trans_color->blue <= sample_max)) + { info_ptr->trans_color = *trans_color; - - if (num_trans == 0) - num_trans = 1; + info_ptr->valid |= PNG_INFO_tRNS; + info_ptr->num_trans = 1; /* for png_get_tRNS */ } - info_ptr->num_trans = (png_uint_16)num_trans; - - if (num_trans != 0) - { - info_ptr->valid |= PNG_INFO_tRNS; - info_ptr->free_me |= PNG_FREE_TRNS; + else + png_chunk_report(png_ptr, + "tRNS chunk has out-of-range samples for bit_depth", + PNG_CHUNK_ERROR); + } } } #endif @@ -1486,29 +1525,29 @@ /* Images with dimensions larger than these limits will be * rejected by png_set_IHDR(). To accept any PNG datastream * regardless of dimensions, set both limits to 0x7ffffffL. */ - if (png_ptr == NULL) - return; - + if (png_ptr != NULL) + { png_ptr->user_width_max = user_width_max; png_ptr->user_height_max = user_height_max; } +} /* This function was added to libpng 1.4.0 */ void PNGAPI png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) { - if (png_ptr) + if (png_ptr != NULL) png_ptr->user_chunk_cache_max = user_chunk_cache_max; } /* This function was added to libpng 1.4.1 */ void PNGAPI png_set_chunk_malloc_max (png_structrp png_ptr, png_alloc_size_t user_chunk_malloc_max) { - if (png_ptr) + if (png_ptr != NULL) png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ diff -ru4NwbB libpng-1.6.0beta34/pngstruct.h libpng-1.7.0alpha04/pngstruct.h --- libpng-1.6.0beta34/pngstruct.h 2012-12-19 16:06:52.932194619 -0600 +++ libpng-1.7.0alpha04/pngstruct.h 2012-12-22 18:00:42.364930707 -0600 @@ -4,9 +4,9 @@ * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.6.0 [(PENDING RELEASE)] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h @@ -27,9 +27,9 @@ #ifndef ZLIB_CONST /* We must ensure that zlib uses 'const' in declarations. */ # define ZLIB_CONST #endif -#include "zlib.h" +#include PNG_ZLIB_HEADER #ifdef const /* zlib.h sometimes #defines const to nothing, undo this. */ # undef const #endif @@ -47,12 +47,12 @@ /* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib * can handle at once. This type need be no larger than 16 bits (so maximum of * 65535), this define allows us to discover how big it is, but limited by the - * maximuum for png_size_t. The value can be overriden in a library build - * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably - * lower value (e.g. 255 works). A lower value may help memory usage (slightly) - * and may even improve performance on some systems (and degrade it on others.) + * maximum for size_t. The value can be overridden in a library build (pngusr.h, + * or set it in CPPFLAGS) and it works to set it to a considerably lower value + * (e.g. 255 works). A lower value may help memory usage (slightly) and may + * even improve performance on some systems (and degrade it on others.) */ #ifndef ZLIB_IO_MAX # define ZLIB_IO_MAX ((uInt)-1) #endif @@ -136,348 +136,416 @@ #define PNG_COLORSPACE_FROM_cHRM 0x0010 #define PNG_COLORSPACE_FROM_sRGB 0x0020 #define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 #define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ +#define PNG_COLORSPACE_RGB_TO_GRAY_SET 0x0100 /* user specified coeffs */ #define PNG_COLORSPACE_INVALID 0x8000 #define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) #endif /* COLORSPACE || GAMMA */ struct png_struct_def { + /* Rearranged in libpng 1.7 to attempt to lessen padding; in general + * (char), (short), (int) and pointer types are kept separate, however + * associated members under the control of the same #define are still + * together. + */ #ifdef PNG_SETJMP_SUPPORTED - jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */ - png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ - jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ - size_t jmp_buf_size; /* size of the above, if allocated */ -#endif - png_error_ptr error_fn; /* function for printing errors and aborting */ -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; /* function for printing warnings */ -#endif - png_voidp error_ptr; /* user supplied struct for error functions */ - png_rw_ptr write_data_fn; /* function for writing output data */ - png_rw_ptr read_data_fn; /* function for reading input data */ - png_voidp io_ptr; /* ptr to application struct for I/O functions */ - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr read_user_transform_fn; /* user read transform */ -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr write_user_transform_fn; /* user write transform */ -#endif - -/* These were added in libpng-1.0.2 */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - png_voidp user_transform_ptr; /* user supplied struct for user transform */ - png_byte user_transform_depth; /* bit depth of user transformed pixels */ - png_byte user_transform_channels; /* channels in user transformed pixels */ -#endif -#endif - - png_uint_32 mode; /* tells us where we are in the PNG file */ - png_uint_32 flags; /* flags indicating various things to libpng */ - png_uint_32 transformations; /* which transformations to perform */ - - png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ - z_stream zstream; /* decompression structure */ - -#ifdef PNG_WRITE_SUPPORTED - png_compression_bufferp zbuffer_list; /* Created on demand during write */ - uInt zbuffer_size; /* size of the actual buffer */ - - int zlib_level; /* holds zlib compression level */ - int zlib_method; /* holds zlib compression method */ - int zlib_window_bits; /* holds zlib compression window bits */ - int zlib_mem_level; /* holds zlib compression memory level */ - int zlib_strategy; /* holds zlib compression strategy */ -#endif -/* Added at libpng 1.5.4 */ -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - int zlib_text_level; /* holds zlib compression level */ - int zlib_text_method; /* holds zlib compression method */ - int zlib_text_window_bits; /* holds zlib compression window bits */ - int zlib_text_mem_level; /* holds zlib compression memory level */ - int zlib_text_strategy; /* holds zlib compression strategy */ -#endif -/* End of material added at libpng 1.5.4 */ -/* Added at libpng 1.6.0 */ -#ifdef PNG_WRITE_SUPPORTED - int zlib_set_level; /* Actual values set into the zstream on write */ - int zlib_set_method; - int zlib_set_window_bits; - int zlib_set_mem_level; - int zlib_set_strategy; + /* jmp_buf can have very high alignment requirements on some systems, so put + * it first (the other setjmp members are later as they are infrequently + * accesed.) + */ + jmp_buf jmp_buf_local; #endif + /* Next the frequently accessed fields. Many processors perform arithmetic + * in the address pipeline, but frequently the amount of addition or + * subtraction is limited. By putting these fields at the head of png_struct + * the hope is that such processors will generate code that is both smaller + * and faster. + */ + png_colorp palette; /* palette from the input file */ + size_t rowbytes; /* size of row in bytes */ + size_t info_rowbytes; /* cache of updated row bytes */ png_uint_32 width; /* width of image in pixels */ png_uint_32 height; /* height of image in pixels */ png_uint_32 num_rows; /* number of rows in current pass */ png_uint_32 usr_width; /* width of row at start of write */ - 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. - * This is a pointer into big_prev_row - */ - png_bytep row_buf; /* buffer to save current (unfiltered) row. - * This is a pointer into big_row_buf - */ -#ifdef PNG_WRITE_SUPPORTED - 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 */ -#endif - png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ - - png_uint_32 idat_size; /* current IDAT size for read */ png_uint_32 crc; /* current chunk CRC value */ - png_colorp palette; /* palette from the input file */ - png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations;/* which transformations to perform */ + png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ + png_uint_32 free_me; /* items libpng is responsible for freeing */ -/* Added at libpng-1.5.10 */ + int maximum_pixel_depth; /* pixel depth used for the row buffers */ #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED int num_palette_max; /* maximum palette index found in IDAT */ #endif + png_uint_16 num_palette; /* number of color entries in palette */ png_uint_16 num_trans; /* number of transparency values */ - png_byte compression; /* file compression type (always 0) */ + + /* Single byte values, typically used either to save space or to hold 1-byte + * values from the PNG chunk specifications. + */ + png_byte compression_type; /* file compression type (always 0) */ png_byte filter; /* file filter type (always 0) */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ png_byte pass; /* current interlace pass (0 - 6) */ 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: write only */ png_byte pixel_depth; /* number of bits per pixel */ png_byte channels; /* number of channels in file */ -#ifdef PNG_WRITE_SUPPORTED - png_byte usr_channels; /* channels at start of write: write only */ -#endif png_byte sig_bytes; /* magic bytes read/written from start of file */ - png_byte maximum_pixel_depth; - /* pixel depth used for the row buffers */ png_byte transformed_pixel_depth; /* pixel depth after read/write transforms */ -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) - png_uint_16 filler; /* filler bytes for pixel expansion */ + + /* ERROR HANDLING */ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ + png_longjmp_ptr longjmp_fn; /* setjmp non-local goto function. */ + size_t jmp_buf_size; /* size of *jmp_buf_ptr, if allocated */ #endif -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - png_byte background_gamma_type; - png_fixed_point background_gamma; - png_color_16 background; /* background color in screen gamma space */ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_color_16 background_1; /* background normalized to gamma 1.0 */ + /* Error/warning callbacks */ + png_error_ptr error_fn; /* print an error message and abort */ +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; /* print a warning and continue */ #endif -#endif /* PNG_bKGD_SUPPORTED */ + png_voidp error_ptr; /* user supplied data for the above */ -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_flush_ptr output_flush_fn; /* Function for flushing output */ - png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ - png_uint_32 flush_rows; /* number of rows written since last flush */ + /* MEMORY ALLOCATION */ +#ifdef PNG_USER_MEM_SUPPORTED + png_malloc_ptr malloc_fn; /* allocate memory */ + png_free_ptr free_fn; /* free memory */ + png_voidp mem_ptr; /* user supplied data for the above */ #endif -#ifdef PNG_READ_GAMMA_SUPPORTED - int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ - png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ + /* IO and BASIC READ/WRITE SUPPORT */ + png_voidp io_ptr; /* user supplied data for IO callbacks */ - png_bytep gamma_table; /* gamma table for 8-bit depth files */ - png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_bytep gamma_from_1; /* converts from 1.0 to screen */ - png_bytep gamma_to_1; /* converts from file to 1.0 */ - png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ - png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -#endif +#ifdef PNG_READ_SUPPORTED + png_rw_ptr read_data_fn; /* read some bytes (must succeed) */ + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_bytep read_buffer; /* buffer for reading chunk data */ -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) - png_color_8 sig_bit; /* significant bits in each available channel */ -#endif + /* During read the following array is set up to point to the appropriate + * un-filter function, this allows per-image and per-processor optimization. + */ + void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row); -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - png_color_8 shift; /* shift for significant bit tranformation */ +#if (defined PNG_COLORSPACE_SUPPORTED || defined PNG_GAMMA_SUPPORTED) + /* The png_struct colorspace structure is only required on read - on write it + * is in (just) the info_struct. + */ + png_colorspace colorspace; #endif +#endif /* PNG_READ_SUPPORTED */ -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ - || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_bytep trans_alpha; /* alpha values for paletted files */ - png_color_16 trans_color; /* transparent color for non-paletted files */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; /* Maximum width on read */ + png_uint_32 user_height_max; /* Maximum height on read */ + /* Total memory that a single zTXt, sPLT, iTXt, iCCP, or unknown chunk + * can occupy when decompressed. 0 means unlimited. This field is a counter + * - it is decremented as memory is allocated. + */ + png_alloc_size_t user_chunk_malloc_max; +#endif +#ifdef PNG_USER_LIMITS_SUPPORTED + /* limit on total *number* of sPLT, text and unknown chunks that can be + * stored. 0 means unlimited. This field is a counter - it is decremented + * as chunks are encountered. + */ + png_uint_32 user_chunk_cache_max; #endif - png_read_status_ptr read_row_fn; /* called after each row is decoded */ - png_write_status_ptr write_row_fn; /* called after each row is encoded */ + /* The progressive reader gets passed data and calls application handling + * functions when appropriate. + */ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED png_progressive_info_ptr info_fn; /* called after header data fully read */ - png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */ + png_progressive_row_ptr row_fn; /* called after a row is decoded */ png_progressive_end_ptr end_fn; /* called after image is complete */ + + /* Progressive read control data */ png_bytep save_buffer_ptr; /* current location in save_buffer */ png_bytep save_buffer; /* buffer for previously read data */ png_bytep current_buffer_ptr; /* current location in current_buffer */ png_bytep current_buffer; /* buffer for recently used data */ + + size_t save_buffer_size; /* amount of data now in save_buffer */ + size_t save_buffer_max; /* total size of save_buffer */ + size_t buffer_size; /* total amount of available input data */ + size_t current_buffer_size; /* amount of data now in current_buffer */ + png_uint_32 push_length; /* size of current input chunk */ png_uint_32 skip_length; /* bytes to skip in input data */ - png_size_t save_buffer_size; /* amount of data now in save_buffer */ - png_size_t save_buffer_max; /* total size of save_buffer */ - png_size_t buffer_size; /* total amount of available input data */ - png_size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ int cur_palette; /* current push library palette index */ +#endif -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ - -#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) -/* For the Borland special 64K segment handler */ - png_bytepp offset_table_ptr; - png_bytep offset_table; - png_uint_16 offset_table_number; - png_uint_16 offset_table_count; - png_uint_16 offset_table_count_free; +#ifdef PNG_WRITE_SUPPORTED + png_rw_ptr write_data_fn;/* write some bytes (must succeed) */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ #endif -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_bytep palette_lookup; /* lookup table for quantizing */ - png_bytep quantize_index; /* index translation for palette files */ +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_flush_ptr output_flush_fn; /* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ #endif #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_byte heuristic_method; /* heuristic for row filter selection */ - png_byte num_prev_filters; /* number of weights for previous rows */ png_bytep prev_filters; /* filter type(s) of previous row(s) */ png_uint_16p filter_weights; /* weight(s) for previous line(s) */ png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ png_uint_16p filter_costs; /* relative filter calculation cost */ png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ +#endif + +#ifdef PNG_WRITE_SUPPORTED + png_byte usr_bit_depth; /* bit depth of users row */ + png_byte usr_channels; /* channels at start of write */ #endif -#if PNG_LIBPNG_VER < 10700 -/* To do: remove this from libpng-1.7 */ -#ifdef PNG_TIME_RFC1123_SUPPORTED - char time_buffer[29]; /* String to hold RFC 1123 time text */ +#ifdef PNG_IO_STATE_SUPPORTED + png_uint_32 io_state; /* tells the app read/write progress */ #endif + + /* ROW BUFFERS + * + * Members that hold pointers to the decompressed image rows. + */ + png_bytep row_buf; /* buffer for the current (unfiltered) row */ +#if (defined PNG_WRITE_FILTER_SUPPORTED) || (defined PNG_READ_SUPPORTED) + png_bytep prev_row; /* buffer to save the previous (unfiltered) row */ #endif -/* New members added in libpng-1.0.6 */ +#ifdef PNG_READ_SUPPORTED + /* The row_buf and prev_row pointers are misaligned so that the start of the + * row - after the filter byte - is aligned, the 'big_' pointers record the + * original allocated pointer. + */ + png_bytep big_row_buf; + png_bytep big_prev_row; + size_t big_row_buf_size; /* Actual size of both */ +#endif - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#ifdef PNG_WRITE_SUPPORTED + /* This is somewhat excessive, there is no obvious reason on write to + * allocate a buffer for each possible filtered row, only for the one being + * tested and the current best. + * + * TODO: fix this + */ + 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 */ +#endif + /* UNKNOWN CHUNK HANDLING */ + /* TODO: this is excessively complicated, there are multiple ways of doing + * the same thing. It should be cleaned up, possibly by finding out which + * APIs applications really use. + */ #ifdef PNG_USER_CHUNKS_SUPPORTED + /* General purpose pointer for all user/unknown chunk handling; points to + * application supplied data for use in the read_user_chunk_fn callback + * (currently there is no write side support - the write side must use the + * set_unknown_chunks interface.) + */ png_voidp user_chunk_ptr; +#endif + #ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* This is called back from the unknown chunk handling */ png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ #endif +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* Temporary storage for unknown chunk that the library doesn't recognize, + * used while reading the chunk. + */ + png_unknown_chunk unknown_chunk; #endif #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - int unknown_default; /* As PNG_HANDLE_* */ - unsigned int num_chunk_list; /* Number of entries in the list */ png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name * followed by a PNG_HANDLE_* byte */ + int unknown_default; /* As PNG_HANDLE_* */ + unsigned int num_chunk_list; /* Number of entries in the list */ #endif -/* New members added in libpng-1.0.3 */ -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - png_byte rgb_to_gray_status; - /* Added in libpng 1.5.5 to record setting of coefficients: */ - png_byte rgb_to_gray_coefficients_set; - /* These were changed from png_byte in libpng-1.0.6 */ - png_uint_16 rgb_to_gray_red_coeff; - png_uint_16 rgb_to_gray_green_coeff; - /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ + /* USER TRANSFORM SUPPORT */ +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + png_voidp user_transform_ptr; /* user supplied data for the above */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ #endif -/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ -#if defined(PNG_MNG_FEATURES_SUPPORTED) -/* Changed from png_byte to png_uint_32 at version 1.2.0 */ - png_uint_32 mng_features_permitted; + /* READ TRANSFORM SUPPORT + * + * Quite a lot of things can be done to the original image data on read, and + * most of these are configurable. The data required by the configurable + * read transforms should be stored here. The png_color_16 and png_color_8 + * structures have low alignment requirements and odd sizes, so may cause + * misalignment when present. Member alignment is as follows: + * + * png_color_16 png_uint_16 + * png_color_8 png_byte + */ + /* GAMMA/BACKGROUND/ALPHA-MODE/RGB-TO-GRAY/tRNS/sBIT + * + * These things are all interrelated because they need some or all of the + * gamma tables. Some attempt has been made below to order these members by + * size, so that as little padding as possible is required. + */ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_uint_16p gamma_16_table; /* gamma table for 16-bit depth files */ + +#if defined PNG_READ_BACKGROUND_SUPPORTED ||\ + defined PNG_READ_ALPHA_MODE_SUPPORTED ||\ + defined PNG_READ_RGB_TO_GRAY_SUPPORTED + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_uint_16p gamma_to_1; /* converts from file to 1.0 */ + png_uint_16p gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16p gamma_16_to_1; /* converts from file to 1.0 */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +#endif /* PNG_READ_GAMMA_SUPPORTED */ + +#if defined PNG_READ_tRNS_SUPPORTED || defined PNG_READ_BACKGROUND_SUPPORTED ||\ + defined PNG_READ_EXPAND_SUPPORTED + png_bytep trans_alpha; /* alpha values for paletted files */ #endif -/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_byte filter_type; + /* Integer values */ +#if defined PNG_READ_BACKGROUND_SUPPORTED ||\ + defined PNG_READ_ALPHA_MODE_SUPPORTED + png_fixed_point background_gamma; +#endif +#ifdef PNG_READ_GAMMA_SUPPORTED + png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ + int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ #endif -/* New members added in libpng-1.2.0 */ + /* png_color_16 */ +#if defined PNG_READ_BACKGROUND_SUPPORTED ||\ + defined PNG_READ_ALPHA_MODE_SUPPORTED + png_color_16 background; /* background color in screen gamma space */ + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#if defined PNG_READ_tRNS_SUPPORTED || defined PNG_READ_BACKGROUND_SUPPORTED ||\ + defined PNG_READ_EXPAND_SUPPORTED + png_color_16 trans_color; /* transparent color for non-paletted files */ +#endif -/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ -#ifdef PNG_USER_MEM_SUPPORTED - png_voidp mem_ptr; /* user supplied struct for mem functions */ - png_malloc_ptr malloc_fn; /* function for allocating memory */ - png_free_ptr free_fn; /* function for freeing memory */ + /* png_uint_16 */ +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + /* The blue coefficient is calculated from the above */ #endif -/* New member added in libpng-1.0.13 and 1.2.0 */ - png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + /* png_color_8 */ +#if defined PNG_READ_GAMMA_SUPPORTED || defined PNG_READ_sBIT_SUPPORTED + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* The following three members were added at version 1.0.14 and 1.2.4 */ - png_bytep quantize_sort; /* working sort array */ - png_bytep index_to_palette; /* where the original index currently is - in the palette */ - png_bytep palette_to_index; /* which original index points to this - palette color */ + /* png_byte */ +#if defined PNG_READ_BACKGROUND_SUPPORTED ||\ + defined PNG_READ_ALPHA_MODE_SUPPORTED + png_byte background_gamma_type; +#endif +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte rgb_to_gray_status; #endif -/* New members added in libpng-1.0.16 and 1.2.6 */ - png_byte compression_type; + /* SHIFT - both READ_SHIFT and WRITE_SHIFT */ +#if defined PNG_READ_SHIFT_SUPPORTED || defined PNG_WRITE_SHIFT_SUPPORTED + png_color_8 shift; /* shift for significant bit tranformation */ +#endif -#ifdef PNG_USER_LIMITS_SUPPORTED - png_uint_32 user_width_max; - png_uint_32 user_height_max; + /* FILLER SUPPORT (pixel expansion or read, contraction on write) */ +#if defined PNG_READ_FILLER_SUPPORTED || defined PNG_WRITE_FILLER_SUPPORTED + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif - /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown - * chunks that can be stored (0 means unlimited). + /* QUANTIZE (convert to color-mapped) */ +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_bytep palette_lookup; /* lookup table for quantizing */ + png_bytep quantize_index; /* index translation for palette files */ + png_bytep quantize_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is in the + * palette */ - png_uint_32 user_chunk_cache_max; - - /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk - * can occupy when decompressed. 0 means unlimited. + png_bytep palette_to_index; /* which original index points to this palette + * color */ - png_alloc_size_t user_chunk_malloc_max; #endif -/* New member added in libpng-1.0.25 and 1.2.17 */ -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - /* Temporary storage for unknown chunk that the library doesn't recognize, - * used while reading the chunk. - */ - png_unknown_chunk unknown_chunk; + /* MNG SUPPORT */ +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_uint_32 mng_features_permitted; + png_byte filter_type; #endif -/* New member added in libpng-1.2.26 */ - png_size_t old_big_row_buf_size; + /* COMPRESSION AND DECOMPRESSION SUPPORT. + * + * zlib expects a 'zstream' as the fundamental control structure, it allows + * all the parameters to be passed as one pointer. + */ + z_stream zstream; /* decompression structure */ #ifdef PNG_READ_SUPPORTED -/* New member added in libpng-1.2.30 */ - png_bytep read_buffer; /* buffer for reading chunk data */ + /* These, and IDAT_read_size below, control how much input and output (at + * most) is available to zlib. + */ + png_uint_32 idat_size; /* current IDAT size for read */ png_alloc_size_t read_buffer_size; /* current size of the buffer */ #endif -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED - uInt IDAT_read_size; /* limit on read buffer size for IDAT */ -#endif -#ifdef PNG_IO_STATE_SUPPORTED -/* New member added in libpng-1.4.0 */ - png_uint_32 io_state; +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + int zlib_text_level; /* holds zlib compression level */ + int zlib_text_method; /* holds zlib compression method */ + int zlib_text_window_bits; /* holds zlib compression window bits */ + int zlib_text_mem_level; /* holds zlib compression memory level */ + int zlib_text_strategy; /* holds zlib compression strategy */ #endif -/* New member added in libpng-1.5.6 */ - png_bytep big_prev_row; +#ifdef PNG_WRITE_SUPPORTED + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ - void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row); + int zlib_set_level; /* Actual values set into the zstream on write */ + int zlib_set_method; + int zlib_set_window_bits; + int zlib_set_mem_level; + int zlib_set_strategy; -#ifdef PNG_READ_SUPPORTED -#if defined PNG_COLORSPACE_SUPPORTED || defined PNG_GAMMA_SUPPORTED - png_colorspace colorspace; + png_compression_bufferp zbuffer_list; /* Created on demand during write */ + uInt zbuffer_size; /* size of the actual zlib buffer */ #endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED + uInt IDAT_read_size; /* limit on read buffer size for IDAT */ #endif }; #endif /* PNGSTRUCT_H */ diff -ru4NwbB libpng-1.6.0beta34/pngtest.c libpng-1.7.0alpha04/pngtest.c --- libpng-1.6.0beta34/pngtest.c 2012-12-19 16:06:53.076840721 -0600 +++ libpng-1.7.0alpha04/pngtest.c 2012-12-22 18:00:42.508110756 -0600 @@ -1,8 +1,8 @@ /* pngtest.c - a simple test program to test libpng * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -43,9 +43,9 @@ #include "png.h" #ifdef PNG_READ_SUPPORTED /* else nothing can be done */ -#include "zlib.h" +#include PNG_ZLIB_HEADER /* defined by pnglibconf.h */ /* Copied from pngpriv.h but only used in error messages below. */ #ifndef PNG_ZBUF_SIZE # define PNG_ZBUF_SIZE 8192 #endif @@ -99,12 +99,8 @@ static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ static int error_count = 0; /* count calls to png_error */ static int warning_count = 0; /* count calls to png_warning */ -#ifdef __TURBOC__ -#include -#endif - /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ #ifndef png_jmpbuf # define png_jmpbuf(png_ptr) png_ptr->jmpbuf #endif @@ -1172,9 +1168,10 @@ png_set_sBIT(write_ptr, write_info_ptr, sig_bit); } #endif #ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +#if defined PNG_FLOATING_POINT_SUPPORTED && \ + defined PNG_FLOATING_ARITHMETIC_SUPPORTED { int unit; double scal_width, scal_height; diff -ru4NwbB libpng-1.6.0beta34/pngtrans.c libpng-1.7.0alpha04/pngtrans.c --- libpng-1.6.0beta34/pngtrans.c 2012-12-19 16:06:53.084766509 -0600 +++ libpng-1.7.0alpha04/pngtrans.c 2012-12-22 18:00:42.515808027 -0600 @@ -1,8 +1,8 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -56,9 +56,11 @@ if (png_ptr->bit_depth < 8) { png_ptr->transformations |= PNG_PACK; +# ifdef PNG_WRITE_SUPPORTED png_ptr->usr_bit_depth = 8; +# endif } } #endif diff -ru4NwbB libpng-1.6.0beta34/pngwio.c libpng-1.7.0alpha04/pngwio.c --- libpng-1.6.0beta34/pngwio.c 2012-12-19 16:06:53.090379760 -0600 +++ libpng-1.7.0alpha04/pngwio.c 2012-12-22 18:00:42.521352321 -0600 @@ -1,8 +1,8 @@ /* pngwio.c - functions for data output * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -150,8 +150,9 @@ png_ptr->output_flush_fn = output_flush_fn; # endif #endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#ifdef PNG_READ_SUPPORTED /* It is an error to read while writing a png file */ if (png_ptr->read_data_fn != NULL) { png_ptr->read_data_fn = NULL; @@ -159,6 +160,7 @@ png_warning(png_ptr, "Can't set both read_data_fn and write_data_fn in the" " same structure"); } +#endif } #endif /* PNG_WRITE_SUPPORTED */ diff -ru4NwbB libpng-1.6.0beta34/pngwrite.c libpng-1.7.0alpha04/pngwrite.c --- libpng-1.6.0beta34/pngwrite.c 2012-12-19 16:06:53.101596421 -0600 +++ libpng-1.7.0alpha04/pngwrite.c 2012-12-22 18:00:42.532393136 -0600 @@ -1,8 +1,8 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -215,10 +215,15 @@ /* Invert the alpha channel (in tRNS) */ if ((png_ptr->transformations & PNG_INVERT_ALPHA) && info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - int j; - for (j = 0; j<(int)info_ptr->num_trans; j++) + int j, jend; + + jend = info_ptr->num_trans; + if (jend > PNG_MAX_PALETTE_LENGTH) + jend = PNG_MAX_PALETTE_LENGTH; + + for (j = 0; jtrans_alpha[j] = (png_byte)(255 - info_ptr->trans_alpha[j]); } #endif @@ -446,9 +451,8 @@ #endif } #ifdef PNG_CONVERT_tIME_SUPPORTED -/* "tm" structure is not supported on WindowsCE */ void PNGAPI png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) { png_debug(1, "in png_convert_from_struct_tm"); @@ -500,17 +504,21 @@ * application after the struct has been created. */ png_ptr->zbuffer_size = PNG_ZBUF_SIZE; - png_ptr->zlib_strategy = Z_FILTERED; /* may be overridden if no filters */ - png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; + /* The 'zlib_strategy' setting is irrelevant because png_default_claim in + * pngwutil.c defaults it according to whether or not filters will be used, + * and ignores this setting. + */ + png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; + png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; png_ptr->zlib_mem_level = 8; png_ptr->zlib_window_bits = 15; png_ptr->zlib_method = 8; #ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED - png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; - png_ptr->zlib_text_level = Z_DEFAULT_COMPRESSION; + png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; + png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; png_ptr->zlib_text_mem_level = 8; png_ptr->zlib_text_window_bits = 15; png_ptr->zlib_text_method = 8; #endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ @@ -926,121 +934,101 @@ #ifdef PNG_MNG_FEATURES_SUPPORTED if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (method == PNG_INTRAPIXEL_DIFFERENCING)) method = PNG_FILTER_TYPE_BASE; - #endif - if (method == PNG_FILTER_TYPE_BASE) - { - switch (filters & (PNG_ALL_FILTERS | 0x07)) - { -#ifdef PNG_WRITE_FILTER_SUPPORTED - case 5: - case 6: - case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); - /* FALL THROUGH */ -#endif /* PNG_WRITE_FILTER_SUPPORTED */ - case PNG_FILTER_VALUE_NONE: - png_ptr->do_filter = PNG_FILTER_NONE; break; + /* The only supported method, except for the check above, is + * PNG_FILTER_TYPE_BASE. The code below does not use 'method' other than + * for the check, so just keep going if png_app_error returns. + */ + if (method != PNG_FILTER_TYPE_BASE) + png_app_error(png_ptr, "Unknown custom filter method"); + + /* If filter writing is not supported the 'filters' value must be zero, + * otherwise the value must be a single, valid, filter value or a set of the + * mask values. The defines in png.h are such that the filter masks used in + * this API and internally are 1<<(3+value), value is in the range 0..4, so + * this fits in a byte. + */ #ifdef PNG_WRITE_FILTER_SUPPORTED - case PNG_FILTER_VALUE_SUB: - png_ptr->do_filter = PNG_FILTER_SUB; break; - - case PNG_FILTER_VALUE_UP: - png_ptr->do_filter = PNG_FILTER_UP; break; + /* Notice that PNG_NO_FILTERS is 0 and passes this test; this is OK + * because filters then gets set to PNG_FILTER_NONE, as is required. + */ + if (filters < PNG_FILTER_VALUE_LAST) + filters = 0x08 << filters; - case PNG_FILTER_VALUE_AVG: - png_ptr->do_filter = PNG_FILTER_AVG; break; + else if ((filters & ~PNG_ALL_FILTERS) != 0) + { + png_app_error(png_ptr, "png_set_filter: invalid filters mask/value"); - case PNG_FILTER_VALUE_PAETH: - png_ptr->do_filter = PNG_FILTER_PAETH; break; + /* For compatibility with the previous behavior assume a mask value was + * passed and ignore the non-mask bits. + */ + filters &= PNG_ALL_FILTERS; - default: - png_ptr->do_filter = (png_byte)filters; break; -#else - default: - png_app_error(png_ptr, "Unknown row filter for method 0"); -#endif /* PNG_WRITE_FILTER_SUPPORTED */ + /* For a possibly foolish consistency (it shouldn't matter) set + * PNG_FILTER_NONE rather than 0. + */ + if (filters == 0) + filters = PNG_FILTER_NONE; } +# else + /* PNG_FILTER_VALUE_NONE and PNG_NO_FILTERS are both 0. */ + if (filters != 0 && filters != PNG_FILTER_NONE) + png_app_error(png_ptr, "png_set_filter: no filters supported"); + filters = PNG_FILTER_NONE; +# endif + +# ifdef PNG_WRITE_FILTER_SUPPORTED /* If we have allocated the row_buf, this means we have already started * with the image and we should have allocated all of the filter buffers * that have been selected. If prev_row isn't already allocated, then * it is too late to start using the filters that need it, since we * will be missing the data in the previous row. If an application * wants to start and stop using particular filters during compression, * it should start out with all of the filters, and then add and * remove them after the start of compression. + * + * NOTE: this is a nasty constraint on the code, because it means that the + * prev_row buffer must be maintained even if there are currently no + * 'prev_row' requiring filters active. */ if (png_ptr->row_buf != NULL) { -#ifdef PNG_WRITE_FILTER_SUPPORTED - if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) - { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; - } - - if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) - { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Up filter after starting"); - png_ptr->do_filter = (png_byte)(png_ptr->do_filter & - ~PNG_FILTER_UP); - } - - else - { - png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; - } - } - - if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) - { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Average filter after starting"); - png_ptr->do_filter = (png_byte)(png_ptr->do_filter & - ~PNG_FILTER_AVG); - } + /* Repeat the checks in png_write_start_row; 1 pixel high or wide + * images cannot benefit from certain filters. If this isn't done here + * the check below will fire on 1 pixel high images. + */ + if (png_ptr->height == 1) + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - else - { - png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; - } - } + if (png_ptr->width == 1) + filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); - if ((png_ptr->do_filter & PNG_FILTER_PAETH) && - png_ptr->paeth_row == NULL) + if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0 + && png_ptr->prev_row == NULL) { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Paeth filter after starting"); - png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); + /* This is the error case, however it is benign - the previous row + * is not available so the filter can't be used. Just warn here. + */ + png_app_warning(png_ptr, + "png_set_filter: UP/AVG/PAETH cannot be added after start"); + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); } - else - { - png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; - } + /* Allocate any required buffers that have not already been allocated. + */ + png_write_alloc_filter_row_buffers(png_ptr, filters); } - - if (png_ptr->do_filter == PNG_NO_FILTERS) #endif /* PNG_WRITE_FILTER_SUPPORTED */ - png_ptr->do_filter = PNG_FILTER_NONE; - } - } - else - png_error(png_ptr, "Unknown custom filter method"); + + /* Finally store the value. + * TODO: this field could probably be removed if neither READ nor + * WRITE_FILTER are supported. + */ + png_ptr->do_filter = (png_byte)filters; /* SAFE: checked above */ } /* This allows us to influence the way in which libpng chooses the "best" * filter for the current scanline. While the "minimum-sum-of-absolute- diff -ru4NwbB libpng-1.6.0beta34/pngwutil.c libpng-1.7.0alpha04/pngwutil.c --- libpng-1.6.0beta34/pngwutil.c 2012-12-19 16:06:53.121433635 -0600 +++ libpng-1.7.0alpha04/pngwutil.c 2012-12-22 18:00:42.552159443 -0600 @@ -1,8 +1,8 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.6.0 [(PENDING RELEASE)] + * Last changed in libpng 1.7.0 [(PENDING RELEASE)] * Copyright (c) 1998-2012 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -337,12 +337,12 @@ if (png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) strategy = png_ptr->zlib_strategy; else if (png_ptr->do_filter != PNG_FILTER_NONE) - strategy = Z_FILTERED; + strategy = PNG_Z_DEFAULT_STRATEGY; else - strategy = Z_DEFAULT_STRATEGY; + strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; } else { @@ -1424,11 +1424,12 @@ png_debug(1, "in png_write_tRNS"); if (color_type == PNG_COLOR_TYPE_PALETTE) { - if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) + if (num_trans <= 0 || num_trans > png_ptr->num_palette) { - png_app_warning(png_ptr, + /* This is an error which can only be reliably detected late. */ + png_app_error(png_ptr, "Invalid number of transparent colors specified"); return; } @@ -1441,9 +1442,10 @@ { /* One 16 bit value */ if (tran->gray >= (1 << png_ptr->bit_depth)) { - png_app_warning(png_ptr, + /* This can no longer happen because it is checked in png_set_tRNS */ + png_app_error(png_ptr, "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); return; } @@ -1463,9 +1465,10 @@ #else if (buf[0] | buf[2] | buf[4]) #endif { - png_app_warning(png_ptr, + /* Also checked in png_set_tRNS */ + png_app_error(png_ptr, "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); return; } @@ -1473,9 +1476,10 @@ } else { - png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); + /* Checked in png_set_tRNS */ + png_app_error(png_ptr, "Can't write tRNS with an alpha channel"); } } #endif @@ -1930,8 +1934,49 @@ png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); } #endif +#ifdef PNG_WRITE_FILTER_SUPPORTED +void /* PRIVATE */ +png_write_alloc_filter_row_buffers(png_structrp png_ptr, int filters) + /* Allocate row buffers for any filters that need them, this is also called + * from png_set_filter if the filters are changed during write to ensure that + * the required buffers exist. png_set_filter ensures that up/avg/paeth are + * only set if png_ptr->prev_row is allocated. + */ +{ + /* The buffer size is determined just by the output row size, not any + * processing requirements. + */ + png_alloc_size_t buf_size = png_ptr->rowbytes + 1; + + if ((filters & PNG_FILTER_SUB) != 0 && png_ptr->sub_row == NULL) + { + png_ptr->sub_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + + if ((filters & PNG_FILTER_UP) != 0 && png_ptr->up_row == NULL) + { + png_ptr->up_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + + if ((filters & PNG_FILTER_AVG) != 0 && png_ptr->avg_row == NULL) + { + png_ptr->avg_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + + if ((filters & PNG_FILTER_PAETH) != 0 && png_ptr->paeth_row == NULL) + { + png_ptr->paeth_row = png_voidcast(png_bytep, png_malloc(png_ptr, + buf_size)); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } +} +#endif /* PNG_WRITE_FILTER_SUPPORTED */ + /* Initializes the row writing capability of libpng */ void /* PRIVATE */ png_write_start_row(png_structrp png_ptr) { @@ -1950,64 +1995,56 @@ /* Offset to next interlace block in the y direction */ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif +#ifdef PNG_WRITE_FILTER_SUPPORTED + int filters; +#endif + png_alloc_size_t buf_size; int usr_pixel_depth; png_debug(1, "in png_write_start_row"); + if (png_ptr == NULL) + return; + 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, buf_size); + png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; #ifdef PNG_WRITE_FILTER_SUPPORTED - /* Set up filtering buffer, if using this filter */ - if (png_ptr->do_filter & PNG_FILTER_SUB) - { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); + filters = png_ptr->do_filter; - png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; - } - - /* We only need to keep the previous row if we are using one of these. */ - 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, buf_size); + if (png_ptr->height == 1) + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - if (png_ptr->do_filter & PNG_FILTER_UP) - { - png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); - - png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; - } + if (png_ptr->width == 1) + filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); - if (png_ptr->do_filter & PNG_FILTER_AVG) - { - png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); + if (filters == 0) + filters = PNG_FILTER_NONE; - png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; - } + /* We only need to keep the previous row if we are using one of the following + * filters. + */ + if (filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) + png_ptr->prev_row = png_voidcast(png_bytep, png_calloc(png_ptr, + buf_size)); - if (png_ptr->do_filter & PNG_FILTER_PAETH) - { - png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); + png_write_alloc_filter_row_buffers(png_ptr, filters); - png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; - } - } + png_ptr->do_filter = (png_byte)filters; /* in case it was changed above */ +#else + png_ptr->do_filter = PNG_FILTER_NONE; #endif /* PNG_WRITE_FILTER_SUPPORTED */ #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* If interlaced, we need to set up width and height of pass */ @@ -2993,8 +3030,9 @@ png_debug1(2, "filter = %d", filtered_row[0]); png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); +#ifdef PNG_WRITE_FILTER_SUPPORTED /* Swap the current and previous rows */ if (png_ptr->prev_row != NULL) { png_bytep tptr; @@ -3002,8 +3040,9 @@ tptr = png_ptr->prev_row; png_ptr->prev_row = png_ptr->row_buf; png_ptr->row_buf = tptr; } +#endif /* PNG_WRITE_FILTER_SUPPORTED */ /* Finish row - updates counters and flushes zlib if last row */ png_write_finish_row(png_ptr); diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/libpng/libpng.vcxproj libpng-1.7.0alpha04/projects/vstudio/libpng/libpng.vcxproj --- libpng-1.6.0beta34/projects/vstudio/libpng/libpng.vcxproj 2012-12-19 16:06:55.607706530 -0600 +++ libpng-1.7.0alpha04/projects/vstudio/libpng/libpng.vcxproj 2012-12-22 18:00:45.109987750 -0600 @@ -22,10 +22,10 @@ {D6973076-9317-4EF2-A0B8-B7A18AC0713E} Win32Proj libpng - + DynamicLibrary MultiByte true @@ -62,25 +62,25 @@ false - $(ProjectName)16 + $(ProjectName)17 false - $(ProjectName)16 + $(ProjectName)17 false - $(ProjectName)16 + $(ProjectName)17 false - $(ProjectName)16 + $(ProjectName)17 Use @@ -106,9 +106,9 @@ Windows true zlib.lib - 16 + 17 $(OutDir) @@ -163,9 +163,9 @@ true true true zlib.lib - 16 + 17 $(OutDir) diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/pnglibconf/pnglibconf.vcxproj libpng-1.7.0alpha04/projects/vstudio/pnglibconf/pnglibconf.vcxproj --- libpng-1.6.0beta34/projects/vstudio/pnglibconf/pnglibconf.vcxproj 2010-08-24 20:16:26.000000000 -0500 +++ libpng-1.7.0alpha04/projects/vstudio/pnglibconf/pnglibconf.vcxproj 2012-12-20 22:50:18.000000000 -0600 @@ -16,8 +16,9 @@ false true MultiByte + diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/pngstest/pngstest.vcxproj libpng-1.7.0alpha04/projects/vstudio/pngstest/pngstest.vcxproj --- libpng-1.6.0beta34/projects/vstudio/pngstest/pngstest.vcxproj 2012-10-27 12:59:30.163926000 -0500 +++ libpng-1.7.0alpha04/projects/vstudio/pngstest/pngstest.vcxproj 2012-12-20 22:50:18.000000000 -0600 @@ -22,10 +22,10 @@ {277AC57F-313B-4D06-B119-A3CDB672D2FF} Win32Proj pngstest - + Application Unicode @@ -95,9 +95,9 @@ Console true - libpng16.lib;zlib.lib + libpng17.lib $(OutDir) Executing libpng simplified API test program @@ -128,9 +128,9 @@ Console true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) Executing libpng simplified API test program @@ -162,9 +162,9 @@ Console true true true - libpng16.lib;zlib.lib + libpng17.lib $(OutDir) UseLinkTimeCodeGeneration @@ -198,9 +198,9 @@ Console true true true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) UseLinkTimeCodeGeneration diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/pngtest/pngtest.vcxproj libpng-1.7.0alpha04/projects/vstudio/pngtest/pngtest.vcxproj --- libpng-1.6.0beta34/projects/vstudio/pngtest/pngtest.vcxproj 2012-12-19 16:06:55.618431036 -0600 +++ libpng-1.7.0alpha04/projects/vstudio/pngtest/pngtest.vcxproj 2012-12-22 18:00:45.121327300 -0600 @@ -22,10 +22,10 @@ {228BA965-50D5-42B2-8BCF-AFCC227E3C1D} Win32Proj pngtest - + Application Unicode @@ -95,9 +95,9 @@ Console true - libpng16.lib + libpng17.lib $(OutDir) Executing PNG test program @@ -128,9 +128,9 @@ Console true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) Executing PNG test program @@ -163,9 +163,9 @@ true true true UseLinkTimeCodeGeneration - libpng16.lib + libpng17.lib $(OutDir) Executing PNG test program @@ -198,9 +198,9 @@ Console true true true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib UseLinkTimeCodeGeneration $(OutDir) diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/pngunknown/pngunknown.vcxproj libpng-1.7.0alpha04/projects/vstudio/pngunknown/pngunknown.vcxproj --- libpng-1.6.0beta34/projects/vstudio/pngunknown/pngunknown.vcxproj 2012-12-19 16:06:55.629295818 -0600 +++ libpng-1.7.0alpha04/projects/vstudio/pngunknown/pngunknown.vcxproj 2012-12-22 18:00:45.132565484 -0600 @@ -22,10 +22,10 @@ {C5D3156C-8C8C-4936-B35F-2B829BA36FEC} Win32Proj pngunknown - + Application Unicode @@ -95,9 +95,9 @@ Console true - libpng16.lib;zlib.lib + libpng17.lib $(OutDir) Executing PNG validation program @@ -128,9 +128,9 @@ Console true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) Executing PNG validation program @@ -162,9 +162,9 @@ Console true true true - libpng16.lib;zlib.lib + libpng17.lib $(OutDir) UseLinkTimeCodeGeneration @@ -198,9 +198,9 @@ Console true true true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) UseLinkTimeCodeGeneration diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/pngvalid/pngvalid.vcxproj libpng-1.7.0alpha04/projects/vstudio/pngvalid/pngvalid.vcxproj --- libpng-1.6.0beta34/projects/vstudio/pngvalid/pngvalid.vcxproj 2012-12-19 16:06:55.640288947 -0600 +++ libpng-1.7.0alpha04/projects/vstudio/pngvalid/pngvalid.vcxproj 2012-12-22 18:00:45.143665998 -0600 @@ -22,10 +22,10 @@ {9B36B6FE-7FC0-434F-A71F-BBEF8099F1D8} Win32Proj pngvalid - + Application Unicode @@ -95,9 +95,9 @@ Console true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) Executing PNG validation program @@ -128,9 +128,9 @@ Console true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) Executing PNG validation program @@ -162,9 +162,9 @@ Console true true true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) UseLinkTimeCodeGeneration @@ -198,9 +198,9 @@ Console true true true - libpng16.lib;zlib.lib + libpng17.lib;zlib.lib $(OutDir) UseLinkTimeCodeGeneration diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/readme.txt libpng-1.7.0alpha04/projects/vstudio/readme.txt --- libpng-1.6.0beta34/projects/vstudio/readme.txt 2012-12-19 16:06:55.587959656 -0600 +++ libpng-1.7.0alpha04/projects/vstudio/readme.txt 2012-12-22 18:00:45.089108483 -0600 @@ -39,9 +39,9 @@ problems. If you don't use the Visual Studio defaults your application must still be built with the default runtime option (/MD). If, for some reason, it is not then your -application will crash inside libpng16.dll as soon as libpng tries to read +application will crash inside libpng17.dll as soon as libpng tries to read from a file handle you pass in. If you do not want to use the DLL, for example for a very small application, the 'release library' configuration may be more appropriate. This is built diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/zlib/zlib.vcxproj libpng-1.7.0alpha04/projects/vstudio/zlib/zlib.vcxproj --- libpng-1.6.0beta34/projects/vstudio/zlib/zlib.vcxproj 2012-10-27 12:59:30.189841000 -0500 +++ libpng-1.7.0alpha04/projects/vstudio/zlib/zlib.vcxproj 2012-12-20 22:50:18.000000000 -0600 @@ -35,10 +35,10 @@ {60F89955-91C6-3A36-8000-13C592FEC2DF} Win32Proj zlib - + StaticLibrary diff -ru4NwbB libpng-1.6.0beta34/projects/vstudio/zlib.props libpng-1.7.0alpha04/projects/vstudio/zlib.props --- libpng-1.6.0beta34/projects/vstudio/zlib.props 2012-12-19 16:06:55.596727743 -0600 +++ libpng-1.7.0alpha04/projects/vstudio/zlib.props 2012-12-22 18:00:45.098760824 -0600 @@ -32,6 +32,14 @@ versions do not match. The zlib version used in this build is recorded below: --> ..\..\..\..\zlib-1.2.5 + + + true diff -ru4NwbB libpng-1.6.0beta34/scripts/def.dfn libpng-1.7.0alpha04/scripts/def.dfn --- libpng-1.6.0beta34/scripts/def.dfn 2012-12-19 16:06:55.038001607 -0600 +++ libpng-1.7.0alpha04/scripts/def.dfn 2012-12-22 18:00:44.496106755 -0600 @@ -24,9 +24,9 @@ S-OS2 DESCRIPTION "PNG image compression library"-E S-OS2 CODE PRELOAD MOVEABLE DISCARDABLE-E S--E S-EXPORTS-E -S-;Version 1.7.0alpha04-E +S-;Version libpng %MAJOR%. PNG_JOIN %MINOR%. PNG_JOIN %RELEASE%-E /* NOTE: PNG_JOIN is interpreted by the calling script as a signal to * join the two things on either side, so we can do symbol * substitution within the name, regular C ## joins the pp-tokens, diff -ru4NwbB libpng-1.6.0beta34/scripts/makefile.linux libpng-1.7.0alpha04/scripts/makefile.linux --- libpng-1.6.0beta34/scripts/makefile.linux 2012-12-19 16:06:55.345878940 -0600 +++ libpng-1.7.0alpha04/scripts/makefile.linux 2012-12-22 18:00:44.816538307 -0600 @@ -235,5 +235,5 @@ pngwtran.o pngwtran.pic.o: %HEADERS% pngwutil.o pngwutil.pic.o: %HEADERS% pngpread.o pngpread.pic.o: %HEADERS% -pngtest.o: png.h pngconf.h +pngtest.o: png.h pngconf.h pnglibconf.h diff -ru4NwbB libpng-1.6.0beta34/scripts/makefile.msys libpng-1.7.0alpha04/scripts/makefile.msys --- libpng-1.6.0beta34/scripts/makefile.msys 1969-12-31 18:00:00.000000000 -0600 +++ libpng-1.7.0alpha04/scripts/makefile.msys 2012-12-22 18:00:44.848366118 -0600 @@ -0,0 +1,204 @@ +# makefile for libpng using MSYS/gcc (shared, static library) +# Copyright (C) 2012 Glenn Randers-Pehrson and Christopher M. Wheeler +# +# Portions taken from makefile.linux: +# Copyright (C) 1998, 1999, 2002, 2006, 2008, 2010-2011 Greg Roelofs and +# Glenn Randers-Pehrson +# Copyright (C) 2000 Cosmin Truta +# Copyright (C) 1996, 1997 Andreas Dilger +# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. +# +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h +# # # # # # # # # # # # # # # # # +prefix=/usr/local +exec_prefix=$(prefix) + +# Library name: +LIBNAME = libpng%NN% +PNGMAJ = %SONUM% +RELEASE = %RELEASE% + +# Shared library names: +LIBSO=$(LIBNAME).dll +LIBSOMAJ=$(LIBNAME).dll.$(PNGMAJ) +LIBSOREL=$(PNGMAJ).$(RELEASE) +OLDSO=libpng.dll + +# Where the zlib library and include files are located. +#ZLIBLIB=../zlib +#ZLIBINC=../zlib +ZLIBLIB=/usr/local/lib +ZLIBINC=/usr/local/include + +# Compiler, linker, lib and other tools +CC = gcc +LD = $(CC) +AR_RC = ar rcs +RANLIB = ranlib +RM_F = rm -rf +MKDIR_P=mkdir -p +LN_SF=ln -sf + +#ARCH = -march=pentium3 +#ARCH = -march=i686 +ARCH = +CDEBUG = -g -DPNG_DEBUG=5 +LDDEBUG = +CRELEASE = -O2 +LDRELEASE = -s +#CFLAGS = -W -Wall $(CDEBUG) +CFLAGS = -W -Wall $(CRELEASE) $(ARCH) +#LDFLAGS = $(LDDEBUG) +LDFLAGS = $(LDRELEASE) +LIBS = -lz -lm + +# File extensions +O=.o +A=.a +EXE=.exe + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. + +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +# Variables +OBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \ + pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \ + pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O) + +# Targets +all: static shared + +# see scripts/pnglibconf.mak for more options +pnglibconf.h: scripts/pnglibconf.h.prebuilt + cp scripts/pnglibconf.h.prebuilt $@ + +.c$(O): + $(CC) -c $(CFLAGS) -I$(ZLIBINC) $< + +static: libpng$(A) pngtest$(EXE) + +shared: $(LIBSOMAJ) + $(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSO) + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): + $(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSOMAJ) + +libpng$(A): $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +install-headers: png.h pngconf.h pnglibconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME) + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \ + -e s!@exec_prefix@!$(exec_prefix)! \ + -e s!@libdir@!$(LIBPATH)! \ + -e s!@includedir@!$(INCPATH)! \ + -e s!-lpng%NN%!-lpng%NN%\ -lz\ -lm! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \ + echo libs=\"-lpng%NN% -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + +install-shared: install-headers $(LIBSOMAJ) libpng.pc + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(OLDSO) + cp $(LIBSO) $(DL)/$(LIBSOREL) + (cd $(DL); \ + $(LN_SF) $(LIBSOREL) $(LIBSO); \ + $(LN_SF) $(LIBSO) $(OLDSO)) + + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +test: pngtest$(EXE) + ./pngtest$(EXE) + +pngtest$(EXE): pngtest$(O) libpng$(A) + $(LD) $(LDFLAGS) -L$(ZLIBLIB) -o $@ pngtest$(O) libpng$(A) $(LIBS) + +clean: + $(RM_F) *$(O) libpng$(A) pngtest$(EXE) pngout.png pnglibconf.h $(LIBSO) \ + $(LIBSOMAJ) libpng-config + +png.o png.pic.o: %HEADERS% +pngerror.o pngerror.pic.o: %HEADERS% +pngrio.o pngrio.pic.o: %HEADERS% +pngwio.o pngwio.pic.o: %HEADERS% +pngmem.o pngmem.pic.o: %HEADERS% +pngset.o pngset.pic.o: %HEADERS% +pngget.o pngget.pic.o: %HEADERS% +pngread.o pngread.pic.o: %HEADERS% +pngrtran.o pngrtran.pic.o: %HEADERS% +pngrutil.o pngrutil.pic.o: %HEADERS% +pngtrans.o pngtrans.pic.o: %HEADERS% +pngwrite.o pngwrite.pic.o: %HEADERS% +pngwtran.o pngwtran.pic.o: %HEADERS% +pngwutil.o pngwutil.pic.o: %HEADERS% +pngpread.o pngpread.pic.o: %HEADERS% + +pngtest.o: png.h pngconf.h pnglibconf.h diff -ru4NwbB libpng-1.6.0beta34/scripts/pnglibconf.dfa libpng-1.7.0alpha04/scripts/pnglibconf.dfa --- libpng-1.6.0beta34/scripts/pnglibconf.dfa 2012-12-19 16:06:55.526080416 -0600 +++ libpng-1.7.0alpha04/scripts/pnglibconf.dfa 2012-12-22 18:00:45.022387917 -0600 @@ -108,8 +108,15 @@ # file or on the command line (after pnglibconf.dfa) logunsupported = 1 +# The following allows the output from configure to modify the contents of +# pnglibconf.h + +@#ifdef HAVE_CONFIG_H +@# include "config.h" +@#endif + # PNG_USER_CONFIG has to be defined on the compiler command line # to cause pngusr.h to be read while constructing pnglibconf.h # # If you create a private DLL you need to define the following @@ -177,8 +184,52 @@ # by causing a similar build-time only file, pngprefix.h, to be generated. setting PREFIX +# This says that a prefix has been added to zlib API function names; at present +# it is informational, the builder of zlib must ensure that zlib.h contains the +# appropriate renames + +setting ZLIB_PREFIX + +# This is used to select an alternative zlib header file - it must look pretty +# much like the standard zlib.h, but this makes it easier to ensure the correct +# header file is used. Set it to the "" or <> quoted file name (a full file +# name is acceptable). Prior to 1.7.0 this used "zlib.h", so it would use a +# zlib.h in the same directory as the libpng source, from 1.7.0 it defaults to +# just searching the -I directories. Prior to 1.6.0 the #include appeared in +# the exported header files - so it was quite important to use "zlib.h" to +# ensure that applications always got the zlib.h from the same directory as +# png.h. + +setting ZLIB_HEADER default + +# These settings configure the default compression level (0-9) and 'strategy'; +# strategy is as defined by the implementors of zlib, it describes the input +# data and modifies the zlib parameters in an attempt to optimize the balance +# between search and huffman encoding in the zlib algorithms. The defaults are +# the zlib.h defaults - the apparently recursive definition does not arise +# because the name of the setting is prefixed by PNG_ +# +# The TEXT values are the defaults when writing compressed text (all forms) + +setting Z_DEFAULT_COMPRESSION default Z_DEFAULT_COMPRESSION +# TODO: why aren't these Z_RLE; zlib.h says that Z_RLE, specifically, is +# appropriate for PNG images, maybe it doesn't exist in all versions? +setting Z_DEFAULT_STRATEGY default Z_FILTERED +setting Z_DEFAULT_NOFILTER_STRATEGY default Z_DEFAULT_STRATEGY + +setting TEXT_Z_DEFAULT_COMPRESSION default Z_DEFAULT_COMPRESSION +setting TEXT_Z_DEFAULT_STRATEGY default Z_DEFAULT_STRATEGY + +# Define this to something that will stop, at least, the current thread; control +# cannot proceed beyond the PNG_ABORT operation and compilation of pngerror.c is +# likely to fail if the operation implemented does not clearly terminate the +# thread or process. The default implementation is the ANSI-C abort function, +# but any manner of C code may be used. + +setting ABORT default { (abort()); } + # Default to using the read macros setting DEFAULT_READ_MACROS default 1 @@ -275,50 +326,42 @@ # Added at libpng-1.4.0 option IO_STATE -# This is only for PowerPC big-endian and 680x0 systems -# some testing, not enabled by default. -# NO LONGER USED - -#option READ_BIG_ENDIAN disabled - -# Allow users to control limits on what the READ code will -# read: - -# Added at libpng-1.2.43; adds limit fields to png_struct, -# allows some usages of these fields - -option USER_LIMITS - -# Added at libpng-1.2.6; adds setting APIs, allows additional -# usage of this field (UTSL) - -option SET_USER_LIMITS requires USER_LIMITS - -# Feature added at libpng-1.4.0, this flag added at 1.4.1 -option SET_USER_LIMITS enables SET_CHUNK_CACHE_LIMIT -# Feature added at libpng-1.4.1, this flag added at 1.4.1 +# Libpng limits: limit the size of images and data on read. +# +# If this option is disabled all the limit checking code will be disabled: -option SET_USER_LIMITS enables SET_CHUNK_MALLOC_LIMIT +option USER_LIMITS requires READ -# Libpng limits. -# -# If these settings are *not* set libpng will not limit the size of +# If the following settings are *not* set libpng will not limit the size of # images or the size of data in ancilliary chunks. This does lead to -# security issues if PNG files come from untrusted sources. +# security issues if PNG files come from untrusted sources. Settings have the +# following interpretations: +# +# USER_WIDTH_MAX: maximum width of an image that will be read +# USER_HEIGHT_MAX: maximum height +# USER_CHUNK_MALLOC_MAX: maximum in-memory (decompressed) size of a single chunk +# USER_CHUNK_CACHE_MAX: maximum number of chunks to be cached +# +# Only chunks that are variable in number are counted towards the +# USER_CHUNK_CACHE_MAX limit setting USER_WIDTH_MAX setting USER_HEIGHT_MAX -setting USER_CHUNK_CACHE_MAX setting USER_CHUNK_MALLOC_MAX +setting USER_CHUNK_CACHE_MAX # To default all these settings to values that are large but probably # safe turn the SAFE_LIMITS option on; this will cause the value in # pngpriv.h to be used. Individual values can also be set, simply set # them in pngusr.dfa with '@#define PNG_setting value' lines. option SAFE_LIMITS enables USER_LIMITS disabled = SAFE_LIMITS SAFE_LIMITS +# If this option is enabled APIs to set the above limits at run time are added; +# without these the hardwired (compile time) limits will be used. +option SET_USER_LIMITS requires USER_LIMITS + # All of the following options relate to code capabilities for # processing image data before creating a PNG or after reading one. # You can remove these capabilities safely and still be PNG # conformant, however the library that results is still non-standard. diff -ru4NwbB libpng-1.6.0beta34/scripts/pnglibconf.h.prebuilt libpng-1.7.0alpha04/scripts/pnglibconf.h.prebuilt --- libpng-1.6.0beta34/scripts/pnglibconf.h.prebuilt 2012-12-19 16:06:55.536794933 -0600 +++ libpng-1.7.0alpha04/scripts/pnglibconf.h.prebuilt 2012-12-22 18:00:45.034306427 -0600 @@ -1,27 +1,21 @@ - -/* libpng STANDARD API DEFINITION */ - /* pnglibconf.h - library build configuration */ -/* Libpng 1.7.0alpha04 - December 23, 2012 */ +/* libpng version 1.7.0alpha04 - December 23, 2012 */ /* Copyright (c) 1998-2012 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ /* For conditions of distribution and use, see the disclaimer */ /* and license in png.h */ /* pnglibconf.h */ +/* Machine generated file: DO NOT EDIT */ /* Derived from: scripts/pnglibconf.dfa */ -/* If you edit this file by hand you must obey the rules expressed in */ -/* pnglibconf.dfa with respect to the dependencies between the following */ -/* symbols. It is much better to generate a new file using */ -/* scripts/libpngconf.mak */ - #ifndef PNGLCONF_H #define PNGLCONF_H /* settings */ +#define PNG_ABORT { (abort()); } #define PNG_API_RULE 0 #define PNG_CALLOC_SUPPORTED #define PNG_COST_SHIFT 3 #define PNG_DEFAULT_READ_MACROS 1 @@ -33,10 +27,16 @@ #define PNG_QUANTIZE_GREEN_BITS 5 #define PNG_QUANTIZE_RED_BITS 5 #define PNG_sCAL_PRECISION 5 #define PNG_sRGB_PROFILE_CHECKS 2 +#define PNG_TEXT_Z_DEFAULT_COMPRESSION Z_DEFAULT_COMPRESSION +#define PNG_TEXT_Z_DEFAULT_STRATEGY Z_DEFAULT_STRATEGY #define PNG_WEIGHT_SHIFT 8 #define PNG_ZBUF_SIZE 8192 +#define PNG_Z_DEFAULT_COMPRESSION Z_DEFAULT_COMPRESSION +#define PNG_Z_DEFAULT_NOFILTER_STRATEGY Z_DEFAULT_STRATEGY +#define PNG_Z_DEFAULT_STRATEGY Z_FILTERED +#define PNG_ZLIB_HEADER /* end of settings */ /* options */ #define PNG_16BIT_SUPPORTED #define PNG_ALIGN_MEMORY_SUPPORTED @@ -129,10 +129,8 @@ #define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_sBIT_SUPPORTED #define PNG_sCAL_SUPPORTED #define PNG_SEQUENTIAL_READ_SUPPORTED -#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED -#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED #define PNG_SETJMP_SUPPORTED #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SET_USER_LIMITS_SUPPORTED #define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED diff -ru4NwbB libpng-1.6.0beta34/scripts/symbols.def libpng-1.7.0alpha04/scripts/symbols.def --- libpng-1.6.0beta34/scripts/symbols.def 2012-12-19 16:06:55.547430244 -0600 +++ libpng-1.7.0alpha04/scripts/symbols.def 2012-12-22 18:00:45.046306925 -0600 @@ -14,22 +14,19 @@ png_get_compression_buffer_size @6 png_set_compression_buffer_size @7 png_set_longjmp_fn @8 png_longjmp @9 - png_reset_zstream @10 png_create_read_struct_2 @11 png_create_write_struct_2 @12 png_write_sig @13 png_write_chunk @14 png_write_chunk_start @15 png_write_chunk_data @16 png_write_chunk_end @17 png_create_info_struct @18 - png_info_init_3 @19 png_write_info_before_PLTE @20 png_write_info @21 png_read_info @22 - png_convert_to_rfc1123 @23 png_convert_from_struct_tm @24 png_convert_from_time_t @25 png_set_expand @26 png_set_expand_gray_1_2_4_to_8 @27 @@ -103,11 +100,8 @@ png_calloc @95 png_malloc_warn @96 png_free @97 png_free_data @98 - png_data_freer @99 - png_malloc_default @100 - png_free_default @101 png_error @102 png_chunk_error @103 png_err @104 png_warning @105