laag-libpng 1.6.34.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +57 -0
- data/LICENSE.txt +133 -0
- data/README.org +34 -0
- data/ext/laag/libpng/extconf.rb +13 -0
- data/laag-libpng.gemspec +20 -0
- data/lib/laag/libpng.rb +29 -0
- data/vendor/git.code.sf.net/p/libpng/code/ANNOUNCE +35 -0
- data/vendor/git.code.sf.net/p/libpng/code/CHANGES +6051 -0
- data/vendor/git.code.sf.net/p/libpng/code/CMakeLists.txt +945 -0
- data/vendor/git.code.sf.net/p/libpng/code/INSTALL +465 -0
- data/vendor/git.code.sf.net/p/libpng/code/LICENSE +133 -0
- data/vendor/git.code.sf.net/p/libpng/code/Makefile.am +392 -0
- data/vendor/git.code.sf.net/p/libpng/code/README +222 -0
- data/vendor/git.code.sf.net/p/libpng/code/TODO +30 -0
- data/vendor/git.code.sf.net/p/libpng/code/arm/arm_init.c +135 -0
- data/vendor/git.code.sf.net/p/libpng/code/arm/filter_neon.S +253 -0
- data/vendor/git.code.sf.net/p/libpng/code/arm/filter_neon_intrinsics.c +387 -0
- data/vendor/git.code.sf.net/p/libpng/code/autogen.sh +225 -0
- data/vendor/git.code.sf.net/p/libpng/code/configure.ac +533 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/README.txt +5 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/arm-neon/README +83 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/arm-neon/android-ndk.c +39 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/arm-neon/linux-auxv.c +120 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/arm-neon/linux.c +161 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/conftest/README +49 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/conftest/pngcp.dfa +57 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/conftest/read.dfa +58 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/conftest/s_read.dfa +35 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/conftest/s_write.dfa +33 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/conftest/simple.dfa +36 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/conftest/write.dfa +45 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/examples/README.txt +24 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/examples/iccfrompng.c +185 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/examples/pngpixel.c +371 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/examples/pngtopng.c +98 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/examples/simpleover.c +648 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/COPYING +340 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/LICENSE +50 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/Makefile.mingw32 +131 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/Makefile.sgi +105 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/Makefile.unx +134 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/Makefile.w32 +114 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/README +186 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/makevms.com +132 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/readpng.c +323 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/readpng.h +88 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/readpng2.c +521 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/readpng2.h +116 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/readppm.c +188 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/rpng-win.c +735 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/rpng-x.c +911 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/rpng2-win.c +1261 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/rpng2-x.c +2143 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/toucan.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/wpng.c +865 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/writepng.c +401 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/gregbook/writepng.h +133 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/fakepng.c +65 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/gentests.sh +102 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/makepng.c +1941 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/pngimage.c +1712 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/pngstest-errors.h +165 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/pngstest.c +3829 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/pngunknown.c +1294 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/pngvalid.c +12230 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/readpng.c +115 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/tarith.c +999 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/libtests/timepng.c +608 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/mips-msa/README +83 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/mips-msa/linux.c +64 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/oss-fuzz/Dockerfile +24 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/oss-fuzz/README.txt +37 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/oss-fuzz/build.sh +50 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/oss-fuzz/libpng_read_fuzzer.cc +180 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/oss-fuzz/libpng_read_fuzzer.options +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/oss-fuzz/newcc +190 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/oss-fuzz/png.dict +39 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/README +5 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/decoder/README +10 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/decoder/makefile +151 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/decoder/pngusr.dfa +40 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/decoder/pngusr.h +23 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/encoder/README +10 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/encoder/makefile +150 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/encoder/pngusr.dfa +39 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/encoder/pngusr.h +23 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/preader/README +15 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/preader/makefile +166 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/preader/pngusr.dfa +40 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminim/preader/pngusr.h +23 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/README +153 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/makefile.std +66 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/makefile.tc3 +38 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/makevms.com +92 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/png2pnm.bat +41 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/png2pnm.c +460 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/png2pnm.sh +42 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/pngminus.bat +4 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/pngminus.sh +5 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/pnm2png.bat +41 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/pnm2png.c +638 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngminus/pnm2png.sh +42 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/README +105 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn0g01.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn0g02.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn0g04.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn0g08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn0g16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn2c08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn2c16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn3p01.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn3p02.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn3p04.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn3p08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn4a08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn4a16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn6a08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/basn6a16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbbn0g01.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbbn0g02.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbbn0g04.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbbn2c16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbbn3p08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbgn2c16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbgn3p08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbrn2c08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbwn0g16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbwn3p08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftbyn3p08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftp0n0g08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftp0n2c08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftp0n3p08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/pngsuite/ftp1n3p08.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/powerpc-vsx/README +81 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/powerpc-vsx/linux.c +57 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/powerpc-vsx/linux_aux.c +36 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/bad_iCCP.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/badadler.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/badcrc.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/empty_ancillary_chunks.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_IDAT.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_bKGD_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_cHRM_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_eXIf_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_gAMA_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_hIST_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_iCCP_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_iTXt_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_pCAL_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_pHYs_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_sCAL_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_sPLT_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_sRGB_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_sTER_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_tEXt_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_tIME_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/crashers/huge_zTXt_chunk.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-1.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-2.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-4.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-16-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-16-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-16-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-8-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-8-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-8-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/gray-alpha-8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/makepngs.sh +94 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-1.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-2.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-4.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/palette-8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8-1.8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8-linear-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8-sRGB-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8-tRNS.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-16-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-16-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-16-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-16.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-8-1.8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-8-linear.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-8-sRGB.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/testpngs/rgb-alpha-8.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/README.txt +27 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/checksum-icc.c +102 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/chkfmt +144 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/cvtcolor.c +188 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/genpng.c +881 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/intgamma.sh +110 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/makesRGB.c +430 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/png-fix-itxt.c +164 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/pngcp.c +2453 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/pngfix.c +4049 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/reindent +25 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/tools/sRGB.h +48 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/PngFile.c +455 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/PngFile.h +30 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/README.txt +61 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/VisualPng.c +978 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/VisualPng.dsp +147 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/VisualPng.dsw +29 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/VisualPng.ico +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/VisualPng.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/VisualPng.rc +152 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/cexcept.h +248 -0
- data/vendor/git.code.sf.net/p/libpng/code/contrib/visupng/resource.h +23 -0
- data/vendor/git.code.sf.net/p/libpng/code/example.c +1066 -0
- data/vendor/git.code.sf.net/p/libpng/code/intel/filter_sse2_intrinsics.c +406 -0
- data/vendor/git.code.sf.net/p/libpng/code/intel/intel_init.c +53 -0
- data/vendor/git.code.sf.net/p/libpng/code/libpng-config.in +127 -0
- data/vendor/git.code.sf.net/p/libpng/code/libpng-manual.txt +5464 -0
- data/vendor/git.code.sf.net/p/libpng/code/libpng.3 +6249 -0
- data/vendor/git.code.sf.net/p/libpng/code/libpng.pc.in +12 -0
- data/vendor/git.code.sf.net/p/libpng/code/libpngpf.3 +18 -0
- data/vendor/git.code.sf.net/p/libpng/code/mips/filter_msa_intrinsics.c +807 -0
- data/vendor/git.code.sf.net/p/libpng/code/mips/mips_init.c +129 -0
- data/vendor/git.code.sf.net/p/libpng/code/png.5 +74 -0
- data/vendor/git.code.sf.net/p/libpng/code/png.c +4614 -0
- data/vendor/git.code.sf.net/p/libpng/code/png.h +3278 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngbar.jpg +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngbar.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngconf.h +622 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngdebug.h +153 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngerror.c +963 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngget.c +1248 -0
- data/vendor/git.code.sf.net/p/libpng/code/pnginfo.h +267 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngmem.c +284 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngnow.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngpread.c +1096 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngpriv.h +2120 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngread.c +4219 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngrio.c +120 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngrtran.c +5010 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngrutil.c +4661 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngset.c +1802 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngstruct.h +483 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngtest.c +2156 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngtest.png +0 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngtrans.c +864 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngusr.dfa +14 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngwio.c +168 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngwrite.c +2396 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngwtran.c +576 -0
- data/vendor/git.code.sf.net/p/libpng/code/pngwutil.c +2784 -0
- data/vendor/git.code.sf.net/p/libpng/code/powerpc/filter_vsx_intrinsics.c +767 -0
- data/vendor/git.code.sf.net/p/libpng/code/powerpc/powerpc_init.c +125 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/owatcom/libpng.tgt +383 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/owatcom/libpng.wpj +112 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/owatcom/pngconfig.mak +160 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/owatcom/pngstest.tgt +219 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/owatcom/pngtest.tgt +179 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/owatcom/pngvalid.tgt +210 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/visualc71/PRJ0041.mak +21 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/visualc71/README.txt +58 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/visualc71/README_zlib.txt +44 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/visualc71/libpng.sln +60 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/visualc71/libpng.vcproj +419 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/visualc71/pngtest.vcproj +267 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/visualc71/zlib.vcproj +391 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/README.txt +97 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/libpng/libpng.vcxproj +234 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/pnglibconf/pnglibconf.vcxproj +61 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/pngstest/pngstest.vcxproj +219 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/pngtest/pngtest.vcxproj +220 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/pngunknown/pngunknown.vcxproj +219 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/pngvalid/pngvalid.vcxproj +219 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/vstudio.sln +109 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/zlib/zlib.vcxproj +175 -0
- data/vendor/git.code.sf.net/p/libpng/code/projects/vstudio/zlib.props +58 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/README.txt +86 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/SCOPTIONS.ppc +7 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/checksym.awk +173 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/def.c +29 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/descrip.mms +52 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/dfn.awk +203 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/genchk.cmake.in +37 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/genout.cmake.in +93 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/gensrc.cmake.in +138 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/intprefix.c +22 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/libpng-config-body.in +96 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/libpng-config-head.in +24 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/libpng.pc.in +10 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/macro.lst +3 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.32sunu +244 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.64sunu +244 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.acorn +57 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.aix +116 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.amiga +58 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.atari +71 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.bc32 +158 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.beos +222 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.bor +170 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.cegcc +116 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.darwin +225 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.dec +210 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.dj2 +72 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.freebsd +69 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.gcc +87 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.hp64 +231 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.hpgcc +234 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.hpux +229 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.ibmc +90 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.intel +115 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.knr +116 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.linux +247 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.linux-opt +265 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.mips +103 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.msc +100 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.msys +201 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.ne12bsd +56 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.netbsd +56 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.openbsd +88 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.sco +226 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.sggcc +236 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.sgi +237 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.so9 +247 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.solaris +244 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.solaris-x86 +243 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.std +134 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.sunos +115 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.tc3 +100 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makefile.vcwin32 +113 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/makevms.com +142 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/options.awk +898 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/pnglibconf.dfa +919 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/pnglibconf.h.prebuilt +220 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/pnglibconf.mak +55 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/pngwin.rc +112 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/prefix.c +24 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/smakefile.ppc +34 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/sym.c +15 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/symbols.c +58 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/symbols.def +256 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/test.cmake.in +31 -0
- data/vendor/git.code.sf.net/p/libpng/code/scripts/vers.c +19 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngimage-full +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngimage-quick +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest +54 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-1.8 +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-1.8-alpha +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-linear +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-linear-alpha +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-none +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-none-alpha +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-sRGB +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngstest-sRGB-alpha +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngtest +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngtest-badpngs +13 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngunknown-IDAT +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngunknown-discard +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngunknown-if-safe +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngunknown-sAPI +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngunknown-sTER +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngunknown-save +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngunknown-vpAg +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-16-to-8 +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-alpha-mode +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-background +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-expand16-alpha-mode +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-expand16-background +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-expand16-transform +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-sbit +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-threshold +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-gamma-transform +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-progressive-interlace-standard +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-progressive-size +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-progressive-standard +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-standard +2 -0
- data/vendor/git.code.sf.net/p/libpng/code/tests/pngvalid-transform +2 -0
- metadata +515 -0
@@ -0,0 +1,1712 @@
|
|
1
|
+
/* pngimage.c
|
2
|
+
*
|
3
|
+
* Copyright (c) 2015,2016 John Cunningham Bowler
|
4
|
+
*
|
5
|
+
* Last changed in libpng 1.6.24 [August 4, 2016]
|
6
|
+
*
|
7
|
+
* This code is released under the libpng license.
|
8
|
+
* For conditions of distribution and use, see the disclaimer
|
9
|
+
* and license in png.h
|
10
|
+
*
|
11
|
+
* Test the png_read_png and png_write_png interfaces. Given a PNG file load it
|
12
|
+
* using png_read_png and then write with png_write_png. Test all possible
|
13
|
+
* transforms.
|
14
|
+
*/
|
15
|
+
#include <stdarg.h>
|
16
|
+
#include <stdlib.h>
|
17
|
+
#include <string.h>
|
18
|
+
#include <errno.h>
|
19
|
+
#include <stdio.h>
|
20
|
+
#include <assert.h>
|
21
|
+
|
22
|
+
#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
|
23
|
+
# include <config.h>
|
24
|
+
#endif
|
25
|
+
|
26
|
+
/* Define the following to use this test against your installed libpng, rather
|
27
|
+
* than the one being built here:
|
28
|
+
*/
|
29
|
+
#ifdef PNG_FREESTANDING_TESTS
|
30
|
+
# include <png.h>
|
31
|
+
#else
|
32
|
+
# include "../../png.h"
|
33
|
+
#endif
|
34
|
+
|
35
|
+
#ifndef PNG_SETJMP_SUPPORTED
|
36
|
+
# include <setjmp.h> /* because png.h did *not* include this */
|
37
|
+
#endif
|
38
|
+
|
39
|
+
/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
|
40
|
+
* a skipped test, in earlier versions we need to succeed on a skipped test, so:
|
41
|
+
*/
|
42
|
+
#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
|
43
|
+
# define SKIP 77
|
44
|
+
#else
|
45
|
+
# define SKIP 0
|
46
|
+
#endif
|
47
|
+
|
48
|
+
#if PNG_LIBPNG_VER < 10700
|
49
|
+
/* READ_PNG and WRITE_PNG were not defined, so: */
|
50
|
+
# ifdef PNG_INFO_IMAGE_SUPPORTED
|
51
|
+
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
|
52
|
+
# define PNG_READ_PNG_SUPPORTED
|
53
|
+
# endif /* SEQUENTIAL_READ */
|
54
|
+
# ifdef PNG_WRITE_SUPPORTED
|
55
|
+
# define PNG_WRITE_PNG_SUPPORTED
|
56
|
+
# endif /* WRITE */
|
57
|
+
# endif /* INFO_IMAGE */
|
58
|
+
#endif /* pre 1.7.0 */
|
59
|
+
|
60
|
+
#ifdef PNG_READ_PNG_SUPPORTED
|
61
|
+
/* If a transform is valid on both read and write this implies that if the
|
62
|
+
* transform is applied to read it must also be applied on write to produce
|
63
|
+
* meaningful data. This is because these transforms when performed on read
|
64
|
+
* produce data with a memory format that does not correspond to a PNG format.
|
65
|
+
*
|
66
|
+
* Most of these transforms are invertible; after applying the transform on
|
67
|
+
* write the result is the original PNG data that would have would have been
|
68
|
+
* read if no transform were applied.
|
69
|
+
*
|
70
|
+
* The exception is _SHIFT, which destroys the low order bits marked as not
|
71
|
+
* significant in a PNG with the sBIT chunk.
|
72
|
+
*
|
73
|
+
* The following table lists, for each transform, the conditions under which it
|
74
|
+
* is expected to do anything. Conditions are defined as follows:
|
75
|
+
*
|
76
|
+
* 1) Color mask bits required - simply a mask to AND with color_type; one of
|
77
|
+
* these must be present for the transform to fire, except that 0 means
|
78
|
+
* 'always'.
|
79
|
+
* 2) Color mask bits which must be absent - another mask - none of these must
|
80
|
+
* be present.
|
81
|
+
* 3) Bit depths - a mask of component bit depths for the transform to fire.
|
82
|
+
* 4) 'read' - the transform works in png_read_png.
|
83
|
+
* 5) 'write' - the transform works in png_write_png.
|
84
|
+
* 6) PNG_INFO_chunk; a mask of the chunks that must be present for the
|
85
|
+
* transform to fire. All must be present - the requirement is that
|
86
|
+
* png_get_valid() & mask == mask, so if mask is 0 there is no requirement.
|
87
|
+
*
|
88
|
+
* The condition refers to the original image state - if multiple transforms are
|
89
|
+
* used together it is possible to cause a transform that wouldn't fire on the
|
90
|
+
* original image to fire.
|
91
|
+
*/
|
92
|
+
static struct transform_info
|
93
|
+
{
|
94
|
+
const char *name;
|
95
|
+
int transform;
|
96
|
+
png_uint_32 valid_chunks;
|
97
|
+
# define CHUNK_NONE 0
|
98
|
+
# define CHUNK_sBIT PNG_INFO_sBIT
|
99
|
+
# define CHUNK_tRNS PNG_INFO_tRNS
|
100
|
+
png_byte color_mask_required;
|
101
|
+
png_byte color_mask_absent;
|
102
|
+
# define COLOR_MASK_X 0
|
103
|
+
# define COLOR_MASK_P PNG_COLOR_MASK_PALETTE
|
104
|
+
# define COLOR_MASK_C PNG_COLOR_MASK_COLOR
|
105
|
+
# define COLOR_MASK_A PNG_COLOR_MASK_ALPHA
|
106
|
+
# define COLOR_MASK_ALL (PALETTE+COLOR+ALPHA) /* absent = gray, no alpha */
|
107
|
+
png_byte bit_depths;
|
108
|
+
# define BD_ALL (1 + 2 + 4 + 8 + 16)
|
109
|
+
# define BD_PAL (1 + 2 + 4 + 8)
|
110
|
+
# define BD_LOW (1 + 2 + 4)
|
111
|
+
# define BD_16 16
|
112
|
+
# define BD_TRUE (8+16) /* i.e. true-color depths */
|
113
|
+
png_byte when;
|
114
|
+
# define TRANSFORM_R 1
|
115
|
+
# define TRANSFORM_W 2
|
116
|
+
# define TRANSFORM_RW 3
|
117
|
+
png_byte tested; /* the transform was tested somewhere */
|
118
|
+
} transform_info[] =
|
119
|
+
{
|
120
|
+
/* List ALL the PNG_TRANSFORM_ macros here. Check for support using the READ
|
121
|
+
* macros; even if the transform is supported on write it cannot be tested
|
122
|
+
* without the read support.
|
123
|
+
*/
|
124
|
+
# define T(name,chunk,cm_required,cm_absent,bd,when)\
|
125
|
+
{ #name, PNG_TRANSFORM_ ## name, CHUNK_ ## chunk,\
|
126
|
+
COLOR_MASK_ ## cm_required, COLOR_MASK_ ## cm_absent, BD_ ## bd,\
|
127
|
+
TRANSFORM_ ## when, 0/*!tested*/ }
|
128
|
+
|
129
|
+
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
|
130
|
+
T(STRIP_16, NONE, X, X, 16, R),
|
131
|
+
/* drops the bottom 8 bits when bit depth is 16 */
|
132
|
+
#endif
|
133
|
+
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
|
134
|
+
T(STRIP_ALPHA, NONE, A, X, ALL, R),
|
135
|
+
/* removes the alpha channel if present */
|
136
|
+
#endif
|
137
|
+
#ifdef PNG_WRITE_PACK_SUPPORTED
|
138
|
+
# define TRANSFORM_RW_PACK TRANSFORM_RW
|
139
|
+
#else
|
140
|
+
# define TRANSFORM_RW_PACK TRANSFORM_R
|
141
|
+
#endif
|
142
|
+
#ifdef PNG_READ_PACK_SUPPORTED
|
143
|
+
T(PACKING, NONE, X, X, LOW, RW_PACK),
|
144
|
+
/* unpacks low-bit-depth components into 1 byte per component on read,
|
145
|
+
* reverses this on write.
|
146
|
+
*/
|
147
|
+
#endif
|
148
|
+
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
|
149
|
+
# define TRANSFORM_RW_PACKSWAP TRANSFORM_RW
|
150
|
+
#else
|
151
|
+
# define TRANSFORM_RW_PACKSWAP TRANSFORM_R
|
152
|
+
#endif
|
153
|
+
#ifdef PNG_READ_PACKSWAP_SUPPORTED
|
154
|
+
T(PACKSWAP, NONE, X, X, LOW, RW_PACKSWAP),
|
155
|
+
/* reverses the order of low-bit-depth components packed into a byte */
|
156
|
+
#endif
|
157
|
+
#ifdef PNG_READ_EXPAND_SUPPORTED
|
158
|
+
T(EXPAND, NONE, P, X, ALL, R),
|
159
|
+
/* expands PLTE PNG files to RGB (no tRNS) or RGBA (tRNS) *
|
160
|
+
* Note that the 'EXPAND' transform does lots of different things: */
|
161
|
+
T(EXPAND, NONE, X, C, ALL, R),
|
162
|
+
/* expands grayscale PNG files to RGB, or RGBA */
|
163
|
+
T(EXPAND, tRNS, X, A, ALL, R),
|
164
|
+
/* expands the tRNS chunk in files without alpha */
|
165
|
+
#endif
|
166
|
+
#ifdef PNG_WRITE_INVERT_SUPPORTED
|
167
|
+
# define TRANSFORM_RW_INVERT TRANSFORM_RW
|
168
|
+
#else
|
169
|
+
# define TRANSFORM_RW_INVERT TRANSFORM_R
|
170
|
+
#endif
|
171
|
+
#ifdef PNG_READ_INVERT_SUPPORTED
|
172
|
+
T(INVERT_MONO, NONE, X, C, ALL, RW_INVERT),
|
173
|
+
/* converts gray-scale components to 1..0 from 0..1 */
|
174
|
+
#endif
|
175
|
+
#ifdef PNG_WRITE_SHIFT_SUPPORTED
|
176
|
+
# define TRANSFORM_RW_SHIFT TRANSFORM_RW
|
177
|
+
#else
|
178
|
+
# define TRANSFORM_RW_SHIFT TRANSFORM_R
|
179
|
+
#endif
|
180
|
+
#ifdef PNG_READ_SHIFT_SUPPORTED
|
181
|
+
T(SHIFT, sBIT, X, X, ALL, RW_SHIFT),
|
182
|
+
/* reduces component values to the original range based on the sBIT chunk,
|
183
|
+
* this is only partially reversible - the low bits are lost and cannot be
|
184
|
+
* recovered on write. In fact write code replicates the bits to generate
|
185
|
+
* new low-order bits.
|
186
|
+
*/
|
187
|
+
#endif
|
188
|
+
#ifdef PNG_WRITE_BGR_SUPPORTED
|
189
|
+
# define TRANSFORM_RW_BGR TRANSFORM_RW
|
190
|
+
#else
|
191
|
+
# define TRANSFORM_RW_BGR TRANSFORM_R
|
192
|
+
#endif
|
193
|
+
#ifdef PNG_READ_BGR_SUPPORTED
|
194
|
+
T(BGR, NONE, C, P, TRUE, RW_BGR),
|
195
|
+
/* reverses the rgb component values of true-color pixels */
|
196
|
+
#endif
|
197
|
+
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
198
|
+
# define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_RW
|
199
|
+
#else
|
200
|
+
# define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_R
|
201
|
+
#endif
|
202
|
+
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
|
203
|
+
T(SWAP_ALPHA, NONE, A, X, TRUE, RW_SWAP_ALPHA),
|
204
|
+
/* swaps the alpha channel of RGBA or GA pixels to the front - ARGB or
|
205
|
+
* AG, on write reverses the process.
|
206
|
+
*/
|
207
|
+
#endif
|
208
|
+
#ifdef PNG_WRITE_SWAP_SUPPORTED
|
209
|
+
# define TRANSFORM_RW_SWAP TRANSFORM_RW
|
210
|
+
#else
|
211
|
+
# define TRANSFORM_RW_SWAP TRANSFORM_R
|
212
|
+
#endif
|
213
|
+
#ifdef PNG_READ_SWAP_SUPPORTED
|
214
|
+
T(SWAP_ENDIAN, NONE, X, P, 16, RW_SWAP),
|
215
|
+
/* byte-swaps 16-bit component values */
|
216
|
+
#endif
|
217
|
+
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
218
|
+
# define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_RW
|
219
|
+
#else
|
220
|
+
# define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_R
|
221
|
+
#endif
|
222
|
+
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
|
223
|
+
T(INVERT_ALPHA, NONE, A, X, TRUE, RW_INVERT_ALPHA),
|
224
|
+
/* converts an alpha channel from 0..1 to 1..0 */
|
225
|
+
#endif
|
226
|
+
#ifdef PNG_WRITE_FILLER_SUPPORTED
|
227
|
+
T(STRIP_FILLER_BEFORE, NONE, A, P, TRUE, W), /* 'A' for a filler! */
|
228
|
+
/* on write skips a leading filler channel; testing requires data with a
|
229
|
+
* filler channel so this is produced from RGBA or GA images by removing
|
230
|
+
* the 'alpha' flag from the color type in place.
|
231
|
+
*/
|
232
|
+
T(STRIP_FILLER_AFTER, NONE, A, P, TRUE, W),
|
233
|
+
/* on write strips a trailing filler channel */
|
234
|
+
#endif
|
235
|
+
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
|
236
|
+
T(GRAY_TO_RGB, NONE, X, C, ALL, R),
|
237
|
+
/* expands grayscale images to RGB, also causes the palette part of
|
238
|
+
* 'EXPAND' to happen. Low bit depth grayscale images are expanded to
|
239
|
+
* 8-bits per component and no attempt is made to convert the image to a
|
240
|
+
* palette image. While this transform is partially reversible
|
241
|
+
* png_write_png does not currently support this.
|
242
|
+
*/
|
243
|
+
T(GRAY_TO_RGB, NONE, P, X, ALL, R),
|
244
|
+
/* The 'palette' side effect mentioned above; a bit bogus but this is the
|
245
|
+
* way the libpng code works.
|
246
|
+
*/
|
247
|
+
#endif
|
248
|
+
#ifdef PNG_READ_EXPAND_16_SUPPORTED
|
249
|
+
T(EXPAND_16, NONE, X, X, PAL, R),
|
250
|
+
/* expands images to 16-bits per component, as a side effect expands
|
251
|
+
* palette images to RGB and expands the tRNS chunk if present, so it can
|
252
|
+
* modify 16-bit per component images as well:
|
253
|
+
*/
|
254
|
+
T(EXPAND_16, tRNS, X, A, 16, R),
|
255
|
+
/* side effect of EXPAND_16 - expands the tRNS chunk in an RGB or G 16-bit
|
256
|
+
* image.
|
257
|
+
*/
|
258
|
+
#endif
|
259
|
+
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
|
260
|
+
T(SCALE_16, NONE, X, X, 16, R),
|
261
|
+
/* scales 16-bit components to 8-bits. */
|
262
|
+
#endif
|
263
|
+
|
264
|
+
{ NULL /*name*/, 0, 0, 0, 0, 0, 0, 0/*!tested*/ }
|
265
|
+
|
266
|
+
#undef T
|
267
|
+
};
|
268
|
+
|
269
|
+
#define ARRAY_SIZE(a) ((sizeof a)/(sizeof a[0]))
|
270
|
+
#define TTABLE_SIZE ARRAY_SIZE(transform_info)
|
271
|
+
|
272
|
+
/* Some combinations of options that should be reversible are not; these cases
|
273
|
+
* are bugs.
|
274
|
+
*/
|
275
|
+
static int known_bad_combos[][2] =
|
276
|
+
{
|
277
|
+
/* problem, antidote */
|
278
|
+
{ PNG_TRANSFORM_SHIFT | PNG_TRANSFORM_INVERT_ALPHA, 0/*antidote*/ }
|
279
|
+
};
|
280
|
+
|
281
|
+
static int
|
282
|
+
is_combo(int transforms)
|
283
|
+
{
|
284
|
+
return transforms & (transforms-1); /* non-zero if more than one set bit */
|
285
|
+
}
|
286
|
+
|
287
|
+
static int
|
288
|
+
first_transform(int transforms)
|
289
|
+
{
|
290
|
+
return transforms & -transforms; /* lowest set bit */
|
291
|
+
}
|
292
|
+
|
293
|
+
static int
|
294
|
+
is_bad_combo(int transforms)
|
295
|
+
{
|
296
|
+
unsigned int i;
|
297
|
+
|
298
|
+
for (i=0; i<ARRAY_SIZE(known_bad_combos); ++i)
|
299
|
+
{
|
300
|
+
int combo = known_bad_combos[i][0];
|
301
|
+
|
302
|
+
if ((combo & transforms) == combo &&
|
303
|
+
(transforms & known_bad_combos[i][1]) == 0)
|
304
|
+
return 1;
|
305
|
+
}
|
306
|
+
|
307
|
+
return 0; /* combo is ok */
|
308
|
+
}
|
309
|
+
|
310
|
+
static const char *
|
311
|
+
transform_name(int t)
|
312
|
+
/* The name, if 't' has multiple bits set the name of the lowest set bit is
|
313
|
+
* returned.
|
314
|
+
*/
|
315
|
+
{
|
316
|
+
unsigned int i;
|
317
|
+
|
318
|
+
t &= -t; /* first set bit */
|
319
|
+
|
320
|
+
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
|
321
|
+
{
|
322
|
+
if ((transform_info[i].transform & t) != 0)
|
323
|
+
return transform_info[i].name;
|
324
|
+
}
|
325
|
+
|
326
|
+
return "invalid transform";
|
327
|
+
}
|
328
|
+
|
329
|
+
/* Variables calculated by validate_T below and used to record all the supported
|
330
|
+
* transforms. Need (unsigned int) here because of the places where these
|
331
|
+
* values are used (unsigned compares in the 'exhaustive' iterator.)
|
332
|
+
*/
|
333
|
+
static unsigned int read_transforms, write_transforms, rw_transforms;
|
334
|
+
|
335
|
+
static void
|
336
|
+
validate_T(void)
|
337
|
+
/* Validate the above table - this just builds the above values */
|
338
|
+
{
|
339
|
+
unsigned int i;
|
340
|
+
|
341
|
+
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
|
342
|
+
{
|
343
|
+
if (transform_info[i].when & TRANSFORM_R)
|
344
|
+
read_transforms |= transform_info[i].transform;
|
345
|
+
|
346
|
+
if (transform_info[i].when & TRANSFORM_W)
|
347
|
+
write_transforms |= transform_info[i].transform;
|
348
|
+
}
|
349
|
+
|
350
|
+
/* Reversible transforms are those which are supported on both read and
|
351
|
+
* write.
|
352
|
+
*/
|
353
|
+
rw_transforms = read_transforms & write_transforms;
|
354
|
+
}
|
355
|
+
|
356
|
+
/* FILE DATA HANDLING
|
357
|
+
* The original file is cached in memory. During write the output file is
|
358
|
+
* written to memory.
|
359
|
+
*
|
360
|
+
* In both cases the file data is held in a linked list of buffers - not all
|
361
|
+
* of these are in use at any time.
|
362
|
+
*/
|
363
|
+
#define NEW(type) ((type *)malloc(sizeof (type)))
|
364
|
+
#define DELETE(ptr) (free(ptr))
|
365
|
+
|
366
|
+
struct buffer_list
|
367
|
+
{
|
368
|
+
struct buffer_list *next; /* next buffer in list */
|
369
|
+
png_byte buffer[1024]; /* the actual buffer */
|
370
|
+
};
|
371
|
+
|
372
|
+
struct buffer
|
373
|
+
{
|
374
|
+
struct buffer_list *last; /* last buffer in use */
|
375
|
+
size_t end_count; /* bytes in the last buffer */
|
376
|
+
struct buffer_list *current; /* current buffer being read */
|
377
|
+
size_t read_count; /* count of bytes read from current */
|
378
|
+
struct buffer_list first; /* the very first buffer */
|
379
|
+
};
|
380
|
+
|
381
|
+
static void
|
382
|
+
buffer_init(struct buffer *buffer)
|
383
|
+
/* Call this only once for a given buffer */
|
384
|
+
{
|
385
|
+
buffer->first.next = NULL;
|
386
|
+
buffer->last = NULL;
|
387
|
+
buffer->current = NULL;
|
388
|
+
}
|
389
|
+
|
390
|
+
static void
|
391
|
+
buffer_destroy_list(struct buffer_list *list)
|
392
|
+
{
|
393
|
+
if (list != NULL)
|
394
|
+
{
|
395
|
+
struct buffer_list *next = list->next;
|
396
|
+
DELETE(list);
|
397
|
+
buffer_destroy_list(next);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
|
401
|
+
static void
|
402
|
+
buffer_destroy(struct buffer *buffer)
|
403
|
+
{
|
404
|
+
struct buffer_list *list = buffer->first.next;
|
405
|
+
buffer_init(buffer);
|
406
|
+
buffer_destroy_list(list);
|
407
|
+
}
|
408
|
+
|
409
|
+
#ifdef PNG_WRITE_PNG_SUPPORTED
|
410
|
+
static void
|
411
|
+
buffer_start_write(struct buffer *buffer)
|
412
|
+
{
|
413
|
+
buffer->last = &buffer->first;
|
414
|
+
buffer->end_count = 0;
|
415
|
+
buffer->current = NULL;
|
416
|
+
}
|
417
|
+
#endif
|
418
|
+
|
419
|
+
static void
|
420
|
+
buffer_start_read(struct buffer *buffer)
|
421
|
+
{
|
422
|
+
buffer->current = &buffer->first;
|
423
|
+
buffer->read_count = 0;
|
424
|
+
}
|
425
|
+
|
426
|
+
#ifdef ENOMEM /* required by POSIX 1003.1 */
|
427
|
+
# define MEMORY ENOMEM
|
428
|
+
#else
|
429
|
+
# define MEMORY ERANGE /* required by ANSI-C */
|
430
|
+
#endif
|
431
|
+
static struct buffer *
|
432
|
+
get_buffer(png_structp pp)
|
433
|
+
/* Used from libpng callbacks to get the current buffer */
|
434
|
+
{
|
435
|
+
return (struct buffer*)png_get_io_ptr(pp);
|
436
|
+
}
|
437
|
+
|
438
|
+
static struct buffer_list *
|
439
|
+
buffer_extend(struct buffer_list *current)
|
440
|
+
{
|
441
|
+
struct buffer_list *add;
|
442
|
+
|
443
|
+
assert(current->next == NULL);
|
444
|
+
|
445
|
+
add = NEW(struct buffer_list);
|
446
|
+
if (add == NULL)
|
447
|
+
return NULL;
|
448
|
+
|
449
|
+
add->next = NULL;
|
450
|
+
current->next = add;
|
451
|
+
|
452
|
+
return add;
|
453
|
+
}
|
454
|
+
|
455
|
+
/* Load a buffer from a file; does the equivalent of buffer_start_write. On a
|
456
|
+
* read error returns an errno value, else returns 0.
|
457
|
+
*/
|
458
|
+
static int
|
459
|
+
buffer_from_file(struct buffer *buffer, FILE *fp)
|
460
|
+
{
|
461
|
+
struct buffer_list *last = &buffer->first;
|
462
|
+
size_t count = 0;
|
463
|
+
|
464
|
+
for (;;)
|
465
|
+
{
|
466
|
+
size_t r = fread(last->buffer+count, 1/*size*/,
|
467
|
+
(sizeof last->buffer)-count, fp);
|
468
|
+
|
469
|
+
if (r > 0)
|
470
|
+
{
|
471
|
+
count += r;
|
472
|
+
|
473
|
+
if (count >= sizeof last->buffer)
|
474
|
+
{
|
475
|
+
assert(count == sizeof last->buffer);
|
476
|
+
count = 0;
|
477
|
+
|
478
|
+
if (last->next == NULL)
|
479
|
+
{
|
480
|
+
last = buffer_extend(last);
|
481
|
+
if (last == NULL)
|
482
|
+
return MEMORY;
|
483
|
+
}
|
484
|
+
|
485
|
+
else
|
486
|
+
last = last->next;
|
487
|
+
}
|
488
|
+
}
|
489
|
+
|
490
|
+
else /* fread failed - probably end of file */
|
491
|
+
{
|
492
|
+
if (feof(fp))
|
493
|
+
{
|
494
|
+
buffer->last = last;
|
495
|
+
buffer->end_count = count;
|
496
|
+
return 0; /* no error */
|
497
|
+
}
|
498
|
+
|
499
|
+
/* Some kind of funky error; errno should be non-zero */
|
500
|
+
return errno == 0 ? ERANGE : errno;
|
501
|
+
}
|
502
|
+
}
|
503
|
+
}
|
504
|
+
|
505
|
+
/* This structure is used to control the test of a single file. */
|
506
|
+
typedef enum
|
507
|
+
{
|
508
|
+
VERBOSE, /* switches on all messages */
|
509
|
+
INFORMATION,
|
510
|
+
WARNINGS, /* switches on warnings */
|
511
|
+
LIBPNG_WARNING,
|
512
|
+
APP_WARNING,
|
513
|
+
ERRORS, /* just errors */
|
514
|
+
APP_FAIL, /* continuable error - no need to longjmp */
|
515
|
+
LIBPNG_ERROR, /* this and higher cause a longjmp */
|
516
|
+
LIBPNG_BUG, /* erroneous behavior in libpng */
|
517
|
+
APP_ERROR, /* such as out-of-memory in a callback */
|
518
|
+
QUIET, /* no normal messages */
|
519
|
+
USER_ERROR, /* such as file-not-found */
|
520
|
+
INTERNAL_ERROR
|
521
|
+
} error_level;
|
522
|
+
#define LEVEL_MASK 0xf /* where the level is in 'options' */
|
523
|
+
|
524
|
+
#define EXHAUSTIVE 0x010 /* Test all combinations of active options */
|
525
|
+
#define STRICT 0x020 /* Fail on warnings as well as errors */
|
526
|
+
#define LOG 0x040 /* Log pass/fail to stdout */
|
527
|
+
#define CONTINUE 0x080 /* Continue on APP_FAIL errors */
|
528
|
+
#define SKIP_BUGS 0x100 /* Skip over known bugs */
|
529
|
+
#define LOG_SKIPPED 0x200 /* Log skipped bugs */
|
530
|
+
#define FIND_BAD_COMBOS 0x400 /* Attempt to deduce bad combos */
|
531
|
+
#define LIST_COMBOS 0x800 /* List combos by name */
|
532
|
+
|
533
|
+
/* Result masks apply to the result bits in the 'results' field below; these
|
534
|
+
* bits are simple 1U<<error_level. A pass requires either nothing worse than
|
535
|
+
* warnings (--relaxes) or nothing worse than information (--strict)
|
536
|
+
*/
|
537
|
+
#define RESULT_STRICT(r) (((r) & ~((1U<<WARNINGS)-1)) == 0)
|
538
|
+
#define RESULT_RELAXED(r) (((r) & ~((1U<<ERRORS)-1)) == 0)
|
539
|
+
|
540
|
+
struct display
|
541
|
+
{
|
542
|
+
jmp_buf error_return; /* Where to go to on error */
|
543
|
+
|
544
|
+
const char *filename; /* The name of the original file */
|
545
|
+
const char *operation; /* Operation being performed */
|
546
|
+
int transforms; /* Transform used in operation */
|
547
|
+
png_uint_32 options; /* See display_log below */
|
548
|
+
png_uint_32 results; /* A mask of errors seen */
|
549
|
+
|
550
|
+
|
551
|
+
png_structp original_pp; /* used on the original read */
|
552
|
+
png_infop original_ip; /* set by the original read */
|
553
|
+
|
554
|
+
png_size_t original_rowbytes; /* of the original rows: */
|
555
|
+
png_bytepp original_rows; /* from the original read */
|
556
|
+
|
557
|
+
/* Original chunks valid */
|
558
|
+
png_uint_32 chunks;
|
559
|
+
|
560
|
+
/* Original IHDR information */
|
561
|
+
png_uint_32 width;
|
562
|
+
png_uint_32 height;
|
563
|
+
int bit_depth;
|
564
|
+
int color_type;
|
565
|
+
int interlace_method;
|
566
|
+
int compression_method;
|
567
|
+
int filter_method;
|
568
|
+
|
569
|
+
/* Derived information for the original image. */
|
570
|
+
int active_transforms; /* transforms that do something on read */
|
571
|
+
int ignored_transforms; /* transforms that should do nothing */
|
572
|
+
|
573
|
+
/* Used on a read, both the original read and when validating a written
|
574
|
+
* image.
|
575
|
+
*/
|
576
|
+
png_structp read_pp;
|
577
|
+
png_infop read_ip;
|
578
|
+
|
579
|
+
# ifdef PNG_WRITE_PNG_SUPPORTED
|
580
|
+
/* Used to write a new image (the original info_ptr is used) */
|
581
|
+
png_structp write_pp;
|
582
|
+
struct buffer written_file; /* where the file gets written */
|
583
|
+
# endif
|
584
|
+
|
585
|
+
struct buffer original_file; /* Data read from the original file */
|
586
|
+
};
|
587
|
+
|
588
|
+
static void
|
589
|
+
display_init(struct display *dp)
|
590
|
+
/* Call this only once right at the start to initialize the control
|
591
|
+
* structure, the (struct buffer) lists are maintained across calls - the
|
592
|
+
* memory is not freed.
|
593
|
+
*/
|
594
|
+
{
|
595
|
+
memset(dp, 0, sizeof *dp);
|
596
|
+
dp->options = WARNINGS; /* default to !verbose, !quiet */
|
597
|
+
dp->filename = NULL;
|
598
|
+
dp->operation = NULL;
|
599
|
+
dp->original_pp = NULL;
|
600
|
+
dp->original_ip = NULL;
|
601
|
+
dp->original_rows = NULL;
|
602
|
+
dp->read_pp = NULL;
|
603
|
+
dp->read_ip = NULL;
|
604
|
+
buffer_init(&dp->original_file);
|
605
|
+
|
606
|
+
# ifdef PNG_WRITE_PNG_SUPPORTED
|
607
|
+
dp->write_pp = NULL;
|
608
|
+
buffer_init(&dp->written_file);
|
609
|
+
# endif
|
610
|
+
}
|
611
|
+
|
612
|
+
static void
|
613
|
+
display_clean_read(struct display *dp)
|
614
|
+
{
|
615
|
+
if (dp->read_pp != NULL)
|
616
|
+
png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL);
|
617
|
+
}
|
618
|
+
|
619
|
+
#ifdef PNG_WRITE_PNG_SUPPORTED
|
620
|
+
static void
|
621
|
+
display_clean_write(struct display *dp)
|
622
|
+
{
|
623
|
+
if (dp->write_pp != NULL)
|
624
|
+
png_destroy_write_struct(&dp->write_pp, NULL);
|
625
|
+
}
|
626
|
+
#endif
|
627
|
+
|
628
|
+
static void
|
629
|
+
display_clean(struct display *dp)
|
630
|
+
{
|
631
|
+
# ifdef PNG_WRITE_PNG_SUPPORTED
|
632
|
+
display_clean_write(dp);
|
633
|
+
# endif
|
634
|
+
display_clean_read(dp);
|
635
|
+
|
636
|
+
dp->original_rowbytes = 0;
|
637
|
+
dp->original_rows = NULL;
|
638
|
+
dp->chunks = 0;
|
639
|
+
|
640
|
+
png_destroy_read_struct(&dp->original_pp, &dp->original_ip, NULL);
|
641
|
+
/* leave the filename for error detection */
|
642
|
+
dp->results = 0; /* reset for next time */
|
643
|
+
}
|
644
|
+
|
645
|
+
static void
|
646
|
+
display_destroy(struct display *dp)
|
647
|
+
{
|
648
|
+
/* Release any memory held in the display. */
|
649
|
+
# ifdef PNG_WRITE_PNG_SUPPORTED
|
650
|
+
buffer_destroy(&dp->written_file);
|
651
|
+
# endif
|
652
|
+
|
653
|
+
buffer_destroy(&dp->original_file);
|
654
|
+
}
|
655
|
+
|
656
|
+
static struct display *
|
657
|
+
get_dp(png_structp pp)
|
658
|
+
/* The display pointer is always stored in the png_struct error pointer */
|
659
|
+
{
|
660
|
+
struct display *dp = (struct display*)png_get_error_ptr(pp);
|
661
|
+
|
662
|
+
if (dp == NULL)
|
663
|
+
{
|
664
|
+
fprintf(stderr, "pngimage: internal error (no display)\n");
|
665
|
+
exit(99); /* prevents a crash */
|
666
|
+
}
|
667
|
+
|
668
|
+
return dp;
|
669
|
+
}
|
670
|
+
|
671
|
+
/* error handling */
|
672
|
+
#ifdef __GNUC__
|
673
|
+
# define VGATTR __attribute__((__format__ (__printf__,3,4)))
|
674
|
+
/* Required to quiet GNUC warnings when the compiler sees a stdarg function
|
675
|
+
* that calls one of the stdio v APIs.
|
676
|
+
*/
|
677
|
+
#else
|
678
|
+
# define VGATTR
|
679
|
+
#endif
|
680
|
+
static void VGATTR
|
681
|
+
display_log(struct display *dp, error_level level, const char *fmt, ...)
|
682
|
+
/* 'level' is as above, fmt is a stdio style format string. This routine
|
683
|
+
* does not return if level is above LIBPNG_WARNING
|
684
|
+
*/
|
685
|
+
{
|
686
|
+
dp->results |= 1U << level;
|
687
|
+
|
688
|
+
if (level > (error_level)(dp->options & LEVEL_MASK))
|
689
|
+
{
|
690
|
+
const char *lp;
|
691
|
+
va_list ap;
|
692
|
+
|
693
|
+
switch (level)
|
694
|
+
{
|
695
|
+
case INFORMATION: lp = "information"; break;
|
696
|
+
case LIBPNG_WARNING: lp = "warning(libpng)"; break;
|
697
|
+
case APP_WARNING: lp = "warning(pngimage)"; break;
|
698
|
+
case APP_FAIL: lp = "error(continuable)"; break;
|
699
|
+
case LIBPNG_ERROR: lp = "error(libpng)"; break;
|
700
|
+
case LIBPNG_BUG: lp = "bug(libpng)"; break;
|
701
|
+
case APP_ERROR: lp = "error(pngimage)"; break;
|
702
|
+
case USER_ERROR: lp = "error(user)"; break;
|
703
|
+
|
704
|
+
case INTERNAL_ERROR: /* anything unexpected is an internal error: */
|
705
|
+
case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
|
706
|
+
default: lp = "bug(pngimage)"; break;
|
707
|
+
}
|
708
|
+
|
709
|
+
fprintf(stderr, "%s: %s: %s",
|
710
|
+
dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);
|
711
|
+
|
712
|
+
if (dp->transforms != 0)
|
713
|
+
{
|
714
|
+
int tr = dp->transforms;
|
715
|
+
|
716
|
+
if (is_combo(tr))
|
717
|
+
{
|
718
|
+
if (dp->options & LIST_COMBOS)
|
719
|
+
{
|
720
|
+
int trx = tr;
|
721
|
+
|
722
|
+
fprintf(stderr, "(");
|
723
|
+
if (trx)
|
724
|
+
{
|
725
|
+
int start = 0;
|
726
|
+
|
727
|
+
while (trx)
|
728
|
+
{
|
729
|
+
int trz = trx & -trx;
|
730
|
+
|
731
|
+
if (start) fprintf(stderr, "+");
|
732
|
+
fprintf(stderr, "%s", transform_name(trz));
|
733
|
+
start = 1;
|
734
|
+
trx &= ~trz;
|
735
|
+
}
|
736
|
+
}
|
737
|
+
|
738
|
+
else
|
739
|
+
fprintf(stderr, "-");
|
740
|
+
fprintf(stderr, ")");
|
741
|
+
}
|
742
|
+
|
743
|
+
else
|
744
|
+
fprintf(stderr, "(0x%x)", tr);
|
745
|
+
}
|
746
|
+
|
747
|
+
else
|
748
|
+
fprintf(stderr, "(%s)", transform_name(tr));
|
749
|
+
}
|
750
|
+
|
751
|
+
fprintf(stderr, ": ");
|
752
|
+
|
753
|
+
va_start(ap, fmt);
|
754
|
+
vfprintf(stderr, fmt, ap);
|
755
|
+
va_end(ap);
|
756
|
+
|
757
|
+
fputc('\n', stderr);
|
758
|
+
}
|
759
|
+
/* else do not output any message */
|
760
|
+
|
761
|
+
/* Errors cause this routine to exit to the fail code */
|
762
|
+
if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
|
763
|
+
longjmp(dp->error_return, level);
|
764
|
+
}
|
765
|
+
|
766
|
+
/* error handler callbacks for libpng */
|
767
|
+
static void PNGCBAPI
|
768
|
+
display_warning(png_structp pp, png_const_charp warning)
|
769
|
+
{
|
770
|
+
display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
|
771
|
+
}
|
772
|
+
|
773
|
+
static void PNGCBAPI
|
774
|
+
display_error(png_structp pp, png_const_charp error)
|
775
|
+
{
|
776
|
+
struct display *dp = get_dp(pp);
|
777
|
+
|
778
|
+
display_log(dp, LIBPNG_ERROR, "%s", error);
|
779
|
+
}
|
780
|
+
|
781
|
+
static void
|
782
|
+
display_cache_file(struct display *dp, const char *filename)
|
783
|
+
/* Does the initial cache of the file. */
|
784
|
+
{
|
785
|
+
FILE *fp;
|
786
|
+
int ret;
|
787
|
+
|
788
|
+
dp->filename = filename;
|
789
|
+
|
790
|
+
if (filename != NULL)
|
791
|
+
{
|
792
|
+
fp = fopen(filename, "rb");
|
793
|
+
if (fp == NULL)
|
794
|
+
display_log(dp, USER_ERROR, "open failed: %s", strerror(errno));
|
795
|
+
}
|
796
|
+
|
797
|
+
else
|
798
|
+
fp = stdin;
|
799
|
+
|
800
|
+
ret = buffer_from_file(&dp->original_file, fp);
|
801
|
+
|
802
|
+
fclose(fp);
|
803
|
+
|
804
|
+
if (ret != 0)
|
805
|
+
display_log(dp, APP_ERROR, "read failed: %s", strerror(ret));
|
806
|
+
}
|
807
|
+
|
808
|
+
static void
|
809
|
+
buffer_read(struct display *dp, struct buffer *bp, png_bytep data,
|
810
|
+
png_size_t size)
|
811
|
+
{
|
812
|
+
struct buffer_list *last = bp->current;
|
813
|
+
size_t read_count = bp->read_count;
|
814
|
+
|
815
|
+
while (size > 0)
|
816
|
+
{
|
817
|
+
size_t avail;
|
818
|
+
|
819
|
+
if (last == NULL ||
|
820
|
+
(last == bp->last && read_count >= bp->end_count))
|
821
|
+
{
|
822
|
+
display_log(dp, USER_ERROR, "file truncated (%lu bytes)",
|
823
|
+
(unsigned long)size);
|
824
|
+
/*NOTREACHED*/
|
825
|
+
break;
|
826
|
+
}
|
827
|
+
|
828
|
+
else if (read_count >= sizeof last->buffer)
|
829
|
+
{
|
830
|
+
/* Move to the next buffer: */
|
831
|
+
last = last->next;
|
832
|
+
read_count = 0;
|
833
|
+
bp->current = last; /* Avoid update outside the loop */
|
834
|
+
|
835
|
+
/* And do a sanity check (the EOF case is caught above) */
|
836
|
+
if (last == NULL)
|
837
|
+
{
|
838
|
+
display_log(dp, INTERNAL_ERROR, "damaged buffer list");
|
839
|
+
/*NOTREACHED*/
|
840
|
+
break;
|
841
|
+
}
|
842
|
+
}
|
843
|
+
|
844
|
+
avail = (sizeof last->buffer) - read_count;
|
845
|
+
if (avail > size)
|
846
|
+
avail = size;
|
847
|
+
|
848
|
+
memcpy(data, last->buffer + read_count, avail);
|
849
|
+
read_count += avail;
|
850
|
+
size -= avail;
|
851
|
+
data += avail;
|
852
|
+
}
|
853
|
+
|
854
|
+
bp->read_count = read_count;
|
855
|
+
}
|
856
|
+
|
857
|
+
static void PNGCBAPI
|
858
|
+
read_function(png_structp pp, png_bytep data, png_size_t size)
|
859
|
+
{
|
860
|
+
buffer_read(get_dp(pp), get_buffer(pp), data, size);
|
861
|
+
}
|
862
|
+
|
863
|
+
static void
|
864
|
+
read_png(struct display *dp, struct buffer *bp, const char *operation,
|
865
|
+
int transforms)
|
866
|
+
{
|
867
|
+
png_structp pp;
|
868
|
+
png_infop ip;
|
869
|
+
|
870
|
+
/* This cleans out any previous read and sets operation and transforms to
|
871
|
+
* empty.
|
872
|
+
*/
|
873
|
+
display_clean_read(dp);
|
874
|
+
|
875
|
+
if (operation != NULL) /* else this is a verify and do not overwrite info */
|
876
|
+
{
|
877
|
+
dp->operation = operation;
|
878
|
+
dp->transforms = transforms;
|
879
|
+
}
|
880
|
+
|
881
|
+
dp->read_pp = pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
|
882
|
+
display_error, display_warning);
|
883
|
+
if (pp == NULL)
|
884
|
+
display_log(dp, LIBPNG_ERROR, "failed to create read struct");
|
885
|
+
|
886
|
+
/* The png_read_png API requires us to make the info struct, but it does the
|
887
|
+
* call to png_read_info.
|
888
|
+
*/
|
889
|
+
dp->read_ip = ip = png_create_info_struct(pp);
|
890
|
+
if (ip == NULL)
|
891
|
+
display_log(dp, LIBPNG_ERROR, "failed to create info struct");
|
892
|
+
|
893
|
+
# ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
894
|
+
/* Remove the user limits, if any */
|
895
|
+
png_set_user_limits(pp, 0x7fffffff, 0x7fffffff);
|
896
|
+
# endif
|
897
|
+
|
898
|
+
/* Set the IO handling */
|
899
|
+
buffer_start_read(bp);
|
900
|
+
png_set_read_fn(pp, bp, read_function);
|
901
|
+
|
902
|
+
png_read_png(pp, ip, transforms, NULL/*params*/);
|
903
|
+
|
904
|
+
#if 0 /* crazy debugging */
|
905
|
+
{
|
906
|
+
png_bytep pr = png_get_rows(pp, ip)[0];
|
907
|
+
size_t rb = png_get_rowbytes(pp, ip);
|
908
|
+
size_t cb;
|
909
|
+
char c = ' ';
|
910
|
+
|
911
|
+
fprintf(stderr, "%.4x %2d (%3lu bytes):", transforms, png_get_bit_depth(pp,ip), (unsigned long)rb);
|
912
|
+
|
913
|
+
for (cb=0; cb<rb; ++cb)
|
914
|
+
fputc(c, stderr), fprintf(stderr, "%.2x", pr[cb]), c='.';
|
915
|
+
|
916
|
+
fputc('\n', stderr);
|
917
|
+
}
|
918
|
+
#endif
|
919
|
+
}
|
920
|
+
|
921
|
+
static void
|
922
|
+
update_display(struct display *dp)
|
923
|
+
/* called once after the first read to update all the info, original_pp and
|
924
|
+
* original_ip must have been filled in.
|
925
|
+
*/
|
926
|
+
{
|
927
|
+
png_structp pp;
|
928
|
+
png_infop ip;
|
929
|
+
|
930
|
+
/* Now perform the initial read with a 0 tranform. */
|
931
|
+
read_png(dp, &dp->original_file, "original read", 0/*no transform*/);
|
932
|
+
|
933
|
+
/* Move the result to the 'original' fields */
|
934
|
+
dp->original_pp = pp = dp->read_pp, dp->read_pp = NULL;
|
935
|
+
dp->original_ip = ip = dp->read_ip, dp->read_ip = NULL;
|
936
|
+
|
937
|
+
dp->original_rowbytes = png_get_rowbytes(pp, ip);
|
938
|
+
if (dp->original_rowbytes == 0)
|
939
|
+
display_log(dp, LIBPNG_BUG, "png_get_rowbytes returned 0");
|
940
|
+
|
941
|
+
dp->chunks = png_get_valid(pp, ip, 0xffffffff);
|
942
|
+
if ((dp->chunks & PNG_INFO_IDAT) == 0) /* set by png_read_png */
|
943
|
+
display_log(dp, LIBPNG_BUG, "png_read_png did not set IDAT flag");
|
944
|
+
|
945
|
+
dp->original_rows = png_get_rows(pp, ip);
|
946
|
+
if (dp->original_rows == NULL)
|
947
|
+
display_log(dp, LIBPNG_BUG, "png_read_png did not create row buffers");
|
948
|
+
|
949
|
+
if (!png_get_IHDR(pp, ip,
|
950
|
+
&dp->width, &dp->height, &dp->bit_depth, &dp->color_type,
|
951
|
+
&dp->interlace_method, &dp->compression_method, &dp->filter_method))
|
952
|
+
display_log(dp, LIBPNG_BUG, "png_get_IHDR failed");
|
953
|
+
|
954
|
+
/* 'active' transforms are discovered based on the original image format;
|
955
|
+
* running one active transform can activate others. At present the code
|
956
|
+
* does not attempt to determine the closure.
|
957
|
+
*/
|
958
|
+
{
|
959
|
+
png_uint_32 chunks = dp->chunks;
|
960
|
+
int active = 0, inactive = 0;
|
961
|
+
int ct = dp->color_type;
|
962
|
+
int bd = dp->bit_depth;
|
963
|
+
unsigned int i;
|
964
|
+
|
965
|
+
for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
|
966
|
+
{
|
967
|
+
int transform = transform_info[i].transform;
|
968
|
+
|
969
|
+
if ((transform_info[i].valid_chunks == 0 ||
|
970
|
+
(transform_info[i].valid_chunks & chunks) != 0) &&
|
971
|
+
(transform_info[i].color_mask_required & ct) ==
|
972
|
+
transform_info[i].color_mask_required &&
|
973
|
+
(transform_info[i].color_mask_absent & ct) == 0 &&
|
974
|
+
(transform_info[i].bit_depths & bd) != 0 &&
|
975
|
+
(transform_info[i].when & TRANSFORM_R) != 0)
|
976
|
+
active |= transform;
|
977
|
+
|
978
|
+
else if ((transform_info[i].when & TRANSFORM_R) != 0)
|
979
|
+
inactive |= transform;
|
980
|
+
}
|
981
|
+
|
982
|
+
/* Some transforms appear multiple times in the table; the 'active' status
|
983
|
+
* is the logical OR of these and the inactive status must be adjusted to
|
984
|
+
* take this into account.
|
985
|
+
*/
|
986
|
+
inactive &= ~active;
|
987
|
+
|
988
|
+
dp->active_transforms = active;
|
989
|
+
dp->ignored_transforms = inactive; /* excluding write-only transforms */
|
990
|
+
}
|
991
|
+
}
|
992
|
+
|
993
|
+
static int
|
994
|
+
compare_read(struct display *dp, int applied_transforms)
|
995
|
+
{
|
996
|
+
/* Compare the png_info from read_ip with original_info */
|
997
|
+
size_t rowbytes;
|
998
|
+
png_uint_32 width, height;
|
999
|
+
int bit_depth, color_type;
|
1000
|
+
int interlace_method, compression_method, filter_method;
|
1001
|
+
const char *e = NULL;
|
1002
|
+
|
1003
|
+
png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth,
|
1004
|
+
&color_type, &interlace_method, &compression_method, &filter_method);
|
1005
|
+
|
1006
|
+
# define C(item) if (item != dp->item) \
|
1007
|
+
display_log(dp, APP_WARNING, "IHDR " #item "(%lu) changed to %lu",\
|
1008
|
+
(unsigned long)dp->item, (unsigned long)item), e = #item
|
1009
|
+
|
1010
|
+
/* The IHDR should be identical: */
|
1011
|
+
C(width);
|
1012
|
+
C(height);
|
1013
|
+
C(bit_depth);
|
1014
|
+
C(color_type);
|
1015
|
+
C(interlace_method);
|
1016
|
+
C(compression_method);
|
1017
|
+
C(filter_method);
|
1018
|
+
|
1019
|
+
/* 'e' remains set to the name of the last thing changed: */
|
1020
|
+
if (e)
|
1021
|
+
display_log(dp, APP_ERROR, "IHDR changed (%s)", e);
|
1022
|
+
|
1023
|
+
/* All the chunks from the original PNG should be preserved in the output PNG
|
1024
|
+
* because the PNG format has not been changed.
|
1025
|
+
*/
|
1026
|
+
{
|
1027
|
+
unsigned long chunks =
|
1028
|
+
png_get_valid(dp->read_pp, dp->read_ip, 0xffffffff);
|
1029
|
+
|
1030
|
+
if (chunks != dp->chunks)
|
1031
|
+
display_log(dp, APP_FAIL, "PNG chunks changed from 0x%lx to 0x%lx",
|
1032
|
+
(unsigned long)dp->chunks, chunks);
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
/* rowbytes should be the same */
|
1036
|
+
rowbytes = png_get_rowbytes(dp->read_pp, dp->read_ip);
|
1037
|
+
|
1038
|
+
/* NOTE: on 64-bit systems this may trash the top bits of rowbytes,
|
1039
|
+
* which could lead to weird error messages.
|
1040
|
+
*/
|
1041
|
+
if (rowbytes != dp->original_rowbytes)
|
1042
|
+
display_log(dp, APP_ERROR, "PNG rowbytes changed from %lu to %lu",
|
1043
|
+
(unsigned long)dp->original_rowbytes, (unsigned long)rowbytes);
|
1044
|
+
|
1045
|
+
/* The rows should be the same too, unless the applied transforms includes
|
1046
|
+
* the shift transform, in which case low bits may have been lost.
|
1047
|
+
*/
|
1048
|
+
{
|
1049
|
+
png_bytepp rows = png_get_rows(dp->read_pp, dp->read_ip);
|
1050
|
+
unsigned int mask; /* mask (if not zero) for the final byte */
|
1051
|
+
|
1052
|
+
if (bit_depth < 8)
|
1053
|
+
{
|
1054
|
+
/* Need the stray bits at the end, this depends only on the low bits
|
1055
|
+
* of the image width; overflow does not matter. If the width is an
|
1056
|
+
* exact multiple of 8 bits this gives a mask of 0, not 0xff.
|
1057
|
+
*/
|
1058
|
+
mask = 0xff & (0xff00 >> ((bit_depth * width) & 7));
|
1059
|
+
}
|
1060
|
+
|
1061
|
+
else
|
1062
|
+
mask = 0;
|
1063
|
+
|
1064
|
+
if (rows == NULL)
|
1065
|
+
display_log(dp, LIBPNG_BUG, "png_get_rows returned NULL");
|
1066
|
+
|
1067
|
+
if ((applied_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
|
1068
|
+
(dp->active_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
|
1069
|
+
color_type == PNG_COLOR_TYPE_PALETTE)
|
1070
|
+
{
|
1071
|
+
unsigned long y;
|
1072
|
+
|
1073
|
+
for (y=0; y<height; ++y)
|
1074
|
+
{
|
1075
|
+
png_bytep row = rows[y];
|
1076
|
+
png_bytep orig = dp->original_rows[y];
|
1077
|
+
|
1078
|
+
if (memcmp(row, orig, rowbytes-(mask != 0)) != 0 || (mask != 0 &&
|
1079
|
+
((row[rowbytes-1] & mask) != (orig[rowbytes-1] & mask))))
|
1080
|
+
{
|
1081
|
+
size_t x;
|
1082
|
+
|
1083
|
+
/* Find the first error */
|
1084
|
+
for (x=0; x<rowbytes-1; ++x) if (row[x] != orig[x])
|
1085
|
+
break;
|
1086
|
+
|
1087
|
+
display_log(dp, APP_FAIL,
|
1088
|
+
"byte(%lu,%lu) changed 0x%.2x -> 0x%.2x",
|
1089
|
+
(unsigned long)x, (unsigned long)y, orig[x], row[x]);
|
1090
|
+
return 0; /* don't keep reporting failed rows on 'continue' */
|
1091
|
+
}
|
1092
|
+
}
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
else
|
1096
|
+
# ifdef PNG_sBIT_SUPPORTED
|
1097
|
+
{
|
1098
|
+
unsigned long y;
|
1099
|
+
int bpp; /* bits-per-pixel then bytes-per-pixel */
|
1100
|
+
/* components are up to 8 bytes in size */
|
1101
|
+
png_byte sig_bits[8];
|
1102
|
+
png_color_8p sBIT;
|
1103
|
+
|
1104
|
+
if (png_get_sBIT(dp->read_pp, dp->read_ip, &sBIT) != PNG_INFO_sBIT)
|
1105
|
+
display_log(dp, INTERNAL_ERROR,
|
1106
|
+
"active shift transform but no sBIT in file");
|
1107
|
+
|
1108
|
+
switch (color_type)
|
1109
|
+
{
|
1110
|
+
case PNG_COLOR_TYPE_GRAY:
|
1111
|
+
sig_bits[0] = sBIT->gray;
|
1112
|
+
bpp = bit_depth;
|
1113
|
+
break;
|
1114
|
+
|
1115
|
+
case PNG_COLOR_TYPE_GA:
|
1116
|
+
sig_bits[0] = sBIT->gray;
|
1117
|
+
sig_bits[1] = sBIT->alpha;
|
1118
|
+
bpp = 2 * bit_depth;
|
1119
|
+
break;
|
1120
|
+
|
1121
|
+
case PNG_COLOR_TYPE_RGB:
|
1122
|
+
sig_bits[0] = sBIT->red;
|
1123
|
+
sig_bits[1] = sBIT->green;
|
1124
|
+
sig_bits[2] = sBIT->blue;
|
1125
|
+
bpp = 3 * bit_depth;
|
1126
|
+
break;
|
1127
|
+
|
1128
|
+
case PNG_COLOR_TYPE_RGBA:
|
1129
|
+
sig_bits[0] = sBIT->red;
|
1130
|
+
sig_bits[1] = sBIT->green;
|
1131
|
+
sig_bits[2] = sBIT->blue;
|
1132
|
+
sig_bits[3] = sBIT->alpha;
|
1133
|
+
bpp = 4 * bit_depth;
|
1134
|
+
break;
|
1135
|
+
|
1136
|
+
default:
|
1137
|
+
display_log(dp, LIBPNG_ERROR, "invalid colour type %d",
|
1138
|
+
color_type);
|
1139
|
+
/*NOTREACHED*/
|
1140
|
+
bpp = 0;
|
1141
|
+
break;
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
{
|
1145
|
+
int b;
|
1146
|
+
|
1147
|
+
for (b=0; 8*b<bpp; ++b)
|
1148
|
+
{
|
1149
|
+
/* libpng should catch this; if not there is a security issue
|
1150
|
+
* because an app (like this one) may overflow an array. In fact
|
1151
|
+
* libpng doesn't catch this at present.
|
1152
|
+
*/
|
1153
|
+
if (sig_bits[b] == 0 || sig_bits[b] > bit_depth/*!palette*/)
|
1154
|
+
display_log(dp, LIBPNG_BUG,
|
1155
|
+
"invalid sBIT[%u] value %d returned for PNG bit depth %d",
|
1156
|
+
b, sig_bits[b], bit_depth);
|
1157
|
+
}
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
if (bpp < 8 && bpp != bit_depth)
|
1161
|
+
{
|
1162
|
+
/* sanity check; this is a grayscale PNG; something is wrong in the
|
1163
|
+
* code above.
|
1164
|
+
*/
|
1165
|
+
display_log(dp, INTERNAL_ERROR, "invalid bpp %u for bit_depth %u",
|
1166
|
+
bpp, bit_depth);
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
switch (bit_depth)
|
1170
|
+
{
|
1171
|
+
int b;
|
1172
|
+
|
1173
|
+
case 16: /* Two bytes per component, big-endian */
|
1174
|
+
for (b = (bpp >> 4); b > 0; --b)
|
1175
|
+
{
|
1176
|
+
unsigned int sig = (unsigned int)(0xffff0000 >> sig_bits[b]);
|
1177
|
+
|
1178
|
+
sig_bits[2*b+1] = (png_byte)sig;
|
1179
|
+
sig_bits[2*b+0] = (png_byte)(sig >> 8); /* big-endian */
|
1180
|
+
}
|
1181
|
+
break;
|
1182
|
+
|
1183
|
+
case 8: /* One byte per component */
|
1184
|
+
for (b=0; b*8 < bpp; ++b)
|
1185
|
+
sig_bits[b] = (png_byte)(0xff00 >> sig_bits[b]);
|
1186
|
+
break;
|
1187
|
+
|
1188
|
+
case 1: /* allowed, but dumb */
|
1189
|
+
/* Value is 1 */
|
1190
|
+
sig_bits[0] = 0xff;
|
1191
|
+
break;
|
1192
|
+
|
1193
|
+
case 2: /* Replicate 4 times */
|
1194
|
+
/* Value is 1 or 2 */
|
1195
|
+
b = 0x3 & ((0x3<<2) >> sig_bits[0]);
|
1196
|
+
b |= b << 2;
|
1197
|
+
b |= b << 4;
|
1198
|
+
sig_bits[0] = (png_byte)b;
|
1199
|
+
break;
|
1200
|
+
|
1201
|
+
case 4: /* Relicate twice */
|
1202
|
+
/* Value is 1, 2, 3 or 4 */
|
1203
|
+
b = 0xf & ((0xf << 4) >> sig_bits[0]);
|
1204
|
+
b |= b << 4;
|
1205
|
+
sig_bits[0] = (png_byte)b;
|
1206
|
+
break;
|
1207
|
+
|
1208
|
+
default:
|
1209
|
+
display_log(dp, LIBPNG_BUG, "invalid bit depth %d", bit_depth);
|
1210
|
+
break;
|
1211
|
+
}
|
1212
|
+
|
1213
|
+
/* Convert bpp to bytes; this gives '1' for low-bit depth grayscale,
|
1214
|
+
* where there are multiple pixels per byte.
|
1215
|
+
*/
|
1216
|
+
bpp = (bpp+7) >> 3;
|
1217
|
+
|
1218
|
+
/* The mask can be combined with sig_bits[0] */
|
1219
|
+
if (mask != 0)
|
1220
|
+
{
|
1221
|
+
mask &= sig_bits[0];
|
1222
|
+
|
1223
|
+
if (bpp != 1 || mask == 0)
|
1224
|
+
display_log(dp, INTERNAL_ERROR, "mask calculation error %u, %u",
|
1225
|
+
bpp, mask);
|
1226
|
+
}
|
1227
|
+
|
1228
|
+
for (y=0; y<height; ++y)
|
1229
|
+
{
|
1230
|
+
png_bytep row = rows[y];
|
1231
|
+
png_bytep orig = dp->original_rows[y];
|
1232
|
+
unsigned long x;
|
1233
|
+
|
1234
|
+
for (x=0; x<(width-(mask!=0)); ++x)
|
1235
|
+
{
|
1236
|
+
int b;
|
1237
|
+
|
1238
|
+
for (b=0; b<bpp; ++b)
|
1239
|
+
{
|
1240
|
+
if ((*row++ & sig_bits[b]) != (*orig++ & sig_bits[b]))
|
1241
|
+
{
|
1242
|
+
display_log(dp, APP_FAIL,
|
1243
|
+
"significant bits at (%lu[%u],%lu) changed %.2x->%.2x",
|
1244
|
+
x, b, y, orig[-1], row[-1]);
|
1245
|
+
return 0;
|
1246
|
+
}
|
1247
|
+
}
|
1248
|
+
}
|
1249
|
+
|
1250
|
+
if (mask != 0 && (*row & mask) != (*orig & mask))
|
1251
|
+
{
|
1252
|
+
display_log(dp, APP_FAIL,
|
1253
|
+
"significant bits at (%lu[end],%lu) changed", x, y);
|
1254
|
+
return 0;
|
1255
|
+
}
|
1256
|
+
} /* for y */
|
1257
|
+
}
|
1258
|
+
# else /* !sBIT */
|
1259
|
+
display_log(dp, INTERNAL_ERROR,
|
1260
|
+
"active shift transform but no sBIT support");
|
1261
|
+
# endif /* !sBIT */
|
1262
|
+
}
|
1263
|
+
|
1264
|
+
return 1; /* compare succeeded */
|
1265
|
+
}
|
1266
|
+
|
1267
|
+
#ifdef PNG_WRITE_PNG_SUPPORTED
|
1268
|
+
static void
|
1269
|
+
buffer_write(struct display *dp, struct buffer *buffer, png_bytep data,
|
1270
|
+
png_size_t size)
|
1271
|
+
/* Generic write function used both from the write callback provided to
|
1272
|
+
* libpng and from the generic read code.
|
1273
|
+
*/
|
1274
|
+
{
|
1275
|
+
/* Write the data into the buffer, adding buffers as required */
|
1276
|
+
struct buffer_list *last = buffer->last;
|
1277
|
+
size_t end_count = buffer->end_count;
|
1278
|
+
|
1279
|
+
while (size > 0)
|
1280
|
+
{
|
1281
|
+
size_t avail;
|
1282
|
+
|
1283
|
+
if (end_count >= sizeof last->buffer)
|
1284
|
+
{
|
1285
|
+
if (last->next == NULL)
|
1286
|
+
{
|
1287
|
+
last = buffer_extend(last);
|
1288
|
+
|
1289
|
+
if (last == NULL)
|
1290
|
+
display_log(dp, APP_ERROR, "out of memory saving file");
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
else
|
1294
|
+
last = last->next;
|
1295
|
+
|
1296
|
+
buffer->last = last; /* avoid the need to rewrite every time */
|
1297
|
+
end_count = 0;
|
1298
|
+
}
|
1299
|
+
|
1300
|
+
avail = (sizeof last->buffer) - end_count;
|
1301
|
+
if (avail > size)
|
1302
|
+
avail = size;
|
1303
|
+
|
1304
|
+
memcpy(last->buffer + end_count, data, avail);
|
1305
|
+
end_count += avail;
|
1306
|
+
size -= avail;
|
1307
|
+
data += avail;
|
1308
|
+
}
|
1309
|
+
|
1310
|
+
buffer->end_count = end_count;
|
1311
|
+
}
|
1312
|
+
|
1313
|
+
static void PNGCBAPI
|
1314
|
+
write_function(png_structp pp, png_bytep data, png_size_t size)
|
1315
|
+
{
|
1316
|
+
buffer_write(get_dp(pp), get_buffer(pp), data, size);
|
1317
|
+
}
|
1318
|
+
|
1319
|
+
static void
|
1320
|
+
write_png(struct display *dp, png_infop ip, int transforms)
|
1321
|
+
{
|
1322
|
+
display_clean_write(dp); /* safety */
|
1323
|
+
|
1324
|
+
buffer_start_write(&dp->written_file);
|
1325
|
+
dp->operation = "write";
|
1326
|
+
dp->transforms = transforms;
|
1327
|
+
|
1328
|
+
dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
|
1329
|
+
display_error, display_warning);
|
1330
|
+
|
1331
|
+
if (dp->write_pp == NULL)
|
1332
|
+
display_log(dp, APP_ERROR, "failed to create write png_struct");
|
1333
|
+
|
1334
|
+
png_set_write_fn(dp->write_pp, &dp->written_file, write_function,
|
1335
|
+
NULL/*flush*/);
|
1336
|
+
|
1337
|
+
# ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
1338
|
+
/* Remove the user limits, if any */
|
1339
|
+
png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
|
1340
|
+
# endif
|
1341
|
+
|
1342
|
+
/* Certain transforms require the png_info to be zapped to allow the
|
1343
|
+
* transform to work correctly.
|
1344
|
+
*/
|
1345
|
+
if (transforms & (PNG_TRANSFORM_PACKING|
|
1346
|
+
PNG_TRANSFORM_STRIP_FILLER|
|
1347
|
+
PNG_TRANSFORM_STRIP_FILLER_BEFORE))
|
1348
|
+
{
|
1349
|
+
int ct = dp->color_type;
|
1350
|
+
|
1351
|
+
if (transforms & (PNG_TRANSFORM_STRIP_FILLER|
|
1352
|
+
PNG_TRANSFORM_STRIP_FILLER_BEFORE))
|
1353
|
+
ct &= ~PNG_COLOR_MASK_ALPHA;
|
1354
|
+
|
1355
|
+
png_set_IHDR(dp->write_pp, ip, dp->width, dp->height, dp->bit_depth, ct,
|
1356
|
+
dp->interlace_method, dp->compression_method, dp->filter_method);
|
1357
|
+
}
|
1358
|
+
|
1359
|
+
png_write_png(dp->write_pp, ip, transforms, NULL/*params*/);
|
1360
|
+
|
1361
|
+
/* Clean it on the way out - if control returns to the caller then the
|
1362
|
+
* written_file contains the required data.
|
1363
|
+
*/
|
1364
|
+
display_clean_write(dp);
|
1365
|
+
}
|
1366
|
+
#endif /* WRITE_PNG */
|
1367
|
+
|
1368
|
+
static int
|
1369
|
+
skip_transform(struct display *dp, int tr)
|
1370
|
+
/* Helper to test for a bad combo and log it if it is skipped */
|
1371
|
+
{
|
1372
|
+
if ((dp->options & SKIP_BUGS) != 0 && is_bad_combo(tr))
|
1373
|
+
{
|
1374
|
+
/* Log this to stdout if logging is on, otherwise just do an information
|
1375
|
+
* display_log.
|
1376
|
+
*/
|
1377
|
+
if ((dp->options & LOG_SKIPPED) != 0)
|
1378
|
+
{
|
1379
|
+
printf("SKIP: %s transforms ", dp->filename);
|
1380
|
+
|
1381
|
+
while (tr != 0)
|
1382
|
+
{
|
1383
|
+
int next = first_transform(tr);
|
1384
|
+
tr &= ~next;
|
1385
|
+
|
1386
|
+
printf("%s", transform_name(next));
|
1387
|
+
if (tr != 0)
|
1388
|
+
putchar('+');
|
1389
|
+
}
|
1390
|
+
|
1391
|
+
putchar('\n');
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
else
|
1395
|
+
display_log(dp, INFORMATION, "%s: skipped known bad combo 0x%x",
|
1396
|
+
dp->filename, tr);
|
1397
|
+
|
1398
|
+
return 1; /* skip */
|
1399
|
+
}
|
1400
|
+
|
1401
|
+
return 0; /* don't skip */
|
1402
|
+
}
|
1403
|
+
|
1404
|
+
static void
|
1405
|
+
test_one_file(struct display *dp, const char *filename)
|
1406
|
+
{
|
1407
|
+
/* First cache the file and update the display original file
|
1408
|
+
* information for the new file.
|
1409
|
+
*/
|
1410
|
+
dp->operation = "cache file";
|
1411
|
+
dp->transforms = 0;
|
1412
|
+
display_cache_file(dp, filename);
|
1413
|
+
update_display(dp);
|
1414
|
+
|
1415
|
+
/* First test: if there are options that should be ignored for this file
|
1416
|
+
* verify that they really are ignored.
|
1417
|
+
*/
|
1418
|
+
if (dp->ignored_transforms != 0)
|
1419
|
+
{
|
1420
|
+
read_png(dp, &dp->original_file, "ignored transforms",
|
1421
|
+
dp->ignored_transforms);
|
1422
|
+
|
1423
|
+
/* The result should be identical to the original_rows */
|
1424
|
+
if (!compare_read(dp, 0/*transforms applied*/))
|
1425
|
+
return; /* no point testing more */
|
1426
|
+
}
|
1427
|
+
|
1428
|
+
#ifdef PNG_WRITE_PNG_SUPPORTED
|
1429
|
+
/* Second test: write the original PNG data out to a new file (to test the
|
1430
|
+
* write side) then read the result back in and make sure that it hasn't
|
1431
|
+
* changed.
|
1432
|
+
*/
|
1433
|
+
dp->operation = "write";
|
1434
|
+
write_png(dp, dp->original_ip, 0/*transforms*/);
|
1435
|
+
read_png(dp, &dp->written_file, NULL, 0/*transforms*/);
|
1436
|
+
if (!compare_read(dp, 0/*transforms applied*/))
|
1437
|
+
return;
|
1438
|
+
#endif
|
1439
|
+
|
1440
|
+
/* Third test: the active options. Test each in turn, or, with the
|
1441
|
+
* EXHAUSTIVE option, test all possible combinations.
|
1442
|
+
*/
|
1443
|
+
{
|
1444
|
+
/* Use unsigned int here because the code below to increment through all
|
1445
|
+
* the possibilities exhaustively has to use a compare and that must be
|
1446
|
+
* unsigned, because some transforms are negative on a 16-bit system.
|
1447
|
+
*/
|
1448
|
+
unsigned int active = dp->active_transforms;
|
1449
|
+
const int exhaustive = (dp->options & EXHAUSTIVE) != 0;
|
1450
|
+
unsigned int current = first_transform(active);
|
1451
|
+
unsigned int bad_transforms = 0;
|
1452
|
+
unsigned int bad_combo = ~0U; /* bitwise AND of failing transforms */
|
1453
|
+
unsigned int bad_combo_list = 0; /* bitwise OR of failures */
|
1454
|
+
|
1455
|
+
for (;;)
|
1456
|
+
{
|
1457
|
+
read_png(dp, &dp->original_file, "active transforms", current);
|
1458
|
+
|
1459
|
+
/* If this involved any irreversible transformations then if we write
|
1460
|
+
* it out with just the reversible transformations and read it in again
|
1461
|
+
* with the same transforms we should get the same thing. At present
|
1462
|
+
* this isn't done - it just seems like a waste of time and it would
|
1463
|
+
* require two sets of read png_struct/png_info.
|
1464
|
+
*
|
1465
|
+
* If there were no irreversible transformations then if we write it
|
1466
|
+
* out and read it back in again (without the reversible transforms)
|
1467
|
+
* we should get back to the place where we started.
|
1468
|
+
*/
|
1469
|
+
#ifdef PNG_WRITE_PNG_SUPPORTED
|
1470
|
+
if ((current & write_transforms) == current)
|
1471
|
+
{
|
1472
|
+
/* All transforms reversible: write the PNG with the transformations
|
1473
|
+
* reversed, then read it back in with no transformations. The
|
1474
|
+
* result should be the same as the original apart from the loss of
|
1475
|
+
* low order bits because of the SHIFT/sBIT transform.
|
1476
|
+
*/
|
1477
|
+
dp->operation = "reversible transforms";
|
1478
|
+
write_png(dp, dp->read_ip, current);
|
1479
|
+
|
1480
|
+
/* And if this is read back in, because all the transformations were
|
1481
|
+
* reversible, the result should be the same.
|
1482
|
+
*/
|
1483
|
+
read_png(dp, &dp->written_file, NULL, 0);
|
1484
|
+
if (!compare_read(dp, current/*for the SHIFT/sBIT transform*/))
|
1485
|
+
{
|
1486
|
+
/* This set of transforms failed. If a single bit is set - if
|
1487
|
+
* there is just one transform - don't include this in further
|
1488
|
+
* 'exhaustive' tests. Notice that each transform is tested on
|
1489
|
+
* its own before testing combos in the exhaustive case.
|
1490
|
+
*/
|
1491
|
+
if (is_combo(current))
|
1492
|
+
{
|
1493
|
+
bad_combo &= current;
|
1494
|
+
bad_combo_list |= current;
|
1495
|
+
}
|
1496
|
+
|
1497
|
+
else
|
1498
|
+
bad_transforms |= current;
|
1499
|
+
}
|
1500
|
+
}
|
1501
|
+
#endif
|
1502
|
+
|
1503
|
+
/* Now move to the next transform */
|
1504
|
+
if (exhaustive) /* all combinations */
|
1505
|
+
{
|
1506
|
+
unsigned int next = current;
|
1507
|
+
|
1508
|
+
do
|
1509
|
+
{
|
1510
|
+
if (next == read_transforms) /* Everything tested */
|
1511
|
+
goto combo;
|
1512
|
+
|
1513
|
+
++next;
|
1514
|
+
} /* skip known bad combos if the relevant option is set; skip
|
1515
|
+
* combos involving known bad single transforms in all cases.
|
1516
|
+
*/
|
1517
|
+
while ( (next & read_transforms) <= current
|
1518
|
+
|| (next & active) == 0 /* skip cases that do nothing */
|
1519
|
+
|| (next & bad_transforms) != 0
|
1520
|
+
|| skip_transform(dp, next));
|
1521
|
+
|
1522
|
+
assert((next & read_transforms) == next);
|
1523
|
+
current = next;
|
1524
|
+
}
|
1525
|
+
|
1526
|
+
else /* one at a time */
|
1527
|
+
{
|
1528
|
+
active &= ~current;
|
1529
|
+
|
1530
|
+
if (active == 0)
|
1531
|
+
goto combo;
|
1532
|
+
|
1533
|
+
current = first_transform(active);
|
1534
|
+
}
|
1535
|
+
}
|
1536
|
+
|
1537
|
+
combo:
|
1538
|
+
if (dp->options & FIND_BAD_COMBOS)
|
1539
|
+
{
|
1540
|
+
/* bad_combos identifies the combos that occur in all failing cases;
|
1541
|
+
* bad_combo_list identifies transforms that do not prevent the
|
1542
|
+
* failure.
|
1543
|
+
*/
|
1544
|
+
if (bad_combo != ~0U)
|
1545
|
+
printf("%s[0x%x]: PROBLEM: 0x%x[0x%x] ANTIDOTE: 0x%x\n",
|
1546
|
+
dp->filename, active, bad_combo, bad_combo_list,
|
1547
|
+
rw_transforms & ~bad_combo_list);
|
1548
|
+
|
1549
|
+
else
|
1550
|
+
printf("%s: no %sbad combos found\n", dp->filename,
|
1551
|
+
(dp->options & SKIP_BUGS) ? "additional " : "");
|
1552
|
+
}
|
1553
|
+
}
|
1554
|
+
}
|
1555
|
+
|
1556
|
+
static int
|
1557
|
+
do_test(struct display *dp, const char *file)
|
1558
|
+
/* Exists solely to isolate the setjmp clobbers */
|
1559
|
+
{
|
1560
|
+
int ret = setjmp(dp->error_return);
|
1561
|
+
|
1562
|
+
if (ret == 0)
|
1563
|
+
{
|
1564
|
+
test_one_file(dp, file);
|
1565
|
+
return 0;
|
1566
|
+
}
|
1567
|
+
|
1568
|
+
else if (ret < ERRORS) /* shouldn't longjmp on warnings */
|
1569
|
+
display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
|
1570
|
+
|
1571
|
+
return ret;
|
1572
|
+
}
|
1573
|
+
|
1574
|
+
int
|
1575
|
+
main(const int argc, const char * const * const argv)
|
1576
|
+
{
|
1577
|
+
/* For each file on the command line test it with a range of transforms */
|
1578
|
+
int option_end, ilog = 0;
|
1579
|
+
struct display d;
|
1580
|
+
|
1581
|
+
validate_T();
|
1582
|
+
display_init(&d);
|
1583
|
+
|
1584
|
+
for (option_end=1; option_end<argc; ++option_end)
|
1585
|
+
{
|
1586
|
+
const char *name = argv[option_end];
|
1587
|
+
|
1588
|
+
if (strcmp(name, "--verbose") == 0)
|
1589
|
+
d.options = (d.options & ~LEVEL_MASK) | VERBOSE;
|
1590
|
+
|
1591
|
+
else if (strcmp(name, "--warnings") == 0)
|
1592
|
+
d.options = (d.options & ~LEVEL_MASK) | WARNINGS;
|
1593
|
+
|
1594
|
+
else if (strcmp(name, "--errors") == 0)
|
1595
|
+
d.options = (d.options & ~LEVEL_MASK) | ERRORS;
|
1596
|
+
|
1597
|
+
else if (strcmp(name, "--quiet") == 0)
|
1598
|
+
d.options = (d.options & ~LEVEL_MASK) | QUIET;
|
1599
|
+
|
1600
|
+
else if (strcmp(name, "--exhaustive") == 0)
|
1601
|
+
d.options |= EXHAUSTIVE;
|
1602
|
+
|
1603
|
+
else if (strcmp(name, "--fast") == 0)
|
1604
|
+
d.options &= ~EXHAUSTIVE;
|
1605
|
+
|
1606
|
+
else if (strcmp(name, "--strict") == 0)
|
1607
|
+
d.options |= STRICT;
|
1608
|
+
|
1609
|
+
else if (strcmp(name, "--relaxed") == 0)
|
1610
|
+
d.options &= ~STRICT;
|
1611
|
+
|
1612
|
+
else if (strcmp(name, "--log") == 0)
|
1613
|
+
{
|
1614
|
+
ilog = option_end; /* prevent display */
|
1615
|
+
d.options |= LOG;
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
else if (strcmp(name, "--nolog") == 0)
|
1619
|
+
d.options &= ~LOG;
|
1620
|
+
|
1621
|
+
else if (strcmp(name, "--continue") == 0)
|
1622
|
+
d.options |= CONTINUE;
|
1623
|
+
|
1624
|
+
else if (strcmp(name, "--stop") == 0)
|
1625
|
+
d.options &= ~CONTINUE;
|
1626
|
+
|
1627
|
+
else if (strcmp(name, "--skip-bugs") == 0)
|
1628
|
+
d.options |= SKIP_BUGS;
|
1629
|
+
|
1630
|
+
else if (strcmp(name, "--test-all") == 0)
|
1631
|
+
d.options &= ~SKIP_BUGS;
|
1632
|
+
|
1633
|
+
else if (strcmp(name, "--log-skipped") == 0)
|
1634
|
+
d.options |= LOG_SKIPPED;
|
1635
|
+
|
1636
|
+
else if (strcmp(name, "--nolog-skipped") == 0)
|
1637
|
+
d.options &= ~LOG_SKIPPED;
|
1638
|
+
|
1639
|
+
else if (strcmp(name, "--find-bad-combos") == 0)
|
1640
|
+
d.options |= FIND_BAD_COMBOS;
|
1641
|
+
|
1642
|
+
else if (strcmp(name, "--nofind-bad-combos") == 0)
|
1643
|
+
d.options &= ~FIND_BAD_COMBOS;
|
1644
|
+
|
1645
|
+
else if (strcmp(name, "--list-combos") == 0)
|
1646
|
+
d.options |= LIST_COMBOS;
|
1647
|
+
|
1648
|
+
else if (strcmp(name, "--nolist-combos") == 0)
|
1649
|
+
d.options &= ~LIST_COMBOS;
|
1650
|
+
|
1651
|
+
else if (name[0] == '-' && name[1] == '-')
|
1652
|
+
{
|
1653
|
+
fprintf(stderr, "pngimage: %s: unknown option\n", name);
|
1654
|
+
return 99;
|
1655
|
+
}
|
1656
|
+
|
1657
|
+
else
|
1658
|
+
break; /* Not an option */
|
1659
|
+
}
|
1660
|
+
|
1661
|
+
{
|
1662
|
+
int i;
|
1663
|
+
int errors = 0;
|
1664
|
+
|
1665
|
+
for (i=option_end; i<argc; ++i)
|
1666
|
+
{
|
1667
|
+
{
|
1668
|
+
int ret = do_test(&d, argv[i]);
|
1669
|
+
|
1670
|
+
if (ret > QUIET) /* abort on user or internal error */
|
1671
|
+
return 99;
|
1672
|
+
}
|
1673
|
+
|
1674
|
+
/* Here on any return, including failures, except user/internal issues
|
1675
|
+
*/
|
1676
|
+
{
|
1677
|
+
const int pass = (d.options & STRICT) ?
|
1678
|
+
RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
|
1679
|
+
|
1680
|
+
if (!pass)
|
1681
|
+
++errors;
|
1682
|
+
|
1683
|
+
if (d.options & LOG)
|
1684
|
+
{
|
1685
|
+
int j;
|
1686
|
+
|
1687
|
+
printf("%s: pngimage ", pass ? "PASS" : "FAIL");
|
1688
|
+
|
1689
|
+
for (j=1; j<option_end; ++j) if (j != ilog)
|
1690
|
+
printf("%s ", argv[j]);
|
1691
|
+
|
1692
|
+
printf("%s\n", d.filename);
|
1693
|
+
}
|
1694
|
+
}
|
1695
|
+
|
1696
|
+
display_clean(&d);
|
1697
|
+
}
|
1698
|
+
|
1699
|
+
/* Release allocated memory */
|
1700
|
+
display_destroy(&d);
|
1701
|
+
|
1702
|
+
return errors != 0;
|
1703
|
+
}
|
1704
|
+
}
|
1705
|
+
#else /* !READ_PNG */
|
1706
|
+
int
|
1707
|
+
main(void)
|
1708
|
+
{
|
1709
|
+
fprintf(stderr, "pngimage: no support for png_read/write_image\n");
|
1710
|
+
return SKIP;
|
1711
|
+
}
|
1712
|
+
#endif
|