diff --git a/ANNOUNCE b/ANNOUNCE index 875d58e1b..dc5d53599 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.5.0beta36 - July 24, 2010 +Libpng 1.5.0beta36 - July 29, 2010 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -226,7 +226,7 @@ version 1.5.0beta24 [May 7, 2010] offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf. Added more blank lines for readability. -version 1.5.0beta25 [July 24, 2010] +version 1.5.0beta25 [July 29, 2010] In pngpread.c: png_push_have_row() add check for new_row > height Removed the now-redundant check for out-of-bounds new_row from example.c @@ -287,7 +287,27 @@ version 1.5.0beta35 [July 24, 2010] Moved the definition of png_snprintf() outside of the enclosing #ifdef blocks in pngconf.h -version 1.5.0beta36 [July 24, 2010] +version 1.5.0beta36 [July 29, 2010] + Patches by John Bowler: + Fixed point APIs are now supported throughout (no missing APIs). + Internal fixed point arithmetic support exists for all internal floating + point operations. + sCAL validates the floating point strings it is passed. + Safe, albeit rudimentary, Watcom support is provided by PNG_API_RULE==2 + Two new APIs exist to get the number of passes without turning on the + PNG_INTERLACE transform and to get the number of rows in the current + pass. + A new test program, pngvalid.c, validates the gamma code. + Errors in the 16 bit gamma correction (overflows) have been corrected. + Gamma handling arithmetic is in a new file, pngarith.c + cHRM chunk testing is done consistently (previously the floating point + API bypassed it, because the test really didn't work on FP, now the test + is performed on the actual values to be stored in the PNG file so it + works in the FP case too.) + Most floating point APIs now simply call the fixed point APIs after + converting the values to the fixed point form used in the PNG file. + The standard headers no longer include zlib.h, which is currently only + required for pngstruct.h and can therefore be internal. Send comments/corrections/commendations to png-mng-implement at lists.sf.net: (subscription required; visit diff --git a/CHANGES b/CHANGES index 9f86b8bc3..6a0c01b8e 100644 --- a/CHANGES +++ b/CHANGES @@ -2769,7 +2769,27 @@ version 1.5.0beta35 [July 24, 2010] Moved the definition of png_snprintf() outside of the enclosing #ifdef blocks in pngconf.h -version 1.5.0beta36 [July 24, 2010] +version 1.5.0beta36 [July 29, 2010] + Patches by John Bowler: + Fixed point APIs are now supported throughout (no missing APIs). + Internal fixed point arithmetic support exists for all internal floating + point operations. + sCAL validates the floating point strings it is passed. + Safe, albeit rudimentary, Watcom support is provided by PNG_API_RULE==2 + Two new APIs exist to get the number of passes without turning on the + PNG_INTERLACE transform and to get the number of rows in the current + pass. + A new test program, pngvalid.c, validates the gamma code. + Errors in the 16 bit gamma correction (overflows) have been corrected. + Gamma handling arithmetic is in a new file, pngarith.c + cHRM chunk testing is done consistently (previously the floating point + API bypassed it, because the test really didn't work on FP, now the test + is performed on the actual values to be stored in the PNG file so it + works in the FP case too.) + Most floating point APIs now simply call the fixed point APIs after + converting the values to the fixed point form used in the PNG file. + The standard headers no longer include zlib.h, which is currently only + required for pngstruct.h and can therefore be internal. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/Makefile.am b/Makefile.am index 61f3521a2..bfdb97037 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,10 +8,12 @@ PNGLIB_BASENAME= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ AUTOMAKE_OPTIONS = foreign color-tests # test programs - run on make check, make distcheck -check_PROGRAMS= pngtest +check_PROGRAMS= pngtest pngvalid pngtest_SOURCES = pngtest.c pngtest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la -TESTS = test-pngtest.sh +pngvalid_SOURCES = pngvalid.c +pngvalid_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la +TESTS = test-pngtest.sh pngvalid TESTS_ENVIRONMENT= srcdir=$(srcdir) # man pages @@ -25,11 +27,10 @@ bin_SCRIPTS= @binconfigs@ # rules to build libpng, only build the old library on request lib_LTLIBRARIES=libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la # EXTRA_LTLIBRARIES= libpng.la -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngset.c pngget.c pngrutil.c \ - pngtrans.c pngwutil.c \ - pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \ - pngwtran.c pngmem.c pngerror.c pngpread.c \ - png.h pngconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngarith.c pngerror.c\ + pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c\ + pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c\ + png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h diff --git a/Makefile.in b/Makefile.in index ec0442f18..a08fb7354 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -40,7 +40,8 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -check_PROGRAMS = pngtest$(EXEEXT) +check_PROGRAMS = pngtest$(EXEEXT) pngvalid$(EXEEXT) +TESTS = test-pngtest.sh pngvalid$(EXEEXT) @HAVE_LD_VERSION_SCRIPT_TRUE@am__append_1 = -Wl,--version-script=libpng.vers @HAVE_LD_VERSION_SCRIPT_FALSE@am__append_2 = -export-symbols libpng.sym subdir = . @@ -89,20 +90,21 @@ LTLIBRARIES = $(lib_LTLIBRARIES) libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD = am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-png.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngread.lo \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrio.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo \ + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwio.lo \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwrite.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo \ - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = \ $(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) \ @@ -115,6 +117,9 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK = $(LIBTOOL) --tag=CC \ am_pngtest_OBJECTS = pngtest.$(OBJEXT) pngtest_OBJECTS = $(am_pngtest_OBJECTS) pngtest_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la +am_pngvalid_OBJECTS = pngvalid.$(OBJEXT) +pngvalid_OBJECTS = $(am_pngvalid_OBJECTS) +pngvalid_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la SCRIPTS = $(bin_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -131,9 +136,9 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \ $(nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \ - $(pngtest_SOURCES) + $(pngtest_SOURCES) $(pngvalid_SOURCES) DIST_SOURCES = $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \ - $(pngtest_SOURCES) + $(pngtest_SOURCES) $(pngvalid_SOURCES) man3dir = $(mandir)/man3 man5dir = $(mandir)/man5 NROFF = nroff @@ -305,7 +310,8 @@ PNGLIB_BASENAME = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ AUTOMAKE_OPTIONS = foreign color-tests pngtest_SOURCES = pngtest.c pngtest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la -TESTS = test-pngtest.sh +pngvalid_SOURCES = pngvalid.c +pngvalid_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la TESTS_ENVIRONMENT = srcdir=$(srcdir) # man pages @@ -316,11 +322,10 @@ bin_SCRIPTS = @binconfigs@ # rules to build libpng, only build the old library on request lib_LTLIBRARIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la # EXTRA_LTLIBRARIES= libpng.la -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngset.c pngget.c pngrutil.c \ - pngtrans.c pngwutil.c \ - pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \ - pngwtran.c pngmem.c pngerror.c pngpread.c \ - png.h pngconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngarith.c pngerror.c\ + pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c\ + pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c\ + png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS = @LIBPNG_DEFINES@ @@ -461,6 +466,9 @@ clean-checkPROGRAMS: pngtest$(EXEEXT): $(pngtest_OBJECTS) $(pngtest_DEPENDENCIES) @rm -f pngtest$(EXEEXT) $(LINK) $(pngtest_OBJECTS) $(pngtest_LDADD) $(LIBS) +pngvalid$(EXEEXT): $(pngvalid_OBJECTS) $(pngvalid_DEPENDENCIES) + @rm -f pngvalid$(EXEEXT) + $(LINK) $(pngvalid_OBJECTS) $(pngvalid_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -503,6 +511,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-png.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.Plo@am__quote@ @@ -518,6 +527,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngtest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngvalid.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -547,12 +557,19 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-png.lo: png.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-png.lo `test -f 'png.c' || echo '$(srcdir)/'`png.c -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo: pngset.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo `test -f 'pngset.c' || echo '$(srcdir)/'`pngset.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngset.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo' libtool=yes @AMDEPBACKSLASH@ +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.lo: pngarith.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.lo `test -f 'pngarith.c' || echo '$(srcdir)/'`pngarith.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngarith.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo `test -f 'pngset.c' || echo '$(srcdir)/'`pngset.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngarith.lo `test -f 'pngarith.c' || echo '$(srcdir)/'`pngarith.c + +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo: pngerror.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo `test -f 'pngerror.c' || echo '$(srcdir)/'`pngerror.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngerror.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo `test -f 'pngerror.c' || echo '$(srcdir)/'`pngerror.c libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.lo: pngget.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.lo `test -f 'pngget.c' || echo '$(srcdir)/'`pngget.c @@ -561,26 +578,19 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.lo: pngget.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngget.lo `test -f 'pngget.c' || echo '$(srcdir)/'`pngget.c -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo: pngrutil.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo `test -f 'pngrutil.c' || echo '$(srcdir)/'`pngrutil.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngrutil.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo' libtool=yes @AMDEPBACKSLASH@ +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo: pngmem.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo `test -f 'pngmem.c' || echo '$(srcdir)/'`pngmem.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngmem.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo `test -f 'pngrutil.c' || echo '$(srcdir)/'`pngrutil.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo `test -f 'pngmem.c' || echo '$(srcdir)/'`pngmem.c -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo: pngtrans.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo `test -f 'pngtrans.c' || echo '$(srcdir)/'`pngtrans.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngtrans.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo' libtool=yes @AMDEPBACKSLASH@ +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo: pngpread.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo `test -f 'pngpread.c' || echo '$(srcdir)/'`pngpread.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngpread.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo `test -f 'pngtrans.c' || echo '$(srcdir)/'`pngtrans.c - -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo: pngwutil.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo `test -f 'pngwutil.c' || echo '$(srcdir)/'`pngwutil.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngwutil.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo `test -f 'pngwutil.c' || echo '$(srcdir)/'`pngwutil.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo `test -f 'pngpread.c' || echo '$(srcdir)/'`pngpread.c libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngread.lo: pngread.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngread.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngread.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngread.lo `test -f 'pngread.c' || echo '$(srcdir)/'`pngread.c @@ -596,6 +606,34 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrio.lo: pngrio.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrio.lo `test -f 'pngrio.c' || echo '$(srcdir)/'`pngrio.c +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo: pngrtran.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo `test -f 'pngrtran.c' || echo '$(srcdir)/'`pngrtran.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngrtran.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo `test -f 'pngrtran.c' || echo '$(srcdir)/'`pngrtran.c + +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo: pngrutil.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo `test -f 'pngrutil.c' || echo '$(srcdir)/'`pngrutil.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngrutil.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrutil.lo `test -f 'pngrutil.c' || echo '$(srcdir)/'`pngrutil.c + +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo: pngset.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo `test -f 'pngset.c' || echo '$(srcdir)/'`pngset.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngset.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngset.lo `test -f 'pngset.c' || echo '$(srcdir)/'`pngset.c + +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo: pngtrans.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo `test -f 'pngtrans.c' || echo '$(srcdir)/'`pngtrans.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngtrans.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngtrans.lo `test -f 'pngtrans.c' || echo '$(srcdir)/'`pngtrans.c + libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwio.lo: pngwio.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwio.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwio.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwio.lo `test -f 'pngwio.c' || echo '$(srcdir)/'`pngwio.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwio.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwio.Plo @@ -610,13 +648,6 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwrite.lo: pngwrite.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwrite.lo `test -f 'pngwrite.c' || echo '$(srcdir)/'`pngwrite.c -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo: pngrtran.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo `test -f 'pngrtran.c' || echo '$(srcdir)/'`pngrtran.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngrtran.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngrtran.lo `test -f 'pngrtran.c' || echo '$(srcdir)/'`pngrtran.c - libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.lo: pngwtran.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.lo `test -f 'pngwtran.c' || echo '$(srcdir)/'`pngwtran.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.Plo @@ -624,26 +655,12 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.lo: pngwtran.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwtran.lo `test -f 'pngwtran.c' || echo '$(srcdir)/'`pngwtran.c -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo: pngmem.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo `test -f 'pngmem.c' || echo '$(srcdir)/'`pngmem.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngmem.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo' libtool=yes @AMDEPBACKSLASH@ +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo: pngwutil.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo `test -f 'pngwutil.c' || echo '$(srcdir)/'`pngwutil.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngwutil.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngmem.lo `test -f 'pngmem.c' || echo '$(srcdir)/'`pngmem.c - -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo: pngerror.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo `test -f 'pngerror.c' || echo '$(srcdir)/'`pngerror.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngerror.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngerror.lo `test -f 'pngerror.c' || echo '$(srcdir)/'`pngerror.c - -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo: pngpread.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo -MD -MP -MF $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.Tpo -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo `test -f 'pngpread.c' || echo '$(srcdir)/'`pngpread.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.Tpo $(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pngpread.c' object='libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngpread.lo `test -f 'pngpread.c' || echo '$(srcdir)/'`pngpread.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la-pngwutil.lo `test -f 'pngwutil.c' || echo '$(srcdir)/'`pngwutil.c mostlyclean-libtool: -rm -f *.lo @@ -983,7 +1000,8 @@ distdir: $(DISTFILES) top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ @@ -1027,17 +1045,17 @@ dist dist-all: distdir distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ - unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/contrib/gregbook/readpng2.c b/contrib/gregbook/readpng2.c index 4644b093c..2414f9091 100644 --- a/contrib/gregbook/readpng2.c +++ b/contrib/gregbook/readpng2.c @@ -55,8 +55,10 @@ #include /* for exit() prototype */ +#include -#include "png.h" /* libpng header; includes zlib.h and setjmp.h */ +#include +#include "png.h" /* libpng header from the local directory */ #include "readpng2.h" /* typedefs, common macros, public prototypes */ @@ -216,7 +218,11 @@ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr) mainprog_info *mainprog_ptr; int color_type, bit_depth; png_uint_32 width, height; +#ifdef PNG_FLOATING_POINT_SUPPORTED double gamma; +#else + png_fixed_point gamma; +#endif /* setjmp() doesn't make sense here, because we'd either have to exit(), @@ -327,11 +333,19 @@ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr) * "gamma" value for the entire display system, i.e., the product of * LUT_exponent and CRT_exponent. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma); else png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455); - +#else + if (png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) + png_set_gamma_fixed(png_ptr, + (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), gamma); + else + png_set_gamma_fixed(png_ptr, + (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), 45455); +#endif /* we'll let libpng expand interlaced images, too */ diff --git a/contrib/gregbook/rpng2-x.c b/contrib/gregbook/rpng2-x.c index 2c2473469..80d4c455f 100644 --- a/contrib/gregbook/rpng2-x.c +++ b/contrib/gregbook/rpng2-x.c @@ -485,9 +485,6 @@ int main(int argc, char **argv) "\nPress Q, Esc or mouse button 1 (within image window, after image\n" "is displayed) to quit.\n" "\n", PROGNAME, -#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) - (int)strlen(PROGNAME), " ", -#endif (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat-1); exit(1); } diff --git a/contrib/pngminim/preader/makefile b/contrib/pngminim/preader/makefile index 282709efa..44bab9588 100644 --- a/contrib/pngminim/preader/makefile +++ b/contrib/pngminim/preader/makefile @@ -64,7 +64,7 @@ ZOBJS = adler32$(O) crc32$(O) \ zutil$(O) # libpng -PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \ +PNGSRCS=png$(C) pngarith$(C) pngerror$(C) pngget$(C) pngmem$(C) \ pngpread$(C) pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \ pngset$(C) pngtrans$(C) @@ -80,7 +80,7 @@ PNGINC= png.h pngconf.h pngusr.h $(PNGCONF) # Headers the PNG library uses PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h -PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \ +PNGOBJS=png$(O) pngarith$(O) pngerror$(O) pngget$(O) pngmem$(O) \ pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \ pngset$(O) pngtrans$(O) diff --git a/contrib/pngminim/preader/pngusr.dfa b/contrib/pngminim/preader/pngusr.dfa index 27b2b0947..31e83a58b 100644 --- a/contrib/pngminim/preader/pngusr.dfa +++ b/contrib/pngminim/preader/pngusr.dfa @@ -12,9 +12,14 @@ everything = off # Just switch on the progressive read code option PROGRESSIVE_READ on -# You must choose fixed or floating point arithmetic: -option FLOATING_POINT on -# option FIXED_POINT on +# You may choose fixed or floating point APIs: +# option FLOATING_POINT on +option FIXED_POINT on +# You must chose the internal fixed point implementation or to +# use the system floating point. The latter is considerably +# smaller (by about 1kbyte on an x86 system): +option FLOATING_ARITHMETIC on +# option FLOATING_ARITHMETIC off # Your program will probably need other options. The example # program here, rpng2-x, requires the following. Take a look diff --git a/example.c b/example.c index ec632906b..bd229a690 100644 --- a/example.c +++ b/example.c @@ -2,7 +2,7 @@ #if 0 /* in case someone actually tries to compile this */ /* example.c - an example of using libpng - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * This file has been placed in the public domain by the authors. * Maintained 1998-2010 Glenn Randers-Pehrson * Maintained 1996, 1997 Andreas Dilger) diff --git a/png.c b/png.c index 66c6907dd..8993842a1 100644 --- a/png.c +++ b/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -560,13 +560,13 @@ png_get_copyright(png_structp png_ptr) #else # ifdef __STDC__ return ((png_charp) PNG_STRING_NEWLINE \ - "libpng version 1.5.0beta36 - July 24, 2010" PNG_STRING_NEWLINE \ + "libpng version 1.5.0beta36 - July 29, 2010" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE); # else - return ((png_charp) "libpng version 1.5.0beta36 - July 24, 2010\ + return ((png_charp) "libpng version 1.5.0beta36 - July 29, 2010\ Copyright (c) 1998-2010 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."); @@ -616,7 +616,7 @@ png_get_header_version(png_structp png_ptr) #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) # ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED int PNGAPI -png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) +png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) { /* Check chunk_name and return "keep" value if it's on the list, else 0 */ int i; @@ -670,48 +670,7 @@ png_convert_size(size_t size) # endif /* PNG_SIZE_T */ /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ -# ifdef PNG_cHRM_SUPPORTED -# ifdef PNG_CHECK_cHRM_SUPPORTED - -/* - * Multiply two 32-bit numbers, V1 and V2, using 32-bit - * arithmetic, to produce a 64 bit result in the HI/LO words. - * - * A B - * x C D - * ------ - * AD || BD - * AC || CB || 0 - * - * where A and B are the high and low 16-bit words of V1, - * C and D are the 16-bit words of V2, AD is the product of - * A and D, and X || Y is (X << 16) + Y. -*/ - -void /* PRIVATE */ -png_64bit_product (long v1, long v2, unsigned long *hi_product, - unsigned long *lo_product) -{ - int a, b, c, d; - long lo, hi, x, y; - - a = (v1 >> 16) & 0xffff; - b = v1 & 0xffff; - c = (v2 >> 16) & 0xffff; - d = v2 & 0xffff; - - lo = b * d; /* BD */ - x = a * d + c * b; /* AD + CB */ - y = ((lo >> 16) & 0xffff) + x; - - lo = (lo & 0xffff) | ((y & 0xffff) << 16); - hi = (y >> 16) & 0xffff; - - hi += a * c; /* AC */ - - *hi_product = (unsigned long)hi; - *lo_product = (unsigned long)lo; -} +# ifdef PNG_CHECK_cHRM_SUPPORTED int /* PRIVATE */ png_check_cHRM_fixed(png_structp png_ptr, @@ -785,8 +744,7 @@ png_check_cHRM_fixed(png_structp png_ptr, return ret; } -# endif /* PNG_CHECK_cHRM_SUPPORTED */ -# endif /* PNG_cHRM_SUPPORTED */ +# endif /* PNG_CHECK_cHRM_SUPPORTED */ void /* PRIVATE */ png_check_IHDR(png_structp png_ptr, @@ -931,3 +889,1273 @@ png_check_IHDR(png_structp png_ptr, png_error(png_ptr, "Invalid IHDR data"); } #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* ASCII to fp functions */ +/* Check an ASCII formated floating point value, see the more detailed + * comments in pngpriv.h + */ +/* The following is used internally to preserve the 'valid' flag */ +#define png_fp_add(state, flags) ((state) |= (flags)) +#define png_fp_set(state, value)\ + ((state) = (value) | ((state) & PNG_FP_WAS_VALID)) + +/* Internal type codes: bits above the base state! */ +#define PNG_FP_SIGN 0 /* [+-] */ +#define PNG_FP_DOT 4 /* . */ +#define PNG_FP_DIGIT 8 /* [0123456789] */ +#define PNG_FP_E 12 /* [Ee] */ + +int /* PRIVATE */ +png_check_fp_number(png_charp string, png_size_t size, int *statep, + png_size_tp whereami) +{ + int state = *statep; + png_size_t i = *whereami; + + while (i < size) + { + int type; + /* First find the type of the next character */ + { + char ch = string[i]; + if (ch >= 48 && ch <= 57) + type = PNG_FP_DIGIT; + else switch (ch) + { + case 43: case 45: type = PNG_FP_SIGN; break; + case 46: type = PNG_FP_DOT; break; + case 69: case 101: type = PNG_FP_E; break; + default: goto PNG_FP_End; + } + } + + /* Now deal with this type according to the current + * state, the type is arranged to not overlap the + * bits of the PNG_FP_STATE. + */ + switch ((state & PNG_FP_STATE) + type) + { + case PNG_FP_INTEGER + PNG_FP_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + png_fp_add(state, PNG_FP_SAW_SIGN); + break; + case PNG_FP_INTEGER + PNG_FP_DOT: + /* Ok as trailer, ok as lead of fraction. */ + if (state & PNG_FP_SAW_DOT) /* two dots */ + goto PNG_FP_End; + else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ + png_fp_add(state, PNG_FP_SAW_DOT); + else + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + break; + case PNG_FP_INTEGER + PNG_FP_DIGIT: + if (state & PNG_FP_SAW_DOT) /* delayed fraction */ + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + break; + case PNG_FP_INTEGER + PNG_FP_E: + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + png_fp_set(state, PNG_FP_EXPONENT); + break; + /* case PNG_FP_FRACTION + PNG_FP_SIGN: + goto PNG_FP_End; ** no sign in exponent */ + /* case PNG_FP_FRACTION + PNG_FP_DOT: + goto PNG_FP_End; ** Because SAW_DOT is always set */ + case PNG_FP_FRACTION + PNG_FP_DIGIT: + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + break; + case PNG_FP_FRACTION + PNG_FP_E: + /* This is correct because the trailing '.' on an + * integer is handled above - so we can only get here + * with the sequence ".E" (with no preceding digits). + */ + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + png_fp_set(state, PNG_FP_EXPONENT); + break; + case PNG_FP_EXPONENT + PNG_FP_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + png_fp_add(state, PNG_FP_SAW_SIGN); + break; + /* case PNG_FP_EXPONENT + PNG_FP_DOT: + goto PNG_FP_End; */ + case PNG_FP_EXPONENT + PNG_FP_DIGIT: + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + break; + /* case PNG_FP_EXPONEXT + PNG_FP_E: + goto PNG_FP_End; */ + default: goto PNG_FP_End; /* I.e. break 2 */ + } + + /* The character seems ok, continue. */ + ++i; + } + +PNG_FP_End: + /* Here at the end, update the state and return the correct + * return code. + */ + *statep = state; + *whereami = i; + + return (state & PNG_FP_SAW_DIGIT) != 0; +} + + +/* The same but for a complete string. */ +int +png_check_fp_string(png_charp string, png_size_t size) +{ + int state=0; + png_size_t index=0; + + return png_check_fp_number(string, size, &state, &index) && + (index == size || string[index] == 0); +} +#endif /* pCAL or sCAL */ + +#ifdef PNG_READ_sCAL_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED +/* Utility used below - a simple accurate power of ten from an integral + * exponent. + */ +static double +png_pow10(int power) +{ + int recip = 0; + double d = 1; + /* Handle negative exponent with a reciprocal at the end because + * 10 is exact whereas .1 is inexact in base 2 + */ + if (power < 0) + recip = 1, power = -power; + if (power > 0) + { + /* Decompose power bitwise. */ + double mult = 10; + do + { + if (power & 1) d *= mult; + mult *= mult; + power >>= 1; + } + while (power > 0); + + if (recip) d = 1/d; + } + /* else power is 0 and d is 1 */ + + return d; +} + +/* Function to format a floating point value in ASCII with a given + * precision. + */ +void /* PRIVATE */ +png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, + double fp, unsigned precision) +{ + /* We use standard functions from math.h, but not printf because + * that would require stdio. The caller must supply a buffer of + * sufficient size or we will png_error. The tests on size and + * the space in ascii[] consumed are indicated below. + */ + if (precision < 1) + precision = DBL_DIG; + + /* Enforce the limit of the implementation precision too. */ + if (precision > DBL_DIG+1) + precision = DBL_DIG+1; + + /* Basic sanity checks */ + if (size >= precision+5) /* See the requirements below. */ + { + if (fp < 0) + { + fp = -fp; + *ascii++ = 45; /* '-' PLUS 1 TOTAL 1*/ + --size; + } + + if (fp >= DBL_MIN && fp <= DBL_MAX) + { + int exp; /* A base 10 exponent */ + double base; /* 10^exp */ + + /* First extract a base 10 exponent of the number, + * the calculation below rounds down when converting + * from base 2 to base 10 (multiply by log10(2) - + * 0.3010, but 77/256 is 0.3008, so exp needs to + * be increased. Note that the arithmetic shift + * performs a floor() unlike C arithmetic - using a + * C multiply would break the following for negative + * exponents. + */ + (void)frexp(fp, &exp); /* exponent to base 2 */ + exp = (exp * 77) >> 8; /* <= exponent to base 10 */ + /* Avoid underflow here. */ + base = png_pow10(exp); /* May underflow */ + while (base < DBL_MIN || base < fp) + { + /* And this may overflow. */ + double test = png_pow10(exp+1); + if (test <= DBL_MAX) + ++exp, base = test; + else + break; + } + + /* Normalize fp and correct exp, after this fp is in the + * range [.1,1) and exp is both the exponent and the digit + * *before* which the decimal point should be inserted + * (starting with 0 for the first digit). Note that this + * works even if 10^exp is out of range because of the + * test on DBL_MAX above. + */ + fp /= base; + while (fp >= 1) fp /= 10, ++exp; + + /* Because of the code above fp may, at this point, be + * less than .1, this is ok because the code below can + * handle the leading zeros this generates, so no attempt + * is made to correct that here. + */ + + { + int czero, clead, cdigits; + char exponent[10]; + + /* Allow up to two leading zeros - this will not lengthen + * the number compared to using E-n. + */ + if (exp < 0 && exp > -3) /* PLUS 3 TOTAL 4 */ + { + czero = -exp; /* PLUS 2 digits: TOTAL 3 */ + exp = 0; /* Dot added below before first output. */ + } + else + czero = 0; /* No zeros to add */ + + /* Generate the digit list, stripping trailing zeros and + * inserting a '.' before a digit if the exponent is 0. + */ + clead = czero; /* Count of leading zeros */ + cdigits = 0; /* Count of digits in list. */ + do + { + double d; + + fp *= 10; + /* Use modf here, not floor and subtract, so that + * the separation is done in one step. At the end + * of the loop don't break the number into parts so + * that the final digit is rounded. + */ + if (cdigits+czero-clead+1 < (int)precision) + fp = modf(fp, &d); + else + { + /* End of loop - round the whole number. */ + d = floor(fp + .5); + + if (d > 9) + { + /* Rounding up to 10, handle that here. */ + if (czero > 0) + { + --czero, d = 1; + if (cdigits == 0) --clead; + } + else + { + while (cdigits > 0 && d > 9) + { + int ch = *--ascii; + if (exp != (-1)) + ++exp; + else if (ch == 46) + { + ch = *--ascii, ++size; + /* Advance exp to '1', so that the + * decimal point happens after the + * previous digit. + */ + exp = 1; + } + + --cdigits; + d = ch - 47; /* I.e. 1+(ch-48) */ + } + + /* Did we reach the beginning? If so adjust the + * exponent but take into account the leading + * decimal point. + */ + if (d > 9) /* cdigits == 0 */ + { + if (exp == (-1)) + { + /* Leading decimal point (plus zeros?), if + * we lose the decimal point here it must + * be reentered below. + */ + int ch = *--ascii; + if (ch == 46) + ++size, exp = 1; + /* Else lost a leading zero, so 'exp' is + * still ok at (-1) + */ + } + else + ++exp; + + /* In all cases we output a '1' */ + d = 1; + } + } + } + fp = 0; /* Guarantees termination below. */ + } + + if (d == 0) + { + ++czero; + if (cdigits == 0) ++clead; + } + else + { + /* Included embedded zeros in the digit count. */ + cdigits += czero - clead; + clead = 0; + + while (czero > 0) + { + /* exp == (-1) means we just output the decimal + * place - after the DP don't adjust 'exp' any + * more! + */ + if (exp != (-1)) + { + if (exp == 0) *ascii++ = 46, --size; + /* PLUS 1: TOTAL 4 */ + --exp; + } + *ascii++ = 48, --czero; + } + + if (exp != (-1)) + { + if (exp == 0) *ascii++ = 46, --size; /* counted above */ + --exp; + } + *ascii++ = 48 + (int)d, ++cdigits; + } + } + while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); + + /* The total output count (max) is now 4+precision */ + + /* Check for an exponent, if we don't need one we are + * done and just need to terminate the string. At + * this point exp==(-1) is effectively if flag - it got + * to '-1' because of the decrement after outputing + * the decimal point above (the exponent required is + * *not* -1!) + */ + if (exp >= (-1) && exp <= 2) + { + /* The following only happens if we didn't output the + * leading zeros above for negative exponent, so this + * doest add to the digit requirement. Note that the + * two zeros here can only be output if the two leading + * zeros were *not* output, so this doesn't increase + * the output count. + */ + while (--exp >= 0) *ascii++ = 48; + *ascii = 0; + /* Total buffer requirement (including the '\0') is + * 5+precision - see check at the start. + */ + return; + } + + /* Here if an exponent is required, adjust size for + * the digits we output but did not count. The total + * digit output here so far is at most 1+precision - no + * decimal point and no leading or trailing zeros have + * been output. + */ + size -= cdigits; + + *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision*/ + if (exp < 0) + { + *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ + exp = -exp; + } + + cdigits = 0; + while (exp > 0) + { + exponent[cdigits++] = 48 + exp % 10; + exp /= 10; + } + + /* Need another size check here for the exponent digits, so + * this need not be considered above. + */ + if ((int)size > cdigits) + { + while (cdigits > 0) *ascii++ = exponent[--cdigits]; + *ascii = 0; + return; + } + } + } + else if (!(fp >= DBL_MIN)) + { + *ascii++ = 48; /* '0' */ + *ascii = 0; + return; + } + else + { + *ascii++ = 105; /* 'i' */ + *ascii++ = 110; /* 'n' */ + *ascii++ = 102; /* 'f' */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII convertion buffer too small"); +} + +# endif /* FLOATING_POINT */ +#endif /* READ_SCAL */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) &&\ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) +png_fixed_point +png_fixed(png_structp png_ptr, double fp, png_const_charp text) +{ + double r = floor(100000 * fp + .5); + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; + + png_fixed_error(png_ptr, text, fp); + return 0; +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* muldiv functions */ +/* This API takes signed arguments and rounds the result to the nearest + * integer (or, for a fixed point number - the standard argument - to + * the nearest .00001). Overflow and divide by zero are signalled in + * the result, a boolean - true on success, false on overflow. + */ +int +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, + png_int_32 div) +{ + /* Return a * times / div, rounded. */ + if (div != 0) + { + if (a == 0 || times == 0) + { + *res = 0; + return 1; + } + else + { +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a; + r *= times; + r /= div; + r = floor(r+.5); + /* A png_fixed_point is a 32 bit integer. */ + if (r <= 2147483647. && r >= -2147483648.) + { + *res = (png_fixed_point)r; + return 1; + } +#else + int negative = 0; + png_uint_32 A, T, D; + if (a < 0) negative = 1, A = -a; else A = a; + if (times < 0) negative = !negative, T = -times; else T = times; + if (div < 0) negative = !negative, D = -div; else D = div; + + /* Following can't overflow because the arguments only + * have 31 bits each, however the result may be 32 bits. + */ + png_uint_32 s16 = (A >> 16) * (T & 0xffff) + + (A & 0xffff) * (T >> 16); + /* Can't overflow because the a*times bit is only 30 + * bits at most. + */ + png_uint_32 s32 = (A >> 16) * (T >> 16) + (s16 >> 16); + png_uint_32 s00 = (A & 0xffff) * (T & 0xffff); + + s16 = (s16 & 0xffff) << 16; + s00 += s16; + if (s00 < s16) ++s32; /* carry */ + + if (s32 < D) /* else overflow */ + { + /* s32.s00 is now the 64 bit product, do a standard + * division, we know that s32 < D, so the maximum + * required shift is 31. + */ + int bitshift = 32; + png_fixed_point result = 0; /* NOTE: signed */ + + while (--bitshift >= 0) + { + png_uint_32 d32, d00; + if (bitshift > 0) + d32 = D >> (32-bitshift), d00 = D << bitshift; + else + d32 = 0, d00 = D; + + if (s32 > d32) + { + if (s00 < d00) --s32; /* carry */ + s32 -= d32, s00 -= d00, result += 1<= d00) + s32 = 0, s00 -= d00, result += 1<= (D >> 1)) ++result; + + if (negative) result = -result; + + /* Check for overflow. */ + if (negative && result <= 0 || !negative && result >= 0) + { + *res = result; + return 1; + } + } +#endif + } + } + + return 0; +} +#endif /* READ_GAMMA || INCH_CONVERSIONS */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* The following is for when the caller doesn't much care about the + * result. + */ +png_fixed_point +png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, + png_int_32 div) +{ + png_fixed_point result; + if (png_muldiv(&result, a, times, div)) + return result; + + png_warning(png_ptr, "fixed point overflow ignored"); + return 0; +} +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gammma */ +/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ +png_fixed_point +png_reciprocal(png_fixed_point a) +{ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(1E10/a+.5); + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + if (png_muldiv(&res, 100000, 100000, a)) + return res; +#endif + + return 0; /* error/overflow */ +} + +/* A local convenience routine. */ +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. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a * 1E-5; + r *= b; + r = floor(r+.5); + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + if (png_muldiv(&res, a, b, 100000)) + return res; +#endif + + return 0; /* overflow */ +} + +/* The inverse of the above. */ +png_fixed_point +png_reciprocal2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b, the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = 1E15/a; + r /= b; + r = floor(r+.5); + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + /* This may overflow because the range of png_fixed_point isn't symmetric, + * but this API is only used for the product of file and screen gamma so it + * doesn't matter that the smallest number it can produce is 1/21474, not + * 1/100000 + */ + png_fixed_point res = png_product2(a, b); + if (res != 0) + return png_reciprocal(res); +#endif + + return 0; /* overflow */ +} +#endif /* READ_GAMMA */ + +#ifdef PNG_CHECK_cHRM_SUPPORTED +/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, + * 2010: moved from pngset.c) */ +/* + * Multiply two 32-bit numbers, V1 and V2, using 32-bit + * arithmetic, to produce a 64 bit result in the HI/LO words. + * + * A B + * x C D + * ------ + * AD || BD + * AC || CB || 0 + * + * where A and B are the high and low 16-bit words of V1, + * C and D are the 16-bit words of V2, AD is the product of + * A and D, and X || Y is (X << 16) + Y. +*/ + +void /* PRIVATE */ +png_64bit_product (long v1, long v2, unsigned long *hi_product, + unsigned long *lo_product) +{ + int a, b, c, d; + long lo, hi, x, y; + + a = (v1 >> 16) & 0xffff; + b = v1 & 0xffff; + c = (v2 >> 16) & 0xffff; + d = v2 & 0xffff; + + lo = b * d; /* BD */ + x = a * d + c * b; /* AD + CB */ + y = ((lo >> 16) & 0xffff) + x; + + lo = (lo & 0xffff) | ((y & 0xffff) << 16); + hi = (y >> 16) & 0xffff; + + hi += a * c; /* AC */ + + *hi_product = (unsigned long)hi; + *lo_product = (unsigned long)lo; +} +#endif /* CHECK_cHRM */ + +#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* Fixed point gamma. + * + * To calculate gamma this code implements fast log() and exp() calls using only + * fixed point arithmetic. This code has sufficient precision for either 8 or + * 16 bit sample values. + * + * The tables used here were calculated using simple 'bc' programs, but C double + * precision floating point arithmetic would work fine. The programs are given + * at the head of each table. + * + * 8 bit log table + * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to + * 255, so it's the base 2 logarithm of a normalized 8 bit floating point + * mantissa. The numbers are 32 bit fractions. + */ +static png_uint_32 +png_8bit_l2[128] = +{ +# if PNG_DO_BC + for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } +# endif + 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, + 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, + 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, + 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, + 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, + 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, + 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, + 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, + 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, + 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, + 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, + 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, + 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, + 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, + 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, + 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, + 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, + 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, + 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, + 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, + 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, + 24347096U, 0U +#if 0 + /* The following are the values for 16 bit tables - these work fine for the 8 + * bit convertions but produce very slightly larger errors in the 16 bit log + * (about 1.2 as opposed to 0.7 absolute error in the final value). To use + * these all the shifts below must be adjusted appropriately. + */ + 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, + 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, + 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, + 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, + 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, + 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, + 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, + 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, + 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, + 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, + 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, + 1119, 744, 372 +#endif +}; + +static png_uint_32 +png_log8bit(unsigned x) +{ + unsigned log = 0; + /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, + * because the log is actually negate that means adding 1. The final + * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 + * input), return 7.99998 for the overflow (log 0) case - so the result is + * always at most 19 bits. + */ + if ((x &= 0xff) == 0) return 0xffffffff; + if ((x & 0xf0) == 0) log = 4, x <<= 4; + if ((x & 0xc0) == 0) log += 2, x <<= 2; + if ((x & 0x80) == 0) log += 1, x <<= 1; + return (log << 16) + ((png_8bit_l2[x-128]+32768)>>16); +} + +/* The above gives exact (to 16 binary places) log2 values for 8 bit images, + * for 16 bit images we use the most significant 8 bits of the 16 bit value to + * get an approximation then multiply the approximation by a correction factor + * determined by the remaining up to 8 bits. This requires an additional step + * in the 16 bit case. + * + * We want log2(value/65535), we have log2(v'/255), where: + * + * value = v' * 256 + v'' + * = v' * f + * + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less + * than 258. The final factor also needs to correct for the fact that our 8 bit + * value is scaled by 255, whereas the 16 bit values must be scaled by 65535. + * + * This gives a final formula using a calculated value 'x' which is value/v' and + * scaling by 65536 to match the above table: + * + * log2(x/257) * 65536 + * + * Since these numbers are so close to '1' we can use simple linear + * interpolation between the two end values 256/257 (result -368.61) and 258/257 + * (result 367.179). The values used below are scaled by a further 64 to give + * 16 bit precision in the interpolation: + * + * Start (256): -23591 + * Zero (257): 0 + * End (258): 23499 + */ +static png_uint_32 +png_log16bit(png_uint_32 x) +{ + unsigned log = 0; + + /* As above, but now the input has 16 bits. */ + if ((x &= 0xffff) == 0) return 0xffffffff; + if ((x & 0xff00) == 0) log = 8, x <<= 8; + if ((x & 0xf000) == 0) log += 4, x <<= 4; + if ((x & 0xc000) == 0) log += 2, x <<= 2; + if ((x & 0x8000) == 0) log += 1, x <<= 1; + + /* Calculate the base logarithm from the top 8 bits as a 28 bit fractional + * value. + */ + log <<= 28; + log += (png_8bit_l2[(x>>8)-128]+8) >> 4; + + /* Now we need to interpolate the factor, this requires a division by the top + * 8 bits. Do this with maximum precision. + */ + x = ((x << 16) + (x >> 9)) / (x >> 8); + + /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, + * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly + * 16 bits to interpolate to get the low bits of the result. Round the + * answer. Note that the end point values are scaled by 64 to retain overall + * precision and that 'log' is current scaled by an extra 12 bits, so adjust + * the overall scaling by 6-12. Round at every step. + */ + x -= 1U << 24; + if (x <= 65536U) /* <= '257' */ + log += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); + else + log -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); + + return (log + 2048) >> 12; +} + +/* The 'exp()' case must invert the above, taking a 20 bit fixed point + * logarithmic value and returning a 16 or 8 bit number as appropriate. In + * each case only the low 16 bits are relevant - the fraction - since the + * integer bits (the top 4) simply determine a shift. + * + * The worst case is the 16 bit distinction between 65535 and 65534, this + * requires perhaps spurious accuracty in the decoding of the logarithm to + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance + * of getting this accuracy in practice. + * + * To deal with this the following exp() function works out the exponent of the + * frational part of the logarithm by using an accurate 32 bit value from the + * top four fractional bits then multiplying in the remaining bits. + */ +static png_uint_32 +png_32bit_exp[16] = +{ +# if PNG_DO_BC + for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } +# endif + /* NOTE: the first entry is deliberately set to the maximum 32 bit value. */ + 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, + 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, + 2553802834U, 2445529972U, 2341847524U, 2242560872U +}; + +/* Adjustment table; provided to explain the numbers in the code below. */ +#if PNG_DO_BC +for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} + 11 44937.64284865548751208448 + 10 45180.98734845585101160448 + 9 45303.31936980687359311872 + 8 45364.65110595323018870784 + 7 45395.35850361789624614912 + 6 45410.72259715102037508096 + 5 45418.40724413220722311168 + 4 45422.25021786898173001728 + 3 45424.17186732298419044352 + 2 45425.13273269940811464704 + 1 45425.61317555035558641664 + 0 45425.85339951654943850496 +#endif + +static png_uint_32 +png_exp(png_uint_32 x) +{ + if (x <= 0xfffff) /* Else zero */ + { + /* Obtain a 4 bit approximation */ + png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; + + /* Incorporate the low 12 bits - these decrease the returned value by + * multiplying by a number less than 1 if the bit is set. The multiplier + * is determined by the above table and the shift, notice that the values + * converge on 45426 and this is used to allow linear interpolation of the + * low bits. + */ + if (x & 0x800) e -= (((e >> 16) * 44938U) + 16U) >> 5; + if (x & 0x400) e -= (((e >> 16) * 45181U) + 32U) >> 6; + if (x & 0x200) e -= (((e >> 16) * 45303U) + 64U) >> 7; + if (x & 0x100) e -= (((e >> 16) * 45365U) + 128U) >> 8; + if (x & 0x080) e -= (((e >> 16) * 45395U) + 256U) >> 9; + if (x & 0x040) e -= (((e >> 16) * 45410U) + 512U) >> 10; + + /* And handle the low 6 bits in a single block. */ + e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; + + /* Handle the upper bits of x. */ + e >>= x >> 16; + return e; + } + + return 0; +} + +static png_byte +png_exp8bit(png_uint_32 log) +{ + /* Get a 32 bit value: */ + png_uint_32 x = png_exp(log); + + /* Convert the 32 bit value to 0..255 by multiplying by 256-1, note that the + * second, rounding, step can't overflow because of the first, subtraction, + * step. + */ + x -= x >> 8; + return (x + 0x7fffffU) >> 24; +} + +static png_uint_16 +png_exp16bit(png_uint_32 log) +{ + /* Get a 32 bit value: */ + png_uint_32 x = png_exp(log); + + /* Convert the 32 bit value to 0..65535 by multiplying by 65536-1: */ + x -= x >> 16; + return (x + 32767U) >> 16; +} +#endif /* FLOATING_ARITHMETIC */ + +png_byte +png_gamma_8bit_correct(unsigned value, png_fixed_point gamma) +{ + if (value > 0 && value < 255) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + return (png_byte)floor(255*pow(value/255.,gamma*.00001)+.5); +# else + png_uint_32 log = png_log8bit(value); + png_fixed_point res; + if (png_muldiv(&res, gamma, log, PNG_FP_1)) + return png_exp8bit(res); +# endif + + /* Overflow. */ + value = 0; + } + + return value; +} + +png_uint_16 +png_gamma_16bit_correct(unsigned value, png_fixed_point gamma) +{ + if (value > 0 && value < 65535) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + return (png_uint_16)floor(65535*pow(value/65535.,gamma*.00001)+.5); +# else + png_uint_32 log = png_log16bit(value); + png_fixed_point res; + if (png_muldiv(&res, gamma, log, PNG_FP_1)) + return png_exp16bit(res); +# endif + + /* Overflow. */ + value = 0; + } + + return value; +} + +/* This does the right thing based on the bit_depth field of the + * png_struct, interpreting values as 8 or 16 bit. While the result + * is nominally a 16 bit value if bit depth is 8 then the result is + * 8 bit (as are the arguments.) + */ +png_uint_16 /* PRIVATE */ +png_gamma_correct(png_structp png_ptr, unsigned value, png_fixed_point gamma) +{ + if (png_ptr->bit_depth == 8) + return png_gamma_8bit_correct(value, gamma); + else + return png_gamma_16bit_correct(value, gamma); +} + +/* This is the shared test on whether a gamma value is 'significant' - whether + * it is worth doing gamma correction. + */ +int /* PRIVATE */ +png_gamma_significant(png_fixed_point gamma) +{ + return gamma < PNG_FP_1-PNG_GAMMA_THRESHOLD_FIXED || + gamma > PNG_FP_1+PNG_GAMMA_THRESHOLD_FIXED; +} + +/* 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 respoonsible 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_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned shift, PNG_CONST png_fixed_point gamma) +{ + /* Various values derived from 'shift': */ + PNG_CONST unsigned num = 1U << (8U - shift); + PNG_CONST unsigned max = (1U << (16U - shift))-1U; + PNG_CONST unsigned max_by_2 = 1U << (15U-shift); + unsigned i; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + for (i = 0; i < num; i++) + { + png_uint_16p sub_table = table[i] = + (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); + + /* 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. + */ + if (png_gamma_significant(gamma)) + { + /* 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. + */ + unsigned j; + for (j = 0; j < 256; j++) + { + png_uint_16 ig = (j << (8-shift)) + i; +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* Inline the 'max' scaling operation: */ + sub_table[j] = (png_uint_16)floor(65535*pow(ig/(double)max, + gamma*.00001)+.5); +# else + if (shift) + ig = (ig * 65535U + max_by_2)/max; + sub_table[j] = png_gamma_16bit_correct(ig, gamma); +# endif + } + } + else + { + /* We must still build a table, but do it the fast way. */ + unsigned j; + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; + if (shift) + ig = (ig * 65535U + max_by_2)/max; + sub_table[j] = ig; + } + } + } +} + +/* NOTE: this function expects the *inverse* of the overall gamma transformation + * required. + */ +static void +png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned shift, PNG_CONST png_fixed_point gamma) +{ + PNG_CONST unsigned num = 1U << (8U - shift); + PNG_CONST unsigned max = (1U << (16U - shift))-1U; + unsigned i; + png_uint_32 last; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + /* '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 * png_sizeof(png_uint_16)); + + /* 'gamma' 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. + * + * 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' + */ + last = 0; + for (i = 0; i < 255; ++i) /* 8 bit output value */ + { + /* Find the corresponding maximum input value */ + png_uint_16 out = i * 257U; /* 16 bit output value */ + /* Find the boundary value in 16 bits: */ + png_uint_16 bound = png_gamma_16bit_correct(out+128U, gamma); + /* Adjust (round) to (16-shift) bits: */ + bound = (bound * max + 32768)/65535; + + while (last <= bound) + { + table[last & (0xffU >> shift)][last >> (8U - shift)] = out; + last++; + } + } + + /* And fill in the final entries. */ + while (last < (num << 8)) + { + table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; + last++; + } +} + +/* 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. + */ +static void +png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, + PNG_CONST png_fixed_point gamma) +{ + unsigned i; + png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); + + if (png_gamma_significant(gamma)) for (i=0; i<256; i++) + table[i] = png_gamma_8bit_correct(i, gamma); + else for (i=0; i<245; ++i) + table[i] = i; +} + +/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit + * tables, we don't make a full table if we are reducing to 8-bit in + * 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_structp png_ptr, png_byte bit_depth) +{ + png_debug(1, "in png_build_gamma_table"); + + if (bit_depth <= 8) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, + png_reciprocal(png_ptr->gamma)); + + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->gamma/* Probably doing rgb_to_gray */); + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } + else + { + png_byte shift, sig_bit; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit = png_ptr->sig_bit.red; + + if (png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; + + if (png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + 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) + shift = 16U - sig_bit; /* shift == insignificant bits */ + else + shift = 0; /* keep all 16 bits */ + + if (png_ptr->transformations & PNG_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. + */ + if (shift < (16U - PNG_MAX_GAMMA_8)) + shift = (16U - PNG_MAX_GAMMA_8); + } + + if (shift > 8U) + shift = 8U; /* Guarantees at least one table! */ + + png_ptr->gamma_shift = shift; + + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + else + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) + { + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, + png_reciprocal(png_ptr->gamma)); + + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, os 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->gamma/* Probably doing rgb_to_gray */); + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } +} +#endif /* READ_GAMMA */ diff --git a/png.h b/png.h index 398b87965..ccc9e992c 100644 --- a/png.h +++ b/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.5.0beta36 - July 24, 2010 + * libpng version 1.5.0beta36 - July 29, 2010 * Copyright (c) 1998-2010 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -11,7 +11,7 @@ * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.5.0beta36 - July 24, 2010: Glenn + * libpng versions 0.97, January 1998, through 1.5.0beta36 - July 29, 2010: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: @@ -172,7 +172,7 @@ * * This code is released under the libpng license. * - * libpng versions 1.2.6, August 15, 2004, through 1.5.0beta36, July 24, 2010, are + * libpng versions 1.2.6, August 15, 2004, through 1.5.0beta36, July 29, 2010, are * Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are * distributed according to the same disclaimer and license as libpng-1.2.5 * with the following individual added to the list of Contributing Authors: @@ -284,14 +284,14 @@ * Y2K compliance in libpng: * ========================= * - * July 24, 2010 + * July 29, 2010 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.5.0beta36 are Y2K compliant. It is my belief that earlier - * versions were also Y2K compliant. + * upward through 1.5.0beta36 are Y2K compliant. It is my belief that + * earlier versions were also Y2K compliant. * * Libpng only has three year fields. One is a 2-byte unsigned integer * that will hold years up to 65535. The other two hold the date in text @@ -348,7 +348,7 @@ /* Version information for png.h - this should match the version in png.c */ #define PNG_LIBPNG_VER_STRING "1.5.0beta36" #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.5.0beta36 - July 24, 2010\n" + " libpng version 1.5.0beta36 - July 29, 2010\n" #define PNG_LIBPNG_VER_SONUM 15 #define PNG_LIBPNG_VER_DLLNUM 15 @@ -397,15 +397,17 @@ #ifndef PNG_VERSION_INFO_ONLY /* Standard header files (not needed for the version info) */ -# ifdef PNG_STDIO_SUPPORTED -# include -# endif # ifdef PNG_SETJMP_SUPPORTED # include # endif -/* Include the compression library's header */ -# include "zlib.h" +/* Need the time information for converting tIME chunks, it + * defines struct tm: + */ +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* "time.h" functions are not supported on all operating systems */ +# include +#endif /* Machine specific configuration. */ # include "pngconf.h" @@ -647,6 +649,12 @@ typedef png_info FAR * FAR * png_infopp; #define PNG_UINT_32_MAX ((png_uint_32)(-1)) #define PNG_SIZE_MAX ((png_size_t)(-1)) +/* These are constants for fixed point values encoded in the + * PNG specification manner (x100000) + */ +#define PNG_FP_1 100000 +#define PNG_FP_HALF 50000 + /* These describe the color_type field in png_info. */ /* color type masks */ #define PNG_COLOR_MASK_PALETTE 1 @@ -794,6 +802,17 @@ typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp),); /* This must match the function definition in , and the * application must include this before png.h to obtain the definition * of jmp_buf. The function is required to be PNG_NORETURN. + * + * If you get a type warning from the compiler when linking against this line + * then your compiler has 'longjmp' that does not match the requirements of the + * compiler that built libpng. You will have to write a wrapper function for + * your compiler's longjmp and call png_set_longjmp_fn directly (not via the + * png_jmpbuf macro.) + * + * If you get a warning here while building the library you will need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! */ typedef void (PNGCAPI *png_longjmp_ptr) PNGARG((jmp_buf, int)) PNG_NORETURN; #endif @@ -853,8 +872,7 @@ PNG_EXPORT(png_uint_32,png_access_version_number,(void),,1); /* Tell lib we have already handled the first magic bytes. * Handling more than 8 bytes from the beginning of the file is an error. */ -PNG_EXPORT(void,png_set_sig_bytes,(png_structp png_ptr, - int num_bytes),,2); +PNG_EXPORT(void,png_set_sig_bytes,(png_structp png_ptr, int num_bytes),,2); /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a * PNG file. Returns zero if the supplied bytes match the 8-byte PNG @@ -870,17 +888,16 @@ PNG_EXPORT(int,png_sig_cmp,(png_bytep sig, png_size_t start, #define png_check_sig(sig,n) !png_sig_cmp((sig), 0, (n)) /* Allocate and initialize png_ptr struct for reading, and any other memory. */ -PNG_EXPORT(png_structp,png_create_read_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED,4); +PNG_EXPORT(png_structp,png_create_read_struct,(png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED,4); /* Allocate and initialize png_ptr struct for writing, and any other memory */ -PNG_EXPORT(png_structp,png_create_write_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED,5); +PNG_EXPORT(png_structp,png_create_write_struct,(png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED,5); -PNG_EXPORT(png_size_t,png_get_compression_buffer_size,(png_structp - png_ptr),,6); +PNG_EXPORT(png_size_t,png_get_compression_buffer_size,(png_structp png_ptr),,6); PNG_EXPORT(void,png_set_compression_buffer_size,(png_structp png_ptr, png_size_t size),,7); @@ -896,7 +913,7 @@ PNG_EXPORT(void,png_set_compression_buffer_size,(png_structp png_ptr, * allocated by the library - the call will return NULL on a mismatch * indicating an ABI mismatch. */ -PNG_EXPORT(jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, +PNG_EXPORT(jmp_buf*,png_set_longjmp_fn,(png_structp png_ptr, png_longjmp_ptr longjmp_fn, size_t jmp_buf_size),,8); # define png_jmpbuf(png_ptr) \ (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) @@ -909,8 +926,7 @@ PNG_EXPORT(jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, * will use it; otherwise it will call PNG_ABORT(). This function was * added in libpng-1.5.0. */ -PNG_EXPORT(void, png_longjmp, (png_structp png_ptr, int val), - PNG_NORETURN,9); +PNG_EXPORT(void,png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN,9); #ifdef PNG_READ_SUPPORTED /* Reset the compression stream */ @@ -919,30 +935,30 @@ PNG_EXPORT(int,png_reset_zstream,(png_structp png_ptr),,10); /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ #ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORT(png_structp,png_create_read_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED,11); -PNG_EXPORT(png_structp,png_create_write_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED,12); +PNG_EXPORT(png_structp,png_create_read_struct_2,(png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED,11); +PNG_EXPORT(png_structp,png_create_write_struct_2,(png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED,12); #endif /* Write the PNG file signature. */ PNG_EXPORT(void,png_write_sig,(png_structp png_ptr),,13); /* Write a PNG chunk - size, type, (optional) data, CRC. */ -PNG_EXPORT(void,png_write_chunk,(png_structp png_ptr, - png_bytep chunk_name, png_bytep data, png_size_t length),,14); +PNG_EXPORT(void,png_write_chunk,(png_structp png_ptr, png_bytep chunk_name, + png_bytep data, png_size_t length),,14); /* Write the start of a PNG chunk - length and chunk name. */ PNG_EXPORT(void,png_write_chunk_start,(png_structp png_ptr, png_bytep chunk_name, png_uint_32 length),,15); /* Write the data of a PNG chunk started with png_write_chunk_start(). */ -PNG_EXPORT(void,png_write_chunk_data,(png_structp png_ptr, - png_bytep data, png_size_t length),,16); +PNG_EXPORT(void,png_write_chunk_data,(png_structp png_ptr, png_bytep data, + png_size_t length),,16); /* Finish a chunk started with png_write_chunk_start() (includes CRC). */ PNG_EXPORT(void,png_write_chunk_end,(png_structp png_ptr),,17); @@ -957,13 +973,11 @@ PNG_EXPORT(void,png_info_init_3,(png_infopp info_ptr, /* Writes all the PNG information before the image. */ PNG_EXPORT(void,png_write_info_before_PLTE,(png_structp png_ptr, png_infop info_ptr),,20); -PNG_EXPORT(void,png_write_info,(png_structp png_ptr, - png_infop info_ptr),,21); +PNG_EXPORT(void,png_write_info,(png_structp png_ptr, png_infop info_ptr),,21); #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read the information before the actual image data. */ -PNG_EXPORT(void,png_read_info,(png_structp png_ptr, - png_infop info_ptr),,22); +PNG_EXPORT(void,png_read_info,(png_structp png_ptr, png_infop info_ptr),,22); #endif #ifdef PNG_TIME_RFC1123_SUPPORTED @@ -977,15 +991,13 @@ PNG_EXPORT(void,png_convert_from_struct_tm,(png_timep ptime, struct tm FAR * ttime),,24); /* Convert from time_t to png_time. Uses gmtime() */ -PNG_EXPORT(void,png_convert_from_time_t,(png_timep ptime, - time_t ttime),,25); +PNG_EXPORT(void,png_convert_from_time_t,(png_timep ptime, time_t ttime),,25); #endif /* PNG_CONVERT_tIME_SUPPORTED */ #ifdef PNG_READ_EXPAND_SUPPORTED /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ PNG_EXPORT(void,png_set_expand,(png_structp png_ptr),,26); -PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8,(png_structp png_ptr),, - 27); +PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8,(png_structp png_ptr),,27); PNG_EXPORT(void,png_set_palette_to_rgb,(png_structp png_ptr),,28); PNG_EXPORT(void,png_set_tRNS_to_alpha,(png_structp png_ptr),,29); #endif @@ -1000,17 +1012,12 @@ PNG_EXPORT(void,png_set_bgr,(png_structp png_ptr),,30); PNG_EXPORT(void,png_set_gray_to_rgb,(png_structp png_ptr),,31); /* Reduce RGB to grayscale. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_rgb_to_gray,(png_structp png_ptr, - int error_action, double red, double green ),,32); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(void,png_set_rgb_to_gray_fixed,(png_structp png_ptr, +PNG_FP_EXPORT(void,png_set_rgb_to_gray,(png_structp png_ptr, int error_action, + double red, double green ),,32); +PNG_FIXED_EXPORT(void,png_set_rgb_to_gray_fixed,(png_structp png_ptr, int error_action, png_fixed_point red, png_fixed_point green),,33); -# endif -PNG_EXPORT(png_byte,png_get_rgb_to_gray_status,(png_structp png_ptr),, - 34); +PNG_EXPORT(png_byte,png_get_rgb_to_gray_status,(png_structp png_ptr),,34); #endif PNG_EXPORT(void,png_build_grayscale_palette,(int bit_depth, @@ -1032,14 +1039,14 @@ PNG_EXPORT(void,png_set_invert_alpha,(png_structp png_ptr),,38); #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) /* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(void,png_set_filler,(png_structp png_ptr, - png_uint_32 filler, int flags),,39); +PNG_EXPORT(void,png_set_filler,(png_structp png_ptr, png_uint_32 filler, + int flags),,39); /* The values of the PNG_FILLER_ defines should NOT be changed */ # define PNG_FILLER_BEFORE 0 # define PNG_FILLER_AFTER 1 /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(void,png_set_add_alpha,(png_structp png_ptr, - png_uint_32 filler, int flags),,40); +PNG_EXPORT(void,png_set_add_alpha,(png_structp png_ptr, png_uint_32 filler, + int flags),,40); #endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) @@ -1060,16 +1067,33 @@ PNG_EXPORT(void,png_set_packswap,(png_structp png_ptr),,43); #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) /* Converts files to legal bit depths. */ -PNG_EXPORT(void,png_set_shift,(png_structp png_ptr, - png_color_8p true_bits),,44); +PNG_EXPORT(void,png_set_shift,(png_structp png_ptr, png_color_8p true_bits),, + 44); #endif #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) -/* Have the code handle the interlacing. Returns the number of passes. */ +/* Have the code handle the interlacing. Returns the number of passes. + * MUST be called before png_read_update_info or png_start_read_image, otherwise + * it will not have the desired effect. Note that it is still necessary to call + * png_read_row or png_read_rows png_get_image_height times for each pass. + */ PNG_EXPORT(int,png_set_interlace_handling,(png_structp png_ptr),,45); #endif +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Alternatively call this to get the number of rows in the current pass. Call + * this after png_read_update_info or png_start_read_image; if you call it + * before it will just return the image height (which is also what it returns + * for a non-interlaced image!). + * + * NOTE: you need to call these to find out how many times to call png_read_row + * if you handle your own de-interlacing. + */ +PNG_EXPORT(int,png_get_num_passes,(png_structp png_ptr),,215); +PNG_EXPORT(png_uint_32,png_get_num_rows,(png_structp png_ptr),,216); +#endif + #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) /* Invert monochrome files */ PNG_EXPORT(void,png_set_invert_mono,(png_structp png_ptr),,46); @@ -1077,12 +1101,14 @@ PNG_EXPORT(void,png_set_invert_mono,(png_structp png_ptr),,46); #ifdef PNG_READ_BACKGROUND_SUPPORTED /* Handle alpha and tRNS by replacing with a background color. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_background,(png_structp png_ptr, - png_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma),,47); -# endif -/* TODO: png_set_background_fixed */ +PNG_FP_EXPORT(void,png_set_background,(png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, int need_expand, + double background_gamma),,47); +PNG_FIXED_EXPORT(void,png_set_background_fixed,(png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, int need_expand, + png_fixed_point background_gamma),,217); +#endif +#ifdef PNG_READ_BACKGROUND_SUPPORTED # define PNG_BACKGROUND_GAMMA_UNKNOWN 0 # define PNG_BACKGROUND_GAMMA_SCREEN 1 # define PNG_BACKGROUND_GAMMA_FILE 2 @@ -1098,18 +1124,22 @@ PNG_EXPORT(void,png_set_strip_16,(png_structp png_ptr),,48); /* Turn on quantizing, and reduce the palette to the number of colors * available. */ -PNG_EXPORT(void,png_set_quantize,(png_structp png_ptr, - png_colorp palette, int num_palette, int maximum_colors, - png_uint_16p histogram, int full_quantize),,49); +PNG_EXPORT(void,png_set_quantize,(png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_uint_16p histogram, + int full_quantize),,49); #endif #ifdef PNG_READ_GAMMA_SUPPORTED +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) + /* Handle gamma correction. Screen_gamma=(display_exponent) */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_gamma,(png_structp png_ptr, - double screen_gamma, double default_file_gamma),,50); -# endif -/* TODO: png_set_gamma_fixed */ +PNG_FP_EXPORT(void,png_set_gamma,(png_structp png_ptr, double screen_gamma, + double default_file_gamma),,50); +PNG_FIXED_EXPORT(void,png_set_gamma_fixed,(png_structp png_ptr, + png_fixed_point screen_gamma, png_fixed_point default_file_gamma),,208); #endif @@ -1124,8 +1154,8 @@ PNG_EXPORT(void,png_write_flush,(png_structp png_ptr),,52); PNG_EXPORT(void,png_start_read_image,(png_structp png_ptr),,53); /* Optional call to update the users info structure */ -PNG_EXPORT(void,png_read_update_info,(png_structp png_ptr, - png_infop info_ptr),,54); +PNG_EXPORT(void,png_read_update_info,(png_structp png_ptr, png_infop info_ptr),, + 54); #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read one or more rows of image data. */ @@ -1141,29 +1171,25 @@ PNG_EXPORT(void,png_read_row,(png_structp png_ptr, png_bytep row, #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read the whole image into memory at once. */ -PNG_EXPORT(void,png_read_image,(png_structp png_ptr, - png_bytepp image),,57); +PNG_EXPORT(void,png_read_image,(png_structp png_ptr, png_bytepp image),,57); #endif /* Write a row of image data */ PNG_EXPORT(void,png_write_row,(png_structp png_ptr, png_bytep row),,58); /* Write a few rows of image data */ -PNG_EXPORT(void,png_write_rows,(png_structp png_ptr, - png_bytepp row, png_uint_32 num_rows),,59); +PNG_EXPORT(void,png_write_rows,(png_structp png_ptr, png_bytepp row, + png_uint_32 num_rows),,59); /* Write the image data */ -PNG_EXPORT(void,png_write_image,(png_structp png_ptr, - png_bytepp image),,60); +PNG_EXPORT(void,png_write_image,(png_structp png_ptr, png_bytepp image),,60); /* Write the end of the PNG file. */ -PNG_EXPORT(void,png_write_end,(png_structp png_ptr, - png_infop info_ptr),,61); +PNG_EXPORT(void,png_write_end,(png_structp png_ptr, png_infop info_ptr),,61); #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read the end of the PNG file. */ -PNG_EXPORT(void,png_read_end,(png_structp png_ptr, - png_infop info_ptr),,62); +PNG_EXPORT(void,png_read_end,(png_structp png_ptr, png_infop info_ptr),,62); #endif /* Free any memory associated with the png_info_struct */ @@ -1179,8 +1205,8 @@ PNG_EXPORT(void,png_destroy_write_struct,(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr),,65); /* Set the libpng method of handling chunk CRC errors */ -PNG_EXPORT(void,png_set_crc_action,(png_structp png_ptr, - int crit_action, int ancil_action),,66); +PNG_EXPORT(void,png_set_crc_action,(png_structp png_ptr, int crit_action, + int ancil_action),,66); /* Values for png_set_crc_action() to say how to handle CRC errors in * ancillary and critical chunks, and whether to use the data contained @@ -1209,8 +1235,8 @@ PNG_EXPORT(void,png_set_crc_action,(png_structp png_ptr, /* Set the filtering method(s) used by libpng. Currently, the only valid * value for "method" is 0. */ -PNG_EXPORT(void,png_set_filter,(png_structp png_ptr, int method, - int filters),,67); +PNG_EXPORT(void,png_set_filter,(png_structp png_ptr, int method, int filters),, + 67); /* 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 @@ -1265,12 +1291,12 @@ PNG_EXPORT(void,png_set_filter,(png_structp png_ptr, int method, * the weights and costs are set to 1.0, this degenerates the WEIGHTED method * to the UNWEIGHTED method, but with added encoding time/computation. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_filter_heuristics,(png_structp png_ptr, +PNG_FP_EXPORT(void,png_set_filter_heuristics,(png_structp png_ptr, int heuristic_method, int num_weights, png_doublep filter_weights, png_doublep filter_costs),,68); -# endif -/* TODO: png_set_filter_heuristics_fixed */ +PNG_FIXED_EXPORT(void,png_set_filter_heuristics_fixed,(png_structp png_ptr, + int heuristic_method, int num_weights, png_fixed_point_p filter_weights, + png_fixed_point_p filter_costs),,209); #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ /* Heuristic used for row filter selection. These defines should NOT be @@ -1288,8 +1314,7 @@ PNG_EXPORT(void,png_set_filter_heuristics,(png_structp png_ptr, * for PNG images, and do considerably fewer caclulations. In the future, * these values may not correspond directly to the zlib compression levels. */ -PNG_EXPORT(void,png_set_compression_level,(png_structp png_ptr, - int level),,69); +PNG_EXPORT(void,png_set_compression_level,(png_structp png_ptr, int level),,69); PNG_EXPORT(void,png_set_compression_mem_level,(png_structp png_ptr, int mem_level),,70); @@ -1300,8 +1325,8 @@ PNG_EXPORT(void,png_set_compression_strategy,(png_structp png_ptr, PNG_EXPORT(void,png_set_compression_window_bits,(png_structp png_ptr, int window_bits),,72); -PNG_EXPORT(void,png_set_compression_method,(png_structp png_ptr, - int method),,73); +PNG_EXPORT(void,png_set_compression_method,(png_structp png_ptr, int method),, + 73); /* These next functions are called for input/output, memory, and error * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, @@ -1325,9 +1350,8 @@ PNG_EXPORT(void,png_init_io,(png_structp png_ptr, png_FILE_p fp),,74); * default function will be used. */ -PNG_EXPORT(void,png_set_error_fn,(png_structp png_ptr, - png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warning_fn),,75); +PNG_EXPORT(void,png_set_error_fn,(png_structp png_ptr, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warning_fn),,75); /* Return the user pointer associated with the error functions */ PNG_EXPORT(png_voidp,png_get_error_ptr,(png_structp png_ptr),,76); @@ -1342,13 +1366,12 @@ PNG_EXPORT(png_voidp,png_get_error_ptr,(png_structp png_ptr),,76); * default flush function, which uses the standard *FILE structure, will * be used. */ -PNG_EXPORT(void,png_set_write_fn,(png_structp png_ptr, - png_voidp io_ptr, png_rw_ptr write_data_fn, - png_flush_ptr output_flush_fn),,77); +PNG_EXPORT(void,png_set_write_fn,(png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn),,77); /* Replace the default data input function with a user supplied one. */ -PNG_EXPORT(void,png_set_read_fn,(png_structp png_ptr, - png_voidp io_ptr, png_rw_ptr read_data_fn),,78); +PNG_EXPORT(void,png_set_read_fn,(png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn),,78); /* Return the user pointer associated with the I/O functions */ PNG_EXPORT(png_voidp,png_get_io_ptr,(png_structp png_ptr),,79); @@ -1361,8 +1384,8 @@ PNG_EXPORT(void,png_set_write_status_fn,(png_structp png_ptr, #ifdef PNG_USER_MEM_SUPPORTED /* Replace the default memory allocation functions with user supplied one(s). */ -PNG_EXPORT(void,png_set_mem_fn,(png_structp png_ptr, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),,82); +PNG_EXPORT(void,png_set_mem_fn,(png_structp png_ptr, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn),,82); /* Return the user pointer associated with the memory functions */ PNG_EXPORT(png_voidp,png_get_mem_ptr,(png_structp png_ptr),,83); #endif @@ -1383,8 +1406,7 @@ PNG_EXPORT(void,png_set_user_transform_info,(png_structp png_ptr, png_voidp user_transform_ptr, int user_transform_depth, int user_transform_channels),,86); /* Return the user pointer associated with the user transform functions */ -PNG_EXPORT(png_voidp,png_get_user_transform_ptr, - (png_structp png_ptr),,87); +PNG_EXPORT(png_voidp,png_get_user_transform_ptr,(png_structp png_ptr),,87); #endif #ifdef PNG_USER_CHUNKS_SUPPORTED @@ -1405,8 +1427,8 @@ PNG_EXPORT(void,png_set_progressive_read_fn,(png_structp png_ptr, PNG_EXPORT(png_voidp,png_get_progressive_ptr,(png_structp png_ptr),,91); /* Function to be called when data becomes available */ -PNG_EXPORT(void,png_process_data,(png_structp png_ptr, - png_infop info_ptr, png_bytep buffer, png_size_t buffer_size),,92); +PNG_EXPORT(void,png_process_data,(png_structp png_ptr, png_infop info_ptr, + png_bytep buffer, png_size_t buffer_size),,92); /* Function that combines rows. Not very much different than the * png_combine_row() call. Is this even used????? @@ -1415,11 +1437,11 @@ PNG_EXPORT(void,png_progressive_combine_row,(png_structp png_ptr, png_bytep old_row, png_bytep new_row),,93); #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -PNG_EXPORT(png_voidp,png_malloc,(png_structp png_ptr, - png_alloc_size_t size),PNG_ALLOCATED,94); +PNG_EXPORT(png_voidp,png_malloc,(png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED,94); /* Added at libpng version 1.4.0 */ -PNG_EXPORT(png_voidp,png_calloc,(png_structp png_ptr, - png_alloc_size_t size),PNG_ALLOCATED,95); +PNG_EXPORT(png_voidp,png_calloc,(png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED,95); /* Added at libpng version 1.2.4 */ PNG_EXPORT(png_voidp,png_malloc_warn,(png_structp png_ptr, @@ -1457,14 +1479,13 @@ PNG_EXPORT(void,png_data_freer,(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_USER_MEM_SUPPORTED PNG_EXPORT(png_voidp,png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED,100); -PNG_EXPORT(void,png_free_default,(png_structp png_ptr, - png_voidp ptr),,101); +PNG_EXPORT(void,png_free_default,(png_structp png_ptr, png_voidp ptr),,101); #endif #ifdef PNG_ERROR_TEXT_SUPPORTED /* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORT(void,png_error,(png_structp png_ptr, - png_const_charp error_message),PNG_NORETURN,102); +PNG_EXPORT(void,png_error,(png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN,102); /* The same, but the chunk name is prepended to the error string. */ PNG_EXPORT(void,png_chunk_error,(png_structp png_ptr, @@ -1495,8 +1516,7 @@ PNG_EXPORT(void,png_benign_error,(png_structp png_ptr, PNG_EXPORT(void,png_chunk_benign_error,(png_structp png_ptr, png_const_charp warning_message),,108); -PNG_EXPORT(void,png_set_benign_errors,(png_structp png_ptr, - int allowed),,109); +PNG_EXPORT(void,png_set_benign_errors,(png_structp png_ptr, int allowed),,109); #else # ifdef PNG_ALLOW_BENIGN_ERRORS # define png_benign_error png_warning @@ -1520,8 +1540,8 @@ PNG_EXPORT(void,png_set_benign_errors,(png_structp png_ptr, * png_info_struct. */ /* Returns "flag" if chunk data is valid in info_ptr. */ -PNG_EXPORT(png_uint_32,png_get_valid,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 flag),,110); +PNG_EXPORT(png_uint_32,png_get_valid,(png_structp png_ptr, png_infop info_ptr, + png_uint_32 flag),,110); /* Returns number of bytes needed to hold a transformed row. */ PNG_EXPORT(png_size_t,png_get_rowbytes,(png_structp png_ptr, @@ -1531,8 +1551,8 @@ PNG_EXPORT(png_size_t,png_get_rowbytes,(png_structp png_ptr, /* Returns row_pointers, which is an array of pointers to scanlines that was * returned from png_read_png(). */ -PNG_EXPORT(png_bytepp,png_get_rows,(png_structp png_ptr, - png_infop info_ptr),,112); +PNG_EXPORT(png_bytepp,png_get_rows,(png_structp png_ptr, png_infop info_ptr),, + 112); /* Set row_pointers, which is an array of pointers to scanlines for use * by png_write_png(). */ @@ -1541,62 +1561,61 @@ PNG_EXPORT(void,png_set_rows,(png_structp png_ptr, png_infop info_ptr, #endif /* Returns number of color channels in image. */ -PNG_EXPORT(png_byte,png_get_channels,(png_structp png_ptr, - png_infop info_ptr),,114); +PNG_EXPORT(png_byte,png_get_channels,(png_structp png_ptr, png_infop info_ptr),, + 114); #ifdef PNG_EASY_ACCESS_SUPPORTED /* Returns image width in pixels. */ -PNG_EXPORT(png_uint_32, png_get_image_width,(png_structp png_ptr, +PNG_EXPORT(png_uint_32,png_get_image_width,(png_structp png_ptr, png_infop info_ptr),,115); /* Returns image height in pixels. */ -PNG_EXPORT(png_uint_32, png_get_image_height,(png_structp png_ptr, +PNG_EXPORT(png_uint_32,png_get_image_height,(png_structp png_ptr, png_infop info_ptr),,116); /* Returns image bit_depth. */ -PNG_EXPORT(png_byte, png_get_bit_depth,(png_structp png_ptr, - png_infop info_ptr),,117); +PNG_EXPORT(png_byte,png_get_bit_depth,(png_structp png_ptr, png_infop info_ptr), + ,117); /* Returns image color_type. */ -PNG_EXPORT(png_byte, png_get_color_type,(png_structp png_ptr, +PNG_EXPORT(png_byte,png_get_color_type,(png_structp png_ptr, png_infop info_ptr),,118); /* Returns image filter_type. */ -PNG_EXPORT(png_byte, png_get_filter_type,(png_structp png_ptr, +PNG_EXPORT(png_byte,png_get_filter_type,(png_structp png_ptr, png_infop info_ptr),,119); /* Returns image interlace_type. */ -PNG_EXPORT(png_byte, png_get_interlace_type,(png_structp png_ptr, +PNG_EXPORT(png_byte,png_get_interlace_type,(png_structp png_ptr, png_infop info_ptr),,120); /* Returns image compression_type. */ -PNG_EXPORT(png_byte, png_get_compression_type,(png_structp png_ptr, +PNG_EXPORT(png_byte,png_get_compression_type,(png_structp png_ptr, png_infop info_ptr),,121); /* Returns image resolution in pixels per meter, from pHYs chunk data. */ -PNG_EXPORT(png_uint_32, png_get_pixels_per_meter,(png_structp png_ptr, +PNG_EXPORT(png_uint_32,png_get_pixels_per_meter,(png_structp png_ptr, png_infop info_ptr),,122); -PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter, - (png_structp png_ptr, png_infop info_ptr),,123); -PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter, - (png_structp png_ptr, png_infop info_ptr),,124); +PNG_EXPORT(png_uint_32,png_get_x_pixels_per_meter,(png_structp png_ptr, + png_infop info_ptr),,123); +PNG_EXPORT(png_uint_32,png_get_y_pixels_per_meter,(png_structp png_ptr, + png_infop info_ptr),,124); /* Returns pixel aspect ratio, computed from pHYs chunk data. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(float, png_get_pixel_aspect_ratio, - (png_structp png_ptr, png_infop info_ptr),,125); -# endif -/* TODO: png_get_pixel_aspect_ratio_fixed */ +PNG_FP_EXPORT(float,png_get_pixel_aspect_ratio,(png_structp png_ptr, + png_infop info_ptr),,125); +PNG_FIXED_EXPORT(png_fixed_point,png_get_pixel_aspect_ratio_fixed, + (png_structp png_ptr, png_infop info_ptr),,210); /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ -PNG_EXPORT(png_int_32, png_get_x_offset_pixels, - (png_structp png_ptr, png_infop info_ptr),,126); -PNG_EXPORT(png_int_32, png_get_y_offset_pixels, - (png_structp png_ptr, png_infop info_ptr),,127); -PNG_EXPORT(png_int_32, png_get_x_offset_microns, - (png_structp png_ptr, png_infop info_ptr),,128); -PNG_EXPORT(png_int_32, png_get_y_offset_microns, - (png_structp png_ptr, png_infop info_ptr),,129); +PNG_EXPORT(png_int_32,png_get_x_offset_pixels,(png_structp png_ptr, + png_infop info_ptr),,126); +PNG_EXPORT(png_int_32,png_get_y_offset_pixels,(png_structp png_ptr, + png_infop info_ptr),,127); +PNG_EXPORT(png_int_32,png_get_x_offset_microns,(png_structp png_ptr, + png_infop info_ptr),,128); +PNG_EXPORT(png_int_32, png_get_y_offset_microns,(png_structp png_ptr, + png_infop info_ptr),,129); #endif /* PNG_EASY_ACCESS_SUPPORTED */ @@ -1605,183 +1624,160 @@ PNG_EXPORT(png_bytep,png_get_signature,(png_structp png_ptr, png_infop info_ptr),,130); #ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_bKGD,(png_structp png_ptr, - png_infop info_ptr, png_color_16p *background),,131); +PNG_EXPORT(png_uint_32,png_get_bKGD,(png_structp png_ptr, png_infop info_ptr, + png_color_16p *background),,131); #endif #ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(void,png_set_bKGD,(png_structp png_ptr, - png_infop info_ptr, png_color_16p background),,132); +PNG_EXPORT(void,png_set_bKGD,(png_structp png_ptr, png_infop info_ptr, + png_color_16p background),,132); #endif #ifdef PNG_cHRM_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_cHRM,(png_structp png_ptr, - png_infop info_ptr, double *white_x, double *white_y, - double *red_x, double *red_y, double *green_x, double *green_y, - double *blue_x, double *blue_y),,133); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_cHRM_fixed,(png_structp png_ptr, - png_infop info_ptr, - png_fixed_point *int_white_x, png_fixed_point *int_white_y, - png_fixed_point *int_red_x, png_fixed_point *int_red_y, - png_fixed_point *int_green_x, png_fixed_point *int_green_y, - png_fixed_point *int_blue_x, png_fixed_point *int_blue_y),,134); -# endif +PNG_FP_EXPORT(png_uint_32,png_get_cHRM,(png_structp png_ptr, + png_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y),,133); +#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */ +PNG_FIXED_EXPORT(png_uint_32,png_get_cHRM_fixed,(png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, + png_fixed_point *int_white_y, png_fixed_point *int_red_x, + png_fixed_point *int_red_y, png_fixed_point *int_green_x, + png_fixed_point *int_green_y, png_fixed_point *int_blue_x, + png_fixed_point *int_blue_y),,134); +#endif #endif #ifdef PNG_cHRM_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_cHRM,(png_structp png_ptr, - png_infop info_ptr, double white_x, double white_y, - double red_x, double red_y, double green_x, double green_y, - double blue_x, double blue_y),,135); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(void,png_set_cHRM_fixed,(png_structp png_ptr, - png_infop info_ptr, - png_fixed_point int_white_x, png_fixed_point int_white_y, - png_fixed_point int_red_x, png_fixed_point int_red_y, - png_fixed_point int_green_x, png_fixed_point int_green_y, - png_fixed_point int_blue_x, png_fixed_point int_blue_y),,136); -# endif +PNG_FP_EXPORT(void,png_set_cHRM,(png_structp png_ptr, png_infop info_ptr, + double white_x, double white_y, double red_x, double red_y, double green_x, + double green_y, double blue_x, double blue_y),,135); +PNG_FIXED_EXPORT(void,png_set_cHRM_fixed,(png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, + png_fixed_point int_white_y, png_fixed_point int_red_x, + png_fixed_point int_red_y, png_fixed_point int_green_x, + png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y),,136); #endif #ifdef PNG_gAMA_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_gAMA,(png_structp png_ptr, - png_infop info_ptr, double *file_gamma),,137); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_gAMA_fixed,(png_structp png_ptr, +PNG_FP_EXPORT(png_uint_32,png_get_gAMA,(png_structp png_ptr, png_infop info_ptr, + double *file_gamma),,137); +PNG_FIXED_EXPORT(png_uint_32,png_get_gAMA_fixed,(png_structp png_ptr, png_infop info_ptr, png_fixed_point *int_file_gamma),,138); -# endif #endif #ifdef PNG_gAMA_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_gAMA,(png_structp png_ptr, - png_infop info_ptr, double file_gamma),,139); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(void,png_set_gAMA_fixed,(png_structp png_ptr, +PNG_FP_EXPORT(void,png_set_gAMA,(png_structp png_ptr, png_infop info_ptr, + double file_gamma),,139); +PNG_FIXED_EXPORT(void,png_set_gAMA_fixed,(png_structp png_ptr, png_infop info_ptr, png_fixed_point int_file_gamma),,140); -# endif #endif #ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_hIST,(png_structp png_ptr, - png_infop info_ptr, png_uint_16p *hist),,141); +PNG_EXPORT(png_uint_32,png_get_hIST,(png_structp png_ptr, png_infop info_ptr, + png_uint_16p *hist),,141); #endif #ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(void,png_set_hIST,(png_structp png_ptr, - png_infop info_ptr, png_uint_16p hist),,142); +PNG_EXPORT(void,png_set_hIST,(png_structp png_ptr, png_infop info_ptr, + png_uint_16p hist),,142); #endif -PNG_EXPORT(png_uint_32,png_get_IHDR,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, - int *bit_depth, int *color_type, int *interlace_method, - int *compression_method, int *filter_method),,143); +PNG_EXPORT(png_uint_32,png_get_IHDR,(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, + int *interlace_method, int *compression_method, int *filter_method),,143); -PNG_EXPORT(void,png_set_IHDR,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_method, int compression_method, - int filter_method),,144); +PNG_EXPORT(void,png_set_IHDR,(png_structp png_ptr, png_infop info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, + int interlace_method, int compression_method, int filter_method),,144); #ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_oFFs,(png_structp png_ptr, - png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, - int *unit_type),,145); +PNG_EXPORT(png_uint_32,png_get_oFFs,(png_structp png_ptr, png_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type),,145); #endif #ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(void,png_set_oFFs,(png_structp png_ptr, - png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, - int unit_type),,146); +PNG_EXPORT(void,png_set_oFFs,(png_structp png_ptr, png_infop info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type),,146); #endif #ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_pCAL,(png_structp png_ptr, - png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, - int *type, int *nparams, png_charp *units, png_charpp *params),,147); +PNG_EXPORT(png_uint_32,png_get_pCAL,(png_structp png_ptr, png_infop info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, + png_charp *units, png_charpp *params),,147); #endif #ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(void,png_set_pCAL,(png_structp png_ptr, - png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, - int type, int nparams, png_charp units, png_charpp params),,148); +PNG_EXPORT(void,png_set_pCAL,(png_structp png_ptr, png_infop info_ptr, + png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params),,148); #endif #ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_pHYs,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type),,149); +PNG_EXPORT(png_uint_32,png_get_pHYs,(png_structp png_ptr, png_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type),,149); #endif #ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(void,png_set_pHYs,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, - int unit_type),,150); +PNG_EXPORT(void,png_set_pHYs,(png_structp png_ptr, png_infop info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type),,150); #endif -PNG_EXPORT(png_uint_32,png_get_PLTE,(png_structp png_ptr, - png_infop info_ptr, png_colorp *palette, int *num_palette),,151); +PNG_EXPORT(png_uint_32,png_get_PLTE,(png_structp png_ptr, png_infop info_ptr, + png_colorp *palette, int *num_palette),,151); -PNG_EXPORT(void,png_set_PLTE,(png_structp png_ptr, - png_infop info_ptr, png_colorp palette, int num_palette),,152); +PNG_EXPORT(void,png_set_PLTE,(png_structp png_ptr, png_infop info_ptr, + png_colorp palette, int num_palette),,152); #ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sBIT,(png_structp png_ptr, - png_infop info_ptr, png_color_8p *sig_bit),,153); +PNG_EXPORT(png_uint_32,png_get_sBIT,(png_structp png_ptr, png_infop info_ptr, + png_color_8p *sig_bit),,153); #endif #ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(void,png_set_sBIT,(png_structp png_ptr, - png_infop info_ptr, png_color_8p sig_bit),,154); +PNG_EXPORT(void,png_set_sBIT,(png_structp png_ptr, png_infop info_ptr, + png_color_8p sig_bit),,154); #endif #ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sRGB,(png_structp png_ptr, - png_infop info_ptr, int *intent),,155); +PNG_EXPORT(png_uint_32,png_get_sRGB,(png_structp png_ptr, png_infop info_ptr, + int *intent),,155); #endif #ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(void,png_set_sRGB,(png_structp png_ptr, - png_infop info_ptr, int intent),,156); +PNG_EXPORT(void,png_set_sRGB,(png_structp png_ptr, png_infop info_ptr, + int intent),,156); PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM,(png_structp png_ptr, png_infop info_ptr, int intent),,157); #endif #ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_iCCP,(png_structp png_ptr, - png_infop info_ptr, png_charpp name, int *compression_type, - png_charpp profile, png_uint_32 *proflen),,158); - /* Note to maintainer: profile should be png_bytepp */ +PNG_EXPORT(png_uint_32,png_get_iCCP,(png_structp png_ptr, png_infop info_ptr, + png_charpp name, int *compression_type, png_bytepp profile, + png_uint_32 *proflen),,158); #endif #ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(void,png_set_iCCP,(png_structp png_ptr, - png_infop info_ptr, png_charp name, int compression_type, - png_charp profile, png_uint_32 proflen),,159); - /* Note to maintainer: profile should be png_bytep */ +PNG_EXPORT(void,png_set_iCCP,(png_structp png_ptr, png_infop info_ptr, + png_charp name, int compression_type, png_bytep profile, + png_uint_32 proflen),,159); #endif #ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sPLT,(png_structp png_ptr, - png_infop info_ptr, png_sPLT_tpp entries),,160); +PNG_EXPORT(png_uint_32,png_get_sPLT,(png_structp png_ptr, png_infop info_ptr, + png_sPLT_tpp entries),,160); #endif #ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(void,png_set_sPLT,(png_structp png_ptr, - png_infop info_ptr, png_sPLT_tp entries, int nentries),,161); +PNG_EXPORT(void,png_set_sPLT,(png_structp png_ptr, png_infop info_ptr, + png_sPLT_tp entries, int nentries),,161); #endif #ifdef PNG_TEXT_SUPPORTED /* png_get_text also returns the number of text chunks in *num_text */ -PNG_EXPORT(png_uint_32,png_get_text,(png_structp png_ptr, - png_infop info_ptr, png_textp *text_ptr, int *num_text),,162); +PNG_EXPORT(png_uint_32,png_get_text,(png_structp png_ptr, png_infop info_ptr, + png_textp *text_ptr, int *num_text),,162); #endif /* Note while png_set_text() will accept a structure whose text, @@ -1792,55 +1788,47 @@ PNG_EXPORT(png_uint_32,png_get_text,(png_structp png_ptr, */ #ifdef PNG_TEXT_SUPPORTED -PNG_EXPORT(void,png_set_text,(png_structp png_ptr, - png_infop info_ptr, png_textp text_ptr, int num_text),,163); +PNG_EXPORT(void,png_set_text,(png_structp png_ptr, png_infop info_ptr, + png_textp text_ptr, int num_text),,163); #endif #ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_tIME,(png_structp png_ptr, - png_infop info_ptr, png_timep *mod_time),,164); +PNG_EXPORT(png_uint_32,png_get_tIME,(png_structp png_ptr, png_infop info_ptr, + png_timep *mod_time),,164); #endif #ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(void,png_set_tIME,(png_structp png_ptr, - png_infop info_ptr, png_timep mod_time),,165); +PNG_EXPORT(void,png_set_tIME,(png_structp png_ptr, png_infop info_ptr, + png_timep mod_time),,165); #endif #ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_tRNS,(png_structp png_ptr, - png_infop info_ptr, png_bytep *trans_alpha, int *num_trans, - png_color_16p *trans_color),,166); +PNG_EXPORT(png_uint_32,png_get_tRNS,(png_structp png_ptr, png_infop info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color),,166); #endif #ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(void,png_set_tRNS,(png_structp png_ptr, - png_infop info_ptr, png_bytep trans_alpha, int num_trans, - png_color_16p trans_color),,167); +PNG_EXPORT(void,png_set_tRNS,(png_structp png_ptr, png_infop info_ptr, + png_bytep trans_alpha, int num_trans, png_color_16p trans_color),,167); #endif #ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sCAL,(png_structp png_ptr, - png_infop info_ptr, int *unit, double *width, double *height),,168); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED +PNG_FP_EXPORT(png_uint_32,png_get_sCAL,(png_structp png_ptr, png_infop info_ptr, + int *unit, double *width, double *height),,168); +PNG_FIXED_EXPORT(png_uint_32,png_get_sCAL_fixed,(png_structp png_ptr, + png_infop info_ptr, int *unit, png_fixed_point *width, + png_fixed_point *height),,214); PNG_EXPORT(png_uint_32,png_get_sCAL_s,(png_structp png_ptr, - png_infop info_ptr, int *unit, png_charpp swidth, - png_charpp sheight),,169); -# endif -#endif /* PNG_sCAL_SUPPORTED */ + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight),,169); -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_sCAL,(png_structp png_ptr, - png_infop info_ptr, int unit, double width, double height),,170); -# endif -# ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(void,png_set_sCAL_s,(png_structp png_ptr, - png_infop info_ptr, int unit, png_charp swidth, - png_charp sheight),,171); -# endif -#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ +PNG_FP_EXPORT(void,png_set_sCAL,(png_structp png_ptr, png_infop info_ptr, + int unit, double width, double height),,170); +PNG_FIXED_EXPORT(void,png_set_sCAL_fixed,(png_structp png_ptr, + png_infop info_ptr, int unit, png_fixed_point width, + png_fixed_point height), ,213); +PNG_EXPORT(void,png_set_sCAL_s,(png_structp png_ptr, png_infop info_ptr, + int unit, png_charp swidth, png_charp sheight),,171); +#endif /* PNG_sCAL_SUPPORTED */ #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED /* Provide a list of chunks and how they are to be handled, if the built-in @@ -1852,18 +1840,16 @@ PNG_EXPORT(void,png_set_sCAL_s,(png_structp png_ptr, = 2: keep only if safe-to-copy = 3: keep even if unsafe-to-copy */ -PNG_EXPORT(void, png_set_keep_unknown_chunks,(png_structp png_ptr, - int keep, png_bytep chunk_list, int num_chunks),,172); +PNG_EXPORT(void, png_set_keep_unknown_chunks,(png_structp png_ptr, int keep, + png_bytep chunk_list, int num_chunks),,172); PNG_EXPORT(int,png_handle_as_unknown,(png_structp png_ptr, - png_bytep chunk_name),,173); + png_const_bytep chunk_name),,173); #endif #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED PNG_EXPORT(void, png_set_unknown_chunks,(png_structp png_ptr, - png_infop info_ptr, png_unknown_chunkp unknowns, - int num_unknowns),,174); -PNG_EXPORT(void, png_set_unknown_chunk_location, - (png_structp png_ptr, png_infop info_ptr, int chunk, - int location),,175); + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns),,174); +PNG_EXPORT(void, png_set_unknown_chunk_location, (png_structp png_ptr, + png_infop info_ptr, int chunk, int location),,175); PNG_EXPORT(png_uint_32,png_get_unknown_chunks,(png_structp png_ptr, png_infop info_ptr, png_unknown_chunkpp entries),,176); #endif @@ -1872,15 +1858,15 @@ PNG_EXPORT(png_uint_32,png_get_unknown_chunks,(png_structp png_ptr, * If you need to turn it off for a chunk that your application has freed, * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ -PNG_EXPORT(void, png_set_invalid,(png_structp png_ptr, - png_infop info_ptr, int mask),,177); +PNG_EXPORT(void, png_set_invalid,(png_structp png_ptr, png_infop info_ptr, + int mask),,177); #ifdef PNG_INFO_IMAGE_SUPPORTED /* The "params" pointer is currently not used and is for future expansion. */ -PNG_EXPORT(void, png_read_png,(png_structp png_ptr, - png_infop info_ptr, int transforms, png_voidp params),,178); -PNG_EXPORT(void, png_write_png,(png_structp png_ptr, - png_infop info_ptr, int transforms, png_voidp params),,179); +PNG_EXPORT(void, png_read_png,(png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params),,178); +PNG_EXPORT(void, png_write_png,(png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params),,179); #endif PNG_EXPORT(png_charp,png_get_copyright,(png_structp png_ptr),,180); @@ -1911,23 +1897,20 @@ PNG_EXPORT(void,png_set_strip_error_numbers,(png_structp png_ptr, #ifdef PNG_SET_USER_LIMITS_SUPPORTED PNG_EXPORT(void,png_set_user_limits,(png_structp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max),,186); -PNG_EXPORT(png_uint_32,png_get_user_width_max, - (png_structp png_ptr),,187); -PNG_EXPORT(png_uint_32,png_get_user_height_max, - (png_structp png_ptr),,188); +PNG_EXPORT(png_uint_32,png_get_user_width_max,(png_structp png_ptr),,187); +PNG_EXPORT(png_uint_32,png_get_user_height_max,(png_structp png_ptr),,188); /* Added in libpng-1.4.0 */ PNG_EXPORT(void,png_set_chunk_cache_max,(png_structp png_ptr, png_uint_32 user_chunk_cache_max),,189); -PNG_EXPORT(png_uint_32,png_get_chunk_cache_max, - (png_structp png_ptr),,190); +PNG_EXPORT(png_uint_32,png_get_chunk_cache_max,(png_structp png_ptr),,190); /* Added in libpng-1.4.1 */ PNG_EXPORT(void,png_set_chunk_malloc_max,(png_structp png_ptr, png_alloc_size_t user_chunk_cache_max),,191); -PNG_EXPORT(png_alloc_size_t,png_get_chunk_malloc_max, - (png_structp png_ptr),,192); +PNG_EXPORT(png_alloc_size_t,png_get_chunk_malloc_max,(png_structp png_ptr),, + 192); #endif -#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) PNG_EXPORT(png_uint_32,png_get_pixels_per_inch,(png_structp png_ptr, png_infop info_ptr),,193); @@ -1937,18 +1920,26 @@ PNG_EXPORT(png_uint_32,png_get_x_pixels_per_inch,(png_structp png_ptr, PNG_EXPORT(png_uint_32,png_get_y_pixels_per_inch,(png_structp png_ptr, png_infop info_ptr),,195); -PNG_EXPORT(float,png_get_x_offset_inches,(png_structp png_ptr, +PNG_FP_EXPORT(float,png_get_x_offset_inches,(png_structp png_ptr, png_infop info_ptr),,196); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(png_fixed_point,png_get_x_offset_inches_fixed, + (png_structp png_ptr, png_infop info_ptr),,211); +#endif -PNG_EXPORT(float,png_get_y_offset_inches,(png_structp png_ptr, +PNG_FP_EXPORT(float,png_get_y_offset_inches,(png_structp png_ptr, png_infop info_ptr),,197); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(png_fixed_point,png_get_y_offset_inches_fixed, + (png_structp png_ptr, png_infop info_ptr),,212); +#endif # ifdef PNG_pHYs_SUPPORTED PNG_EXPORT(png_uint_32,png_get_pHYs_dpi,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type),,198); + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type), + ,198); # endif /* PNG_pHYs_SUPPORTED */ -#endif /* PNG_INCH_CONVERSIONS_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ /* Added in libpng-1.4.0 */ #ifdef PNG_IO_STATE_SUPPORTED @@ -1968,10 +1959,6 @@ PNG_EXPORT(png_bytep,png_get_io_chunk_name,(png_structp png_ptr),,200); # define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ #endif /* ?PNG_IO_STATE_SUPPORTED */ -/* Maintainer: Put new public prototypes here ^, in libpng.3, and project - * defs - */ - #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* With these routines we avoid an integer divide, which will be slower on * most machines. However, it does take more operations than the corresponding @@ -2027,25 +2014,20 @@ PNG_EXPORT(png_bytep,png_get_io_chunk_name,(png_structp png_ptr),,200); # define png_get_uint_16(buf) \ (((png_uint_32)(*(buf)) << 8) + \ ((png_uint_32)(*((buf) + 1)))) -# ifdef PNG_GET_INT_32_SUPPORTED -# define png_get_int_32(buf) \ - (((png_int_32)(*(buf)) << 24) + \ - ((png_int_32)(*((buf) + 1)) << 16) + \ - ((png_int_32)(*((buf) + 2)) << 8) + \ - ((png_int_32)(*((buf) + 3)))) -# endif +# define png_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_get_uint_32(buf) ^ 0xffffffff)+1) \ + : png_get_uint_32(buf))) #endif #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED PNG_EXPORT(png_uint_32,png_get_uint_32,(png_bytep buf),,201); PNG_EXPORT(png_uint_16,png_get_uint_16,(png_bytep buf),,202); -#endif -#ifdef PNG_GET_INT_32_SUPPORTED PNG_EXPORT(png_int_32,png_get_int_32,(png_bytep buf),,203); #endif -PNG_EXPORT(png_uint_32,png_get_uint_31,(png_structp png_ptr, - png_bytep buf),,204); +PNG_EXPORT(png_uint_32,png_get_uint_31,(png_structp png_ptr, png_bytep buf),, + 204); /* No png_get_int_16 -- may be added if there's a real need for it. */ /* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ @@ -2065,11 +2047,15 @@ PNG_EXPORT(void,png_save_uint_16,(png_bytep buf, unsigned int i),,207); /* No png_save_int_16 -- may be added if there's a real need for it. */ #endif +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project + * defs + */ + /* The last ordinal number (this is the *last* one, the next one to * use is one more than this.) */ #ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(207); + PNG_EXPORT_LAST_ORDINAL(217); #endif #ifdef __cplusplus diff --git a/pngconf.h b/pngconf.h index b8fea48d1..744e6afb6 100644 --- a/pngconf.h +++ b/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.5.0beta36 - July 24, 2010 + * libpng version 1.5.0beta36 - July 29, 2010 * * Copyright (c) 1998-2010 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -22,14 +22,6 @@ #ifndef PNGCONF_H #define PNGCONF_H -/* Need the time information for converting tIME chunks, it - * defines struct tm: - */ -#ifdef PNG_CONVERT_tIME_SUPPORTED - /* "time.h" functions are not supported on WindowsCE */ -# include -#endif - /* PNG_NO_LIMITS_H may be used to turn off the use of the standard C * definition file for machine specific limits, this may impact the * correctness of the definitons below (see uses of INT_MAX). @@ -38,6 +30,23 @@ # include #endif +/* For the memory copy APIs (i.e. the standard definitions of these), + * because this file defines png_memcpy and so on the base APIs must + * be defined here. + */ +#ifdef BSD +# include +#else +# include +#endif + +/* For png_FILE_p - this provides the standard definition of a + * FILE + */ +#ifdef PNG_STDIO_SUPPORTED +# include +#endif + /* This controls optimization of the reading of 16 and 32 bit values * from PNG files. It can be set on a per-app-file basis - it * just changes whether a macro is used to the function is called. @@ -171,9 +180,20 @@ 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. + /* 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 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* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + # if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) # define PNGCAPI __cdecl # if PNG_API_RULE == 1 @@ -266,7 +286,7 @@ #endif #ifndef PNG_EXPORT # define PNG_EXPORT(type, name, args, attributes, ordinal)\ - PNG_EXPORT_TYPE(type) (PNGAPI name) PNGARG(args) attributes + extern PNG_EXPORT_TYPE(type) (PNGAPI name) PNGARG(args) attributes #endif /* Use PNG_REMOVED to comment out a removed interface. */ @@ -351,6 +371,22 @@ #ifndef PNG_PRIVATE # define PNG_PRIVATE /* This is a private libpng function */ #endif +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(type, name, args, attributes, ordinal)\ + PNG_EXPORT(type, name, args, attributes, ordinal) +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(type, name, args, attributes, ordinal) +# endif +#endif +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(type, name, args, attributes, ordinal)\ + PNG_EXPORT(type, name, args, attributes, ordinal) +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(type, name, args, attributes, ordinal) +# endif +#endif /* The following uses const char * instead of char * for error * and warning message functions, so some compilers won't complain. @@ -454,20 +490,22 @@ typedef size_t png_size_t; #endif /* Typedef for floating-point numbers that are converted - * to fixed-point with a multiple of 100,000, e.g., int_gamma + * to fixed-point with a multiple of 100,000, e.g., gamma */ typedef png_int_32 png_fixed_point; /* Add typedefs for pointers */ -typedef void FAR * png_voidp; -typedef png_byte FAR * png_bytep; -typedef png_uint_32 FAR * png_uint_32p; -typedef png_int_32 FAR * png_int_32p; -typedef png_uint_16 FAR * png_uint_16p; -typedef png_int_16 FAR * png_int_16p; -typedef PNG_CONST char FAR * png_const_charp; -typedef char FAR * png_charp; -typedef png_fixed_point FAR * png_fixed_point_p; +typedef void FAR * png_voidp; +typedef png_byte FAR * png_bytep; +typedef PNG_CONST png_byte FAR * png_const_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST char FAR * png_const_charp; +typedef char FAR * png_charp; +typedef png_fixed_point FAR * png_fixed_point_p; +typedef png_size_t FAR * png_size_tp; #ifdef PNG_STDIO_SUPPORTED typedef FILE * png_FILE_p; @@ -493,81 +531,6 @@ typedef double FAR * FAR * png_doublepp; /* Pointers to pointers to pointers; i.e., pointer to array */ typedef char FAR * FAR * FAR * png_charppp; -#define PNG_USE_LOCAL_ARRAYS /* Not used in libpng, defined for legacy apps */ - -/* 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 - -#ifdef USE_FAR_KEYWORD -/* Use this to make far-to-near assignments */ -# define CHECK 1 -# define NOCHECK 0 -# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) -# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) -# define png_strcpy _fstrcpy -# define png_strncpy _fstrncpy /* Added to v 1.2.6 */ -# define png_strlen _fstrlen -# define png_memcmp _fmemcmp /* SJT: added */ -# define png_memcpy _fmemcpy -# define png_memset _fmemset -# define png_sprintf sprintf -#else -# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ -# define CVT_PTR(ptr) (ptr) -# define CVT_PTR_NOCHECK(ptr) (ptr) -# define png_strcpy lstrcpyA -# define png_strncpy lstrcpynA -# define png_strlen lstrlenA -# define png_memcmp memcmp -# define png_memcpy CopyMemory -# define png_memset memset -# define png_sprintf wsprintfA -# else -# define CVT_PTR(ptr) (ptr) -# define CVT_PTR_NOCHECK(ptr) (ptr) -# define png_strcpy strcpy -# define png_strncpy strncpy /* Added to v 1.2.6 */ -# define png_strlen strlen -# define png_memcmp memcmp /* SJT: added */ -# define png_memcpy memcpy -# define png_memset memset -# define png_sprintf sprintf -# endif -#endif - -#ifndef PNG_NO_SNPRINTF -# ifdef _MSC_VER -# define png_snprintf _snprintf /* Added to v 1.2.19 */ -# define png_snprintf2 _snprintf -# define png_snprintf6 _snprintf -# else -# define png_snprintf snprintf /* Added to v 1.2.19 */ -# define png_snprintf2 snprintf -# define png_snprintf6 snprintf -# endif -#else - /* You don't have or don't want to use snprintf(). Caution: Using - * sprintf instead of snprintf exposes your application to accidental - * or malevolent buffer overflows. If you don't have snprintf() - * as a general rule you should provide one (you can get one from - * Portable OpenSSH). - */ -# define png_snprintf(s1,n,fmt,x1) png_sprintf(s1,fmt,x1) -# define png_snprintf2(s1,n,fmt,x1,x2) png_sprintf(s1,fmt,x1,x2) -# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ - png_sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) -#endif - /* png_alloc_size_t is guaranteed to be no smaller than png_size_t, * and no smaller than png_uint_32. Casts from png_size_t or png_uint_32 * to png_alloc_size_t are not necessary; in fact, it is recommended @@ -598,6 +561,5 @@ typedef char FAR * FAR * FAR * png_charppp; # endif # endif #endif -/* End of memory model/platform independent support */ #endif /* PNGCONF_H */ diff --git a/pngdebug.h b/pngdebug.h index e3f415da9..123113ee9 100644 --- a/pngdebug.h +++ b/pngdebug.h @@ -5,7 +5,7 @@ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * - * Last changed in libpng version 1.5.0 - July 24, 2010 + * Last changed in libpng version 1.5.0 - July 29, 2010 * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer diff --git a/pngerror.c b/pngerror.c index 635680eaa..7f1f7b195 100644 --- a/pngerror.c +++ b/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -237,6 +237,30 @@ png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) #endif #endif /* PNG_READ_SUPPORTED */ +#ifdef PNG_ERROR_TEXT_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +void +png_fixed_error(png_structp png_ptr, png_const_charp name, double value) +{ +# define fixed_message "fixed point overflow in " +# define fixed_message_ln ((sizeof fixed_message)-1) + int iin; + char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; + png_memcpy(msg, fixed_message, fixed_message_ln); + iin = 0; + if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) + { + msg[fixed_message_ln + iin] = name[iin]; + ++iin; + } + msg[fixed_message_ln + iin] = 0; + /* To discover 'value' put a breakpoint here: */ + png_error(png_ptr, msg); + value = value; png_ptr = png_ptr; /* Quiet the compiler */ +} +#endif +#endif + #ifdef PNG_SETJMP_SUPPORTED /* This API only exists if ANSI-C style error handling is used, * otherwise it is necessary for png_default_error to be overridden. diff --git a/pngget.c b/pngget.c index 1854988bb..31804f031 100644 --- a/pngget.c +++ b/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.4.1 [July 24, 2010] + * Last changed in libpng 1.4.1 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -254,7 +254,7 @@ png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_oFFs_SUPPORTED if (info_ptr->valid & PNG_INFO_oFFs) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); + png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) return (0); @@ -276,7 +276,7 @@ png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_oFFs_SUPPORTED if (info_ptr->valid & PNG_INFO_oFFs) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); + png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) return (0); @@ -290,42 +290,106 @@ png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) return (0); } -#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) && \ - defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_INCH_CONVERSIONS_SUPPORTED +static png_uint_32 +ppi_from_ppm(png_uint_32 ppm) +{ +#if 0 + /* The convertion is *(2.54/100), in binary (32 digits): + * .00000110100000001001110101001001 + */ + png_uint_32 t1001, t1101; + ppm >>= 1; /* .1 */ + t1001 = ppm + (ppm >> 3); /* .1001 */ + t1101 = t1001 + (ppm >> 1); /* .1101 */ + ppm >>= 20; /* .000000000000000000001 */ + t1101 += t1101 >> 15; /* .1101000000000001101 */ + t1001 >>= 11; /* .000000000001001 */ + t1001 += t1001 >> 12; /* .000000000001001000000001001 */ + ppm += t1001; /* .000000000001001000001001001 */ + ppm += t1101; /* .110100000001001110101001001 */ + return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ +#else + /* The argument is a PNG unsigned integer, so it is not permitted + * to be bigger than 2^31. + */ + png_fixed_point result; + if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, ppm, 127, 5000)) + return result; + + /* Overflow. */ + return 0; +#endif +} + png_uint_32 PNGAPI png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { - return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr) - *.0254 +.5)); + return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); } png_uint_32 PNGAPI png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { - return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr) - *.0254 +.5)); + return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); } png_uint_32 PNGAPI png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { - return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr) - *.0254 +.5)); + return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); } +#ifdef PNG_FIXED_POINT_SUPPORTED +static png_fixed_point +png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns) +{ + /* Convert from metres * 1,000,000 to inches * 100,000, meters to + * inches is simply *(100/2.54), so we want *(10/2.54) == 1000/254. + * Notice that this can overflow - a warning is output and 0 is + * returned. + */ + return png_muldiv_warn(png_ptr, microns, 500, 127); +} + +png_fixed_point PNGAPI +png_get_x_offset_inches_fixed(png_structp png_ptr, png_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_x_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_y_offset_inches_fixed(png_structp png_ptr, png_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_y_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED float PNGAPI png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr) { - return ((float)png_get_x_offset_microns(png_ptr, info_ptr) - *.00003937); + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return png_get_x_offset_microns(png_ptr, info_ptr) * .00003937f; } +#endif +#ifdef PNG_FLOATING_POINT_SUPPORTED float PNGAPI png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr) { - return ((float)png_get_y_offset_microns(png_ptr, info_ptr) - *.00003937); + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return png_get_y_offset_microns(png_ptr, info_ptr) * .00003937f; } +#endif #ifdef PNG_pHYs_SUPPORTED png_uint_32 PNGAPI @@ -364,7 +428,7 @@ png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, return (retval); } #endif /* PNG_pHYs_SUPPORTED */ -#endif /* PNG_INCH_CONVERSIONS_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ /* png_get_channels really belongs in here, too, but it's been around longer */ @@ -419,26 +483,27 @@ png_get_cHRM(png_structp png_ptr, png_infop info_ptr, png_debug1(1, "in %s retrieval function", "cHRM"); if (white_x != NULL) - *white_x = (double)info_ptr->x_white; + *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X"); if (white_y != NULL) - *white_y = (double)info_ptr->y_white; + *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y"); if (red_x != NULL) - *red_x = (double)info_ptr->x_red; + *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X"); if (red_y != NULL) - *red_y = (double)info_ptr->y_red; + *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y"); if (green_x != NULL) - *green_x = (double)info_ptr->x_green; + *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X"); if (green_y != NULL) - *green_y = (double)info_ptr->y_green; + *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y"); if (blue_x != NULL) - *blue_x = (double)info_ptr->x_blue; + *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X"); if (blue_y != NULL) - *blue_y = (double)info_ptr->y_blue; + *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y"); return (PNG_INFO_cHRM); } return (0); } #endif + #ifdef PNG_FIXED_POINT_SUPPORTED png_uint_32 PNGAPI png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, @@ -451,21 +516,21 @@ png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) { if (white_x != NULL) - *white_x = info_ptr->int_x_white; + *white_x = info_ptr->x_white; if (white_y != NULL) - *white_y = info_ptr->int_y_white; + *white_y = info_ptr->y_white; if (red_x != NULL) - *red_x = info_ptr->int_x_red; + *red_x = info_ptr->x_red; if (red_y != NULL) - *red_y = info_ptr->int_y_red; + *red_y = info_ptr->y_red; if (green_x != NULL) - *green_x = info_ptr->int_x_green; + *green_x = info_ptr->x_green; if (green_y != NULL) - *green_y = info_ptr->int_y_green; + *green_y = info_ptr->y_green; if (blue_x != NULL) - *blue_x = info_ptr->int_x_blue; + *blue_x = info_ptr->x_blue; if (blue_y != NULL) - *blue_y = info_ptr->int_y_blue; + *blue_y = info_ptr->y_blue; return (PNG_INFO_cHRM); } return (0); @@ -474,36 +539,30 @@ png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, #endif #ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma) +png_uint_32 PNGFAPI +png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point *file_gamma) { png_debug1(1, "in %s retrieval function", "gAMA"); if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) && file_gamma != NULL) { - *file_gamma = (double)info_ptr->gamma; + *file_gamma = info_ptr->gamma; return (PNG_INFO_gAMA); } + return (0); } -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI -png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, - png_fixed_point *int_file_gamma) +png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma) { - png_debug1(1, "in %s retrieval function", "gAMA"); - - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) - && int_file_gamma != NULL) - { - *int_file_gamma = info_ptr->int_gamma; - return (PNG_INFO_gAMA); - } - - return (0); + png_fixed_point igamma; + png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma); + if (ok) + *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA"); + return ok; } #endif #endif @@ -529,7 +588,7 @@ png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) png_uint_32 PNGAPI png_get_iCCP(png_structp png_ptr, png_infop info_ptr, png_charpp name, int *compression_type, - png_charpp profile, png_uint_32 *proflen) + png_bytepp profile, png_uint_32 *proflen) { png_debug1(1, "in %s retrieval function", "iCCP"); @@ -668,6 +727,25 @@ png_get_pCAL(png_structp png_ptr, png_infop info_ptr, #endif #ifdef PNG_sCAL_SUPPORTED +#ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, + int *unit, png_fixed_point *width, png_fixed_point *height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + /*TODO: make this work */ + *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); + *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), + "sCAL height"); + return (PNG_INFO_sCAL); + } + + return(0); +} +#endif #ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_sCAL(png_structp png_ptr, png_infop info_ptr, @@ -677,15 +755,14 @@ png_get_sCAL(png_structp png_ptr, png_infop info_ptr, (info_ptr->valid & PNG_INFO_sCAL)) { *unit = info_ptr->scal_unit; - *width = info_ptr->scal_pixel_width; - *height = info_ptr->scal_pixel_height; + *width = atof(info_ptr->scal_s_width); + *height = atof(info_ptr->scal_s_height); return (PNG_INFO_sCAL); } return(0); } #endif -#ifdef PNG_FIXED_POINT_SUPPORTED png_uint_32 PNGAPI png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr, int *unit, png_charpp width, png_charpp height) @@ -702,7 +779,6 @@ png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr, return(0); } #endif -#endif #ifdef PNG_pHYs_SUPPORTED png_uint_32 PNGAPI diff --git a/pnginfo.h b/pnginfo.h index a5d02f456..d929edeb5 100644 --- a/pnginfo.h +++ b/pnginfo.h @@ -5,7 +5,7 @@ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * - * Last changed in libpng version 1.5.0 - July 24, 2010 + * Last changed in libpng version 1.5.0 - July 29, 2010 * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -82,12 +82,12 @@ struct png_info_def * and initialize the appropriate fields below. */ -#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +#if defined(PNG_gAMA_SUPPORTED) /* The gAMA chunk describes the gamma characteristics of the system * on which the image was created, normally in the range [1.0, 2.5]. * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. */ - float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */ + png_fixed_point gamma; #endif #ifdef PNG_sRGB_SUPPORTED @@ -191,16 +191,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) * colors in the image as the creator. Values are in the range * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - float x_white; - float y_white; - float x_red; - float y_red; - float x_green; - float y_green; - float x_blue; - float y_blue; -#endif + png_fixed_point x_white; + png_fixed_point y_white; + png_fixed_point x_red; + png_fixed_point y_red; + png_fixed_point x_green; + png_fixed_point y_green; + png_fixed_point x_blue; + png_fixed_point y_blue; #endif #ifdef PNG_pCAL_SUPPORTED @@ -237,8 +235,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) #ifdef PNG_iCCP_SUPPORTED /* iCCP chunk data. */ png_charp iccp_name; /* profile name */ - png_charp iccp_profile; /* International Color Consortium profile data */ - /* Note to maintainer: should be png_bytep */ + png_bytep iccp_profile; /* International Color Consortium profile data */ png_uint_32 iccp_proflen; /* ICC profile data length */ png_byte iccp_compression; /* Always zero */ #endif @@ -254,19 +251,13 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) * subject matter of the graphic. The chunk contains a unit specification * a byte value, and two ASCII strings representing floating-point * values. The values are width and height corresponsing to one pixel - * in the image. This external representation is converted to double - * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero. + * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is + * non-zero. */ png_byte scal_unit; /* unit of physical scale */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - double scal_pixel_width; /* width of one pixel */ - double scal_pixel_height; /* height of one pixel */ -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED png_charp scal_s_width; /* string containing height */ png_charp scal_s_height; /* string containing width */ #endif -#endif #ifdef PNG_INFO_IMAGE_SUPPORTED /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) @@ -275,20 +266,5 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytepp row_pointers; /* the image bits */ #endif -#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED) - png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */ -#endif - -#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED) - png_fixed_point int_x_white; - png_fixed_point int_y_white; - png_fixed_point int_x_red; - png_fixed_point int_y_red; - png_fixed_point int_x_green; - png_fixed_point int_y_green; - png_fixed_point int_x_blue; - png_fixed_point int_y_blue; -#endif - }; #endif /* PNGINFO_H */ diff --git a/pngmem.c b/pngmem.c index 94a573a93..dde1d349e 100644 --- a/pngmem.c +++ b/pngmem.c @@ -1,7 +1,7 @@ /* pngmem.c - stub functions for memory allocation * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) diff --git a/pngpread.c b/pngpread.c index 63eac4cb9..936b2f1e7 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,7 +1,7 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) diff --git a/pngpriv.h b/pngpriv.h index a00f2c13a..68f031b26 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -1,7 +1,7 @@ /* pngpriv.h - private declarations for use inside libpng * - * libpng version 1.5.0beta36 - July 24, 2010 + * libpng version 1.5.0beta36 - July 29, 2010 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2010 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -32,12 +32,10 @@ #include "pnginfo.h" #include "pngstruct.h" +/* This is required for the definition of abort(), used as a last ditch + * error handler when all else fails. + */ #include -#ifdef BSD -# include -#else -# include -#endif /* Added at libpng-1.2.9 */ /* Moved to pngpriv.h at libpng-1.5.0 */ @@ -53,6 +51,9 @@ #endif /* Moved to pngpriv.h at libpng-1.5.0 */ +/* NOTE: some of these may be used in external applications as these definitions + * were exposed in pngconf.h prior to 1.5. + */ /* If you are running on a machine where you cannot allocate more * than 64K of memory at once, uncomment this. While libpng will not * normally need that much memory in a chunk (unless you load up a very @@ -68,16 +69,12 @@ # define PNG_MAX_MALLOC_64K #endif -/* Moved to pngpriv.h at libpng-1.5.0 */ -/* Feature support: in 1.4 this was in pngconf.h, but these - * features have no affect on the libpng API. Add library - * only features to the end of this list. Add features that - * affect the API to scipts/config.dfn using png_on or png_off - * as determined by the default and update scripts/config.std +/* Just a little check that someone hasn't tried to define something + * contradictory. */ -/* Added at libpng version 1.4.0 */ -#if !defined(PNG_NO_WARNINGS) && !defined(PNG_WARNINGS_SUPPORTED) -# define PNG_WARNINGS_SUPPORTED +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L #endif /* If warnings or errors are turned off the code is disabled @@ -90,57 +87,7 @@ #ifndef PNG_ERROR_TEXT_SUPPORTED # define png_error(s1,s2) png_err(s1) # define png_chunk_error(s1,s2) png_err(s1) -#endif - -/* Added at libpng version 1.4.0 */ -#if !defined(PNG_NO_CHECK_cHRM) && !defined(PNG_CHECK_cHRM_SUPPORTED) -# define PNG_CHECK_cHRM_SUPPORTED -#endif - -/* Added at libpng version 1.4.0 */ -#if !defined(PNG_NO_ALIGNED_MEMORY) && !defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_ALIGNED_MEMORY_SUPPORTED -#endif - -/* Buggy compilers (e.g., gcc 2.7.2.2) need PNG_NO_POINTER_INDEXING - * See png[wr]util.c - */ -#if !defined(PNG_NO_POINTER_INDEXING) && \ - !defined(PNG_POINTER_INDEXING_SUPPORTED) -# define PNG_POINTER_INDEXING_SUPPORTED -#endif - -/* Other defines for things like memory and the like can go here. */ - -/* This controls how fine the quantizing gets. As this allocates - * a largish chunk of memory (32K), those who are not as concerned - * with quantizing quality can decrease some or all of these. - */ -#ifndef PNG_QUANTIZE_RED_BITS -# define PNG_QUANTIZE_RED_BITS 5 -#endif -#ifndef PNG_QUANTIZE_GREEN_BITS -# define PNG_QUANTIZE_GREEN_BITS 5 -#endif -#ifndef PNG_QUANTIZE_BLUE_BITS -# define PNG_QUANTIZE_BLUE_BITS 5 -#endif - -/* This controls how fine the gamma correction becomes when you - * are only interested in 8 bits anyway. Increasing this value - * results in more memory being used, and more pow() functions - * being called to fill in the gamma tables. Don't set this value - * less then 8, and even that may not work (I haven't tested it). - */ -#ifndef PNG_MAX_GAMMA_8 -# define PNG_MAX_GAMMA_8 11 -#endif - -/* This controls how much a difference in gamma we can tolerate before - * we actually start doing gamma conversion. - */ -#ifndef PNG_GAMMA_THRESHOLD -# define PNG_GAMMA_THRESHOLD 0.05 +# define png_fixed_error(s1,s2,s3) png_err(s1) #endif #ifndef PNG_EXTERN @@ -154,11 +101,30 @@ # define PNG_EXTERN #endif +/* Some fixed point APIs are still required even if not exported because + * they get used by the corresponding floating point APIs. This magic + * deals with this: + */ +#ifdef PNG_FIXED_POINT_SUPPORTED +# define PNGFAPI PNGAPI +#else +# define PNGFAPI /* PRIVATE */ +#endif + /* 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) + /* pngarith.c requires the following ANSI-C constants if the convertion of + * floating point to ASCII is implemented therein: + * + * DBL_DIG Maximum number of decimal digits (can be set to any constant) + * DBL_MIN Smalles normalized fp number (can be set to an arbitrary value) + * DBL_MAX Maximum floating point number (can be set to an arbitrary value) + */ +# include -#ifdef PNG_FLOATING_POINT_SUPPORTED # 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 @@ -194,31 +160,85 @@ # endif #endif -/* This is the size of the compression buffer, and thus the size of - * an IDAT chunk. Make this whatever size you feel is best for your - * machine. One of these will be allocated per png_struct. When this - * is full, it writes the data to the disk, and does some other - * calculations. Making this an extremely small size will slow - * the library down, but you may want to experiment to determine - * where it becomes significant, if you are concerned with memory - * usage. Note that zlib allocates at least 32Kb also. For readers, - * this describes the size of the buffer available to read the data in. - * Unless this gets smaller than the size of a row (compressed), - * it should not make much difference how big this is. +/* 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. */ -#ifndef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 8192 +/* Memory model/platform independent fns */ +#ifndef PNG_ABORT +# ifdef _WINDOWS_ +# define PNG_ABORT() ExitProcess(0) +# else +# define PNG_ABORT() abort() +# endif #endif -/* Just a little check that someone hasn't tried to define something - * contradictory. +#ifdef USE_FAR_KEYWORD +/* Use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_strcpy _fstrcpy +# define png_strncpy _fstrncpy /* Added to v 1.2.6 */ +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +# define png_sprintf sprintf +#else +# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strcpy lstrcpyA +# define png_strncpy lstrcpynA +# define png_strlen lstrlenA +# define png_memcmp memcmp +# define png_memcpy CopyMemory +# define png_memset memset +# define png_sprintf wsprintfA +# else +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strcpy strcpy +# define png_strncpy strncpy /* Added to v 1.2.6 */ +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +# define png_sprintf sprintf +# endif +#endif +/* End of memory model/platform independent support */ + +#ifndef PNG_NO_SNPRINTF +# ifdef _MSC_VER +# define png_snprintf _snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 _snprintf +# define png_snprintf6 _snprintf +# else +# define png_snprintf snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 snprintf +# define png_snprintf6 snprintf +# endif +#else + /* You don't have or don't want to use snprintf(). Caution: Using + * sprintf instead of snprintf exposes your application to accidental + * or malevolent buffer overflows. If you don't have snprintf() + * as a general rule you should provide one (you can get one from + * Portable OpenSSH). + */ +# define png_snprintf(s1,n,fmt,x1) png_sprintf(s1,fmt,x1) +# define png_snprintf2(s1,n,fmt,x1,x2) png_sprintf(s1,fmt,x1,x2) +# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ + png_sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) +#endif +/* End of 1.5.0beta36 move from pngconf.h */ + +/* CONSTANTS and UTILITY MACROS + * These are used internally by libpng and not exposed in the API */ -#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) -# undef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 65536L -#endif - /* Various modes of operation. Note that after an init, mode is set to * zero automatically when the structure is created. */ @@ -276,9 +296,7 @@ #define PNG_STRUCT_INFO 0x0002 /* Scaling factor for filter heuristic weighting calculations */ -#define PNG_WEIGHT_SHIFT 8 #define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) -#define PNG_COST_SHIFT 3 #define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) /* Flags for the png_ptr->flags rather than declaring a byte for each one */ @@ -343,6 +361,44 @@ #define PNG_OUT_OF_RANGE(value, ideal, delta) \ ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) +/* Convertions between fixed and floating point, only defined if + * required (to make sure the code doesn't accidentally use float + * when it is supposedly disabled.) + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* The floating point convertion can't overflow, though it can and + * does lose accuracy relative to the original fixed point value. + * In practice this doesn't matter because png_fixed_point only + * stores numbers with very low precision. The png_ptr and s + * arguments are unused by default but are there in case error + * checking becomes a requirement. + */ +#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) + +/* The fixed point convertion performs range checking and evaluates + * its argument multiple times, so must be used with care. The + * range checking uses the PNG specification values for a signed + * 32 bit fixed point value except that the values are deliberately + * rounded-to-zero to an integral value - 21474. 's' is a string + * that describes the value being converted. + * + * NOTE: this macro will raise a png_error if the range check fails, + * therefore it is normally only appropriate to use this on values + * that come from API calls or other sources where an out of range + * error indicates a programming error, not a data error! + * + * NOTE: by default this is off - the macro is not used - because the + * function call saves a lot of code. + */ +#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED +#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ + ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s, fp),0)) +#else +PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, + png_const_charp text)); +#endif +#endif + /* Constant strings for known chunk types. If you need to add a chunk, * define the name here, and add an invocation of the macro wherever it's * needed. @@ -404,8 +460,8 @@ PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); /* Next four functions are used internally as callbacks. PNGCBAPI is required - * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to PNGCBAPI - * at 1.5.0 + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to + * PNGCBAPI at 1.5.0 */ PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr, @@ -597,15 +653,8 @@ PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, #endif #ifdef PNG_WRITE_sCAL_SUPPORTED -# if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, - int unit, double width, double height)); -# else -# ifdef PNG_FIXED_POINT_SUPPORTED PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, int unit, png_charp width, png_charp height)); -# endif -# endif #endif /* Called when finished processing a row of data */ @@ -945,7 +994,7 @@ PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, #endif /* Added at libpng version 1.4.0 */ -#ifdef PNG_cHRM_SUPPORTED +#ifdef PNG_CHECK_cHRM_SUPPORTED PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point @@ -953,12 +1002,11 @@ PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, png_fixed_point int_blue_y)); #endif -#ifdef PNG_cHRM_SUPPORTED -# ifdef PNG_CHECK_cHRM_SUPPORTED +#ifdef PNG_CHECK_cHRM_SUPPORTED /* Added at libpng version 1.2.34 and 1.4.0 */ +/* Currently only used by png_check_cHRM_fixed */ PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, unsigned long *hi_product, unsigned long *lo_product)); -# endif #endif /* Added at libpng version 1.4.0 */ @@ -968,21 +1016,165 @@ PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, int filter_type)); /* Free all memory used by the read (old method - NOT DLL EXPORTED) */ -PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, - png_infop end_info_ptr)); +PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr, png_infop end_info_ptr)); /* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr)); #ifdef USE_FAR_KEYWORD /* memory model conversion function */ -PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, +PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr, int check)); #endif /* USE_FAR_KEYWORD */ -#include "pngdebug.h" +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_EXTERN void png_fixed_error PNGARG((png_structp png_ptr, + png_const_charp name, double value)); +#endif + +/* ASCII to FP interfaces, currently only implemented if sCAL + * support is required. + */ +#if defined(PNG_READ_sCAL_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +/* MAX_DIGITS is actually the maximum number of characters in an sCAL + * width or height, derived from the precision (number of significant + * digits - a build time settable option) and assumpitions about the + * maximum ridiculous exponent. + */ +#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) +PNG_EXTERN void png_ascii_from_fp(png_structp png_ptr, png_charp ascii, + png_size_t size, double fp, unsigned precision); +#endif /* READ_sCAL && FLOATING_POINT */ + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* An internal API to validate the format of a floating point number. + * The result is the index of the next character. If the number is + * not valid it will be the index of a character in the supposed number. + * + * The format of a number is defined in the PNG extensions specification + * and this API is strictly conformant to that spec, not anyone elses! + * + * The format as a regular expression is: + * + * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? + * + * or: + * + * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? + * + * The complexity is that either integer or fraction must be present and the + * fraction is permitted to have no digits only if the integer is present. + * + * NOTE: The dangling E problem. + * There is a PNG valid floating point number in the following: + * + * PNG floating point numb1.ers are not greedy. + * + * Working this out requires *TWO* character lookahead (because of the + * sign), the parser does not do this - it will fail at the 'r' - this + * doesn't matter for PNG sCAL chunk values, but it requires more care + * if the value were ever to be embedded in something more complex. Use + * ANSI-C strtod if you need the lookahead. + */ +/* State table for the parser. */ +#define PNG_FP_INTEGER 0 /* before or in integer */ +#define PNG_FP_FRACTION 1 /* before or in fraction */ +#define PNG_FP_EXPONENT 2 /* before or in exponent */ +#define PNG_FP_STATE 3 /* mask for the above */ +#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ +#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ +#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ +#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ +#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ +#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ +#define PNG_FP_INVALID 128 /* Available for callers as a distinct value */ + +/* Result codes for the parser (boolean - true meants ok, false means + * not ok yet.) + */ +#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ +#define PNG_FP_OK 1 /* The number is valid */ + +/* The actual parser. This can be called repeatedly, it updates + * the index into the string and the state variable (which must + * be initialzed to 0). It returns a result code, as above. There + * is no point calling the parser any more if it fails to advance to + * the end of the string - it is stuck on an invalid character (or + * terminated by '\0'). + * + * Note that the pointer will consume an E or even an E+ then leave + * a 'maybe' state even though a preceding integer.fraction is valid. + * The PNG_FP_WAS_VALID flag indicates that a preceding substring was + * a valid number. It's possible to recover from this by calling + * the parser again (from the start, with state 0) but with a string + * that omits the last character (i.e. set the size to the index of + * the problem character.) This has not been tested within libpng. + */ +PNG_EXTERN int png_check_fp_number(png_charp string, png_size_t size, + int *statep, png_size_tp whereami); + +/* This is the same but it checks a complete string and returns true + * only if it just contains a floating point number. + */ +PNG_EXTERN int png_check_fp_string(png_charp string, png_size_t size); +#endif /* pCAL || sCAL */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* Added at libpng version 1.5.0 */ +/* This is a utility to provide a*times/div (rounded) and indicate + * if there is an overflow. The result is a boolean - false (0) + * for overflow, true (1) if no overflow, in which case *res + * holds the result. + */ +PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a, + png_int_32 times, png_int_32 div)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* Same deal, but issue a warning on overflow and return 0. */ +PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr, + png_fixed_point a, png_int_32 times, png_int_32 div)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Calculate a reciprocal - used for gamma values. This returns + * 0 if the argument is 0 in order to maintain an undefined value, + * there are no warnings. + */ +PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a)); + +/* The same but gives a reciprocal of the product of two fixed point + * values. Accuracy is suitable for gamma calculations but this is + * not exact - use png_muldiv for that. + */ +PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a, + png_fixed_point b)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Internal fixed point gamma correction. These APIs are called as + * required to convert single values - they don't need to be fast, + * they are not used when processing image pixel values. + * + * While the input is an 'unsigned' value it must actually be the + * correct bit value - 0..255 or 0..65535 as required. + */ +PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr, + unsigned value, png_fixed_point gamma)); +PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma)); +PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned value, + png_fixed_point gamma)); +PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned value, + png_fixed_point gamma)); +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, + png_byte bit_depth)); +#endif /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#include "pngdebug.h" + #ifdef __cplusplus } #endif diff --git a/pngread.c b/pngread.c index 6fbd687fe..2e18f4fcb 100644 --- a/pngread.c +++ b/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -500,6 +500,10 @@ png_start_read_image(png_structp png_ptr) if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); + else + png_warning(png_ptr, + "Ignoring extra png_start_read_image() call;" + " row buffer not reallocated"); } #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ @@ -852,7 +856,31 @@ png_read_image(png_structp png_ptr, png_bytepp image) return; #ifdef PNG_READ_INTERLACING_SUPPORTED - pass = png_set_interlace_handling(png_ptr); + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + { + pass = png_set_interlace_handling(png_ptr); + /* And make sure transforms are initialized. */ + png_start_read_image(png_ptr); + } + else + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + /* Caller called png_start_read_image or png_read_update_info without + * first turning on the PNG_INTERLACE transform. We can fix this here, + * but the caller should do it! + */ + png_warning(png_ptr, "Interlace handling should be turned on when " + "using png_read_image"); + /* Make sure this is set correctly */ + png_ptr->num_rows = png_ptr->height; + } + + /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in + * the above error case. + */ + pass = png_set_interlace_handling(png_ptr); + } #else if (png_ptr->interlaced) png_error(png_ptr, @@ -861,9 +889,7 @@ png_read_image(png_structp png_ptr, png_bytepp image) pass = 1; #endif - image_height=png_ptr->height; - png_ptr->num_rows = image_height; /* Make sure this is set correctly */ for (j = 0; j < pass; j++) { diff --git a/pngrio.c b/pngrio.c index d14e1887a..d3f6ec7ac 100644 --- a/pngrio.c +++ b/pngrio.c @@ -1,7 +1,7 @@ /* pngrio.c - functions for data input * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) diff --git a/pngrtran.c b/pngrtran.c index 061713d00..f9b506e94 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -88,15 +88,14 @@ png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) } } -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_READ_BACKGROUND_SUPPORTED /* Handle alpha and tRNS via a background color */ -void PNGAPI -png_set_background(png_structp png_ptr, +void PNGFAPI +png_set_background_fixed(png_structp png_ptr, png_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma) + int need_expand, png_fixed_point background_gamma) { - png_debug(1, "in png_set_background"); + png_debug(1, "in png_set_background_fixed"); if (png_ptr == NULL) return; @@ -110,11 +109,22 @@ png_set_background(png_structp png_ptr, png_ptr->transformations |= PNG_BACKGROUND; png_memcpy(&(png_ptr->background), background_color, png_sizeof(png_color_16)); - png_ptr->background_gamma = (float)background_gamma; + png_ptr->background_gamma = background_gamma; png_ptr->background_gamma_type = (png_byte)(background_gamma_code); png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); } -#endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_background(png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) +{ + png_set_background_fixed(png_ptr, background_color, background_gamma_code, + need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); +} +# endif /* FLOATING_POINT */ +#endif /* READ_BACKGROUND */ #ifdef PNG_READ_16_TO_8_SUPPORTED /* Strip 16 bit depth files to 8 bit depth */ @@ -549,7 +559,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, } #endif /* PNG_READ_QUANTIZE_SUPPORTED */ -#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED /* Transform the image from the file_gamma to the screen_gamma. We * only do transformations on images where the file_gamma and screen_gamma * are not close reciprocals, otherwise it slows things down slightly, and @@ -559,22 +569,48 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, * are present in the tRNS array for palette images. We can't do it here * because we don't necessarily have the tRNS chunk yet. */ -void PNGAPI -png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +static int /* PRIVATE */ +png_gamma_threshold(png_fixed_point scrn_gamma, png_fixed_point file_gamma) { - png_debug(1, "in png_set_gamma"); + /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma + * correction as a difference of the overall transform from 1.0 + * + * We want to compare the threshold with s*f - 1, if we get + * overflow here it is because of wacky gamma values so we + * turn on processing anyway. + */ + png_fixed_point gtest; + return !png_muldiv(>est, scrn_gamma, file_gamma, PNG_FP_1) || + png_gamma_significant(gtest); +} + +void PNGFAPI +png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, + png_fixed_point file_gamma) +{ + png_debug(1, "in png_set_gamma_fixed"); if (png_ptr == NULL) return; - if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || + png_gamma_threshold(scrn_gamma, file_gamma)) png_ptr->transformations |= PNG_GAMMA; - png_ptr->gamma = (float)file_gamma; - png_ptr->screen_gamma = (float)scrn_gamma; + png_ptr->gamma = file_gamma; + png_ptr->screen_gamma = scrn_gamma; } -#endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +{ + png_set_gamma_fixed(png_ptr, + png_fixed(png_ptr, scrn_gamma, "png_set_gamma screen gamma"), + png_fixed(png_ptr, file_gamma, "png_set_gamma file gamma")); +} +# endif /* FLOATING_POINT_SUPPORTED */ +#endif /* READ_GAMMA */ #ifdef PNG_READ_EXPAND_SUPPORTED /* Expand paletted images to RGB, expand grayscale images of @@ -662,12 +698,7 @@ png_set_gray_to_rgb(png_structp png_ptr) #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -void -#ifdef PNG_FIXED_POINT_SUPPORTED - PNGAPI -#else - /* PRIVATE */ -#endif +void PNGFAPI png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, png_fixed_point red, png_fixed_point green) { @@ -735,15 +766,14 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, void PNGAPI png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, - double green) + double green) { - int red_fixed = (int)((float)red*100000.0 + 0.5); - int green_fixed = (int)((float)green*100000.0 + 0.5); - if (png_ptr == NULL) return; - png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); + png_set_rgb_to_gray_fixed(png_ptr, error_action, + png_fixed(png_ptr, red, "rgb to gray red coefficient"), + png_fixed(png_ptr, green, "rgb to gray green coefficient")); } #endif /* FLOATING POINT */ @@ -886,7 +916,8 @@ png_init_read_transformations(png_structp png_ptr) int i, istop; istop=(int)png_ptr->num_trans; for (i=0; itrans_alpha[i] = (png_byte)(255 - png_ptr->trans_alpha[i]); + png_ptr->trans_alpha[i] = (png_byte)(255 - + png_ptr->trans_alpha[i]); } } #endif @@ -898,11 +929,10 @@ png_init_read_transformations(png_structp png_ptr) #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) png_ptr->background_1 = png_ptr->background; #endif -#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) - && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) - < PNG_GAMMA_THRESHOLD)) + && png_gamma_threshold(png_ptr->screen_gamma, png_ptr->gamma)) { int i, k; k=0; @@ -916,7 +946,7 @@ png_init_read_transformations(png_structp png_ptr) } if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && - png_ptr->gamma != 0.0) + png_ptr->gamma != 0) { png_build_gamma_table(png_ptr, png_ptr->bit_depth); @@ -932,6 +962,7 @@ png_init_read_transformations(png_structp png_ptr) 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]; @@ -942,31 +973,33 @@ png_init_read_transformations(png_structp png_ptr) } else { - double g, gs; + png_fixed_point g, gs; switch (png_ptr->background_gamma_type) { case PNG_BACKGROUND_GAMMA_SCREEN: g = (png_ptr->screen_gamma); - gs = 1.0; + gs = PNG_FP_1; break; case PNG_BACKGROUND_GAMMA_FILE: - g = 1.0 / (png_ptr->gamma); - gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: - g = 1.0 / (png_ptr->background_gamma); - gs = 1.0 / (png_ptr->background_gamma * - png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); break; default: - g = 1.0; /* back_1 */ - gs = 1.0; /* back */ + g = PNG_FP_1; /* back_1 */ + gs = PNG_FP_1; /* back */ + break; } - if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD) + if ( png_gamma_significant(gs) ) { back.red = (png_byte)png_ptr->background.red; back.green = (png_byte)png_ptr->background.green; @@ -975,24 +1008,18 @@ png_init_read_transformations(png_structp png_ptr) else { - back.red = (png_byte)(pow( - (double)png_ptr->background.red/255.0, gs) * 255.0 + .5); - back.green = (png_byte)(pow( - (double)png_ptr->background.green/255.0, gs) * 255.0 - + .5); - back.blue = (png_byte)(pow( - (double)png_ptr->background.blue/255.0, gs) * 255.0 - + .5); + 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); } - - back_1.red = (png_byte)(pow( - (double)png_ptr->background.red/255.0, g) * 255.0 + .5); - - back_1.green = (png_byte)(pow( - (double)png_ptr->background.green/255.0, g) * 255.0 + .5); - - back_1.blue = (png_byte)(pow( - (double)png_ptr->background.blue/255.0, g) * 255.0 + .5); + 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); } for (i = 0; i < num_palette; i++) { @@ -1040,57 +1067,56 @@ png_init_read_transformations(png_structp png_ptr) else /* color_type != PNG_COLOR_TYPE_PALETTE */ { - double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1); - double g = 1.0; - double gs = 1.0; + png_fixed_point g = PNG_FP_1; + png_fixed_point gs = PNG_FP_1; switch (png_ptr->background_gamma_type) { case PNG_BACKGROUND_GAMMA_SCREEN: - g = (png_ptr->screen_gamma); - gs = 1.0; + g = png_ptr->screen_gamma; + /* gs = PNG_FP_1; */ break; case PNG_BACKGROUND_GAMMA_FILE: - g = 1.0 / (png_ptr->gamma); - gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: - g = 1.0 / (png_ptr->background_gamma); - gs = 1.0 / (png_ptr->background_gamma * - png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); break; } - png_ptr->background_1.gray = (png_uint_16)(pow( - (double)png_ptr->background.gray / m, g) * m + .5); + png_ptr->background_1.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, g); - png_ptr->background.gray = (png_uint_16)(pow( - (double)png_ptr->background.gray / m, gs) * m + .5); + 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 */ - png_ptr->background_1.red = (png_uint_16)(pow( - (double)png_ptr->background.red / m, g) * m + .5); + png_ptr->background_1.red = png_gamma_correct(png_ptr, + png_ptr->background.red, g); - png_ptr->background_1.green = (png_uint_16)(pow( - (double)png_ptr->background.green / m, g) * m + .5); + png_ptr->background_1.green = png_gamma_correct(png_ptr, + png_ptr->background.green, g); - png_ptr->background_1.blue = (png_uint_16)(pow( - (double)png_ptr->background.blue / m, g) * m + .5); + png_ptr->background_1.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, g); - png_ptr->background.red = (png_uint_16)(pow( - (double)png_ptr->background.red / m, gs) * m + .5); + png_ptr->background.red = png_gamma_correct(png_ptr, + png_ptr->background.red, gs); - png_ptr->background.green = (png_uint_16)(pow( - (double)png_ptr->background.green / m, gs) * m + .5); + png_ptr->background.green = png_gamma_correct(png_ptr, + png_ptr->background.green, gs); - png_ptr->background.blue = (png_uint_16)(pow( - (double)png_ptr->background.blue / m, gs) * m + .5); + png_ptr->background.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, gs); } else @@ -1127,7 +1153,7 @@ png_init_read_transformations(png_structp png_ptr) #ifdef PNG_READ_BACKGROUND_SUPPORTED else #endif -#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ +#endif /* PNG_READ_GAMMA_SUPPORTED */ #ifdef PNG_READ_BACKGROUND_SUPPORTED /* No GAMMA transformation */ if ((png_ptr->transformations & PNG_BACKGROUND) && @@ -1255,12 +1281,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_READ_GAMMA_SUPPORTED if (png_ptr->transformations & PNG_GAMMA) { -#ifdef PNG_FLOATING_POINT_SUPPORTED info_ptr->gamma = png_ptr->gamma; -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = png_ptr->int_gamma; -#endif } #endif @@ -4066,267 +4087,6 @@ png_do_quantize(png_row_infop row_info, png_bytep row, } #endif /* PNG_READ_QUANTIZE_SUPPORTED */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -#ifdef PNG_READ_GAMMA_SUPPORTED -static PNG_CONST int png_gamma_shift[] = - {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; - -/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit - * tables, we don't make a full table if we are reducing to 8-bit in - * 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. - * - * See the PNG extensions document for an integer algorithm for creating - * the gamma tables. Maybe we will implement that here someday. - * - * We should only reach this point if - * - * the file_gamma is known (i.e., the gAMA or sRGB chunk is present, - * or the application has provided a file_gamma) - * - * AND - * { - * the screen_gamma is known - * - * OR - * - * RGB_to_gray transformation is being performed - * } - * - * AND - * { - * the screen_gamma is different from the reciprocal of the - * file_gamma by more than the specified threshold - * - * OR - * - * a background color has been specified and the file_gamma - * and screen_gamma are not 1.0, within the specified threshold. - * } - */ - -void /* PRIVATE */ -png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) -{ - png_debug(1, "in png_build_gamma_table"); - - if (bit_depth <= 8) - { - int i; - double g; - - if (png_ptr->screen_gamma > .000001) - g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); - - else - g = 1.0; - - png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); - - for (i = 0; i < 256; i++) - { - png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); - } - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) - { - - g = 1.0 / (png_ptr->gamma); - - png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); - - for (i = 0; i < 256; i++) - { - png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); - } - - png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); - - if (png_ptr->screen_gamma > 0.000001) - g = 1.0 / png_ptr->screen_gamma; - - else - g = png_ptr->gamma; /* Probably doing rgb_to_gray */ - - for (i = 0; i < 256; i++) - { - png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); - - } - } -#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ - } - else - { - double g; - int i, j, shift, num; - int sig_bit; - png_uint_32 ig; - - if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - { - sig_bit = (int)png_ptr->sig_bit.red; - - if ((int)png_ptr->sig_bit.green > sig_bit) - sig_bit = png_ptr->sig_bit.green; - - if ((int)png_ptr->sig_bit.blue > sig_bit) - sig_bit = png_ptr->sig_bit.blue; - } - else - { - sig_bit = (int)png_ptr->sig_bit.gray; - } - - if (sig_bit > 0) - shift = 16 - sig_bit; - - else - shift = 0; - - if (png_ptr->transformations & PNG_16_TO_8) - { - if (shift < (16 - PNG_MAX_GAMMA_8)) - shift = (16 - PNG_MAX_GAMMA_8); - } - - if (shift > 8) - shift = 8; - - if (shift < 0) - shift = 0; - - png_ptr->gamma_shift = (png_byte)shift; - - num = (1 << (8 - shift)); - - if (png_ptr->screen_gamma > .000001) - g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); - - else - g = 1.0; - - png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr, - (png_uint_32)(num * png_sizeof(png_uint_16p))); - - if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) - { - double fin, fout; - png_uint_32 last, max; - - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - } - - g = 1.0 / g; - last = 0; - for (i = 0; i < 256; i++) - { - fout = ((double)i + 0.5) / 256.0; - fin = pow(fout, g); - max = (png_uint_32)(fin * (double)((png_uint_32)num << 8)); - while (last <= max) - { - png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] - [(int)(last >> (8 - shift))] = (png_uint_16)( - (png_uint_16)i | ((png_uint_16)i << 8)); - last++; - } - } - - while (last < ((png_uint_32)num << 8)) - { - png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] - [(int)(last >> (8 - shift))] = (png_uint_16)65535L; - last++; - } - } - else - { - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - - ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); - - for (j = 0; j < 256; j++) - { - png_ptr->gamma_16_table[i][j] = - (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / - 65535.0, g) * 65535.0 + .5); - } - } - } - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) - { - - g = 1.0 / (png_ptr->gamma); - - png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr, - (png_uint_32)(num * png_sizeof(png_uint_16p ))); - - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - - ig = (((png_uint_32)i * - (png_uint_32)png_gamma_shift[shift]) >> 4); - - for (j = 0; j < 256; j++) - { - png_ptr->gamma_16_to_1[i][j] = - (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / - 65535.0, g) * 65535.0 + .5); - } - } - - if (png_ptr->screen_gamma > 0.000001) - g = 1.0 / png_ptr->screen_gamma; - - else - g = png_ptr->gamma; /* Probably doing rgb_to_gray */ - - png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr, - (png_uint_32)(num * png_sizeof(png_uint_16p))); - - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - - ig = (((png_uint_32)i * - (png_uint_32)png_gamma_shift[shift]) >> 4); - - for (j = 0; j < 256; j++) - { - png_ptr->gamma_16_from_1[i][j] = - (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / - 65535.0, g) * 65535.0 + .5); - } - } - } -#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ - } -} -#endif -/* To do: install integer version of png_build_gamma_table here */ -#endif - #ifdef PNG_MNG_FEATURES_SUPPORTED /* Undoes intrapixel differencing */ void /* PRIVATE */ diff --git a/pngrutil.c b/pngrutil.c index 867f5121c..85ad57598 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.4.1 [July 24, 2010] + * Last changed in libpng 1.4.1 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -27,6 +27,29 @@ png_get_uint_31(png_structp png_ptr, png_bytep buf) png_error(png_ptr, "PNG unsigned integer out of range"); return (i); } + +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) +/* The following is a variation on the above for use with the fixed + * point values used for gAMA and cHRM. Instead of png_error it + * issues a warning and returns (-1) - an invalid value because both + * gAMA and cHRM use *unsigned* integers for fixed point values. + */ +#define PNG_FIXED_ERROR (-1) + +png_fixed_point /* PRIVATE */ +png_get_fixed_point(png_structp png_ptr, png_bytep buf) +{ + png_uint_32 u = png_get_uint_32(buf); + if (u <= PNG_UINT_31_MAX) + return (png_fixed_point)u; /* known to be in range */ + + /* The caller can turn off the warning by passing NULL. */ + if (png_ptr != NULL) + png_warning(png_ptr, "PNG fixed point integer out of range"); + return PNG_FIXED_ERROR; +} +#endif + #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED /* NOTE: the read macros will obscure these definitions, so that if * PNG_USE_READ_MACROS is set the library will not use them internally, @@ -46,22 +69,20 @@ png_get_uint_32)(png_bytep buf) } /* Grab a signed 32-bit integer from a buffer in big-endian format. The - * data is stored in the PNG file in two's complement format, and it is - * assumed that the machine format for signed integers is the same. - * Only used internally in this file. + * data is stored in the PNG file in two's complement format and there + * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore + * the following code does a two's complement to native convertion. */ -#if defined(PNG_GET_INT_32_SUPPORTED) png_int_32 (PNGAPI png_get_int_32)(png_bytep buf) { - png_int_32 i = ((png_int_32)(*buf) << 24) + - ((png_int_32)(*(buf + 1)) << 16) + - ((png_int_32)(*(buf + 2)) << 8) + - (png_int_32)(*(buf + 3)); + png_uint_32 u = png_get_uint_32(buf); + if ((u & 0x80000000) == 0) /* negative */ + return u; - return (i); + u = (u ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ + return -u; } -#endif /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ png_uint_16 (PNGAPI @@ -677,9 +698,6 @@ void /* PRIVATE */ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_fixed_point igamma; -#ifdef PNG_FLOATING_POINT_SUPPORTED - float file_gamma; -#endif png_byte buf[4]; png_debug(1, "in png_handle_gAMA"); @@ -718,12 +736,12 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_crc_finish(png_ptr, 0)) return; - igamma = (png_fixed_point)png_get_uint_32(buf); - /* Check for zero gamma */ - if (igamma == 0) + igamma = png_get_fixed_point(NULL, buf); + /* Check for zero gamma or an error. */ + if (igamma <= 0) { png_warning(png_ptr, - "Ignoring gAMA chunk with gamma=0"); + "Ignoring gAMA chunk with out of range gamma"); return; } @@ -740,16 +758,12 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif /* PNG_READ_sRGB_SUPPORTED */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - file_gamma = (float)igamma / (float)100000.0; # ifdef PNG_READ_GAMMA_SUPPORTED - png_ptr->gamma = file_gamma; + /* Gamma correction on read is supported. */ + png_ptr->gamma = igamma; # endif - png_set_gAMA(png_ptr, info_ptr, file_gamma); -#else - /* Fixed point must be set! */ + /* And set the 'info' structure members. */ png_set_gAMA_fixed(png_ptr, info_ptr, igamma); -#endif } #endif @@ -831,13 +845,8 @@ void /* PRIVATE */ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[32]; -#ifdef PNG_FLOATING_POINT_SUPPORTED - float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; -#endif - png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, - int_y_green, int_x_blue, int_y_blue; - - png_uint_32 uint_x, uint_y; + png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, + y_blue; png_debug(1, "in png_handle_cHRM"); @@ -877,80 +886,54 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_crc_finish(png_ptr, 0)) return; - uint_x = png_get_uint_32(buf); - uint_y = png_get_uint_32(buf + 4); - int_x_white = (png_fixed_point)uint_x; - int_y_white = (png_fixed_point)uint_y; - - uint_x = png_get_uint_32(buf + 8); - uint_y = png_get_uint_32(buf + 12); - int_x_red = (png_fixed_point)uint_x; - int_y_red = (png_fixed_point)uint_y; - - uint_x = png_get_uint_32(buf + 16); - uint_y = png_get_uint_32(buf + 20); - int_x_green = (png_fixed_point)uint_x; - int_y_green = (png_fixed_point)uint_y; - - uint_x = png_get_uint_32(buf + 24); - uint_y = png_get_uint_32(buf + 28); - int_x_blue = (png_fixed_point)uint_x; - int_y_blue = (png_fixed_point)uint_y; - -#ifdef PNG_FLOATING_POINT_SUPPORTED - white_x = (float)int_x_white / (float)100000.0; - white_y = (float)int_y_white / (float)100000.0; - red_x = (float)int_x_red / (float)100000.0; - red_y = (float)int_y_red / (float)100000.0; - green_x = (float)int_x_green / (float)100000.0; - green_y = (float)int_y_green / (float)100000.0; - blue_x = (float)int_x_blue / (float)100000.0; - blue_y = (float)int_y_blue / (float)100000.0; -#endif + x_white = png_get_fixed_point(NULL, buf); + y_white = png_get_fixed_point(NULL, buf + 4); + x_red = png_get_fixed_point(NULL, buf + 8); + y_red = png_get_fixed_point(NULL, buf + 12); + x_green = png_get_fixed_point(NULL, buf + 16); + y_green = png_get_fixed_point(NULL, buf + 20); + x_blue = png_get_fixed_point(NULL, buf + 24); + y_blue = png_get_fixed_point(NULL, buf + 28); + if (x_white == PNG_FIXED_ERROR || + y_white == PNG_FIXED_ERROR || + x_red == PNG_FIXED_ERROR || + y_red == PNG_FIXED_ERROR || + x_green == PNG_FIXED_ERROR || + y_green == PNG_FIXED_ERROR || + x_blue == PNG_FIXED_ERROR || + y_blue == PNG_FIXED_ERROR) + { + png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); + return; + } #ifdef PNG_READ_sRGB_SUPPORTED if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) { - if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || - PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || - PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) + if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) { png_warning(png_ptr, "Ignoring incorrect cHRM value when sRGB is also present"); #ifdef PNG_CONSOLE_IO_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED - fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", - white_x, white_y, red_x, red_y); - fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", - green_x, green_y, blue_x, blue_y); -#else - fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", - (long)int_x_white, (long)int_y_white, - (long)int_x_red, (long)int_y_red); - fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", - (long)int_x_green, (long)int_y_green, - (long)int_x_blue, (long)int_y_blue); -#endif + fprintf(stderr, "wx=%d, wy=%d, rx=%d, ry=%d\n", + x_white, y_white, x_red, y_red); + fprintf(stderr, "gx=%d, gy=%d, bx=%d, by=%d\n", + x_green, y_green, x_blue, y_blue); #endif /* PNG_CONSOLE_IO_SUPPORTED */ } return; } #endif /* PNG_READ_sRGB_SUPPORTED */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - png_set_cHRM(png_ptr, info_ptr, - white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - png_set_cHRM_fixed(png_ptr, info_ptr, - int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, - int_y_green, int_x_blue, int_y_blue); -#endif + png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, + x_green, y_green, x_blue, y_blue); } #endif @@ -1007,48 +990,31 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) { - png_fixed_point igamma; -#ifdef PNG_FIXED_POINT_SUPPORTED - igamma=info_ptr->int_gamma; -#else -# ifdef PNG_FLOATING_POINT_SUPPORTED - igamma=(png_fixed_point)(info_ptr->gamma * 100000.); -# endif -#endif - if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) + if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500)) { - png_warning(png_ptr, - "Ignoring incorrect gAMA value when sRGB is also present"); + png_warning(png_ptr, + "Ignoring incorrect gAMA value when sRGB is also present"); #ifdef PNG_CONSOLE_IO_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED - fprintf(stderr, "incorrect gamma=(%d/100000)\n", - (int)png_ptr->int_gamma); -# else -# ifdef PNG_FLOATING_POINT_SUPPORTED - fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma); -# endif -# endif + fprintf(stderr, "incorrect gamma=(%d/100000)\n", info_ptr->gamma); #endif } } #endif /* PNG_READ_gAMA_SUPPORTED */ #ifdef PNG_READ_cHRM_SUPPORTED -#ifdef PNG_FIXED_POINT_SUPPORTED if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) - if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) + if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) { png_warning(png_ptr, "Ignoring incorrect cHRM value when sRGB is also present"); } -#endif /* PNG_FIXED_POINT_SUPPORTED */ #endif /* PNG_READ_cHRM_SUPPORTED */ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); @@ -1144,7 +1110,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) profile_length = data_length - prefix_length; - if ( prefix_length > data_length || profile_length < 4) + if (prefix_length > data_length || profile_length < 4) { png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; @@ -1167,22 +1133,24 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; #ifdef PNG_STDIO_SUPPORTED - { - char umsg[80]; + { + char umsg[80]; - png_snprintf2(umsg, 80, - "Ignoring iCCP chunk with declared size = %lu " - "and actual length = %lu", - (unsigned long)profile_size, - (unsigned long)profile_length); - png_warning(png_ptr, umsg); - } + png_snprintf2(umsg, 80, + "Ignoring iCCP chunk with declared size = %u " + "and actual length = %u", profile_size, profile_length); + png_warning(png_ptr, umsg); + } +#else + png_warning(png_ptr, + "Ignoring iCCP chunk with uncompressed size mismatch"); #endif return; } png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, - compression_type, png_ptr->chunkdata + prefix_length, profile_length); + compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, + profile_length); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; } @@ -1854,16 +1822,8 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) void /* PRIVATE */ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_charp ep; -#ifdef PNG_FLOATING_POINT_SUPPORTED - double width, height; - png_charp vp; -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - png_charp swidth, sheight; -#endif -#endif - png_size_t slength; + png_size_t slength, index; + int state; png_debug(1, "in png_handle_sCAL"); @@ -1897,6 +1857,7 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ if (png_crc_finish(png_ptr, 0)) { @@ -1905,115 +1866,40 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } - png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ - - ep = png_ptr->chunkdata + 1; /* Skip unit byte */ - -#ifdef PNG_FLOATING_POINT_SUPPORTED - width = png_strtod(png_ptr, ep, &vp); - if (*vp) + /* Validate the unit. */ + if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) { - png_warning(png_ptr, "malformed width string in sCAL chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); - - if (swidth == NULL) - { - png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); + png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; return; } - png_memcpy(swidth, ep, png_strlen(ep)); -#endif -#endif - - for (ep = png_ptr->chunkdata; *ep; ep++) - /* Empty loop */ ; - - ep++; - - if (png_ptr->chunkdata + slength < ep) + /* Validate the ASCII numbers, need two ASCII numbers separated by + * a '\0' and they need to fit exactly in the chunk data. + */ + index = 0; + state = 0; + if (png_ptr->chunkdata[1] == 45 /* negative width */ || + !png_check_fp_number(png_ptr->chunkdata, slength, &state, &index) || + index >= slength || png_ptr->chunkdata[index++] != 0) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); + else { - png_warning(png_ptr, "Truncated sCAL chunk"); -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); -#endif - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; + png_size_t heighti = index; + if (png_ptr->chunkdata[index] == 45 /* negative height */ || + !png_check_fp_number(png_ptr->chunkdata, slength, &state, &index) || + index != slength) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); + else + /* This is the (only) success case. */ + png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], + png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); } -#ifdef PNG_FLOATING_POINT_SUPPORTED - height = png_strtod(png_ptr, ep, &vp); - - if (*vp) - { - png_warning(png_ptr, "malformed height string in sCAL chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); -#endif - return; - } - -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); - - if (sheight == NULL) - { - png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); -#endif - return; - } - - png_memcpy(sheight, ep, png_strlen(ep)); -#endif -#endif - - if (png_ptr->chunkdata + slength < ep -#ifdef PNG_FLOATING_POINT_SUPPORTED - || width <= 0. || height <= 0. -#endif - ) - { - png_warning(png_ptr, "Invalid sCAL data"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); - png_free(png_ptr, sheight); -#endif - return; - } - - -#ifdef PNG_FLOATING_POINT_SUPPORTED - png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height); -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); -#endif -#endif - + /* Clean up - just free the temporarily allocated buffer. */ png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); - png_free(png_ptr, sheight); -#endif } #endif @@ -3567,4 +3453,37 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) png_ptr->flags |= PNG_FLAG_ROW_INIT; } + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +int PNGAPI +png_get_num_passes(png_structp png_ptr) +{ + if (png_ptr != NULL) + { + if (png_ptr->interlaced) + return 7; + else + return 1; + } + + /* Here on error */ + return 0; +} + +png_uint_32 PNGAPI +png_get_num_rows(png_structp png_ptr) +{ + if (png_ptr != NULL) + { + if (png_ptr->flags & PNG_FLAG_ROW_INIT) + return png_ptr->num_rows; + else + png_error(png_ptr, "Call png_start_read_image or png_read_update_info " + "before png_get_num_rows"); + } + + /* Here on error */ + return 0; +} +#endif /* SEQUENTIAL READ */ #endif /* PNG_READ_SUPPORTED */ diff --git a/pngset.c b/pngset.c index 67cd1a5b5..e68ffe551 100644 --- a/pngset.c +++ b/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -35,42 +35,7 @@ png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) #endif #ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_cHRM(png_structp png_ptr, png_infop info_ptr, - double white_x, double white_y, double red_x, double red_y, - double green_x, double green_y, double blue_x, double blue_y) -{ - png_debug1(1, "in %s storage function", "cHRM"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* TODO: call png_check_cHRM_fixed */ - info_ptr->x_white = (float)white_x; - info_ptr->y_white = (float)white_y; - info_ptr->x_red = (float)red_x; - info_ptr->y_red = (float)red_y; - info_ptr->x_green = (float)green_x; - info_ptr->y_green = (float)green_y; - info_ptr->x_blue = (float)blue_x; - info_ptr->y_blue = (float)blue_y; -#ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_x_white = (png_fixed_point)(white_x*100000. + 0.5); - info_ptr->int_y_white = (png_fixed_point)(white_y*100000. + 0.5); - info_ptr->int_x_red = (png_fixed_point)( red_x*100000. + 0.5); - info_ptr->int_y_red = (png_fixed_point)( red_y*100000. + 0.5); - info_ptr->int_x_green = (png_fixed_point)(green_x*100000. + 0.5); - info_ptr->int_y_green = (png_fixed_point)(green_y*100000. + 0.5); - info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000. + 0.5); - info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000. + 0.5); -#endif - info_ptr->valid |= PNG_INFO_cHRM; -} -#endif /* PNG_FLOATING_POINT_SUPPORTED */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI +void PNGFAPI png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, @@ -86,99 +51,71 @@ png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) #endif { - info_ptr->int_x_white = white_x; - info_ptr->int_y_white = white_y; - info_ptr->int_x_red = red_x; - info_ptr->int_y_red = red_y; - info_ptr->int_x_green = green_x; - info_ptr->int_y_green = green_y; - info_ptr->int_x_blue = blue_x; - info_ptr->int_y_blue = blue_y; -#ifdef PNG_FLOATING_POINT_SUPPORTED - info_ptr->x_white = (float)(white_x/100000.); - info_ptr->y_white = (float)(white_y/100000.); - info_ptr->x_red = (float)( red_x/100000.); - info_ptr->y_red = (float)( red_y/100000.); - info_ptr->x_green = (float)(green_x/100000.); - info_ptr->y_green = (float)(green_y/100000.); - info_ptr->x_blue = (float)( blue_x/100000.); - info_ptr->y_blue = (float)( blue_y/100000.); -#endif + info_ptr->x_white = white_x; + info_ptr->y_white = white_y; + info_ptr->x_red = red_x; + info_ptr->y_red = red_y; + info_ptr->x_green = green_x; + info_ptr->y_green = green_y; + info_ptr->x_blue = blue_x; + info_ptr->y_blue = blue_y; info_ptr->valid |= PNG_INFO_cHRM; } } -#endif /* PNG_FIXED_POINT_SUPPORTED */ + +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cHRM(png_structp png_ptr, png_infop info_ptr, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y) +{ + png_set_cHRM_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, white_x, "cHRM White X"), + png_fixed(png_ptr, white_y, "cHRM White Y"), + png_fixed(png_ptr, red_x, "cHRM Red X"), + png_fixed(png_ptr, red_y, "cHRM Red Y"), + png_fixed(png_ptr, green_x, "cHRM Green X"), + png_fixed(png_ptr, green_y, "cHRM Green Y"), + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); +} +#endif /* PNG_FLOATING_POINT_SUPPORTED */ + #endif /* PNG_cHRM_SUPPORTED */ #ifdef PNG_gAMA_SUPPORTED +void PNGFAPI +png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point + gamma) +{ + png_debug1(1, "in %s storage function", "gAMA"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Previously these values were limited, however they must be + * wrong, therfore storing them (and setting PNG_INFO_gAMA) + * must be wrong too. + */ + if (gamma > (png_fixed_point)PNG_UINT_31_MAX) + png_warning(png_ptr, "Gamma too large, ignored"); + + else if (gamma <= 0) + png_warning(png_ptr, "Negative gamma ignored"); + + else + { + info_ptr->gamma = gamma; + info_ptr->valid |= PNG_INFO_gAMA; + } +} + #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) { - double png_gamma; - - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Check for overflow */ - if (file_gamma > 21474.83) - { - png_warning(png_ptr, "Limiting gamma to 21474.83"); - png_gamma = 21474.83; - } - - else - png_gamma = file_gamma; - - info_ptr->gamma = (float)png_gamma; -#ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = (int)(png_gamma*100000.+.5); -#endif - info_ptr->valid |= PNG_INFO_gAMA; - - if (png_gamma == 0.0) - png_warning(png_ptr, "Setting gamma = 0"); -} -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point - int_gamma) -{ - png_fixed_point png_gamma; - - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Limiting gamma to 21474.83"); - png_gamma = PNG_UINT_31_MAX; - } - - else - { - if (int_gamma < 0) - { - png_warning(png_ptr, "Setting negative gamma to zero"); - png_gamma = 0; - } - - else - png_gamma = int_gamma; - } -#ifdef PNG_FLOATING_POINT_SUPPORTED - info_ptr->gamma = (float)(png_gamma/100000.); -#endif - info_ptr->int_gamma = png_gamma; - info_ptr->valid |= PNG_INFO_gAMA; - - if (png_gamma == 0) - png_warning(png_ptr, "Setting gamma = 0"); + png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, + "png_set_gAMA")); } #endif #endif @@ -309,6 +246,17 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, png_debug1(3, "allocating purpose for info (%lu bytes)", (unsigned long)length); + /* TODO: validate format of calibration name and unit name */ + + /* Check that the type matches the specification. */ + if (type < 0 || type > 3) + png_error(png_ptr, "Invalid pCAL equation type"); + + /* Validate params[nparams] */ + for (i=0; ipcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); if (info_ptr->pcal_purpose == NULL) { @@ -370,75 +318,94 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, #endif #ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_sCAL(png_structp png_ptr, png_infop info_ptr, - int unit, double width, double height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->scal_unit = (png_byte)unit; - info_ptr->scal_pixel_width = width; - info_ptr->scal_pixel_height = height; - - info_ptr->valid |= PNG_INFO_sCAL; -} -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI +void PNGFAPI png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, int unit, png_charp swidth, png_charp sheight) { - png_size_t length; + png_size_t lengthw, lengthh; png_debug1(1, "in %s storage function", "sCAL"); if (png_ptr == NULL || info_ptr == NULL) return; + /* Double check the unit (should never get here with an invalid + * unit unless this is an API call.) + */ + if (unit != 1 && unit != 2) + png_error(png_ptr, "Invalid sCAL unit"); + + if (swidth == NULL || (lengthw = png_strlen(swidth)) <= 0 || + swidth[0] == 45 /*'-'*/ || !png_check_fp_string(swidth, lengthw)) + png_error(png_ptr, "Invalid sCAL width"); + + if (sheight == NULL || (lengthh = png_strlen(sheight)) <= 0 || + sheight[0] == 45 /*'-'*/ || !png_check_fp_string(sheight, lengthh)) + png_error(png_ptr, "Invalid sCAL height"); + info_ptr->scal_unit = (png_byte)unit; - length = png_strlen(swidth) + 1; + ++lengthw; - png_debug1(3, "allocating unit for info (%u bytes)", - (unsigned int)length); + png_debug1(3, "allocating unit for info (%u bytes)", lengthw); - info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length); + info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); if (info_ptr->scal_s_width == NULL) { - png_warning(png_ptr, - "Memory allocation failed while processing sCAL"); + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); return; } - png_memcpy(info_ptr->scal_s_width, swidth, length); + png_memcpy(info_ptr->scal_s_width, swidth, lengthw); - length = png_strlen(sheight) + 1; + ++lengthh; - png_debug1(3, "allocating unit for info (%u bytes)", - (unsigned int)length); + png_debug1(3, "allocating unit for info (%u bytes)", lengthh); - info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length); + info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); if (info_ptr->scal_s_height == NULL) { png_free (png_ptr, info_ptr->scal_s_width); info_ptr->scal_s_width = NULL; - png_warning(png_ptr, - "Memory allocation failed while processing sCAL"); - + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); return; } - png_memcpy(info_ptr->scal_s_height, sheight, length); + png_memcpy(info_ptr->scal_s_height, sheight, lengthh); + info_ptr->valid |= PNG_INFO_sCAL; info_ptr->free_me |= PNG_FREE_SCAL; } + +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, + double height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, + PNG_sCAL_PRECISION); + png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, + PNG_sCAL_PRECISION); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} #endif #endif @@ -543,16 +510,10 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, png_set_sRGB(png_ptr, info_ptr, intent); #ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FIXED_POINT_SUPPORTED png_set_gAMA_fixed(png_ptr, info_ptr, 45455L); -#else - /* Floating point must be set! */ - png_set_gAMA(png_ptr, info_ptr, .45455); -#endif #endif #ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_FIXED_POINT_SUPPORTED png_set_cHRM_fixed(png_ptr, info_ptr, /* color x y */ /* white */ 31270L, 32900L, @@ -560,16 +521,6 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, /* green */ 30000L, 60000L, /* blue */ 15000L, 6000L ); -#else - /* Floating point must be supported! */ - png_set_cHRM(png_ptr, info_ptr, - /* color x y */ - /* while */ .3127, .3290, - /* red */ .64, .33, - /* green */ .30, .60, - /* blue */ .15, .06 - ); -#endif #endif /* cHRM */ } #endif /* sRGB */ @@ -579,10 +530,10 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, void PNGAPI png_set_iCCP(png_structp png_ptr, png_infop info_ptr, png_charp name, int compression_type, - png_charp profile, png_uint_32 proflen) + png_bytep profile, png_uint_32 proflen) { png_charp new_iccp_name; - png_charp new_iccp_profile; + png_bytep new_iccp_profile; png_uint_32 length; png_debug1(1, "in %s storage function", "iCCP"); @@ -598,7 +549,7 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, return; } png_memcpy(new_iccp_name, name, length); - new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); + new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); if (new_iccp_profile == NULL) { @@ -844,8 +795,8 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, 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_bytep)png_malloc(png_ptr, - (png_size_t)PNG_MAX_PALETTE_LENGTH); + png_ptr->trans_alpha = info_ptr->trans_alpha = + (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); @@ -864,7 +815,8 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, png_warning(png_ptr, "tRNS chunk has out-of-range samples for bit_depth"); - png_memcpy(&(info_ptr->trans_color), trans_color, png_sizeof(png_color_16)); + png_memcpy(&(info_ptr->trans_color), trans_color, + png_sizeof(png_color_16)); if (num_trans == 0) num_trans = 1; diff --git a/pngstruct.h b/pngstruct.h index d0d7ae694..a9d6c90e4 100644 --- a/pngstruct.h +++ b/pngstruct.h @@ -5,7 +5,7 @@ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * - * Last changed in libpng version 1.5.0 - July 24, 2010 + * Last changed in libpng version 1.5.0 - July 29, 2010 * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -20,6 +20,12 @@ #ifndef PNGSTRUCT_H #define PNGSTRUCT_H +/* zlib.h defines the structure z_stream, an instance of which is included + * in this structure and is required for decompressing the LZ compressed + * data in PNG files. + */ +#include "zlib.h" + struct png_struct_def { #ifdef PNG_SETJMP_SUPPORTED @@ -104,9 +110,7 @@ struct png_struct_def #ifdef PNG_bKGD_SUPPORTED png_byte background_gamma_type; -# ifdef PNG_FLOATING_POINT_SUPPORTED - float background_gamma; -# endif + 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 */ @@ -121,10 +125,8 @@ struct png_struct_def #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - float gamma; /* file gamma value */ - float screen_gamma; /* screen gamma value (display_exponent) */ -#endif + png_fixed_point gamma; /* file gamma value */ + png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ #endif #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) @@ -154,7 +156,7 @@ struct png_struct_def png_write_status_ptr write_row_fn; /* called after each row is encoded */ #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 each prog. row is decoded */ + png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */ png_progressive_end_ptr end_fn; /* called after image is complete */ png_bytep save_buffer_ptr; /* current location in save_buffer */ png_bytep save_buffer; /* buffer for previously read data */ @@ -241,11 +243,6 @@ struct png_struct_def png_uint_32 mng_features_permitted; #endif -/* New member added in libpng-1.0.7 */ -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_fixed_point int_gamma; -#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; diff --git a/pngtest.c b/pngtest.c index 4323f9599..07dc466f1 100644 --- a/pngtest.c +++ b/pngtest.c @@ -1,7 +1,7 @@ /* pngtest.c - a simple test program to test libpng * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -31,6 +31,7 @@ * of files at once by typing "pngtest -m file1.png file2.png ..." */ +#include "zlib.h" #include "png.h" /* Copied from pngpriv.h but only used in error messages below. */ #ifndef PNG_ZBUF_SIZE @@ -64,6 +65,17 @@ typedef FILE * png_FILE_p; # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ #endif +/* The code uses memcmp and memcpy on large objects (typically row pointers) so + * it is necessary to do soemthing special on certain architectures, note that + * the actual support for this was effectively removed in 1.4, so only the + * memory remains in this program: + */ +#define CVT_PTR(ptr) (ptr) +#define CVT_PTR_NOCHECK(ptr) (ptr) +#define png_memcmp memcmp +#define png_memcpy memcpy +#define png_memset memset + /* Turn on CPU timing #define PNGTEST_TIMING */ @@ -957,7 +969,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #ifdef PNG_iCCP_SUPPORTED { png_charp name; - png_charp profile; + png_bytep profile; png_uint_32 proflen; int compression_type; diff --git a/pngtrans.c b/pngtrans.c index ff851ba63..d48ab369b 100644 --- a/pngtrans.c +++ b/pngtrans.c @@ -1,7 +1,7 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) diff --git a/pngvalid.c b/pngvalid.c new file mode 100644 index 000000000..5070e0ae1 --- /dev/null +++ b/pngvalid.c @@ -0,0 +1,2075 @@ + +/* pngvalid.c - validate libpng by constructing then reading png files. + * + * Last changed in libpng 1.5.0 [July 5, 2010] + * Copyright (c) 2010-2010 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 + * + * NOTES: + * This is a C program that is intended to be linked against libpng. It + * generates bitmaps internally, stores them as PNG files (using the + * sequential write code) then reads them back (using the sequential + * read code) and validates that the result has the correct data. + * + * The program can be modified and extended to test the correctness of + * transformations performed by libpng. + */ + +#include "png.h" +#include "zlib.h" /* For crc32 */ + +#include /* For malloc */ +#include /* For memcpy, memset */ +#include /* For jmp_buf, setjmp, longjmp */ +#include /* For floor */ + +/******************************* ERROR UTILITIES ******************************/ +static size_t safecat(char *buffer, size_t bufsize, size_t pos, const char *cat) +{ + while (pos < bufsize && cat != NULL && *cat != 0) buffer[pos++] = *cat++; + if (pos >= bufsize) pos = bufsize-1; + buffer[pos] = 0; + return pos; +} + +static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n) +{ + char number[64]; + sprintf(number, "%d", n); + return safecat(buffer, bufsize, pos, number); +} + +static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d, + int precision) +{ + char number[64]; + sprintf(number, "%.*f", precision, d); + return safecat(buffer, bufsize, pos, number); +} + +static const char invalid[] = "invalid"; +static const char sep[] = ": "; + +/* NOTE: this is indexed by ln2(bit_depth)! */ +static const char *bit_depths[8] = +{ + "1", "2", "4", "8", "16", invalid, invalid, invalid +}; + +static const char *colour_types[8] = +{ + "greyscale", invalid, "truecolour", "indexed-colour", + "greyscale with alpha", invalid, "truecolour with alpha", invalid +}; + +/* Convenience API to list valid formats: */ +static int +next_format(png_bytep colour_type, png_bytep bit_depth) +{ + if (*bit_depth == 0) + { + *colour_type = 0, *bit_depth = 1; + return 1; + } + else switch (*colour_type) + { + case 0: + *bit_depth <<= 1; + if (*bit_depth <= 16) return 1; + *colour_type = 2; + *bit_depth = 8; + return 1; + case 2: + *bit_depth <<= 1; + if (*bit_depth <= 16) return 1; + *colour_type = 3; + *bit_depth = 1; + return 1; + case 3: + *bit_depth <<= 1; + if (*bit_depth <= 8) return 1; + *colour_type = 4; + *bit_depth = 8; + return 1; + case 4: + *bit_depth <<= 1; + if (*bit_depth <= 16) return 1; + *colour_type = 6; + *bit_depth = 8; + return 1; + case 6: + *bit_depth <<= 1; + if (*bit_depth <= 16) return 1; + break; + } + + /* Here at the end. */ + return 0; +} + +static inline unsigned +sample(png_byte *row, png_byte colour_type, png_byte bit_depth, png_uint_32 x, + unsigned sample) +{ + png_uint_32 index, result; + + /* Find a sample index for the desired sample: */ + x *= bit_depth; + index = x; + if ((colour_type & 1) == 0) /* !palette */ + { + if (colour_type & 2) + index *= 3, index += sample; /* Colour channels; select one */ + if (colour_type & 4) index += x; /* Alpha channel */ + } + + /* Return the sample from the row as an integer. */ + row += index >> 3; + result = *row; + if (bit_depth == 8) + return result; + else if (bit_depth > 8) + return (result << 8) + *++row; + /* Less than 8 bits per sample. */ + index &= 7; + return (result >> (8-index-bit_depth)) & ((1U<verbose = 0; + ps->nerrors = ps->nwarnings = 0; + ps->treat_warnings_as_errors = 0; + ps->pread = NULL; + ps->piread = NULL; + ps->saved = ps->current = NULL; + ps->next = NULL; + ps->readpos = 0; + ps->pwrite = NULL; + ps->piwrite = NULL; + ps->writepos = 0; + ps->new.prev = NULL; +} + +static void +sucker_freebuffer(png_sucker_buffer* psb) +{ + if (psb->prev) + { + sucker_freebuffer(psb->prev); + free(psb->prev); + psb->prev = NULL; + } +} + +static void +sucker_freenew(png_sucker *ps) +{ + sucker_freebuffer(&ps->new); + ps->writepos = 0; +} + +static void +sucker_storenew(png_sucker *ps) +{ + png_sucker_buffer *pb; + if (ps->writepos != SUCKER_BUFFER_SIZE) + png_error(ps->pwrite, "invalid store call"); + pb = malloc(sizeof *pb); + if (pb == NULL) + png_error(ps->pwrite, "store new: OOM"); + *pb = ps->new; + ps->new.prev = pb; + ps->writepos = 0; +} + +static void +sucker_freefile(png_sucker_file *pf) +{ + if (pf->next) + sucker_freefile(pf->next); + pf->next = NULL; + sucker_freebuffer(&pf->data); + pf->datacount = 0; + free(pf); +} + +/* Main interface to file storeage, after writing a new PNG file (see the API + * below) call sucker_storefile to store the result with the given name and id. + */ +static void +sucker_storefile(png_sucker *ps, png_uint_32 id) +{ + png_sucker_file *pf = malloc(sizeof *pf); + if (pf == NULL) + png_error(ps->pwrite, "storefile: OOM"); + safecat(pf->name, sizeof pf->name, 0, ps->wname); + pf->id = id; + pf->data = ps->new; + pf->datacount = ps->writepos; + ps->new.prev = NULL; + ps->writepos = 0; + + /* And save it. */ + pf->next = ps->saved; + ps->saved = pf; +} + +/* Generate an error message (in the given buffer) */ +static size_t +sucker_message(png_structp pp, char *buffer, size_t bufsize, const char *msg) +{ + size_t pos = 0; + png_sucker *ps = png_get_error_ptr(pp); + + if (pp == ps->pread) + { + /* Reading a file */ + pos = safecat(buffer, bufsize, pos, "read: "); + if (ps->current != NULL) + { + pos = safecat(buffer, bufsize, pos, ps->current->name); + pos = safecat(buffer, bufsize, pos, sep); + } + } + else if (pp == ps->pwrite) + { + /* Writing a file */ + pos = safecat(buffer, bufsize, pos, "write: "); + pos = safecat(buffer, bufsize, pos, ps->wname); + } + else + { + /* Neither reading nor writing */ + pos = safecat(buffer, bufsize, pos, "pngvalid: "); + } + + pos = safecat(buffer, bufsize, pos, ps->test); + pos = safecat(buffer, bufsize, pos, " "); + pos = safecat(buffer, bufsize, pos, msg); + return pos; +} + +/* Functions to use as PNG callbacks. */ +static void +sucker_error(png_structp pp, png_const_charp message) /* PNG_NORETURN */ +{ + png_sucker *ps = png_get_error_ptr(pp); + char buffer[256]; + + sucker_message(pp, buffer, sizeof buffer, message); + + if (ps->nerrors++ == 0) + safecat(ps->error, sizeof ps->error, 0, buffer); + + if (ps->verbose) + fprintf(stderr, "error: %s\n", buffer); + + /* The longjmp argument is because, by UTSL, libpng calls longjmp with 1, and + * libpng is *not* expected to ever call longjmp, so this is a sanity + * check. The code below ensures that libpng gets a copy of our jmp_buf. + */ + longjmp(ps->jmpbuf, SUCKER_ERROR); +} + +static void +sucker_warning(png_structp pp, png_const_charp message) +{ + png_sucker *ps = png_get_error_ptr(pp); + char buffer[256]; + + sucker_message(pp, buffer, sizeof buffer, message); + + if (ps->nwarnings++ == 0 && ps->nerrors == 0) + safecat(ps->error, sizeof ps->error, 0, buffer); + + if (ps->verbose) + fprintf(stderr, "warning: %s\n", buffer); +} + +static void +sucker_write(png_structp pp, png_bytep pb, png_size_t st) +{ + png_sucker *ps = png_get_io_ptr(pp); + if (ps->pwrite != pp) + png_error(pp, "sucker state damaged"); + while (st > 0) + { + size_t cb; + + if (ps->writepos >= SUCKER_BUFFER_SIZE) + sucker_storenew(ps); + + cb = st; + if (cb > SUCKER_BUFFER_SIZE - ps->writepos) + cb = SUCKER_BUFFER_SIZE - ps->writepos; + memcpy(ps->new.buffer + ps->writepos, pb, cb); + pb += cb; + st -= cb; + ps->writepos += cb; + } +} + +static void +sucker_flush(png_structp pp) +{ + /*DOES NOTHING*/ +} + +static size_t +sucker_read_buffer_size(png_sucker *ps) +{ + /* Return the bytes available for read in the current buffer. */ + if (ps->next != &ps->current->data) + return SUCKER_BUFFER_SIZE; + + return ps->current->datacount; +} + +static int +sucker_read_buffer_next(png_sucker *ps) +{ + png_sucker_buffer *pbOld = ps->next; + png_sucker_buffer *pbNew = &ps->current->data; + if (pbOld != pbNew) + { + while (pbNew != NULL && pbNew->prev != pbOld) + pbNew = pbNew->prev; + if (pbNew != NULL) + { + ps->next = pbNew; + ps->readpos = 0; + return 1; + } + + png_error(ps->pread, "buffer lost"); + } + + return 0; /* EOF or error */ +} + +static void +sucker_read(png_structp pp, png_bytep pb, png_size_t st) +{ + png_sucker *ps = png_get_io_ptr(pp); + if (ps->pread != pp || ps->current == NULL || ps->next == NULL) + png_error(pp, "sucker state damaged"); + while (st > 0) + { + size_t cbAvail = sucker_read_buffer_size(ps) - ps->readpos; + + if (cbAvail > 0) + { + if (cbAvail > st) cbAvail = st; + memcpy(pb, ps->next->buffer + ps->readpos, cbAvail); + st -= cbAvail; + pb += cbAvail; + ps->readpos += cbAvail; + } + else if (!sucker_read_buffer_next(ps)) + png_error(pp, "read beyond end of file"); + } +} + +/* Setup functions. */ +/* Cleanup when aborting a write or after storing the new file. */ +static void +sucker_write_reset(png_sucker *ps) +{ + if (ps->pwrite != NULL) + { + png_destroy_write_struct(&ps->pwrite, &ps->piwrite); + ps->pwrite = NULL; + ps->piwrite = NULL; + } + + sucker_freenew(ps); +} + +/* The following is the main write function, it returns a png_struct and, + * optionally, a png)info suitable for writiing a new PNG file. Use + * sucker_storefile above to record this file after it has been written. The + * returned libpng structures as destroyed by sucker_write_reset above. + */ +static png_structp +set_sucker_for_write(png_sucker *ps, png_infopp ppi, const char name[64]) +{ + if (setjmp(ps->jmpbuf) != 0) + return NULL; + + if (ps->pwrite != NULL) + png_error(ps->pwrite, "sucker already in use"); + + sucker_write_reset(ps); + safecat(ps->wname, sizeof ps->wname, 0, name); + + ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING, ps, sucker_error, + sucker_warning); + png_set_write_fn(ps->pwrite, ps, sucker_write, sucker_flush); + + if (ppi != NULL) + *ppi = ps->piwrite = png_create_info_struct(ps->pwrite); + + return ps->pwrite; +} + +/* Cleanup when finished reading (either due to error or in the success case. ) + */ +static void +sucker_read_reset(png_sucker *ps) +{ + if (ps->pread != NULL) + { + png_destroy_read_struct(&ps->pread, &ps->piread, NULL); + ps->pread = NULL; + ps->piread = NULL; + } + + ps->current = NULL; + ps->next = NULL; + ps->readpos = 0; +} + +static void +sucker_read_set(png_sucker *ps, png_uint_32 id) +{ + png_sucker_file *pf = ps->saved; + + while (pf != NULL) + { + if (pf->id == id) + { + ps->current = pf; + ps->next = NULL; + sucker_read_buffer_next(ps); + return; + } + + pf = pf->next; + } + + png_error(ps->pread, "unable to find file to read"); +} + +/* The main interface for reading a saved file - pass the id number of the file + * to retrieve. Ids must be unique or the earlier file will be hidden. The API + * returns a png_struct and, optionally, a png_info. Both of these will be + * destroyed by sucker_read_reset above. + */ +static png_structp +set_sucker_for_read(png_sucker *ps, png_infopp ppi, png_uint_32 id, + const char *name) +{ + safecat(ps->test, sizeof ps->test, 0, name); + + if (setjmp(ps->jmpbuf) != 0) + return NULL; + + if (ps->pread != NULL) + png_error(ps->pread, "sucker already in use"); + + sucker_read_reset(ps); + + ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, sucker_error, + sucker_warning); + sucker_read_set(ps, id); + png_set_read_fn(ps->pread, ps, sucker_read); + + if (ppi != NULL) + *ppi = ps->piread = png_create_info_struct(ps->pread); + + return ps->pread; +} + +/*********************** PNG FILE MODIFICATION ON READ ************************/ +/* Files may be modified on read. The following structure contains a complete + * png_sucker together with extra members to handle modification and a special + * read callback for libpng. To use this the 'modifications' field must be set + * to a list of png_modification structures that actually perform the + * modification, otherwise a png_modifier is functionally equivalent to a + * png_sucker. There is a special read function, set_modifier_for_read, which + * replaces set_sucker_for_read. + */ +typedef struct png_modifier +{ + png_sucker this; /* I am a png_sucker */ + struct png_modification *modifications; /* Changes to make */ + enum modifier_state + { + modifier_start, /* Initial value */ + modifier_signature, /* Have a signature */ + modifier_IHDR /* Have an IHDR */ + } state; /* My state */ + + /* Information from IHDR: */ + png_byte bit_depth; /* From IHDR */ + png_byte colour_type; /* From IHDR */ + + /* While handling PLTE, IDAT and IEND these chunks may be pended to allow + * other chunks to be inserted. + */ + png_uint_32 pending_len; + png_uint_32 pending_chunk; + + /* Test values */ + double *gammas; + unsigned ngammas; + + /* Lowest sbit to test (libpng fails for sbit < 8) */ + unsigned sbitlow; + + /* Error control - these are the limits on errors accepted by the gamma tests + * below. + */ + double maxout8; /* Maximum output value error */ + double maxabs8; /* Abosulte sample error 0..1 */ + double maxpc8; /* Percentage sample error 0..100% */ + double maxout16; /* Maximum output value error */ + double maxabs16; /* Absolute sample error 0..1 */ + double maxpc16; /* Percentage sample error 0..100% */ + + /* Logged 8 and 16 bit errors ('output' values): */ + double error_gray_2; + double error_gray_4; + double error_gray_8; + double error_gray_16; + double error_color_8; + double error_color_16; + + /* Flags: */ + /* When to use the use_input_precision option: */ + int use_input_precision :1; + int use_input_precision_sbit :1; + int use_input_precision_16to8 :1; + int log :1; /* Log max error */ + + /* Buffer information, the buffer size limits the size of the chunks that can + * be modified - they must fit (including header and CRC) into the buffer! + */ + size_t flush; /* Count of bytes to flush */ + size_t buffer_count; /* Bytes in buffer */ + size_t buffer_position; /* Position in buffer */ + png_byte buffer[1024]; +} png_modifier; + +static double abserr(png_modifier *pm, png_byte bit_depth) +{ + return bit_depth == 16 ? pm->maxabs16 : pm->maxabs8; +} + +static double pcerr(png_modifier *pm, png_byte bit_depth) +{ + return (bit_depth == 16 ? pm->maxpc16 : pm->maxpc8) * .01; +} + +static double outerr(png_modifier *pm, png_byte bit_depth) +{ + /* There is a serious error in the 2 and 4 bit grayscale transform because + * the gamma table value (8 bits) is simply shifted, not rouned, so the + * error in 4 bit greyscale gamma is up to the value below. This is a hack + * to allow pngvalid to succeed: + */ + if (bit_depth == 2) return .73182-.5; + if (bit_depth == 4) return .90644-.5; + if (bit_depth == 16) return pm->maxout16; + return pm->maxout8; +} + +/* This returns true if the test should be stopped now because it has already + * failed and it is running silently. + */ +static int fail(png_modifier *pm) +{ + return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 || + pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0); +} + +static void +modifier_init(png_modifier *pm) +{ + memset(pm, 0, sizeof *pm); + sucker_init(&pm->this); + pm->modifications = NULL; + pm->state = modifier_start; + pm->sbitlow = 1; + pm->maxout8 = pm->maxpc8 = pm->maxabs8 = 0; + pm->maxout16 = pm->maxpc16 = pm->maxabs16 = 0; + 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; + pm->use_input_precision = 0; + pm->use_input_precision_sbit = 0; + pm->use_input_precision_16to8 = 0; + pm->log = 0; + + /* Rely on the memset for all the other fields - there are no pointers */ +} + +/* One modification strucutre must be provided for each chunk to be modified (in + * fact more than one can be provided if multiple separate changes are desired + * for a single chunk.) Modifications include adding a new chunk when a + * suitable chunk does not exist. + * + * The caller of modify_fn will reset the CRC of the chunk and record 'modified' + * or 'added' as appropriate if the modify_fn returns 1 (true). If the + * modify_fn is NULL the chunk is simply removed. + */ +typedef struct png_modification +{ + struct png_modification *next; + png_uint_32 chunk; + /* If the following is NULL all matching chunks will be removed: */ + int (*modify_fn)(png_structp pp, struct png_modifier *pm, + struct png_modification *me, int add); + /* If the following is set to PLTE, IDAT or IEND and the chunk has not been + * found and modified (and there is a modify_fn) the modify_fn will be called + * to add the chunk before the relevant chunk. + */ + png_uint_32 add; + int modified :1; /* Chunk was modified */ + int added :1; /* Chunk was added */ + int removed :1; /* Chunk was removed */ +} png_modification; + +static void modification_reset(png_modification *pmm) +{ + if (pmm != NULL) + { + pmm->modified = 0; + pmm->added = 0; + pmm->removed = 0; + modification_reset(pmm->next); + } +} + +static void +modification_init(png_modification *pmm) +{ + memset(pmm, 0, sizeof *pmm); + pmm->next = NULL; + pmm->chunk = 0; + pmm->modify_fn = NULL; + pmm->add = 0; + modification_reset(pmm); +} + +static void +modifier_reset(png_modifier *pm) +{ + sucker_read_reset(&pm->this); + pm->modifications = NULL; + pm->state = modifier_start; + pm->bit_depth = pm->colour_type = 0; + pm->pending_len = pm->pending_chunk = 0; + pm->flush = pm->buffer_count = pm->buffer_position = 0; +} + +/* Convenience macros. */ +#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d)) +#define CHUNK_IHDR CHUNK(73,72,68,82) +#define CHUNK_PLTE CHUNK(80,76,84,69) +#define CHUNK_IDAT CHUNK(73,68,65,84) +#define CHUNK_IEND CHUNK(73,69,78,68) +#define CHUNK_cHRM CHUNK(99,72,82,77) +#define CHUNK_gAMA CHUNK(103,65,77,65) +#define CHUNK_sBIT CHUNK(115,66,73,84) +#define CHUNK_sRGB CHUNK(115,82,71,66) + +/* The guts of modification are performed during a read. */ +static void +modifier_crc(png_bytep buffer) +{ + /* Recalculate the chunk CRC - a complete chunk must be in + * the buffer, at the start. + */ + uInt datalen = png_get_uint_32(buffer); + png_save_uint_32(buffer+datalen+8, crc32(0L, buffer+4, datalen+4)); +} + +static void +modifier_setbuffer(png_modifier *pm) +{ + modifier_crc(pm->buffer); + pm->buffer_count = png_get_uint_32(pm->buffer)+12; + pm->buffer_position = 0; +} + +static void +modifier_read(png_structp pp, png_bytep pb, png_size_t st) +{ + png_modifier *pm = png_get_io_ptr(pp); + + while (st > 0) + { + size_t cb; + png_uint_32 len, chunk; + png_modification *mod; + + if (pm->buffer_position >= pm->buffer_count) switch (pm->state) + { + static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; + case modifier_start: + sucker_read(pp, pm->buffer, 8); /* size of signature. */ + pm->buffer_count = 8; + pm->buffer_position = 0; + + if (memcmp(pm->buffer, sign, 8) != 0) + png_error(pp, "invalid PNG file signature"); + pm->state = modifier_signature; + break; + + case modifier_signature: + sucker_read(pp, pm->buffer, 13+12); /* size of IHDR */ + pm->buffer_count = 13+12; + pm->buffer_position = 0; + + if (png_get_uint_32(pm->buffer) != 13 || + png_get_uint_32(pm->buffer+4) != CHUNK_IHDR) + png_error(pp, "invalid IHDR"); + + /* Check the list of modifiers for modifications to the IHDR. */ + mod = pm->modifications; + while (mod != NULL) + { + if (mod->chunk == CHUNK_IHDR && mod->modify_fn && + (*mod->modify_fn)(pp, pm, mod, 0)) + { + mod->modified = 1; + modifier_setbuffer(pm); + } + + /* Ignore removal or add if IHDR! */ + mod = mod->next; + } + + /* Cache information from the IHDR (the modified one.) */ + pm->bit_depth = pm->buffer[8+8]; + pm->colour_type = pm->buffer[8+8+1]; + + pm->state = modifier_IHDR; + pm->flush = 0; + break; + + default: + /* Read a new chunk and process it until we see PLTE, IDAT or + * IEND. 'flush' indicates that there is still some data to + * output from the preceding chunk. + */ + if ((cb = pm->flush) > 0) + { + if (cb > st) cb = st; + pm->flush -= cb; + sucker_read(pp, pb, cb); + pb += cb; + st -= cb; + if (st <= 0) return; + } + + /* No more bytes to flush, read a header, or handle a pending + * chunk. + */ + if (pm->pending_chunk != 0) + { + png_save_uint_32(pm->buffer, pm->pending_len); + png_save_uint_32(pm->buffer+4, pm->pending_chunk); + pm->pending_len = 0; + pm->pending_chunk = 0; + } + else + sucker_read(pp, pm->buffer, 8); + + pm->buffer_count = 8; + pm->buffer_position = 0; + + /* Check for something to modify or a terminator chunk. */ + len = png_get_uint_32(pm->buffer); + chunk = png_get_uint_32(pm->buffer+4); + + /* Terminators first, they may have to be delayed for added + * chunks + */ + if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT || chunk == CHUNK_IEND) + { + mod = pm->modifications; + + while (mod != NULL) + { + if ((mod->add == chunk || + mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT) && + mod->modify_fn != NULL && !mod->modified && !mod->added) + { + /* Regardless of what the modify function does do not run this + * again. + */ + mod->added = 1; + + if ((*mod->modify_fn)(pp, pm, mod, 1/*add*/)) + { + /* Reset the CRC on a new chunk */ + if (pm->buffer_count > 0) + modifier_setbuffer(pm); + else + { + pm->buffer_position = 0; + mod->removed = 1; + } + + /* The buffer has been filled with something (we assume) so + * output this. Pend the current chunk. + */ + pm->pending_len = len; + pm->pending_chunk = chunk; + break; /* out of while */ + } + } + + mod = mod->next; + } + + /* Don't do any further processing if the buffer was modified - + * otherwise the code will end up modifying a chunk that was just + * added. + */ + if (mod != NULL) + break; /* out of switch */ + } + + /* If we get to here then this chunk may need to be modified. To do + * this is must be less than 1024 bytes in total size, otherwise + * it just gets flushed. + */ + if (len+12 <= sizeof pm->buffer) + { + sucker_read(pp, pm->buffer+pm->buffer_count, + len+12-pm->buffer_count); + pm->buffer_count = len+12; + + /* Check for a modification, else leave it be. */ + mod = pm->modifications; + while (mod != NULL) + { + if (mod->chunk == chunk) + { + if (mod->modify_fn == NULL) + { + /* Remove this chunk */ + pm->buffer_count = pm->buffer_position = 0; + mod->removed = 1; + break; /* Terminate the while loop */ + } + else if ((*mod->modify_fn)(pp, pm, mod, 0)) + { + mod->modified = 1; + /* The chunk may have been removed: */ + if (pm->buffer_count == 0) + { + pm->buffer_position = 0; + break; + } + modifier_setbuffer(pm); + } + } + + mod = mod->next; + } + } + else + pm->flush = len+12 - pm->buffer_count; /* data + crc */ + + /* Take the data from the buffer (if there is any). */ + break; + } + + /* Here to read from the modifier buffer (not directly from + * the sucker, as in the flush case above.) + */ + cb = pm->buffer_count - pm->buffer_position; + if (cb > st) cb = st; + memcpy(pb, pm->buffer + pm->buffer_position, cb); + st -= cb; + pb += cb; + pm->buffer_position += cb; + } +} + +/* Set up a modifier. */ +static png_structp +set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id, + const char *name) +{ + png_structp pp = set_sucker_for_read(&pm->this, ppi, id, name); + + if (pp != NULL) + { + if (setjmp(pm->this.jmpbuf) == 0) + { + png_set_read_fn(pp, pm, modifier_read); + + pm->state = modifier_start; + pm->bit_depth = 0; + pm->colour_type = 255; + + pm->pending_len = 0; + pm->pending_chunk = 0; + pm->flush = 0; + pm->buffer_count = 0; + pm->buffer_position = 0; + } + else + { + sucker_read_reset(&pm->this); + pp = NULL; + } + } + + return pp; +} + +/***************************** STANDARD PNG FILES *****************************/ +/* Standard files - write and save standard files. */ +/* The standard files are constructed with rows which fit into a 1024 byte row + * buffer. This makes allocation easier below. Further regardless of the file + * format every file has 128 pixels (giving 1024 bytes for 64bpp formats). + * + * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed + * and with an ID derived from the colour type and bit depth as follows: + */ +#define FILEID(col, depth) ((png_uint_32)((col) + ((depth)<<3))) +#define COL_FROM_ID(id) ((id)& 0x7) +#define DEPTH_FROM_ID(id) (((id) >> 3) & 0x1f) + +#define STD_WIDTH 128 +#define STD_ROWMAX (STD_WIDTH*8) + +static unsigned +bit_size(png_structp pp, png_byte colour_type, png_byte bit_depth) +{ + switch (colour_type) + { + case 0: return bit_depth; + case 2: return 3*bit_depth; + case 3: return bit_depth; + case 4: return 2*bit_depth; + case 6: return 4*bit_depth; + default: png_error(pp, "invalid color type"); + } +} + +static size_t +standard_rowsize(png_structp pp, png_byte colour_type, png_byte bit_depth) +{ + return (STD_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8; +} + +static png_uint_32 +standard_width(png_structp pp, png_byte colour_type, png_byte bit_depth) +{ + return STD_WIDTH; +} + +static png_uint_32 +standard_height(png_structp pp, png_byte colour_type, png_byte bit_depth) +{ + switch (bit_size(pp, colour_type, bit_depth)) + { + case 1: + case 2: + case 4: + return 1; /* Total of 128 pixels */ + case 8: + return 2; /* Total of 256 pixels/bytes */ + case 16: + return 512; /* Total of 65536 pixels */ + case 24: + case 32: + return 512; /* 65536 pixels */ + case 48: + case 64: + return 2048;/* 4 x 65536 pixels. */ + } +} + +static void +standard_row(png_structp pp, png_byte buffer[STD_ROWMAX], png_byte colour_type, + png_byte bit_depth, png_uint_32 y) +{ + png_uint_32 v = y << 7; + png_uint_32 i = 0; + + switch (bit_size(pp, colour_type, bit_depth)) + { + case 1: + while (i<128/8) buffer[i] = v & 0xff, v += 17, ++i; + return; + case 2: + while (i<128/4) buffer[i] = v & 0xff, v += 33, ++i; + return; + case 4: + while (i<128/2) buffer[i] = v & 0xff, v += 65, ++i; + return; + case 8: + /* 256 bytes total, 128 bytes in each row set as follows: */ + while (i<128) buffer[i] = v & 0xff, ++v, ++i; + return; + case 16: + /* Generate all 65536 pixel values in order, this includes the 8 bit GA + * case as we as the 16 bit G case. + */ + while (i<128) + buffer[2*i] = (v>>8) & 0xff, buffer[2*i+1] = v & 0xff, ++v, ++i; + return; + case 24: + /* 65535 pixels, but rotate the values. */ + while (i<128) + { + /* Three bytes per pixel, r, g, b, make b by r^g */ + buffer[3*i+0] = (v >> 8) & 0xff; + buffer[3*i+1] = v & 0xff; + buffer[3*i+2] = ((v >> 8) ^ v) & 0xff; + ++v; + ++i; + } + return; + case 32: + /* 65535 pixels, r, g, b, a; just replicate */ + while (i<128) + { + buffer[4*i+0] = (v >> 8) & 0xff; + buffer[4*i+1] = v & 0xff; + buffer[4*i+2] = (v >> 8) & 0xff; + buffer[4*i+3] = v & 0xff; + ++v; + ++i; + } + return; + case 48: + /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at + * each pixel, g increase by 257 (0x101) and 'b' by 0x1111: + */ + while (i<128) + { + png_uint_32 t = v++; + buffer[6*i+0] = (t >> 8) & 0xff; + buffer[6*i+1] = t & 0xff; + t *= 257; + buffer[6*i+2] = (t >> 8) & 0xff; + buffer[6*i+3] = t & 0xff; + t *= 17; + buffer[6*i+4] = (t >> 8) & 0xff; + buffer[6*i+5] = t & 0xff; + ++i; + } + return; + case 64: + /* As above in the 32 bit case. */ + while (i<128) + { + png_uint_32 t = v++; + buffer[8*i+0] = (t >> 8) & 0xff; + buffer[8*i+1] = t & 0xff; + buffer[8*i+4] = (t >> 8) & 0xff; + buffer[8*i+5] = t & 0xff; + t *= 257; + buffer[8*i+2] = (t >> 8) & 0xff; + buffer[8*i+3] = t & 0xff; + buffer[8*i+6] = (t >> 8) & 0xff; + buffer[8*i+7] = t & 0xff; + ++i; + } + return; + } + + png_error(pp, "internal error"); +} + +static void +make_standard(png_sucker* ps, png_byte colour_type, int bdlo, int bdhi) +{ + for (; bdlo <= bdhi; ++bdlo) + { + png_byte bit_depth = 1U << bdlo; + png_uint_32 h, y; + png_structp pp; + png_infop pi; + + { + size_t pos; + char name[64]; /* Same size as the buffer in a file. */ + + /* Build a name */ + pos = safecat(name, sizeof name, 0, bit_depths[bdlo]); + pos = safecat(name, sizeof name, pos, "bit "); + pos = safecat(name, sizeof name, pos, colour_types[colour_type]); + + /* Get a png_struct for writing the image. */ + pp = set_sucker_for_write(ps, &pi, name); + } + if (pp == NULL) return; + + /* Do the honourable write stuff, protected by a local setjmp */ + if (setjmp(ps->jmpbuf) != 0) + { + sucker_write_reset(ps); + continue; + } + + h = standard_height(pp, colour_type, bit_depth), + png_set_IHDR(pp, pi, standard_width(pp, colour_type, bit_depth), h, + bit_depth, colour_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + + if (colour_type == 3) /* palette */ + { + int i; + png_color pal[256]; + for (i=0; i<256; ++i) pal[i].red = pal[i].green = pal[i].blue = i; + png_set_PLTE(pp, pi, pal, 256); + } + + png_write_info(pp, pi); + + if (png_get_rowbytes(pp, pi) != + standard_rowsize(pp, colour_type, bit_depth)) + png_error(pp, "row size incorrect"); + + else for (y=0; yjmpbuf) != 0) + { + sucker_read_reset(ps); + continue; + } + + h = standard_height(pp, colour_type, bit_depth); + + /* Check the header values: */ + png_read_info(pp, pi); + + if (png_get_image_width(pp, pi) != + standard_width(pp, colour_type, bit_depth)) + png_error(pp, "validate: image width changed"); + if (png_get_image_height(pp, pi) != h) + png_error(pp, "validate: image height changed"); + if (png_get_bit_depth(pp, pi) != bit_depth) + png_error(pp, "validate: bit depth changed"); + if (png_get_color_type(pp, pi) != colour_type) + png_error(pp, "validate: color type changed"); + if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE) + png_error(pp, "validate: filter type changed"); + if (png_get_interlace_type(pp, pi) != PNG_INTERLACE_NONE) + png_error(pp, "validate: interlacing changed"); + if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE) + png_error(pp, "validate: compression type changed"); + if (png_set_interlace_handling(pp) != 1) + png_error(pp, "validate: interlacing unexpected"); + + if (colour_type == 3) /* palette */ + { + png_colorp pal; + int num; + if (png_get_PLTE(pp, pi, &pal, &num) & PNG_INFO_PLTE) + { + int i; + if (num != 256) + png_error(pp, "validate: color type 3 PLTE chunk size changed"); + for (i=0; ithis, 0, 0, 4); + if (fail(pm)) return; + test_standard(&pm->this, 2, 3, 4); + if (fail(pm)) return; + test_standard(&pm->this, 3, 0, 3); + if (fail(pm)) return; + test_standard(&pm->this, 4, 3, 4); + if (fail(pm)) return; + test_standard(&pm->this, 6, 3, 4); +} + + +/********************************* GAMMA TESTS ********************************/ +/* Gamma test images. */ +static void +make_gamma_images(png_sucker *ps) +{ + /* Do nothing - the standard greyscale images are used. */ +} + +typedef struct gamma_modification +{ + png_modification this; + png_fixed_point gamma; +} +gamma_modification; + +static int +gamma_modify(png_structp pp, png_modifier *pm, png_modification *me, int add) +{ + /* This simply dumps the given gamma value into the buffer. */ + png_save_uint_32(pm->buffer, 4); + png_save_uint_32(pm->buffer+4, CHUNK_gAMA); + png_save_uint_32(pm->buffer+8, ((gamma_modification*)me)->gamma); + return 1; +} + +static void +gamma_modification_init(gamma_modification *me, png_modifier *pm, double gamma) +{ + modification_init(&me->this); + me->this.chunk = CHUNK_gAMA; + me->this.modify_fn = gamma_modify; + me->this.add = CHUNK_PLTE; + me->gamma = floor(gamma * 100000 + .5); + me->this.next = pm->modifications; + pm->modifications = &me->this; +} + +typedef struct srgb_modification +{ + png_modification this; + png_byte intent; +} +srgb_modification; + +static int +srgb_modify(png_structp pp, png_modifier *pm, png_modification *me, int add) +{ + /* As above, ignore add and just make a new chunk */ + png_save_uint_32(pm->buffer, 1); + png_save_uint_32(pm->buffer+4, CHUNK_sRGB); + pm->buffer[8] = ((srgb_modification*)me)->intent; + return 1; +} + +static void +srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent) +{ + modification_init(&me->this); + me->this.chunk = CHUNK_sBIT; + if (intent <= 3) /* if valid, else *delete* sRGB chunks */ + { + me->this.modify_fn = srgb_modify; + me->this.add = CHUNK_PLTE; + me->intent = intent; + } + else + { + me->this.modify_fn = 0; + me->this.add = 0; + me->intent = 0; + } + me->this.next = pm->modifications; + pm->modifications = &me->this; +} + +typedef struct sbit_modification +{ + png_modification this; + png_byte sbit; +} +sbit_modification; + +static int +sbit_modify(png_structp pp, png_modifier *pm, png_modification *me, int add) +{ + png_byte sbit = ((sbit_modification*)me)->sbit; + if (pm->bit_depth > sbit) + { + int cb = 0; + switch (pm->colour_type) + { + case 0: cb = 1; break; + case 2: + case 3: cb = 3; break; + case 4: cb = 2; break; + case 6: cb = 4; break; + default: + png_error(pp, "unexpected colour type in sBIT modification"); + } + + png_save_uint_32(pm->buffer, cb); + png_save_uint_32(pm->buffer+4, CHUNK_sBIT); + while (cb > 0) + (pm->buffer+8)[--cb] = sbit; + + return 1; + } + else if (!add) + { + /* Remove the sBIT chunk */ + pm->buffer_count = pm->buffer_position = 0; + return 1; + } + else + return 0; /* do nothing */ +} + +static void +sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit) +{ + modification_init(&me->this); + me->this.chunk = CHUNK_sBIT; + me->this.modify_fn = sbit_modify; + me->this.add = CHUNK_PLTE; + me->sbit = sbit; + me->this.next = pm->modifications; + pm->modifications = &me->this; +} + +/* maxabs: maximum absolute error as a fraction + * maxout: maximum output error in the output units + * maxpc: maximum percentage error (as a percentage) + */ +static void +gamma_test(png_modifier *pm, const png_byte colour_type, + const png_byte bit_depth, const double file_gamma, const double screen_gamma, + const png_byte sbit, const int threshold_test, const char *name, + const int speed, const int use_input_precision, const int strip16) +{ + png_structp pp; + png_infop pi; + double maxerrout = 0, maxerrpc = 0, maxerrabs = 0; + + gamma_modification gamma_mod; + srgb_modification srgb_mod; + sbit_modification sbit_mod; + + /* Make an appropriate modifier to set the PNG file gamma to the + * given gamma value and the sBIT chunk to the given precision. + */ + pm->modifications = NULL; + gamma_modification_init(&gamma_mod, pm, file_gamma); + srgb_modification_init(&srgb_mod, pm, 127/*delete*/); + sbit_modification_init(&sbit_mod, pm, sbit); + + modification_reset(pm->modifications); + + /* Get a png_struct for writing the image. */ + pp = set_modifier_for_read(pm, &pi, FILEID(colour_type, bit_depth), name); + if (pp == NULL) return; + + /* Do the honourable write stuff, protected by a local setjmp */ + if (setjmp(pm->this.jmpbuf) != 0) + { + modifier_reset(pm); + return; + } + + /* Set up gamma processing. */ + png_set_gamma(pp, screen_gamma, file_gamma); + + /* Check the header values: */ + png_read_info(pp, pi); + + /* If requested strip 16 to 8 bits - this is handled automagically below + * because the output bit depth is read from the library. Note that there + * are interactions with sBIT but, internally, libpng makes sbit at most + * PNG_MAX_GAMMA_8 when doing the following. + */ + if (strip16) + png_set_strip_16(pp); + + if (png_set_interlace_handling(pp) != 1) + png_error(pp, "gamma: interlaced images not supported"); + + png_read_update_info(pp, pi); + + { + const png_byte out_ct = png_get_color_type(pp, pi); + const png_byte out_bd = png_get_bit_depth(pp, pi); + const unsigned outmax = (1U<= + PNG_GAMMA_THRESHOLD && !threshold_test && !speed && colour_type != 3) + || bit_depth != out_bd; + const int samples_per_pixel = (out_ct & 2) ? 3 : 1; + const double gamma = 1/(file_gamma*screen_gamma); /* Overall correction */ + + for (y=0; y> (bit_depth-sbit); + double i, sample, encoded_sample, output, encoded_error, error; + double es_lo, es_hi; + + /* First check on the 'perfect' result obtained from the digitized + * input value, id, and compare this against the actual digitized + * result, 'od'. 'i' is the input result in the range 0..1: + * + * NOTE: sbit should be taken into account here but isn't, as + * described above. + */ + i = isbit; i /= (1U< maxerrout) + maxerrout = encoded_error; + + if (encoded_error < .5+maxout) + continue; + + /* There may be an error, calculate the actual sample values - + * unencoded light intensity values. Note that in practice these + * are not unencoded because they include a 'viewing correction' to + * decrease or (normally) increase the perceptual contrast of the + * image. There's nothing we can do about this - we don't know what + * it is - so assume the unencoded value is perceptually linear. + */ + sample = pow(i, 1/file_gamma); /* In range 0..1 */ + output = od; + output /= outmax; + output = pow(output, screen_gamma); + + /* Now we have the numbers for real errors, both absolute values as + * as a percentage of the correct value (output): + */ + error = fabs(sample-output); + if (error > maxerrabs) + maxerrabs = error; + /* The following is an attempt to ignore the tendency of + * quantization to dominate the percentage errors for low output + * sample values: + */ + if (sample*maxpc > .5+maxabs) + { + double pcerr = error/sample; + if (pcerr > maxerrpc) maxerrpc = pcerr; + } + + /* Now calculate the digitization limits for 'encoded_sample' using + * the 'max' values. Note that maxout is in the encoded space but + * maxpc and maxabs are in linear light space. + * + * First find the maximum error in linear light space, range 0..1: + */ + { + double tmp = sample * maxpc; + if (tmp < maxabs) tmp = maxabs; + + /* Low bound - the minimum of the three: */ + es_lo = encoded_sample - maxout; + if (es_lo > 0 && sample-tmp > 0) + { + double l = outmax * pow(sample-tmp, 1/screen_gamma); + if (l < es_lo) es_lo = l; + } + else + es_lo = 0; + + es_hi = encoded_sample + maxout; + if (es_hi < outmax && sample+tmp < 1) + { + double h = outmax * pow(sample+tmp, 1/screen_gamma); + if (h > es_hi) es_hi = h; + } + else + es_hi = outmax; + } + + /* The primary test is that the final encoded value returned by the + * library should be between the two limits (inclusive) that were + * calculated above. At this point quantization of the output must + * be taken into account. + */ + if (od+.5 < es_lo || od-.5 > es_hi) + { + /* Thee has been an error in processing. */ + double is_lo, is_hi; + + if (use_input_precision) + { + /* Ok, something is wrong - this actually happens in current + * libpng sbit 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. + */ + double tmp = (isbit - .5)/((1U< 0) + { + is_lo = outmax * pow(tmp, gamma) - maxout; + if (is_lo < 0) is_lo = 0; + } + else + is_lo = 0; + + tmp = (isbit + .5)/((1U< outmax) is_hi = outmax; + } + else + is_hi = outmax; + + if (!(od+.5 < is_lo || od-.5 > is_hi)) + continue; + } + + { + char msg[256]; + sprintf(msg, + "error: %.3f; %u{%u;%u} -> %u not %.2f (%.1f-%.1f)", + od-encoded_sample, id, sbit, isbit, od, encoded_sample, + use_input_precision ? is_lo : es_lo, + use_input_precision ? is_hi : es_hi); + png_warning(pp, msg); + } + } + } + else if (!speed && memcmp(std, display, cb) != 0) + { + char msg[64]; + /* No transform is expected on the threshold tests. */ + sprintf(msg, "gamma: below threshold row %d (of %d) changed", y, h); + png_error(pp, msg); + } + } + } + + png_read_end(pp, pi); + modifier_reset(pm); + + if (pm->log && !threshold_test && !speed) + fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n", bit_depth, + colour_types[colour_type], name, maxerrout, maxerrabs, 100*maxerrpc); + + /* Log the summary values too. */ + if (colour_type == 0 || colour_type == 4) switch (bit_depth) + { + case 2: + if (maxerrout > pm->error_gray_2) pm->error_gray_2 = maxerrout; break; + case 4: + if (maxerrout > pm->error_gray_4) pm->error_gray_4 = maxerrout; break; + case 8: + if (maxerrout > pm->error_gray_8) pm->error_gray_8 = maxerrout; break; + case 16: + if (maxerrout > pm->error_gray_16) pm->error_gray_16 = maxerrout; break; + } + else if (colour_type == 2 || colour_type == 6) switch (bit_depth) + { + case 8: + if (maxerrout > pm->error_color_8) pm->error_color_8 = maxerrout; break; + case 16: + if (maxerrout > pm->error_color_16) pm->error_color_16 = maxerrout; break; + } +} + +static void gamma_threshold_test(png_modifier *pm, png_byte colour_type, + png_byte bit_depth, double file_gamma, double screen_gamma) +{ + size_t pos = 0; + char name[64]; + pos = safecat(name, sizeof name, pos, "threshold "); + pos = safecatd(name, sizeof name, pos, file_gamma, 3); + pos = safecat(name, sizeof name, pos, "/"); + pos = safecatd(name, sizeof name, pos, screen_gamma, 3); + + (void)gamma_test(pm, colour_type, bit_depth, file_gamma, screen_gamma, + bit_depth, 1, name, 0/*speed*/, 0/*no input precision*/, 0/*no strip16*/); +} + +static void +perform_gamma_threshold_tests(png_modifier *pm) +{ + png_byte colour_type = 0; + png_byte bit_depth = 0; + + while (next_format(&colour_type, &bit_depth)) + { + double gamma = 1.0; + while (gamma >= .4) + { + gamma_threshold_test(pm, colour_type, bit_depth, gamma, 1/gamma); + gamma *= .95; + } + + /* And a special test for sRGB */ + gamma_threshold_test(pm, colour_type, bit_depth, .45455, 2.2); + if (fail(pm)) return; + } +} + +static void gamma_transform_test(png_modifier *pm, const png_byte colour_type, + const png_byte bit_depth, const double file_gamma, const double screen_gamma, + const png_byte sbit, const int speed, const int use_input_precision, + const int strip16) +{ + size_t pos = 0; + char name[64]; + if (sbit != bit_depth) + { + pos = safecat(name, sizeof name, pos, "sbit("); + pos = safecatn(name, sizeof name, pos, sbit); + pos = safecat(name, sizeof name, pos, ") "); + } + else + pos = safecat(name, sizeof name, pos, "gamma "); + if (strip16) + pos = safecat(name, sizeof name, pos, "16to8 "); + pos = safecatd(name, sizeof name, pos, file_gamma, 3); + pos = safecat(name, sizeof name, pos, "->"); + pos = safecatd(name, sizeof name, pos, screen_gamma, 3); + + gamma_test(pm, colour_type, bit_depth, file_gamma, screen_gamma, sbit, 0, + name, speed, use_input_precision, strip16); +} + +static void perform_gamma_transform_tests(png_modifier *pm, int speed) +{ + png_byte colour_type = 0; + png_byte bit_depth = 0; + + /* Ignore palette images - the gamma correction happens on the palette entry, + * haven't got the tests for this yet. + */ + while (next_format(&colour_type, &bit_depth)) if (colour_type != 3) + { + int i, j; + + for (i=0; ingammas; ++i) for (j=0; jngammas; ++j) if (i != j) + { + gamma_transform_test(pm, colour_type, bit_depth, 1/pm->gammas[i], + pm->gammas[j], bit_depth, speed, pm->use_input_precision, + 0/*do not strip16*/); + if (fail(pm)) return; + } + } +} + +static void perform_gamma_sbit_tests(png_modifier *pm, int speed) +{ + png_byte sbit; + + /* The only interesting cases are colour and grayscale, alpha is ignored here + * for overall speed. Only bit depths 8 and 16 are tested. + */ + for (sbit=pm->sbitlow; sbit<16; ++sbit) + { + int i, j; + for (i=0; ingammas; ++i) for (j=0; jngammas; ++j) + if (i != j) + { + if (sbit < 8) + { + gamma_transform_test(pm, 0, 8, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); + if (fail(pm)) return; + gamma_transform_test(pm, 2, 8, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); + if (fail(pm)) return; + } + gamma_transform_test(pm, 0, 16, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); + if (fail(pm)) return; + gamma_transform_test(pm, 2, 16, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); + if (fail(pm)) return; + } + } +} + +static void perform_gamma_strip16_tests(png_modifier *pm, int speed) +{ +# ifndef PNG_MAX_GAMMA_8 +# define PNG_MAX_GAMMA_8 11 +# endif + /* Include the alpha cases here, not that sbit matches the internal value + * used by the library - otherwise we will get spurious errors from the + * internal sbit style approximation. + * + * The threshold test is here because otherwise the 16 to 8 convertion will + * proceed *without* gamma correction, and the tests above will fail (but not + * by much) - this could be fixed, it only appears with the -g option. + */ + int i, j; + for (i=0; ingammas; ++i) for (j=0; jngammas; ++j) + if (i != j && fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD) + { + gamma_transform_test(pm, 0, 16, 1/pm->gammas[i], pm->gammas[j], + PNG_MAX_GAMMA_8, speed, pm->use_input_precision_16to8, 1/*strip16*/); + if (fail(pm)) return; + gamma_transform_test(pm, 2, 16, 1/pm->gammas[i], pm->gammas[j], + PNG_MAX_GAMMA_8, speed, pm->use_input_precision_16to8, 1/*strip16*/); + if (fail(pm)) return; + gamma_transform_test(pm, 4, 16, 1/pm->gammas[i], pm->gammas[j], + PNG_MAX_GAMMA_8, speed, pm->use_input_precision_16to8, 1/*strip16*/); + if (fail(pm)) return; + gamma_transform_test(pm, 6, 16, 1/pm->gammas[i], pm->gammas[j], + PNG_MAX_GAMMA_8, speed, pm->use_input_precision_16to8, 1/*strip16*/); + if (fail(pm)) return; + } +} + +static void +perform_gamma_test(png_modifier *pm, int speed, int summary) +{ + /* First some arbitrary no-transform tests: */ + if (!speed) + { + perform_gamma_threshold_tests(pm); + if (fail(pm)) return; + } + + /* Now some real transforms. */ + perform_gamma_transform_tests(pm, speed); + if (summary) + { + printf("Gamma correction error summary (output value error):\n"); + 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(" 16 bit gray: %.5f\n", pm->error_gray_16); + printf(" 8 bit color: %.5f\n", pm->error_color_8); + printf(" 16 bit color: %.5f\n", pm->error_color_16); + } + + /* The sbit tests produce much larger errors: */ + pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = pm->error_gray_16 = + pm->error_color_8 = pm->error_color_16 = 0; + perform_gamma_sbit_tests(pm, speed); + if (summary) + { + printf("Gamma correction with sBIT:\n"); + if (pm->sbitlow < 8) + { + 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(" 16 bit gray: %.5f\n", pm->error_gray_16); + if (pm->sbitlow < 8) + printf(" 8 bit color: %.5f\n", pm->error_color_8); + printf(" 16 bit color: %.5f\n", pm->error_color_16); + } + + /* The 16 to 8 bit strip operations: */ + pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = pm->error_gray_16 = + pm->error_color_8 = pm->error_color_16 = 0; + perform_gamma_strip16_tests(pm, speed); + if (summary) + { + printf("Gamma 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); + } +} + +/* main program */ +int main(int argc, const char **argv) +{ + int summary = 1; /* Print the error sumamry at the end */ + int speed = 0; /* Speed test only (for gamma stuff) */ + + /* This is an array of standard gamma values (believe it or not I've seen + * every one of these mentioned somewhere.) + * + * In the following list the most useful values are first! + */ + static double gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9}; + + png_modifier pm; + modifier_init(&pm); + + /* Default to error on warning: */ + pm.this.treat_warnings_as_errors = 1; + + /* Store the test gammas */ + pm.gammas = gammas; + pm.ngammas = 3; /* for speed */ + pm.sbitlow = 8; /* because libpng doesn't do sbit below 8! */ + pm.use_input_precision_16to8 = 1; /* Because of the way libpng does it */ + + /* Some default values (set the behavior for 'make check' here) */ + pm.maxout8 = .1; /* Arithmetic error in *encoded* value */ + pm.maxabs8 = .00005; /* 1/20000 */ + pm.maxpc8 = .499; /* I.e. .499% fractional error */ + pm.maxout16 = .499; /* Error in *encoded* value */ + pm.maxabs16 = .00005;/* 1/20000 */ + /* NOTE: this is a reasonable perceptual limit, we assume that humans can + * perceive light level differences of 1% over a 100:1 range, so we need to + * maintain 1 in 10000 accuracy (in linear light space), this is what the + * following guarantees. It also allows significantly higher errors at + * higher 16 bit values, which is important for performance. The actual + * maximum 16 bit error is about +/-1.9 in the fixed point implementation but + * this is only allowed for values >38149 by the following: + */ + pm.maxpc16 = .005; /* I.e. 1/200% - 1/20000 */ + + /* Now parse the command line options. */ + while (--argc >= 1) + if (strcmp(*++argv, "-v") == 0) + pm.this.verbose = 1; + else if (strcmp(*argv, "-l") == 0) + pm.log = 1; + else if (strcmp(*argv, "-q") == 0) + pm.this.verbose = pm.log = summary = 0; + else if (strcmp(*argv, "-g") == 0) + pm.ngammas = (sizeof gammas)/(sizeof gammas[0]); + else if (strcmp(*argv, "-w") == 0) + pm.this.treat_warnings_as_errors = 0; + else if (strcmp(*argv, "-speed") == 0) + speed = 1, pm.ngammas = (sizeof gammas)/(sizeof gammas[0]); + else if (argc >= 1 && strcmp(*argv, "-sbitlow") == 0) + --argc, pm.sbitlow = atol(*++argv); + else if (argc >= 1 && strncmp(*argv, "-max", 4) == 0) + { + --argc; + if (strcmp(4+*argv, "abs8") == 0) + pm.maxabs8 = atof(*++argv); + else if (strcmp(4+*argv, "abs16") == 0) + pm.maxabs16 = atof(*++argv); + else if (strcmp(4+*argv, "out8") == 0) + pm.maxout8 = atof(*++argv); + else if (strcmp(4+*argv, "out16") == 0) + pm.maxout16 = atof(*++argv); + else if (strcmp(4+*argv, "pc8") == 0) + pm.maxpc8 = atof(*++argv); + else if (strcmp(4+*argv, "pc16") == 0) + pm.maxpc16 = atof(*++argv); + else + { + fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv); + exit(1); + } + } + else + { + fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv); + exit(1); + } + + /* Make useful base images */ + make_standard_images(&pm.this); + make_gamma_images(&pm.this); + + /* Perform the standard and gamma tests. */ + if (!speed) + perform_standard_test(&pm); + perform_gamma_test(&pm, speed, summary && !speed); + if (summary && !speed) + printf("Results using %s point arithmetic %s\n", +#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500 + "floating", +#else + "fixed", +#endif + (pm.this.nerrors || pm.this.treat_warnings_as_errors && + pm.this.nwarnings) ? "(errors)" : (pm.this.nwarnings ? + "(warnings)" : "(no errors or warnings)") + ); + + /* Error exit if there are any errors, and maybe if there are any + * warnings. + */ + if (pm.this.nerrors || pm.this.treat_warnings_as_errors && pm.this.nwarnings) + { + if (!pm.this.verbose) + fprintf(stderr, "pngvalid: %s\n", pm.this.error); + fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors, + pm.this.nwarnings); + exit(1); + } + + return 0; +} + +/* vim: set sw=3 ts=8 tw=80: */ diff --git a/pngwio.c b/pngwio.c index 795e2f7c2..20955af40 100644 --- a/pngwio.c +++ b/pngwio.c @@ -1,7 +1,7 @@ /* pngwio.c - functions for data output * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) diff --git a/pngwrite.c b/pngwrite.c index b7564ba66..15d7f6e18 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1,7 +1,7 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -60,15 +60,7 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) */ #ifdef PNG_WRITE_gAMA_SUPPORTED if (info_ptr->valid & PNG_INFO_gAMA) - { -# ifdef PNG_FLOATING_POINT_SUPPORTED - png_write_gAMA(png_ptr, info_ptr->gamma); -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma); -# endif -#endif - } + png_write_gAMA_fixed(png_ptr, info_ptr->gamma); #endif #ifdef PNG_WRITE_sRGB_SUPPORTED if (info_ptr->valid & PNG_INFO_sRGB) @@ -78,32 +70,19 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_WRITE_iCCP_SUPPORTED if (info_ptr->valid & PNG_INFO_iCCP) png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, - info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); + (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); #endif #ifdef PNG_WRITE_sBIT_SUPPORTED if (info_ptr->valid & PNG_INFO_sBIT) png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); #endif - #ifdef PNG_WRITE_cHRM_SUPPORTED if (info_ptr->valid & PNG_INFO_cHRM) - { -#ifdef PNG_FLOATING_POINT_SUPPORTED - png_write_cHRM(png_ptr, + png_write_cHRM_fixed(png_ptr, info_ptr->x_white, info_ptr->y_white, info_ptr->x_red, info_ptr->y_red, info_ptr->x_green, info_ptr->y_green, info_ptr->x_blue, info_ptr->y_blue); -#else -# ifdef PNG_FIXED_POINT_SUPPORTED - png_write_cHRM_fixed(png_ptr, - info_ptr->int_x_white, info_ptr->int_y_white, - info_ptr->int_x_red, info_ptr->int_y_red, - info_ptr->int_x_green, info_ptr->int_y_green, - info_ptr->int_x_blue, info_ptr->int_y_blue); -# endif -#endif - } #endif #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED @@ -168,7 +147,8 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) { int j; for (j = 0; j<(int)info_ptr->num_trans; j++) - info_ptr->trans_alpha[j] = (png_byte)(255 - info_ptr->trans_alpha[j]); + info_ptr->trans_alpha[j] = + (png_byte)(255 - info_ptr->trans_alpha[j]); } #endif png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), @@ -198,25 +178,10 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) info_ptr->pcal_units, info_ptr->pcal_params); #endif -#ifdef PNG_sCAL_SUPPORTED - if (info_ptr->valid & PNG_INFO_sCAL) #ifdef PNG_WRITE_sCAL_SUPPORTED - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) - png_write_sCAL(png_ptr, (int)info_ptr->scal_unit, - info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); -#else /* !FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED + if (info_ptr->valid & PNG_INFO_sCAL) png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, info_ptr->scal_s_width, info_ptr->scal_s_height); -#endif /* FIXED_POINT */ - -#endif /* FLOATING_POINT */ -#else /* !WRITE_sCAL */ - png_warning(png_ptr, - "png_write_sCAL not supported; sCAL chunk not written"); -#endif /* WRITE_sCAL */ #endif /* sCAL */ #ifdef PNG_WRITE_pHYs_SUPPORTED diff --git a/pngwtran.c b/pngwtran.c index d150420ba..dff65850a 100644 --- a/pngwtran.c +++ b/pngwtran.c @@ -1,7 +1,7 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) diff --git a/pngwutil.c b/pngwutil.c index e3e96fb7b..ced9f0f2f 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1,7 +1,7 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.5.0 [July 24, 2010] + * Last changed in libpng 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 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.) @@ -32,7 +32,9 @@ png_save_uint_32(png_bytep buf, png_uint_32 i) #ifdef PNG_SAVE_INT_32_SUPPORTED /* The png_save_int_32 function assumes integers are stored in two's * complement format. If this isn't the case, then this routine needs to - * be modified to write data in two's complement format. + * be modified to write data in two's complement format. Note that, + * the following works correctly even if png_int_32 has more than 32 bits + * (compare the more complex code required on read for sign extention.) */ void PNGAPI png_save_int_32(png_bytep buf, png_int_32 i) @@ -770,23 +772,6 @@ png_write_IEND(png_structp png_ptr) #ifdef PNG_WRITE_gAMA_SUPPORTED /* Write a gAMA chunk */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -void /* PRIVATE */ -png_write_gAMA(png_structp png_ptr, double file_gamma) -{ - PNG_gAMA; - png_uint_32 igamma; - png_byte buf[4]; - - png_debug(1, "in png_write_gAMA"); - - /* file_gamma is saved in 1/100,000ths */ - igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); - png_save_uint_32(buf, igamma); - png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); -} -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) { @@ -800,7 +785,6 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); } #endif -#endif #ifdef PNG_WRITE_sRGB_SUPPORTED /* Write a sRGB chunk */ @@ -1044,53 +1028,6 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) #ifdef PNG_WRITE_cHRM_SUPPORTED /* Write the cHRM chunk */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -void /* PRIVATE */ -png_write_cHRM(png_structp png_ptr, double white_x, double white_y, - double red_x, double red_y, double green_x, double green_y, - double blue_x, double blue_y) -{ - PNG_cHRM; - png_byte buf[32]; - - png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, - int_green_x, int_green_y, int_blue_x, int_blue_y; - - png_debug(1, "in png_write_cHRM"); - - int_white_x = (png_uint_32)(white_x * 100000.0 + 0.5); - int_white_y = (png_uint_32)(white_y * 100000.0 + 0.5); - int_red_x = (png_uint_32)(red_x * 100000.0 + 0.5); - int_red_y = (png_uint_32)(red_y * 100000.0 + 0.5); - int_green_x = (png_uint_32)(green_x * 100000.0 + 0.5); - int_green_y = (png_uint_32)(green_y * 100000.0 + 0.5); - int_blue_x = (png_uint_32)(blue_x * 100000.0 + 0.5); - int_blue_y = (png_uint_32)(blue_y * 100000.0 + 0.5); - -#ifdef PNG_CHECK_cHRM_SUPPORTED - if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y, - int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y)) -#endif - { - /* Each value is saved in 1/100,000ths */ - - png_save_uint_32(buf, int_white_x); - png_save_uint_32(buf + 4, int_white_y); - - png_save_uint_32(buf + 8, int_red_x); - png_save_uint_32(buf + 12, int_red_y); - - png_save_uint_32(buf + 16, int_green_x); - png_save_uint_32(buf + 20, int_green_y); - - png_save_uint_32(buf + 24, int_blue_x); - png_save_uint_32(buf + 28, int_blue_y); - - png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); - } -} -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, @@ -1124,7 +1061,6 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, } } #endif -#endif #ifdef PNG_WRITE_tRNS_SUPPORTED /* Write the tRNS chunk */ @@ -1691,27 +1627,6 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, #ifdef PNG_WRITE_sCAL_SUPPORTED /* Write the sCAL chunk */ -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -void /* PRIVATE */ -png_write_sCAL(png_structp png_ptr, int unit, double width, double height) -{ - PNG_sCAL; - char buf[64]; - png_size_t total_len; - - png_debug(1, "in png_write_sCAL"); - - buf[0] = (char)unit; - png_snprintf(buf + 1, 63, "%12.12e", width); - total_len = 1 + png_strlen(buf + 1) + 1; - png_snprintf(buf + total_len, 64 - total_len, "%12.12e", height); - total_len += png_strlen(buf + total_len); - - png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len); -} -#else -#ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, png_charp height) @@ -1740,8 +1655,6 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len); } #endif -#endif -#endif #ifdef PNG_WRITE_pHYs_SUPPORTED /* Write the pHYs chunk */ diff --git a/scripts/README.txt b/scripts/README.txt index af6a570ee..7109ef943 100644 --- a/scripts/README.txt +++ b/scripts/README.txt @@ -1,5 +1,5 @@ -Makefiles for libpng version 1.5.0beta36 - July 24, 2010 +Makefiles for libpng version 1.5.0beta36 - July 29, 2010 pnglibconf.h => Stores configuration settings makefile.linux => Linux/ELF makefile diff --git a/scripts/makefile.dj2 b/scripts/makefile.dj2 index 1163043b3..c821cbaf4 100644 --- a/scripts/makefile.dj2 +++ b/scripts/makefile.dj2 @@ -1,5 +1,5 @@ # DJGPP (DOS gcc) makefile for libpng -# Copyright (C) 2002, 2006, 2009 Glenn Randers-Pehrson +# Copyright (C) 2002, 2006, 2009-2010 Glenn Randers-Pehrson # Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc. # # This code is released under the libpng license. diff --git a/scripts/makefile.watcom b/scripts/makefile.watcom index 4f9c7a177..aa1cf5be0 100644 --- a/scripts/makefile.watcom +++ b/scripts/makefile.watcom @@ -50,8 +50,14 @@ OBJS3=pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) all: test # see scripts/pnglibconf.mak for more options +# to support watcom calling conventions it is necessary to set PNG_API_RULE to 2 +# in pnglibconf.h - copy scripts/pnglibconf.h, delete the first line and change +# the definition of PNG_API_RULE from 0 to 2. +# +# If you know how to do this with the Watcom build system please supply a patch +# for this makefile to the PNG implementation list. pnglibconf.h: scripts/pnglibconf.h - cp scripts/pnglibconf.h $@ + @echo please copy scripts/pnglibconf.h and change PNG_API_RULE to 2 png$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h $(CC) $(CFLAGS) $*.c $(ERRFILE) diff --git a/scripts/options.awk b/scripts/options.awk index e58fe4bc1..67b4626b6 100755 --- a/scripts/options.awk +++ b/scripts/options.awk @@ -1,7 +1,7 @@ #!/bin/awk -f # scripts/options.awk - library build configuration control # -# last changed in libpng version 1.5.0 - July 24, 2010 +# last changed in libpng version 1.5.0 - July 29, 2010 # # Copyright (c) 1998-2010 Glenn Randers-Pehrson # diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa index d05783886..6e8e8b43c 100644 --- a/scripts/pnglibconf.dfa +++ b/scripts/pnglibconf.dfa @@ -6,7 +6,7 @@ # com pnglibconf.h - library build configuration com -com libpng version PNGLIB_VERSION - last changed on July 24, 2010 +com libpng version PNGLIB_VERSION - last changed on July 29, 2010 com com Copyright (c) 1998-2010 Glenn Randers-Pehrson com @@ -134,6 +134,17 @@ logunsupported = 1 @# include "pngusr.h" @#endif +# This is a special fixup for the Watcom C compiler on Windows, which has +# multiple procedure call standards. Unless PNG_API_RULE is set explicitly +# (i.e. if it is not defined at this point) it will be forced to '2' here when +# using Watcom. This indicates to the other header files that Watcom behaviour +# is required where appropriate. +@#ifdef __WATCOMC__ +@# ifndef PNG_API_RULE +@# define PNG_API_RULE 2 /* Use Watcom calling conventions */ +@# endif +@#endif + # Note that PNG_USR_CONFIG only has an effect when building # pnglibconf.h setting USER_CONFIG requires USER_PRIVATEBUILD USER_DLLFNAME_POSTFIX @@ -166,8 +177,14 @@ option WRITE_INT_FUNCTIONS disabled option WRITE enables WRITE_INT_FUNCTIONS # Generic options - affect both read and write. +option WARNINGS option BENIGN_ERRORS option MNG_FEATURES + +# Arithmetic options, the first is the big switch that chooses between internal +# floating and fixed point arithmetic implementations - it does not affect any +# APIs. The second two (the _POINT settings) switch off individual APIs. +option FLOATING_ARITHMETIC option FLOATING_POINT enables ok_math option FIXED_POINT enables ok_math @@ -287,8 +304,8 @@ option SEQUENTIAL_READ requires READ option READ_COMPOSITE_NODIV requires READ = NO_READ_COMPOSITE_NODIV PNG_NO_READ_COMPOSITED_NODIV -# Inch conversions: not switched on by default -option INCH_CONVERSIONS requires FLOATING_POINT +# Inch conversions +option INCH_CONVERSIONS = INCH_CONVERSIONS PNG_INCH_CONVERSIONS # IN DEVELOPMENT @@ -319,6 +336,8 @@ option WRITE_USER_TRANSFORM requires WRITE_TRANSFORMS # trouble if left undefined option WRITE_INTERLACING requires WRITE +# The following depends, internally, on WEIGHT_SHIFT and COST_SHIFT +# where are set below. option WRITE_WEIGHTED_FILTER requires WRITE FLOATING_POINT option WRITE_FLUSH requires WRITE @@ -349,6 +368,81 @@ option WRITE_ANCILLARY_CHUNKS requires WRITE option READ_TEXT requires READ_ANCILLARY_CHUNKS enables TEXT option WRITE_TEXT requires WRITE_ANCILLARY_CHUNKS enables TEXT +# Moved to pnglibconf.h at libpng-1.5.0 +# Feature support: in 1.4 this was in pngconf.h, but the following +# features have no affect on the libpng API. Add library +# only features to the end of this list. Add features that +# affect the API above. (Note: the list of chunks follows +# the library-only settings.) +# +# BUILD TIME ONLY OPTIONS +# These options do not affect the API but rather alter how the +# API is implemented, they get recorded in pnglibconf.h, but +# can't be changed by the application. + +# Check the correctness of cHRM chunks +option CHECK_cHRM requires cHRM +# +# Artificially align memory - the code typically aligns to 8 byte +# boundaries if this is switched on, it's a small waste of space +# but can help (in theory) on some architectures. Only affects +# internal structures. Added at libpng 1.4.0 +option ALIGN_MEMORY + +# Buggy compilers (e.g., gcc 2.7.2.2) need PNG_NO_POINTER_INDEXING +# See png[wr]util.c, normally this should always be *on* +option POINTER_INDEXING + +# Other defines for things like memory and the like can go here. + +# BUILD TIME SETTINGS +# Like build time options these do not affect the API, but they +# may be useful to applications because they record details of +# how the API will behave particularly with regard to overall +# accuracy. + +# This controls how fine the quantizing gets. As this allocates +# a largish chunk of memory (32K), those who are not as concerned +# with quantizing quality can decrease some or all of these. +setting QUANTIZE_RED_BITS default 5 +setting QUANTIZE_GREEN_BITS default 5 +setting QUANTIZE_BLUE_BITS default 5 + +# This controls how fine the gamma correction becomes when you +# are only interested in 8 bits anyway. Increasing this value +# results in more memory being used, and more pow() functions +# being called to fill in the gamma tables. Don't set this value +# less then 8, and even that may not work (I haven't tested it). +setting MAX_GAMMA_8 default 11 + +# This controls how much a difference in gamma we can tolerate before +# we actually start doing gamma conversion, it's a fixed point value, +# so the default below is 0.05, meaning libpng ignores corrections in +# the range 0.95 to 1.05 +setting GAMMA_THRESHOLD_FIXED default 5000 + +# Scaling factor for filter heuristic weighting calculations +setting WEIGHT_SHIFT default 8 +setting COST_SHIFT default 3 + +# Precision to use when converting a floating point value to a PNG +# extension format string in an sCAL chunk (only relevant if the +# floating point API is enabled) +setting sCAL_PRECISION default 5 + +# This is the size of the compression buffer, and thus the size of +# an IDAT chunk. Make this whatever size you feel is best for your +# machine. One of these will be allocated per png_struct. When this +# is full, it writes the data to the disk, and does some other +# calculations. Making this an extremely small size may slow +# the library down, but you may want to experiment to determine +# where it becomes significant, if you are concerned with memory +# usage. Note that zlib allocates at least 32Kb also. For readers, +# this describes the size of the buffer available to read the data in. +# Unless this gets smaller than the size of a row (compressed), +# it should not make much difference how big this is. +setting ZBUF_SIZE default 8192 + # Ancillary chunks chunk bKGD chunk cHRM @@ -389,13 +483,8 @@ option WRITE_UNKNOWN_CHUNKS requires WRITE option HANDLE_AS_UNKNOWN -option GET_INT_32 requires READ -# png_get_int_32 is required by the ancillary chunks oFFs and pCAL -option READ_oFFs enables GET_INT_32 -option READ_pCAL enables GET_INT_32 - option SAVE_INT_32 requires WRITE -# Likewise for png_save_int_32 +# png_save_int_32 is required by the ancillary chunks oFFs and pCAL option WRITE_oFFs enables SAVE_INT_32 option WRITE_pCAL enables SAVE_INT_32 diff --git a/scripts/pnglibconf.h b/scripts/pnglibconf.h index 783c438ea..4469b0f20 100644 --- a/scripts/pnglibconf.h +++ b/scripts/pnglibconf.h @@ -1,7 +1,7 @@ /* libpng-1.5.0beta36 STANDARD API DEFINITION */ /* pnglibconf.h - library build configuration */ -/* last changed in libpng version 1.5.0 - July 24, 2010 */ +/* last changed in libpng version 1.5.0 - July 29, 2010 */ /* Copyright (c) 1998-2010 Glenn Randers-Pehrson */ @@ -15,20 +15,33 @@ #ifndef PNGLCONF_H #define PNGLCONF_H /* settings */ +#define PNG_MAX_GAMMA_8 11 #define PNG_CALLOC_SUPPORTED +#define PNG_QUANTIZE_RED_BITS 5 #define PNG_USER_WIDTH_MAX 1000000L +#define PNG_QUANTIZE_GREEN_BITS 5 #define PNG_API_RULE 0 +#define PNG_QUANTIZE_BLUE_BITS 5 #define PNG_USER_CHUNK_CACHE_MAX 0 #define PNG_USER_HEIGHT_MAX 1000000L +#define PNG_sCAL_PRECISION 5 +#define PNG_COST_SHIFT 3 +#define PNG_WEIGHT_SHIFT 8 #define PNG_USER_CHUNK_MALLOC_MAX 0 #define PNG_DEFAULT_READ_MACROS 1 +#define PNG_ZBUF_SIZE 8192 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 /* end of settings */ /* options */ #define PNG_INFO_IMAGE_SUPPORTED #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_POINTER_INDEXING_SUPPORTED +#define PNG_WARNINGS_SUPPORTED +#define PNG_FLOATING_ARITHMETIC_SUPPORTED #define PNG_WRITE_SUPPORTED #define PNG_WRITE_INTERLACING_SUPPORTED #define PNG_EASY_ACCESS_SUPPORTED +#define PNG_ALIGN_MEMORY_SUPPORTED #define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_USER_LIMITS_SUPPORTED #define PNG_FIXED_POINT_SUPPORTED @@ -112,7 +125,6 @@ #define PNG_WRITE_BGR_SUPPORTED #define PNG_USER_CHUNKS_SUPPORTED #define PNG_CONSOLE_IO_SUPPORTED -#define PNG_GET_INT_32_SUPPORTED #define PNG_WRITE_PACK_SUPPORTED #define PNG_READ_FILLER_SUPPORTED #define PNG_WRITE_bKGD_SUPPORTED @@ -144,6 +156,7 @@ #define PNG_READ_zTXt_SUPPORTED #define PNG_gAMA_SUPPORTED #define PNG_pCAL_SUPPORTED +#define PNG_CHECK_cHRM_SUPPORTED #define PNG_tIME_SUPPORTED #define PNG_pHYs_SUPPORTED #define PNG_READ_iTXt_SUPPORTED diff --git a/scripts/pngwin.def b/scripts/pngwin.def index 69450a456..020d69ba6 100644 --- a/scripts/pngwin.def +++ b/scripts/pngwin.def @@ -217,3 +217,13 @@ EXPORTS png_save_uint_32 @205 png_save_int_32 @206 png_save_uint_16 @207 + png_set_gamma_fixed @208 + png_set_filter_heuristics_fixed @209 + png_get_pixel_aspect_ratio_fixed @210 + png_get_x_offset_inches_fixed @211 + png_get_y_offset_inches_fixed @212 + png_set_sCAL_fixed @213 + png_get_sCAL_fixed @214 + png_get_num_passes @215 + png_get_num_rows @216 + png_set_background_fixed @217 diff --git a/scripts/pngwin.dfn b/scripts/pngwin.dfn index 0e50f9849..9fd159f30 100644 --- a/scripts/pngwin.dfn +++ b/scripts/pngwin.dfn @@ -1,7 +1,7 @@ /* pngwin.dfn - define format of pngwin.def * - * Last changed in libpng version 1.5.0 [July 24, 2010] + * Last changed in libpng version 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 Glenn Randers-Pehrson * * This code is released under the libpng license. diff --git a/scripts/sym.dfn b/scripts/sym.dfn index db0de6790..42a802dd0 100644 --- a/scripts/sym.dfn +++ b/scripts/sym.dfn @@ -1,7 +1,7 @@ /* sym.dfn - define format of libpng.sym * - * Last changed in libpng version 1.5.0 [July 24, 2010] + * Last changed in libpng version 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 Glenn Randers-Pehrson * * This code is released under the libpng license. diff --git a/scripts/symbols.def b/scripts/symbols.def index f29a7409f..c449c3bee 100644 --- a/scripts/symbols.def +++ b/scripts/symbols.def @@ -213,3 +213,13 @@ EXPORTS png_save_uint_32 @205 png_save_int_32 @206 png_save_uint_16 @207 + png_set_gamma_fixed @208 + png_set_filter_heuristics_fixed @209 + png_get_pixel_aspect_ratio_fixed @210 + png_get_x_offset_inches_fixed @211 + png_get_y_offset_inches_fixed @212 + png_set_sCAL_fixed @213 + png_get_sCAL_fixed @214 + png_get_num_passes @215 + png_get_num_rows @216 + png_set_background_fixed @217 diff --git a/scripts/symbols.dfn b/scripts/symbols.dfn index 30c10a6ca..fd2fce290 100644 --- a/scripts/symbols.dfn +++ b/scripts/symbols.dfn @@ -1,7 +1,7 @@ /* symbols.dfn - find all exported symbols * - * Last changed in libpng version 1.5.0 [July 24, 2010] + * Last changed in libpng version 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 Glenn Randers-Pehrson * * This code is released under the libpng license. diff --git a/scripts/vers.dfn b/scripts/vers.dfn index 79c6781d8..2ef4c203c 100644 --- a/scripts/vers.dfn +++ b/scripts/vers.dfn @@ -1,7 +1,7 @@ /* vers.dfn - define format of libpng.vers * - * Last changed in libpng version 1.5.0 [July 24, 2010] + * Last changed in libpng version 1.5.0 [July 29, 2010] * Copyright (c) 1998-2010 Glenn Randers-Pehrson * * This code is released under the libpng license.