summaryrefslogtreecommitdiff
path: root/Build/source/libs/libpng/libpng-src/contrib
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/libs/libpng/libpng-src/contrib
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/libpng/libpng-src/contrib')
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/README.txt5
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/arm-neon/README83
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/arm-neon/android-ndk.c39
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux-auxv.c120
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux.c161
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/conftest/README49
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/conftest/pngcp.dfa57
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/conftest/read.dfa58
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/conftest/s_read.dfa35
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/conftest/s_write.dfa33
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/conftest/simple.dfa36
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/conftest/write.dfa45
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/examples/README.txt24
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/examples/iccfrompng.c185
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/examples/pngpixel.c371
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/examples/pngtopng.c98
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/examples/simpleover.c648
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/COPYING340
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/LICENSE50
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.mingw32131
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.sgi105
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.unx134
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.w32114
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/README186
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/makevms.com132
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.c323
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.h88
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.c521
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.h116
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/readppm.c188
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-win.c735
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-x.c911
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-win.c1261
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-x.c2143
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/toucan.pngbin12901 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/wpng.c865
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.c401
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.h133
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/fakepng.c65
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/libtests/gentests.sh102
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/makepng.c1941
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c1712
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest-errors.h165
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest.c3828
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/pngunknown.c1294
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/pngvalid.c12230
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/readpng.c115
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/tarith.c999
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/libtests/timepng.c608
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/mips-msa/README83
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c64
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/Dockerfile25
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/README.txt37
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/oss-fuzz/build.sh51
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.cc190
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.options2
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/png.dict39
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/README5
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/README10
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/makefile151
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.dfa40
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.h23
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/README10
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/makefile150
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.dfa39
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.h23
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/README15
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/makefile166
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.dfa40
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.h23
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt13
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt24
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/LICENSE.txt22
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/Makefile62
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/README.txt120
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/makevms.com92
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.bat41
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c427
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.sh42
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.bat4
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.sh5
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.bat41
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c620
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.sh42
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/README107
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/bad_interlace_conversions.txt9
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g01.pngbin164 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g02.pngbin104 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g04.pngbin145 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g08.pngbin138 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g16.pngbin167 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c08.pngbin145 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c16.pngbin302 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p01.pngbin112 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p02.pngbin146 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p04.pngbin216 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p08.pngbin1286 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a08.pngbin126 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a16.pngbin2206 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a08.pngbin184 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a16.pngbin3435 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g01.pngbin176 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g02.pngbin197 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g04.pngbin429 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn2c16.pngbin2041 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn3p08.pngbin1499 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn2c16.pngbin2041 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn3p08.pngbin1499 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbrn2c08.pngbin1633 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn0g16.pngbin1313 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn3p08.pngbin1496 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbyn3p08.pngbin1499 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n0g08.pngbin719 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n2c08.pngbin1594 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n3p08.pngbin1476 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp1n3p08.pngbin1483 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g08.pngbin237 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g16.pngbin274 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c08.pngbin299 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c16.pngbin558 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn3p08.pngbin1492 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a08.pngbin198 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a16.pngbin2839 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a08.pngbin339 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a16.pngbin4164 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn2c16.pngbin2624 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn3p08.pngbin1507 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn2c16.pngbin2624 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn3p08.pngbin1507 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbrn2c08.pngbin1624 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn0g16.pngbin1448 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn3p08.pngbin1507 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbyn3p08.pngbin1507 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n0g08.pngbin847 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n2c08.pngbin2020 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n3p08.pngbin1495 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp1n3p08.pngbin1507 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/README2
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g01.pngbin201 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g02.pngbin138 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g04.pngbin231 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p01.pngbin116 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p02.pngbin163 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p04.pngbin288 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g01.pngbin214 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g02.pngbin211 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g04.pngbin489 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/README81
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux.c57
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux_aux.c34
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/bad_iCCP.pngbin321 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badadler.pngbin67 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badcrc.pngbin67 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/empty_ancillary_chunks.pngbin730 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_IDAT.pngbin79 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_bKGD_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_cHRM_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_eXIf_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_gAMA_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_hIST_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iCCP_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iTXt_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNk_safe_to_copy.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pCAL_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pHYs_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sCAL_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sPLT_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sRGB_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sTER_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tEXt_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tIME_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_zTXt_chunk.pngbin57 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8-tRNS.pngbin325 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8.pngbin311 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear-tRNS.pngbin325 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear.pngbin311 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB-tRNS.pngbin278 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB.pngbin264 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-tRNS.pngbin265 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1.pngbin251 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8-tRNS.pngbin744 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8.pngbin744 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear-tRNS.pngbin744 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear.pngbin744 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB-tRNS.pngbin697 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB.pngbin697 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-tRNS.pngbin684 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16.pngbin684 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8-tRNS.pngbin325 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8.pngbin311 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear-tRNS.pngbin325 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear.pngbin311 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB-tRNS.pngbin278 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB.pngbin264 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-tRNS.pngbin265 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2.pngbin251 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8-tRNS.pngbin327 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8.pngbin313 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear-tRNS.pngbin327 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear.pngbin313 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB-tRNS.pngbin280 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB.pngbin266 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-tRNS.pngbin267 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4.pngbin253 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8-tRNS.pngbin327 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8.pngbin313 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear-tRNS.pngbin327 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear.pngbin313 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB-tRNS.pngbin280 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB.pngbin266 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-tRNS.pngbin267 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8.pngbin253 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-1.8.pngbin919 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-linear.pngbin919 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-sRGB.pngbin872 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16.pngbin859 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-1.8.pngbin744 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-linear.pngbin744 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-sRGB.pngbin697 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8.pngbin684 -> 0 bytes
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh94
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8-tRNS.pngbin342 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8.pngbin329 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear-tRNS.pngbin342 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear.pngbin329 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB-tRNS.pngbin295 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB.pngbin282 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-tRNS.pngbin282 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1.pngbin269 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8-tRNS.pngbin350 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8.pngbin335 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear-tRNS.pngbin350 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear.pngbin335 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB-tRNS.pngbin303 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB.pngbin288 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-tRNS.pngbin290 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2.pngbin275 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8-tRNS.pngbin400 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8.pngbin373 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear-tRNS.pngbin400 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear.pngbin373 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB-tRNS.pngbin353 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB.pngbin326 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-tRNS.pngbin340 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4.pngbin313 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8-tRNS.pngbin1360 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8.pngbin1093 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear-tRNS.pngbin1360 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear.pngbin1093 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB-tRNS.pngbin1313 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB.pngbin1046 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-tRNS.pngbin1300 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8.pngbin1033 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8-tRNS.pngbin1211 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8.pngbin1211 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear-tRNS.pngbin1211 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear.pngbin1211 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB-tRNS.pngbin1164 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB.pngbin1164 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-tRNS.pngbin1151 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16.pngbin1151 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8-tRNS.pngbin837 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8.pngbin819 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear-tRNS.pngbin837 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear.pngbin819 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB-tRNS.pngbin790 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB.pngbin772 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-tRNS.pngbin777 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8.pngbin759 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-1.8.pngbin1437 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-linear.pngbin1437 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-sRGB.pngbin1390 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16.pngbin1377 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-1.8.pngbin919 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-linear.pngbin919 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-sRGB.pngbin872 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8.pngbin859 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/README.txt27
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/checksum-icc.c102
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/chkfmt144
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/cvtcolor.c188
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/genpng.c881
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh110
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/makesRGB.c430
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/png-fix-itxt.c164
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c2453
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c4049
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/reindent25
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/sRGB.h48
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.c454
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.h30
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/README.txt61
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.c978
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsp147
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsw29
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.icobin766 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.pngbin208 -> 0 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.rc152
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/cexcept.h248
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/visupng/resource.h23
301 files changed, 0 insertions, 47851 deletions
diff --git a/Build/source/libs/libpng/libpng-src/contrib/README.txt b/Build/source/libs/libpng/libpng-src/contrib/README.txt
deleted file mode 100644
index 97963c6d545..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/README.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-
-This "contrib" directory contains contributions which are not necessarily under
-the libpng license, although all are open source. They are not part of
-libpng proper and are not used for building the library, although some are used
-for testing the library via "make check".
diff --git a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/README b/Build/source/libs/libpng/libpng-src/contrib/arm-neon/README
deleted file mode 100644
index b4248cf2897..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/README
+++ /dev/null
@@ -1,83 +0,0 @@
-OPERATING SYSTEM SPECIFIC ARM NEON DETECTION
---------------------------------------------
-
-Detection of the ability to execute ARM NEON on an ARM processor requires
-operating system support. (The information is not available in user mode.)
-
-HOW TO USE THIS
----------------
-
-This directory contains C code fragments that can be included in arm/arm_init.c
-by setting the macro PNG_ARM_NEON_FILE to the file name in "" or <> at build
-time. This setting is not recorded in pnglibconf.h and can be changed simply by
-rebuilding arm/arm_init.o with the required macro definition.
-
-For any of this code to be used the ARM NEON code must be enabled and run time
-checks must be supported. I.e.:
-
-#if PNG_ARM_NEON_OPT > 0
-#ifdef PNG_ARM_NEON_CHECK_SUPPORTED
-
-This is done in a 'configure' build by passing configure the argument:
-
- --enable-arm-neon=check
-
-Apart from the basic Linux implementation in contrib/arm-neon/linux.c this code
-is unsupported. That means that it is not even compiled on a regular basis and
-may be broken in any given minor release.
-
-FILE FORMAT
------------
-
-Each file documents its testing status as of the last time it was tested (which
-may have been a long time ago):
-
-STATUS: one of:
- SUPPORTED: This indicates that the file is included in the regularly
- performed test builds and bugs are fixed when discovered.
- COMPILED: This indicates that the code did compile at least once. See the
- more detailed description for the extent to which the result was
- successful.
- TESTED: This means the code was fully compiled into the libpng test programs
- and these were run at least once.
-
-BUG REPORTS: an email address to which to send reports of problems
-
-The file is a fragment of C code. It should not define any 'extern' symbols;
-everything should be static. It must define the function:
-
-static int png_have_neon(png_structp png_ptr);
-
-That function must return 1 if ARM NEON instructions are supported, 0 if not.
-It must not execute png_error unless it detects a bug. A png_error will prevent
-the reading of the PNG and in the future, writing too.
-
-BUG REPORTS
------------
-
-If you mail a bug report for any file that is not SUPPORTED there may only be
-limited response. Consider fixing it and sending a patch to fix the problem -
-this is more likely to result in action.
-
-CONTRIBUTIONS
--------------
-
-You may send contributions of new implementations to
-png-mng-implement@sourceforge.net. Please write code in strict C90 C where
-possible. Obviously OS dependencies are to be expected. If you submit code you
-must have the authors permission and it must have a license that is acceptable
-to the current maintainer; in particular that license must permit modification
-and redistribution.
-
-Please try to make the contribution a single file and give the file a clear and
-unambiguous name that identifies the target OS. If multiple files really are
-required put them all in a sub-directory.
-
-You must also be prepared to handle bug reports from users of the code, either
-by joining the png-mng-implement mailing list or by providing an email for the
-"BUG REPORTS" entry or both. Please make sure that the header of the file
-contains the STATUS and BUG REPORTS fields as above.
-
-Please list the OS requirements as precisely as possible. Ideally you should
-also list the environment in which the code has been tested and certainly list
-any environments where you suspect it might not work.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/android-ndk.c b/Build/source/libs/libpng/libpng-src/contrib/arm-neon/android-ndk.c
deleted file mode 100644
index fb3a4898de6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/android-ndk.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* contrib/arm-neon/android-ndk.c
- *
- * Copyright (c) 2014 Glenn Randers-Pehrson
- * Written by John Bowler, 2014.
- * Last changed in libpng 1.6.10 [March 6, 2014]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * SEE contrib/arm-neon/README before reporting bugs
- *
- * STATUS: COMPILED, UNTESTED
- * BUG REPORTS: png-mng-implement@sourceforge.net
- *
- * png_have_neon implemented for the Android NDK, see:
- *
- * Documentation:
- * http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
- * https://code.google.com/p/android/issues/detail?id=49065
- *
- * NOTE: this requires that libpng is built against the Android NDK and linked
- * with an implementation of the Android ARM 'cpu-features' library. The code
- * has been compiled only, not linked: no version of the library has been found,
- * only the header files exist in the NDK.
- */
-#include <cpu-features.h>
-
-static int
-png_have_neon(png_structp png_ptr)
-{
- /* This is a whole lot easier than the linux code, however it is probably
- * implemented as below, therefore it is better to cache the result (these
- * function calls may be slow!)
- */
- PNG_UNUSED(png_ptr)
- return android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&
- (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux-auxv.c b/Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux-auxv.c
deleted file mode 100644
index 4d26bd3b354..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux-auxv.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* contrib/arm-neon/linux-auxv.c
- *
- * Copyright (c) 2014 Glenn Randers-Pehrson
- * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.10 [March 6, 2014]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * SEE contrib/arm-neon/README before reporting bugs
- *
- * STATUS: COMPILED, TESTED
- * BUG REPORTS: png-mng-implement@sourceforge.net
- *
- * png_have_neon implemented for Linux versions which allow access to
- * /proc/self/auxv. This is probably faster, cleaner and safer than the code to
- * read /proc/cpuinfo in contrib/arm-neon/linux, however it is yet another piece
- * of potentially untested code and has more complex dependencies than the code
- * to read cpuinfo.
- *
- * This generic __linux__ implementation requires reading /proc/self/auxv and
- * looking at each element for one that records NEON capabilities.
- */
-#include <unistd.h> /* for POSIX 1003.1 */
-#include <errno.h> /* for EINTR */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <elf.h>
-#include <asm/hwcap.h>
-
-/* A read call may be interrupted, in which case it returns -1 and sets errno to
- * EINTR if nothing was done, otherwise (if something was done) a partial read
- * may result.
- */
-static size_t
-safe_read(png_structp png_ptr, int fd, void *buffer_in, size_t nbytes)
-{
- size_t ntotal = 0;
- char *buffer = png_voidcast(char*, buffer_in);
-
- while (nbytes > 0)
- {
- unsigned int nread;
- int iread;
-
- /* Passing nread > INT_MAX to read is implementation defined in POSIX
- * 1003.1, therefore despite the unsigned argument portable code must
- * limit the value to INT_MAX!
- */
- if (nbytes > INT_MAX)
- nread = INT_MAX;
-
- else
- nread = (unsigned int)/*SAFE*/nbytes;
-
- iread = read(fd, buffer, nread);
-
- if (iread == -1)
- {
- /* This is the devil in the details, a read can terminate early with 0
- * bytes read because of EINTR, yet it still returns -1 otherwise end
- * of file cannot be distinguished.
- */
- if (errno != EINTR)
- {
- png_warning(png_ptr, "/proc read failed");
- return 0; /* I.e., a permanent failure */
- }
- }
-
- else if (iread < 0)
- {
- /* Not a valid 'read' result: */
- png_warning(png_ptr, "OS /proc read bug");
- return 0;
- }
-
- else if (iread > 0)
- {
- /* Continue reading until a permanent failure, or EOF */
- buffer += iread;
- nbytes -= (unsigned int)/*SAFE*/iread;
- ntotal += (unsigned int)/*SAFE*/iread;
- }
-
- else
- return ntotal;
- }
-
- return ntotal; /* nbytes == 0 */
-}
-
-static int
-png_have_neon(png_structp png_ptr)
-{
- int fd = open("/proc/self/auxv", O_RDONLY);
- Elf32_auxv_t aux;
-
- /* Failsafe: failure to open means no NEON */
- if (fd == -1)
- {
- png_warning(png_ptr, "/proc/self/auxv open failed");
- return 0;
- }
-
- while (safe_read(png_ptr, fd, &aux, sizeof aux) == sizeof aux)
- {
- if (aux.a_type == AT_HWCAP && (aux.a_un.a_val & HWCAP_NEON) != 0)
- {
- close(fd);
- return 1;
- }
- }
-
- close(fd);
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux.c b/Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux.c
deleted file mode 100644
index a9bc360dd5b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/arm-neon/linux.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* contrib/arm-neon/linux.c
- *
- * Last changed in libpng 1.6.31 [July 27, 2017]
- * Copyright (c) 2014, 2017 Glenn Randers-Pehrson
- * Written by John Bowler, 2014, 2017.
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * SEE contrib/arm-neon/README before reporting bugs
- *
- * STATUS: SUPPORTED
- * BUG REPORTS: png-mng-implement@sourceforge.net
- *
- * png_have_neon implemented for Linux by reading the widely available
- * pseudo-file /proc/cpuinfo.
- *
- * This code is strict ANSI-C and is probably moderately portable; it does
- * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
- */
-#include <stdio.h>
-
-static int
-png_have_neon(png_structp png_ptr)
-{
- FILE *f = fopen("/proc/cpuinfo", "rb");
-
- if (f != NULL)
- {
- /* This is a simple state machine which reads the input byte-by-byte until
- * it gets a match on the 'neon' feature or reaches the end of the stream.
- */
- static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 };
- static const char ch_neon[] = { 78, 69, 79, 78 };
-
- enum
- {
- StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine
- } state;
- int counter;
-
- for (state=StartLine, counter=0;;)
- {
- int ch = fgetc(f);
-
- if (ch == EOF)
- {
- /* EOF means error or end-of-file, return false; neon at EOF is
- * assumed to be a mistake.
- */
- fclose(f);
- return 0;
- }
-
- switch (state)
- {
- case StartLine:
- /* Match spaces at the start of line */
- if (ch <= 32) /* skip control characters and space */
- break;
-
- counter=0;
- state = Feature;
- /* FALLTHROUGH */
-
- case Feature:
- /* Match 'FEATURE', ASCII case insensitive. */
- if ((ch & ~0x20) == ch_feature[counter])
- {
- if (++counter == (sizeof ch_feature))
- state = Colon;
- break;
- }
-
- /* did not match 'feature' */
- state = SkipLine;
- /* FALLTHROUGH */
-
- case SkipLine:
- skipLine:
- /* Skip everything until we see linefeed or carriage return */
- if (ch != 10 && ch != 13)
- break;
-
- state = StartLine;
- break;
-
- case Colon:
- /* Match any number of space or tab followed by ':' */
- if (ch == 32 || ch == 9)
- break;
-
- if (ch == 58) /* i.e. ':' */
- {
- state = StartTag;
- break;
- }
-
- /* Either a bad line format or a 'feature' prefix followed by
- * other characters.
- */
- state = SkipLine;
- goto skipLine;
-
- case StartTag:
- /* Skip space characters before a tag */
- if (ch == 32 || ch == 9)
- break;
-
- state = Neon;
- counter = 0;
- /* FALLTHROUGH */
-
- case Neon:
- /* Look for 'neon' tag */
- if ((ch & ~0x20) == ch_neon[counter])
- {
- if (++counter == (sizeof ch_neon))
- state = HaveNeon;
- break;
- }
-
- state = SkipTag;
- /* FALLTHROUGH */
-
- case SkipTag:
- /* Skip non-space characters */
- if (ch == 10 || ch == 13)
- state = StartLine;
-
- else if (ch == 32 || ch == 9)
- state = StartTag;
- break;
-
- case HaveNeon:
- /* Have seen a 'neon' prefix, but there must be a space or new
- * line character to terminate it.
- */
- if (ch == 10 || ch == 13 || ch == 32 || ch == 9)
- {
- fclose(f);
- return 1;
- }
-
- state = SkipTag;
- break;
-
- default:
- png_error(png_ptr, "png_have_neon: internal error (bug)");
- }
- }
- }
-
-#ifdef PNG_WARNINGS_SUPPORTED
- else
- png_warning(png_ptr, "/proc/cpuinfo open failed");
-#endif
-
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/conftest/README b/Build/source/libs/libpng/libpng-src/contrib/conftest/README
deleted file mode 100644
index 0f472791f27..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/conftest/README
+++ /dev/null
@@ -1,49 +0,0 @@
-This directory contains test configuration files, currently always '.dfa' files
-intended to be used in the build by setting the make macro DFA_XTRA to the name
-of the file.
-
-These files are used in release validation of the 'configure' builds of libpng
-by building 'make check', or 'make all-am' for cross-builds, with each .dfa
-file.
-
-The files in this directory may change between minor releases, however
-contributions describing specific builds of libpng are welcomed. There is no
-guarantee that libpng will continue to build with such configurations; support
-for given configurations can be, and has been, dropped between successive minor
-releases. However if a .dfa file describing a configuration is not in this
-directory it is very unlikely that it will be tested before a minor release!
-
-You can use these .dfa files as the basis of new configurations. Files in this
-directory should not have any use restrictions or restrictive licenses.
-
-This directory is not included in the .zip and .7z distributions, which do
-not contain 'configure' scripts.
-
-DOCUMENTATION
-=============
-
-Examples:
- ${srcdir}/pngusr.dfa
- ${srcdir}/contrib/pngminim/*/pngusr.dfa
-
-Documentation of the options:
- ${srcdir}/scripts/pnglibconf.dfa
-
-Documentation of the file format:
- ${srcdir}/scripts/options.awk
-
-FILE NAMING
-===========
-
-File names in this directory may NOT contain any of the five characters:
-
- - , + * ?
-
-Neither may they contain any space character.
-
-While other characters may be used it is strongly suggested that file names be
-limited to lower case Latiin alphabetic characters (a-z), digits (0-9) and, if
-necessary the underscore (_) character. File names should be about 8 characters
-long (excluding the .dfa extension). Submitted .dfa files should have names
-between 7 and 16 characters long, shorter names (6 characters or less) are
-reserved for standard tests.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/conftest/pngcp.dfa b/Build/source/libs/libpng/libpng-src/contrib/conftest/pngcp.dfa
deleted file mode 100644
index 31c411d5f82..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/conftest/pngcp.dfa
+++ /dev/null
@@ -1,57 +0,0 @@
-# pngcp.dfa
-# Build time configuration of libpng
-#
-# Author: John Bowler
-# Copyright: (c) John Bowler, 2016
-# Usage rights:
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Build libpng with support for pngcp. This means just png_read_png,
-# png_write_png and small number of configuration settings.
-#
-everything = off
-
-# This option is specific to this configuration; it adds a #define to the
-# generated pnglibconf.h which turns on the (not portable) timing option for
-# pngcp. Note that any option is automatically preceded by PNG_; there is no
-# way round this and this is deliberate.
-option PNGCP_TIMING
-
-# Because of the everything off above the option must also be turned on. This
-# may not be done in one step because it is safer and avoids mis-spelled options
-# in user .dfa files to error out if an unrecognized option is turned on.
-option PNGCP_TIMING on
-
-# Options to turn on png_read_png and png_write_png:
-option INFO_IMAGE on
-option SEQUENTIAL_READ on
-option EASY_ACCESS on
-option WRITE on
-option WRITE_16BIT on
-option WRITE_FILTER on
-
-# pngcp needs this to preserve unknown chunks, switching all these on means that
-# pngcp can work without explicit known chunk reading support
-option UNKNOWN_CHUNKS on
-option SET_UNKNOWN_CHUNKS on
-option HANDLE_AS_UNKNOWN on
-option SAVE_UNKNOWN_CHUNKS on
-option WRITE_UNKNOWN_CHUNKS on
-
-# pngcp needs this to handle palette files with invalid indices:
-option CHECK_FOR_INVALID_INDEX on
-option GET_PALETTE_MAX on
-
-# Pre-libpng 1.7 pngcp has to stash text chunks manually, post 1.7 without this
-# text chunks should be handled as unknown ok.
-option TEXT on
-
-# this is used to turn off limits:
-option USER_LIMITS on
-option SET_USER_LIMITS on
-
-# these are just required for specific customizations
-option WRITE_CUSTOMIZE_ZTXT_COMPRESSION on
-option WRITE_CUSTOMIZE_COMPRESSION on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/conftest/read.dfa b/Build/source/libs/libpng/libpng-src/contrib/conftest/read.dfa
deleted file mode 100644
index 21e88d01a21..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/conftest/read.dfa
+++ /dev/null
@@ -1,58 +0,0 @@
-# read.dfa
-# Build time configuration of libpng
-#
-# Author: John Bowler
-# Copyright: (c) John Bowler, 2013
-# Usage rights:
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Build libpng with basic read support. This enables the lowest level libpng
-# read API - the one where the calling code has to use a loop to read each row.
-# At present this is the API used by most programs.
-#
-# Support is enabled only for those chunks and transformations that are
-# typically required - others can be added easily.
-#
-
-everything = off
-
-# The sequential read code is enabled here; the progressive code can be used
-# instead but there is no point enabling both.
-
-option SEQUENTIAL_READ on
-
-# Likewise it is pointless enabling both fixed and floating point APIs. Choose
-# one or the other for both the API and the internal math.
-
-#Fixed point:
-#option FIXED_POINT on
-#option FLOATING_ARITHMETIC off
-
-#Floating point:
-option FLOATING_POINT on
-option FLOATING_ARITHMETIC on
-
-# Basic error handling, IO and user memory support. The latter allows the
-# application program to provide its own implementations of 'malloc' and 'free'.
-option SETJMP on
-option STDIO on
-option USER_MEM on
-
-# To read the full set of PNG images correctly interlace, transparency and
-# 16-bit support is required. The application can implement interlace itself,
-# but very few do and it's no longer possible to disable it when READ is
-# enabled.
-option READ_tRNS on
-option READ_16BIT on
-
-# Everything else is application dependent. This file assumes the app handles
-# all the native PNG bit layouts, so it doesn't need any of layout change
-# transforms, but needs libpng to perform gamma correction. It doesn't do any
-# colorspace stuff and ignores the 'significant bit' information.
-#
-# If your app always expands the image to a limited set of bit layouts you
-# probably want to consider using the simplified API instead of the low level
-# one - see png.h and s_read.dfa.
-option READ_GAMMA on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/conftest/s_read.dfa b/Build/source/libs/libpng/libpng-src/contrib/conftest/s_read.dfa
deleted file mode 100644
index cb1ce0ba65f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/conftest/s_read.dfa
+++ /dev/null
@@ -1,35 +0,0 @@
-# s_read.dfa
-# Build time configuration of libpng
-#
-# Author: John Bowler
-# Copyright: (c) John Bowler, 2013
-# Usage rights:
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Build libpng with simplified read support (only). This builds a minimal
-# libpng able to read all PNG formats and convert them into a small number of
-# well understood memory formats.
-#
-
-everything = off
-
-option SIMPLIFIED_READ on
-
-# It isn't necessary to chose fixed or floating point for the APIs because the
-# simplified API doesn't need fixed or floating point numbers. It is necessary
-# to chose an internal math implementation. The default (because of 'everything
-# = off') is fixed point - turn the floating point implementation on if you have
-# hardware floating point or prefer your software floating point implementation.
-option FLOATING_ARITHMETIC on
-
-# This is not strictly necessary, but without it the message strings in the API
-# will not be filled in
-option ERROR_TEXT on
-
-# Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't
-# need this if you don't use them, they just allow the in-memory layout to be
-# changed to match common hardware formats.
-option SIMPLIFIED_READ_AFIRST on
-option SIMPLIFIED_READ_BGR on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/conftest/s_write.dfa b/Build/source/libs/libpng/libpng-src/contrib/conftest/s_write.dfa
deleted file mode 100644
index e540a46dc8b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/conftest/s_write.dfa
+++ /dev/null
@@ -1,33 +0,0 @@
-# s_write.dfa
-# Build time configuration of libpng
-#
-# Author: John Bowler
-# Copyright: (c) John Bowler, 2013
-# Usage rights:
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Build libpng with (just) simplified write support
-#
-
-everything = off
-
-option SIMPLIFIED_WRITE on
-
-# It isn't necessary to chose fixed or floating point for the APIs because the
-# simplified API doesn't need fixed or floating point numbers. It is necessary
-# to chose an internal math implementation. The default (because of 'everything
-# = off') is fixed point - turn the floating point implementation on if you have
-# hardware floating point or prefer your software floating point implementation.
-option FLOATING_ARITHMETIC on
-
-# This is not strictly necessary, but without it the message strings in the API
-# will not be filled in
-option ERROR_TEXT on
-
-# Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't
-# need this if you don't use them, they just allow the in-memory layout to be
-# changed to match common hardware formats.
-option SIMPLIFIED_WRITE_AFIRST on
-option SIMPLIFIED_WRITE_BGR on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/conftest/simple.dfa b/Build/source/libs/libpng/libpng-src/contrib/conftest/simple.dfa
deleted file mode 100644
index 04193334452..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/conftest/simple.dfa
+++ /dev/null
@@ -1,36 +0,0 @@
-# simple.dfa
-# Build time configuration of libpng
-#
-# Author: John Bowler
-# Copyright: (c) John Bowler, 2013
-# Usage rights:
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Build libpng with just the simplified APIs (read and write).
-#
-
-everything = off
-
-option SIMPLIFIED_WRITE on
-option SIMPLIFIED_READ on
-
-# It isn't necessary to chose fixed or floating point for the APIs because the
-# simplified API doesn't need fixed or floating point numbers. It is necessary
-# to chose an internal math implementation. The default (because of 'everything
-# = off') is fixed point - turn the floating point implementation on if you have
-# hardware floating point or prefer your software floating point implementation.
-option FLOATING_ARITHMETIC on
-
-# This is not strictly necessary, but without it the message strings in the API
-# will not be filled in
-option ERROR_TEXT on
-
-# Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't
-# need this if you don't use them, they just allow the in-memory layout to be
-# changed to match common hardware formats.
-option SIMPLIFIED_READ_AFIRST on
-option SIMPLIFIED_READ_BGR on
-option SIMPLIFIED_WRITE_AFIRST on
-option SIMPLIFIED_WRITE_BGR on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/conftest/write.dfa b/Build/source/libs/libpng/libpng-src/contrib/conftest/write.dfa
deleted file mode 100644
index 3319aabeeb3..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/conftest/write.dfa
+++ /dev/null
@@ -1,45 +0,0 @@
-# write.dfa
-# Build time configuration of libpng
-#
-# Author: John Bowler
-# Copyright: (c) John Bowler, 2013
-# Usage rights:
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Build libpng with no read support and minimal write support.
-#
-
-everything = off
-
-# Switch on the write code - this makes a minimalist encoder
-
-option WRITE on
-
-# Choose fixed or floating point APIs and arithmetic. The choices are
-# independent but normally they will match. It is typically better to use the
-# floating point if you have floating point hardware. If you don't know, or
-# (perhaps) to make libpng smaller used fixed point throughout.
-
-#Fixed point:
-#option FIXED_POINT on
-#option FLOATING_ARITHMETIC off
-
-#Floating point:
-option FLOATING_POINT on
-option FLOATING_ARITHMETIC on
-
-# Basic error handling, IO and user memory support. The latter allows the
-# application program to provide its own implementations of 'malloc' and 'free'.
-option SETJMP on
-option STDIO on
-option USER_MEM on
-
-# Everything else is optional. Unlike the read code in libpng the write code
-# does not need to deal with arbitrary formats, so only add support for things
-# you really do write! For example you might only write sRGB images, sometimes
-# with transparency and never write 16 bit images, so:
-option WRITE_sRGB on
-option WRITE_tRNS on
-#option WRITE_16BIT off (this is the default with 'everything = off')
diff --git a/Build/source/libs/libpng/libpng-src/contrib/examples/README.txt b/Build/source/libs/libpng/libpng-src/contrib/examples/README.txt
deleted file mode 100644
index 48dab4f0fda..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/examples/README.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-This directory (contrib/examples) contains examples of libpng usage.
-
-NO COPYRIGHT RIGHTS ARE CLAIMED TO ANY OF THE FILES IN THIS DIRECTORY.
-
-To the extent possible under law, the authors have waived all copyright and
-related or neighboring rights to this work. This work is published from:
-United States.
-
-The files may be used freely in any way. The intention is that appropriate
-parts of the files be used in other libpng-using programs without any need for
-the authors of the using code to seek copyright or license from the original
-authors.
-
-The source code and comments in this directory are the original work of the
-people named below. No other person or organization has made contributions to
-the work in this directory.
-
-ORIGINAL AUTHORS
- The following people have contributed to the code in this directory. None
- of the people below claim any rights with regard to the contents of this
- directory.
-
- John Bowler <jbowler at acm.org>
diff --git a/Build/source/libs/libpng/libpng-src/contrib/examples/iccfrompng.c b/Build/source/libs/libpng/libpng-src/contrib/examples/iccfrompng.c
deleted file mode 100644
index 00056abfd71..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/examples/iccfrompng.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*- iccfrompng
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2011.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Extract any icc profiles found in the given PNG files. This is a simple
- * example of a program that extracts information from the header of a PNG file
- * without processing the image. Notice that some header information may occur
- * after the image data. Textual data and comments are an example; the approach
- * in this file won't work reliably for such data because it only looks for the
- * information in the section of the file that precedes the image data.
- *
- * Compile and link against libpng and zlib, plus anything else required on the
- * system you use.
- *
- * To use supply a list of PNG files containing iCCP chunks, the chunks will be
- * extracted to a similarly named file with the extension replaced by 'icc',
- * which will be overwritten without warning.
- */
-#include <stdlib.h>
-#include <setjmp.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <png.h>
-
-#if defined(PNG_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) && \
- defined (PNG_iCCP_SUPPORTED)
-
-
-static int verbose = 1;
-static png_byte no_profile[] = "no profile";
-
-static png_bytep
-extract(FILE *fp, png_uint_32 *proflen)
-{
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
- png_infop info_ptr = NULL;
- png_bytep result = NULL;
-
- /* Initialize for error or no profile: */
- *proflen = 0;
-
- if (png_ptr == NULL)
- {
- fprintf(stderr, "iccfrompng: version library mismatch?\n");
- return 0;
- }
-
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return 0;
- }
-
- png_init_io(png_ptr, fp);
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- png_error(png_ptr, "OOM allocating info structure");
-
- png_read_info(png_ptr, info_ptr);
-
- {
- png_charp name;
- int compression_type;
- png_bytep profile;
-
- if (png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile,
- proflen) & PNG_INFO_iCCP)
- {
- result = malloc(*proflen);
- if (result != NULL)
- memcpy(result, profile, *proflen);
-
- else
- png_error(png_ptr, "OOM allocating profile buffer");
- }
-
- else
- result = no_profile;
- }
-
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return result;
-}
-
-static int
-extract_one_file(const char *filename)
-{
- int result = 0;
- FILE *fp = fopen(filename, "rb");
-
- if (fp != NULL)
- {
- png_uint_32 proflen = 0;
- png_bytep profile = extract(fp, &proflen);
-
- if (profile != NULL && profile != no_profile)
- {
- size_t len;
- char *output;
-
- {
- const char *ep = strrchr(filename, '.');
-
- if (ep != NULL)
- len = ep-filename;
-
- else
- len = strlen(filename);
- }
-
- output = malloc(len + 5);
- if (output != NULL)
- {
- FILE *of;
-
- memcpy(output, filename, len);
- strcpy(output+len, ".icc");
-
- of = fopen(output, "wb");
- if (of != NULL)
- {
- if (fwrite(profile, proflen, 1, of) == 1 &&
- fflush(of) == 0 &&
- fclose(of) == 0)
- {
- if (verbose)
- printf("%s -> %s\n", filename, output);
- /* Success return */
- result = 1;
- }
-
- else
- {
- fprintf(stderr, "%s: error writing profile\n", output);
- if (remove(output))
- fprintf(stderr, "%s: could not remove file\n", output);
- }
- }
-
- else
- fprintf(stderr, "%s: failed to open output file\n", output);
-
- free(output);
- }
-
- else
- fprintf(stderr, "%s: OOM allocating string!\n", filename);
-
- free(profile);
- }
-
- else if (verbose && profile == no_profile)
- printf("%s has no profile\n", filename);
- }
-
- else
- fprintf(stderr, "%s: could not open file\n", filename);
-
- return result;
-}
-
-int
-main(int argc, char **argv)
-{
- int i;
- int extracted = 0;
-
- for (i=1; i<argc; ++i)
- {
- if (strcmp(argv[i], "-q") == 0)
- verbose = 0;
-
- else if (extract_one_file(argv[i]))
- extracted = 1;
- }
-
- /* Exit code is true if any extract succeeds */
- return extracted == 0;
-}
-#endif /* READ && STDIO && iCCP */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/examples/pngpixel.c b/Build/source/libs/libpng/libpng-src/contrib/examples/pngpixel.c
deleted file mode 100644
index 9185d518fba..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/examples/pngpixel.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*- pngpixel
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2011.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Read a single pixel value from a PNG file.
- *
- * This code illustrates basic 'by-row' reading of a PNG file using libpng.
- * Rows are read until a particular pixel is found; the value of this pixel is
- * then printed on stdout.
- *
- * The code illustrates how to do this on interlaced as well as non-interlaced
- * images. Normally you would call png_set_interlace_handling() to have libpng
- * deal with the interlace for you, but that obliges you to buffer half of the
- * image to assemble the interlaced rows. In this code
- * png_set_interlace_handling() is not called and, instead, the code handles the
- * interlace passes directly looking for the required pixel.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <setjmp.h> /* required for error handling */
-
-/* Normally use <png.h> here to get the installed libpng, but this is done to
- * ensure the code picks up the local libpng implementation:
- */
-#include "../../png.h"
-
-#if defined(PNG_READ_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)
-
-/* Return component 'c' of pixel 'x' from the given row. */
-static unsigned int
-component(png_const_bytep row, png_uint_32 x, unsigned int c,
- unsigned int bit_depth, unsigned int channels)
-{
- /* PNG images can be up to 2^31 pixels wide, but this means they can be up to
- * 2^37 bits wide (for a 64-bit pixel - the largest possible) and hence 2^34
- * bytes wide. Since the row fitted into memory, however, the following must
- * work:
- */
- png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels);
- png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c);
-
- row = (png_const_bytep)(((const png_byte (*)[8])row) + bit_offset_hi);
- row += bit_offset_lo >> 3;
- bit_offset_lo &= 0x07;
-
- /* PNG pixels are packed into bytes to put the first pixel in the highest
- * bits of the byte and into two bytes for 16-bit values with the high 8 bits
- * first, so:
- */
- switch (bit_depth)
- {
- case 1: return (row[0] >> (7-bit_offset_lo)) & 0x01;
- case 2: return (row[0] >> (6-bit_offset_lo)) & 0x03;
- case 4: return (row[0] >> (4-bit_offset_lo)) & 0x0f;
- case 8: return row[0];
- case 16: return (row[0] << 8) + row[1];
- default:
- /* This should never happen; it indicates a bug in this program or in
- * libpng itself:
- */
- fprintf(stderr, "pngpixel: invalid bit depth %u\n", bit_depth);
- exit(1);
- }
-}
-
-/* Print a pixel from a row returned by libpng; determine the row format, find
- * the pixel, and print the relevant information to stdout.
- */
-static void
-print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
- png_uint_32 x)
-{
- unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
-
- switch (png_get_color_type(png_ptr, info_ptr))
- {
- case PNG_COLOR_TYPE_GRAY:
- printf("GRAY %u\n", component(row, x, 0, bit_depth, 1));
- return;
-
- /* The palette case is slightly more difficult - the palette and, if
- * present, the tRNS ('transparency', though the values are really
- * opacity) data must be read to give the full picture:
- */
- case PNG_COLOR_TYPE_PALETTE:
- {
- int index = component(row, x, 0, bit_depth, 1);
- png_colorp palette = NULL;
- int num_palette = 0;
-
- if ((png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) &
- PNG_INFO_PLTE) && num_palette > 0 && palette != NULL)
- {
- png_bytep trans_alpha = NULL;
- int num_trans = 0;
- if ((png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans,
- NULL) & PNG_INFO_tRNS) && num_trans > 0 &&
- trans_alpha != NULL)
- printf("INDEXED %u = %d %d %d %d\n", index,
- palette[index].red, palette[index].green,
- palette[index].blue,
- index < num_trans ? trans_alpha[index] : 255);
-
- else /* no transparency */
- printf("INDEXED %u = %d %d %d\n", index,
- palette[index].red, palette[index].green,
- palette[index].blue);
- }
-
- else
- printf("INDEXED %u = invalid index\n", index);
- }
- return;
-
- case PNG_COLOR_TYPE_RGB:
- printf("RGB %u %u %u\n", component(row, x, 0, bit_depth, 3),
- component(row, x, 1, bit_depth, 3),
- component(row, x, 2, bit_depth, 3));
- return;
-
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- printf("GRAY+ALPHA %u %u\n", component(row, x, 0, bit_depth, 2),
- component(row, x, 1, bit_depth, 2));
- return;
-
- case PNG_COLOR_TYPE_RGB_ALPHA:
- printf("RGBA %u %u %u %u\n", component(row, x, 0, bit_depth, 4),
- component(row, x, 1, bit_depth, 4),
- component(row, x, 2, bit_depth, 4),
- component(row, x, 3, bit_depth, 4));
- return;
-
- default:
- png_error(png_ptr, "pngpixel: invalid color type");
- }
-}
-
-int main(int argc, const char **argv)
-{
- /* This program uses the default, <setjmp.h> based, libpng error handling
- * mechanism, therefore any local variable that exists before the call to
- * setjmp and is changed after the call to setjmp returns successfully must
- * be declared with 'volatile' to ensure that their values don't get
- * destroyed by longjmp:
- */
- volatile int result = 1/*fail*/;
-
- if (argc == 4)
- {
- long x = atol(argv[1]);
- long y = atol(argv[2]);
- FILE *f = fopen(argv[3], "rb");
- volatile png_bytep row = NULL;
-
- if (f != NULL)
- {
- /* libpng requires a callback function for handling errors; this
- * callback must not return. The default callback function uses a
- * stored <setjmp.h> style jmp_buf which is held in a png_struct and
- * writes error messages to stderr. Creating the png_struct is a
- * little tricky; just copy the following code.
- */
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
-
- if (png_ptr != NULL)
- {
- png_infop info_ptr = png_create_info_struct(png_ptr);
-
- if (info_ptr != NULL)
- {
- /* Declare stack variables to hold pointers to locally allocated
- * data.
- */
-
- /* Initialize the error control buffer: */
- if (setjmp(png_jmpbuf(png_ptr)) == 0)
- {
- png_uint_32 width, height;
- int bit_depth, color_type, interlace_method,
- compression_method, filter_method;
- png_bytep row_tmp;
-
- /* Now associate the recently opened (FILE*) with the default
- * libpng initialization functions. Sometimes libpng is
- * compiled without stdio support (it can be difficult to do
- * in some environments); in that case you will have to write
- * your own read callback to read data from the (FILE*).
- */
- png_init_io(png_ptr, f);
-
- /* And read the first part of the PNG file - the header and
- * all the information up to the first pixel.
- */
- png_read_info(png_ptr, info_ptr);
-
- /* This fills in enough information to tell us the width of
- * each row in bytes, allocate the appropriate amount of
- * space. In this case png_malloc is used - it will not
- * return if memory isn't available.
- */
- row = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
- info_ptr));
-
- /* To avoid the overhead of using a volatile auto copy row_tmp
- * to a local here - just use row for the png_free below.
- */
- row_tmp = row;
-
- /* All the information we need is in the header is returned by
- * png_get_IHDR, if this fails we can now use 'png_error' to
- * signal the error and return control to the setjmp above.
- */
- if (png_get_IHDR(png_ptr, info_ptr, &width, &height,
- &bit_depth, &color_type, &interlace_method,
- &compression_method, &filter_method))
- {
- int passes, pass;
-
- /* png_set_interlace_handling returns the number of
- * passes required as well as turning on libpng's
- * handling, but since we do it ourselves this is
- * necessary:
- */
- switch (interlace_method)
- {
- case PNG_INTERLACE_NONE:
- passes = 1;
- break;
-
- case PNG_INTERLACE_ADAM7:
- passes = PNG_INTERLACE_ADAM7_PASSES;
- break;
-
- default:
- png_error(png_ptr, "pngpixel: unknown interlace");
- }
-
- /* Now read the pixels, pass-by-pass, row-by-row: */
- png_start_read_image(png_ptr);
-
- for (pass=0; pass<passes; ++pass)
- {
- png_uint_32 ystart, xstart, ystep, xstep;
- png_uint_32 py;
-
- if (interlace_method == PNG_INTERLACE_ADAM7)
- {
- /* Sometimes the whole pass is empty because the
- * image is too narrow or too short. libpng
- * expects to be called for each row that is
- * present in the pass, so it may be necessary to
- * skip the loop below (over py) if the image is
- * too narrow.
- */
- if (PNG_PASS_COLS(width, pass) == 0)
- continue;
-
- /* We need the starting pixel and the offset
- * between each pixel in this pass; use the macros
- * in png.h:
- */
- xstart = PNG_PASS_START_COL(pass);
- ystart = PNG_PASS_START_ROW(pass);
- xstep = PNG_PASS_COL_OFFSET(pass);
- ystep = PNG_PASS_ROW_OFFSET(pass);
- }
-
- else
- {
- ystart = xstart = 0;
- ystep = xstep = 1;
- }
-
- /* To find the pixel, loop over 'py' for each pass
- * reading a row and then checking to see if it
- * contains the pixel.
- */
- for (py = ystart; py < height; py += ystep)
- {
- png_uint_32 px, ppx;
-
- /* png_read_row takes two pointers. When libpng
- * handles the interlace the first is filled in
- * pixel-by-pixel, and the second receives the same
- * pixels but they are replicated across the
- * unwritten pixels so far for each pass. When we
- * do the interlace, however, they just contain
- * the pixels from the interlace pass - giving
- * both is wasteful and pointless, so we pass a
- * NULL pointer.
- */
- png_read_row(png_ptr, row_tmp, NULL);
-
- /* Now find the pixel if it is in this row; there
- * are, of course, much better ways of doing this
- * than using a for loop:
- */
- if (y == py) for (px = xstart, ppx = 0;
- px < width; px += xstep, ++ppx) if (x == px)
- {
- /* 'ppx' is the index of the pixel in the row
- * buffer.
- */
- print_pixel(png_ptr, info_ptr, row_tmp, ppx);
-
- /* Now terminate the loops early - we have
- * found and handled the required data.
- */
- goto pass_loop_end;
- } /* x loop */
- } /* y loop */
- } /* pass loop */
-
- /* Finally free the temporary buffer: */
- pass_loop_end:
- row = NULL;
- png_free(png_ptr, row_tmp);
- }
-
- else
- png_error(png_ptr, "pngpixel: png_get_IHDR failed");
-
- }
-
- else
- {
- /* Else libpng has raised an error. An error message has
- * already been output, so it is only necessary to clean up
- * locally allocated data:
- */
- if (row != NULL)
- {
- /* The default implementation of png_free never errors out
- * (it just crashes if something goes wrong), but the safe
- * way of using it is still to clear 'row' before calling
- * png_free:
- */
- png_bytep row_tmp = row;
- row = NULL;
- png_free(png_ptr, row_tmp);
- }
- }
-
- png_destroy_info_struct(png_ptr, &info_ptr);
- }
-
- else
- fprintf(stderr, "pngpixel: out of memory allocating png_info\n");
-
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- }
-
- else
- fprintf(stderr, "pngpixel: out of memory allocating png_struct\n");
- }
-
- else
- fprintf(stderr, "pngpixel: %s: could not open file\n", argv[3]);
- }
-
- else
- /* Wrong number of arguments */
- fprintf(stderr, "pngpixel: usage: pngpixel x y png-file\n");
-
- return result;
-}
-#endif /* READ && SEQUENTIAL_READ */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/examples/pngtopng.c b/Build/source/libs/libpng/libpng-src/contrib/examples/pngtopng.c
deleted file mode 100644
index 904b972382f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/examples/pngtopng.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*- pngtopng
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2011, 2017.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Last changed in libpng 1.6.29 [March 16, 2017]
- *
- * Read a PNG and write it out in a fixed format, using the 'simplified API'
- * that was introduced in libpng-1.6.0.
- *
- * This sample code is just the code from the top of 'example.c' with some error
- * handling added. See example.c for more comments.
- */
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-/* Normally use <png.h> here to get the installed libpng, but this is done to
- * ensure the code picks up the local libpng implementation:
- */
-#include "../../png.h"
-#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && \
- defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
-
-int main(int argc, const char **argv)
-{
- int result = 1;
-
- if (argc == 3)
- {
- png_image image;
-
- /* Only the image structure version number needs to be set. */
- memset(&image, 0, sizeof image);
- image.version = PNG_IMAGE_VERSION;
-
- if (png_image_begin_read_from_file(&image, argv[1]))
- {
- png_bytep buffer;
-
- /* Change this to try different formats! If you set a colormap format
- * then you must also supply a colormap below.
- */
- image.format = PNG_FORMAT_RGBA;
-
- buffer = malloc(PNG_IMAGE_SIZE(image));
-
- if (buffer != NULL)
- {
- if (png_image_finish_read(&image, NULL/*background*/, buffer,
- 0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */))
- {
- if (png_image_write_to_file(&image, argv[2],
- 0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
- NULL/*colormap*/))
- result = 0;
-
- else
- fprintf(stderr, "pngtopng: write %s: %s\n", argv[2],
- image.message);
- }
-
- else
- fprintf(stderr, "pngtopng: read %s: %s\n", argv[1],
- image.message);
-
- free(buffer);
- }
-
- else
- {
- fprintf(stderr, "pngtopng: out of memory: %lu bytes\n",
- (unsigned long)PNG_IMAGE_SIZE(image));
-
- /* This is the only place where a 'free' is required; libpng does
- * the cleanup on error and success, but in this case we couldn't
- * complete the read because of running out of memory and so libpng
- * has not got to the point where it can do cleanup.
- */
- png_image_free(&image);
- }
- }
-
- else
- /* Failed to read the first argument: */
- fprintf(stderr, "pngtopng: %s: %s\n", argv[1], image.message);
- }
-
- else
- /* Wrong number of arguments */
- fprintf(stderr, "pngtopng: usage: pngtopng input-file output-file\n");
-
- return result;
-}
-#endif /* READ && WRITE */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/examples/simpleover.c b/Build/source/libs/libpng/libpng-src/contrib/examples/simpleover.c
deleted file mode 100644
index 59dd313688c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/examples/simpleover.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*- simpleover
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2015.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Read several PNG files, which should have an alpha channel or transparency
- * information, and composite them together to produce one or more 16-bit linear
- * RGBA intermediates. This involves doing the correct 'over' composition to
- * combine the alpha channels and corresponding data.
- *
- * Finally read an output (background) PNG using the 24-bit RGB format (the
- * PNG will be composited on green (#00ff00) by default if it has an alpha
- * channel), and apply the intermediate image generated above to specified
- * locations in the image.
- *
- * The command line has the general format:
- *
- * simpleover <background.png> [output.png]
- * {--sprite=width,height,name {[--at=x,y] {sprite.png}}}
- * {--add=name {x,y}}
- *
- * The --sprite and --add options may occur multiple times. They are executed
- * in order. --add may refer to any sprite already read.
- *
- * This code is intended to show how to composite multiple images together
- * correctly. Apart from the libpng Simplified API the only work done in here
- * is to combine multiple input PNG images into a single sprite; this involves
- * a Porter-Duff 'over' operation and the input PNG images may, as a result,
- * be regarded as being layered one on top of the other with the first (leftmost
- * on the command line) being at the bottom and the last on the top.
- */
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-/* Normally use <png.h> here to get the installed libpng, but this is done to
- * ensure the code picks up the local libpng implementation, so long as this
- * file is linked against a sufficiently recent libpng (1.6+) it is ok to
- * change this to <png.h>:
- */
-#include "../../png.h"
-
-#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
-
-#define sprite_name_chars 15
-struct sprite {
- FILE *file;
- png_uint_16p buffer;
- unsigned int width;
- unsigned int height;
- char name[sprite_name_chars+1];
-};
-
-#if 0 /* div by 65535 test program */
-#include <math.h>
-#include <stdio.h>
-
-int main(void) {
- double err = 0;
- unsigned int xerr = 0;
- unsigned int r = 32769;
- {
- unsigned int x = 0;
-
- do {
- unsigned int t = x + (x >> 16) /*+ (x >> 31)*/ + r;
- double v = x, errtest;
-
- if (t < x) {
- fprintf(stderr, "overflow: %u+%u -> %u\n", x, r, t);
- return 1;
- }
-
- v /= 65535;
- errtest = v;
- t >>= 16;
- errtest -= t;
-
- if (errtest > err) {
- err = errtest;
- xerr = x;
-
- if (errtest >= .5) {
- fprintf(stderr, "error: %u/65535 = %f, not %u, error %f\n",
- x, v, t, errtest);
- return 0;
- }
- }
- } while (++x <= 65535U*65535U);
- }
-
- printf("error %f @ %u\n", err, xerr);
-
- return 0;
-}
-#endif /* div by 65535 test program */
-
-static void
-sprite_op(const struct sprite *sprite, int x_offset, int y_offset,
- png_imagep image, const png_uint_16 *buffer)
-{
- /* This is where the Porter-Duff 'Over' operator is evaluated; change this
- * code to change the operator (this could be parameterized). Any other
- * image processing operation could be used here.
- */
-
-
- /* Check for an x or y offset that pushes any part of the image beyond the
- * right or bottom of the sprite:
- */
- if ((y_offset < 0 || (unsigned)/*SAFE*/y_offset < sprite->height) &&
- (x_offset < 0 || (unsigned)/*SAFE*/x_offset < sprite->width))
- {
- unsigned int y = 0;
-
- if (y_offset < 0)
- y = -y_offset; /* Skip to first visible row */
-
- do
- {
- unsigned int x = 0;
-
- if (x_offset < 0)
- x = -x_offset;
-
- do
- {
- /* In and out are RGBA values, so: */
- const png_uint_16 *in_pixel = buffer + (y * image->width + x)*4;
- png_uint_32 in_alpha = in_pixel[3];
-
- /* This is the optimized Porter-Duff 'Over' operation, when the
- * input alpha is 0 the output is not changed.
- */
- if (in_alpha > 0)
- {
- png_uint_16 *out_pixel = sprite->buffer +
- ((y+y_offset) * sprite->width + (x+x_offset))*4;
-
- /* This is the weight to apply to the output: */
- in_alpha = 65535-in_alpha;
-
- if (in_alpha > 0)
- {
- /* The input must be composed onto the output. This means
- * multiplying the current output pixel value by the inverse
- * of the input alpha (1-alpha). A division is required but
- * it is by the constant 65535. Approximate this as:
- *
- * (x + (x >> 16) + 32769) >> 16;
- *
- * This is exact (and does not overflow) for all values of
- * x in the range 0..65535*65535. (Note that the calculation
- * produces the closest integer; the maximum error is <0.5).
- */
- png_uint_32 tmp;
-
-# define compose(c)\
- tmp = out_pixel[c] * in_alpha;\
- tmp = (tmp + (tmp >> 16) + 32769) >> 16;\
- out_pixel[c] = tmp + in_pixel[c]
-
- /* The following is very vectorizable... */
- compose(0);
- compose(1);
- compose(2);
- compose(3);
- }
-
- else
- out_pixel[0] = in_pixel[0],
- out_pixel[1] = in_pixel[1],
- out_pixel[2] = in_pixel[2],
- out_pixel[3] = in_pixel[3];
- }
- }
- while (++x < image->width);
- }
- while (++y < image->height);
- }
-}
-
-static int
-create_sprite(struct sprite *sprite, int *argc, const char ***argv)
-{
- /* Read the arguments and create this sprite. The sprite buffer has already
- * been allocated. This reads the input PNGs one by one in linear format,
- * composes them onto the sprite buffer (the code in the function above)
- * then saves the result, converting it on the fly to PNG RGBA 8-bit format.
- */
- while (*argc > 0)
- {
- char tombstone;
- int x = 0, y = 0;
-
- if ((*argv)[0][0] == '-' && (*argv)[0][1] == '-')
- {
- /* The only supported option is --at. */
- if (sscanf((*argv)[0], "--at=%d,%d%c", &x, &y, &tombstone) != 2)
- break; /* success; caller will parse this option */
-
- ++*argv, --*argc;
- }
-
- else
- {
- /* The argument has to be a file name */
- png_image image;
-
- image.version = PNG_IMAGE_VERSION;
- image.opaque = NULL;
-
- if (png_image_begin_read_from_file(&image, (*argv)[0]))
- {
- png_uint_16p buffer;
-
- image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
-
- buffer = malloc(PNG_IMAGE_SIZE(image));
-
- if (buffer != NULL)
- {
- if (png_image_finish_read(&image, NULL/*background*/, buffer,
- 0/*row_stride*/,
- NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/))
- {
- /* This is the place where the Porter-Duff 'Over' operator
- * needs to be done by this code. In fact, any image
- * processing required can be done here; the data is in
- * the correct format (linear, 16-bit) and source and
- * destination are in memory.
- */
- sprite_op(sprite, x, y, &image, buffer);
- free(buffer);
- ++*argv, --*argc;
- /* And continue to the next argument */
- continue;
- }
-
- else
- {
- free(buffer);
- fprintf(stderr, "simpleover: read %s: %s\n", (*argv)[0],
- image.message);
- }
- }
-
- else
- {
- fprintf(stderr, "simpleover: out of memory: %lu bytes\n",
- (unsigned long)PNG_IMAGE_SIZE(image));
-
- /* png_image_free must be called if we abort the Simplified API
- * read because of a problem detected in this code. If problems
- * are detected in the Simplified API it cleans up itself.
- */
- png_image_free(&image);
- }
- }
-
- else
- {
- /* Failed to read the first argument: */
- fprintf(stderr, "simpleover: %s: %s\n", (*argv)[0], image.message);
- }
-
- return 0; /* failure */
- }
- }
-
- /* All the sprite operations have completed successfully. Save the RGBA
- * buffer as a PNG using the simplified write API.
- */
- sprite->file = tmpfile();
-
- if (sprite->file != NULL)
- {
- png_image save;
-
- memset(&save, 0, sizeof save);
- save.version = PNG_IMAGE_VERSION;
- save.opaque = NULL;
- save.width = sprite->width;
- save.height = sprite->height;
- save.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
- save.flags = PNG_IMAGE_FLAG_FAST;
- save.colormap_entries = 0;
-
- if (png_image_write_to_stdio(&save, sprite->file, 1/*convert_to_8_bit*/,
- sprite->buffer, 0/*row_stride*/, NULL/*colormap*/))
- {
- /* Success; the buffer is no longer needed: */
- free(sprite->buffer);
- sprite->buffer = NULL;
- return 1; /* ok */
- }
-
- else
- fprintf(stderr, "simpleover: write sprite %s: %s\n", sprite->name,
- save.message);
- }
-
- else
- fprintf(stderr, "simpleover: sprite %s: could not allocate tmpfile: %s\n",
- sprite->name, strerror(errno));
-
- return 0; /* fail */
-}
-
-static int
-add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite,
- int *argc, const char ***argv)
-{
- /* Given a --add argument naming this sprite, perform the operations listed
- * in the following arguments. The arguments are expected to have the form
- * (x,y), which is just an offset at which to add the sprite to the
- * output.
- */
- while (*argc > 0)
- {
- char tombstone;
- int x, y;
-
- if ((*argv)[0][0] == '-' && (*argv)[0][1] == '-')
- return 1; /* success */
-
- if (sscanf((*argv)[0], "%d,%d%c", &x, &y, &tombstone) == 2)
- {
- /* Now add the new image into the sprite data, but only if it
- * will fit.
- */
- if (x < 0 || y < 0 ||
- (unsigned)/*SAFE*/x >= output->width ||
- (unsigned)/*SAFE*/y >= output->height ||
- sprite->width > output->width-x ||
- sprite->height > output->height-y)
- {
- fprintf(stderr, "simpleover: sprite %s @ (%d,%d) outside image\n",
- sprite->name, x, y);
- /* Could just skip this, but for the moment it is an error */
- return 0; /* error */
- }
-
- else
- {
- /* Since we know the sprite fits we can just read it into the
- * output using the simplified API.
- */
- png_image in;
-
- in.version = PNG_IMAGE_VERSION;
- rewind(sprite->file);
-
- if (png_image_begin_read_from_stdio(&in, sprite->file))
- {
- in.format = PNG_FORMAT_RGB; /* force compose */
-
- if (png_image_finish_read(&in, NULL/*background*/,
- out_buf + (y*output->width + x)*3/*RGB*/,
- output->width*3/*row_stride*/,
- NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/))
- {
- ++*argv, --*argc;
- continue;
- }
- }
-
- /* The read failed: */
- fprintf(stderr, "simpleover: add sprite %s: %s\n", sprite->name,
- in.message);
- return 0; /* error */
- }
- }
-
- else
- {
- fprintf(stderr, "simpleover: --add='%s': invalid position %s\n",
- sprite->name, (*argv)[0]);
- return 0; /* error */
- }
- }
-
- return 1; /* ok */
-}
-
-static int
-simpleover_process(png_imagep output, png_bytep out_buf, int argc,
- const char **argv)
-{
- int result = 1; /* success */
-# define csprites 10/*limit*/
-# define str(a) #a
- int nsprites = 0;
- struct sprite sprites[csprites];
-
- while (argc > 0)
- {
- result = 0; /* fail */
-
- if (strncmp(argv[0], "--sprite=", 9) == 0)
- {
- char tombstone;
-
- if (nsprites < csprites)
- {
- int n;
-
- sprites[nsprites].width = sprites[nsprites].height = 0;
- sprites[nsprites].name[0] = 0;
-
- n = sscanf(argv[0], "--sprite=%u,%u,%" str(sprite_name_chars) "s%c",
- &sprites[nsprites].width, &sprites[nsprites].height,
- sprites[nsprites].name, &tombstone);
-
- if ((n == 2 || n == 3) &&
- sprites[nsprites].width > 0 && sprites[nsprites].height > 0)
- {
- size_t buf_size, tmp;
-
- /* Default a name if not given. */
- if (sprites[nsprites].name[0] == 0)
- sprintf(sprites[nsprites].name, "sprite-%d", nsprites+1);
-
- /* Allocate a buffer for the sprite and calculate the buffer
- * size:
- */
- buf_size = sizeof (png_uint_16 [4]);
- buf_size *= sprites[nsprites].width;
- buf_size *= sprites[nsprites].height;
-
- /* This can overflow a (size_t); check for this: */
- tmp = buf_size;
- tmp /= sprites[nsprites].width;
- tmp /= sprites[nsprites].height;
-
- if (tmp == sizeof (png_uint_16 [4]))
- {
- sprites[nsprites].buffer = malloc(buf_size);
- /* This buffer must be initialized to transparent: */
- memset(sprites[nsprites].buffer, 0, buf_size);
-
- if (sprites[nsprites].buffer != NULL)
- {
- sprites[nsprites].file = NULL;
- ++argv, --argc;
-
- if (create_sprite(sprites+nsprites++, &argc, &argv))
- {
- result = 1; /* still ok */
- continue;
- }
-
- break; /* error */
- }
- }
-
- /* Overflow, or OOM */
- fprintf(stderr, "simpleover: %s: sprite too large\n", argv[0]);
- break;
- }
-
- else
- {
- fprintf(stderr, "simpleover: %s: invalid sprite (%u,%u)\n",
- argv[0], sprites[nsprites].width, sprites[nsprites].height);
- break;
- }
- }
-
- else
- {
- fprintf(stderr, "simpleover: %s: too many sprites\n", argv[0]);
- break;
- }
- }
-
- else if (strncmp(argv[0], "--add=", 6) == 0)
- {
- const char *name = argv[0]+6;
- int isprite = nsprites;
-
- ++argv, --argc;
-
- while (--isprite >= 0)
- {
- if (strcmp(sprites[isprite].name, name) == 0)
- {
- if (!add_sprite(output, out_buf, sprites+isprite, &argc, &argv))
- goto out; /* error in add_sprite */
-
- break;
- }
- }
-
- if (isprite < 0) /* sprite not found */
- {
- fprintf(stderr, "simpleover: --add='%s': sprite not found\n", name);
- break;
- }
- }
-
- else
- {
- fprintf(stderr, "simpleover: %s: unrecognized operation\n", argv[0]);
- break;
- }
-
- result = 1; /* ok */
- }
-
- /* Clean up the cache of sprites: */
-out:
- while (--nsprites >= 0)
- {
- if (sprites[nsprites].buffer != NULL)
- free(sprites[nsprites].buffer);
-
- if (sprites[nsprites].file != NULL)
- (void)fclose(sprites[nsprites].file);
- }
-
- return result;
-}
-
-int main(int argc, const char **argv)
-{
- int result = 1; /* default to fail */
-
- if (argc >= 2)
- {
- int argi = 2;
- const char *output = NULL;
- png_image image;
-
- if (argc > 2 && argv[2][0] != '-'/*an operation*/)
- {
- output = argv[2];
- argi = 3;
- }
-
- image.version = PNG_IMAGE_VERSION;
- image.opaque = NULL;
-
- if (png_image_begin_read_from_file(&image, argv[1]))
- {
- png_bytep buffer;
-
- image.format = PNG_FORMAT_RGB; /* 24-bit RGB */
-
- buffer = malloc(PNG_IMAGE_SIZE(image));
-
- if (buffer != NULL)
- {
- png_color background = {0, 0xff, 0}; /* fully saturated green */
-
- if (png_image_finish_read(&image, &background, buffer,
- 0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */))
- {
- /* At this point png_image_finish_read has cleaned up the
- * allocated data in png_image, and only the buffer needs to be
- * freed.
- *
- * Perform the remaining operations:
- */
- if (simpleover_process(&image, buffer, argc-argi, argv+argi))
- {
- /* Write the output: */
- if ((output != NULL &&
- png_image_write_to_file(&image, output,
- 0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
- NULL/*colormap*/)) ||
- (output == NULL &&
- png_image_write_to_stdio(&image, stdout,
- 0/*convert_to_8bit*/, buffer, 0/*row_stride*/,
- NULL/*colormap*/)))
- result = 0;
-
- else
- fprintf(stderr, "simpleover: write %s: %s\n",
- output == NULL ? "stdout" : output, image.message);
- }
-
- /* else simpleover_process writes an error message */
- }
-
- else
- fprintf(stderr, "simpleover: read %s: %s\n", argv[1],
- image.message);
-
- free(buffer);
- }
-
- else
- {
- fprintf(stderr, "simpleover: out of memory: %lu bytes\n",
- (unsigned long)PNG_IMAGE_SIZE(image));
-
- /* This is the only place where a 'free' is required; libpng does
- * the cleanup on error and success, but in this case we couldn't
- * complete the read because of running out of memory.
- */
- png_image_free(&image);
- }
- }
-
- else
- {
- /* Failed to read the first argument: */
- fprintf(stderr, "simpleover: %s: %s\n", argv[1], image.message);
- }
- }
-
- else
- {
- /* Usage message */
- fprintf(stderr,
- "simpleover: usage: simpleover background.png [output.png]\n"
- " Output 'background.png' as a 24-bit RGB PNG file in 'output.png'\n"
- " or, if not given, stdout. 'background.png' will be composited\n"
- " on fully saturated green.\n"
- "\n"
- " Optionally, before output, process additional PNG files:\n"
- "\n"
- " --sprite=width,height,name {[--at=x,y] {sprite.png}}\n"
- " Produce a transparent sprite of size (width,height) and with\n"
- " name 'name'.\n"
- " For each sprite.png composite it using a Porter-Duff 'Over'\n"
- " operation at offset (x,y) in the sprite (defaulting to (0,0)).\n"
- " Input PNGs will be truncated to the area of the sprite.\n"
- "\n"
- " --add='name' {x,y}\n"
- " Optionally, before output, composite a sprite, 'name', which\n"
- " must have been previously produced using --sprite, at each\n"
- " offset (x,y) in the output image. Each sprite must fit\n"
- " completely within the output image.\n"
- "\n"
- " PNG files are processed in the order they occur on the command\n"
- " line and thus the first PNG processed appears as the bottommost\n"
- " in the output image.\n");
- }
-
- return result;
-}
-#endif /* SIMPLIFIED_READ */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/COPYING b/Build/source/libs/libpng/libpng-src/contrib/gregbook/COPYING
deleted file mode 100644
index a3e97747969..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/LICENSE b/Build/source/libs/libpng/libpng-src/contrib/gregbook/LICENSE
deleted file mode 100644
index d9567178cb6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/LICENSE
+++ /dev/null
@@ -1,50 +0,0 @@
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.mingw32 b/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.mingw32
deleted file mode 100644
index 3a3ff607e81..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.mingw32
+++ /dev/null
@@ -1,131 +0,0 @@
-# Sample makefile for rpng-win / rpng2-win / wpng using mingw32-gcc and make.
-# Greg Roelofs
-# Last modified: 2 June 2007
-#
-# The programs built by this makefile are described in the book,
-# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
-# Associates, 1999). Go buy a copy, eh? Well, OK, it's not
-# generally for sale anymore, but it's the thought that counts,
-# right? (Hint: http://www.libpng.org/pub/png/book/ )
-#
-# Invoke this makefile from a DOS-prompt window via:
-#
-# make -f Makefile.mingw32
-#
-# This makefile assumes libpng and zlib have already been built or downloaded
-# and are in subdirectories at the same level as the current subdirectory
-# (as indicated by the PNGDIR and ZDIR macros below). It makes no assumptions
-# at all about the mingw32 installation tree (W32DIR). Edit as appropriate.
-#
-# Note that the names of the dynamic and static libpng and zlib libraries
-# used below may change in later releases of the libraries. This makefile
-# builds both statically and dynamically linked executables by default.
-# (You need only one set, but for testing it can be handy to have both.)
-
-
-# macros --------------------------------------------------------------------
-
-#PNGDIR = ../..# for libpng-x.y.z/contrib/gregbook builds
-PNGDIR = ../libpng-win32
-PNGINC = -I$(PNGDIR)
-PNGLIBd = $(PNGDIR)/libpng.dll.a # dynamically linked
-PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng
-
-#ZDIR = ../../../zlib-win32# for libpng-x.y.z/contrib/gregbook builds
-ZDIR = ../zlib-win32
-ZINC = -I$(ZDIR)
-ZLIBd = $(ZDIR)/libzdll.a
-ZLIBs = $(ZDIR)/libz.a
-
-# change this to be the path where mingw32 installs its stuff:
-W32DIR =
-#W32DIR = /usr/local/cross-tools/i386-mingw32msvc
-W32INC = -I$(W32DIR)/include
-W32LIB = $(W32DIR)/lib/libuser32.a $(W32DIR)/lib/libgdi32.a
-
-CC = gcc
-#CC = i386-mingw32msvc-gcc # e.g., Linux -> Win32 cross-compilation
-LD = $(CC)
-RM = rm -f
-CPPFLAGS = $(INCS)
-CFLAGS = -O -Wall $(MINGW_CCFLAGS)
-# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
-# [-ansi, -pedantic and -W can also be used]
-LDFLAGS = $(MINGW_LDFLAGS)
-O = .o
-E = .exe
-
-INCS = $(PNGINC) $(ZINC) $(W32INC)
-RLIBSd = $(PNGLIBd) $(ZLIBd) $(W32LIB) -lm
-RLIBSs = $(PNGLIBs) $(ZLIBs) $(W32LIB) -lm
-WLIBSd = $(PNGLIBd) $(ZLIBd)
-WLIBSs = $(PNGLIBs) $(ZLIBs)
-
-RPNG = rpng-win
-RPNG2 = rpng2-win
-WPNG = wpng
-
-ROBJSd = $(RPNG)$(O) readpng.pic$(O)
-ROBJS2d = $(RPNG2)$(O) readpng2.pic$(O)
-WOBJSd = $(WPNG)$(O) writepng.pic$(O)
-
-RPNGs = $(RPNG)-static
-RPNG2s = $(RPNG2)-static
-WPNGs = $(WPNG)-static
-
-ROBJSs = $(RPNG)$(O) readpng$(O)
-ROBJS2s = $(RPNG2)$(O) readpng2$(O)
-WOBJSs = $(WPNG)$(O) writepng$(O)
-
-STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E)
-DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
-
-EXES = $(STATIC_EXES) $(DYNAMIC_EXES)
-
-
-# implicit make rules -------------------------------------------------------
-
-.c$(O):
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-%.pic$(O): %.c
- $(CC) -c $(CPPFLAGS) $(CFLAGS) -DPNG_BUILD_DLL -o $@ $<
-
-
-# dependencies --------------------------------------------------------------
-
-all: $(EXES)
-
-$(RPNGs)$(E): $(ROBJSs)
- $(LD) $(LDFLAGS) -o $@ $(ROBJSs) $(RLIBSs)
-
-$(RPNG)$(E): $(ROBJSd)
- $(LD) $(LDFLAGS) -o $@ $(ROBJSd) $(RLIBSd)
-
-$(RPNG2s)$(E): $(ROBJS2s)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS2s) $(RLIBSs)
-
-$(RPNG2)$(E): $(ROBJS2d)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS2d) $(RLIBSd)
-
-$(WPNGs)$(E): $(WOBJSs)
- $(LD) $(LDFLAGS) -o $@ $(WOBJSs) $(WLIBSs)
-
-$(WPNG)$(E): $(WOBJSd)
- $(LD) $(LDFLAGS) -o $@ $(WOBJSd) $(WLIBSd)
-
-$(RPNG)$(O): $(RPNG).c readpng.h
-$(RPNG2)$(O): $(RPNG2).c readpng2.h
-$(WPNG)$(O): $(WPNG).c writepng.h
-
-readpng$(O) readpng.pic$(O): readpng.c readpng.h
-readpng2$(O) readpng2.pic$(O): readpng2.c readpng2.h
-writepng$(O) writepng.pic$(O): writepng.c writepng.h
-
-
-# maintenance ---------------------------------------------------------------
-
-clean:
- $(RM) $(EXES)
- $(RM) $(ROBJSs) $(ROBJS2s) $(WOBJSs)
- $(RM) $(ROBJSd) $(ROBJS2d) $(WOBJSd)
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.sgi b/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.sgi
deleted file mode 100644
index 94d61b4652c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.sgi
+++ /dev/null
@@ -1,105 +0,0 @@
-# Sample makefile for rpng-x / rpng2-x / wpng for SGI using cc and make.
-# Greg Roelofs
-# Last modified: 7 March 2002
-#
-# The programs built by this makefile are described in the book,
-# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
-# Associates, 1999). Go buy a copy, eh? Buy some for friends
-# and family, too. (Not that this is a blatant plug or anything.)
-#
-# Invoke this makefile from a shell prompt in the usual way; for example:
-#
-# make -f Makefile.sgi
-#
-# This makefile assumes libpng and zlib have already been built or downloaded
-# and are both installed in /usr/local/{include,lib} (as indicated by the
-# PNG* and Z* macros below). Edit as appropriate--choose only ONE each of
-# the PNGINC, PNGLIB, ZINC and ZLIB lines.
-#
-# This makefile builds dynamically linked executables (against libpng and zlib,
-# that is), but that can be changed by uncommenting the appropriate PNGLIB and
-# ZLIB lines.
-
-
-# macros --------------------------------------------------------------------
-
-PNGINC = -I/usr/local/include/libpng16
-PNGLIB = -L/usr/local/lib -lpng16 # dynamically linked against libpng
-#PNGLIB = /usr/local/lib/libpng16.a # statically linked against libpng
-# or:
-#PNGINC = -I../..
-#PNGLIB = -L../.. -lpng
-#PNGLIB = ../../libpng.a
-
-ZINC = -I/usr/local/include
-ZLIB = -L/usr/local/lib -lz # dynamically linked against zlib
-#ZLIB = /usr/local/lib/libz.a # statically linked against zlib
-#ZINC = -I../zlib
-#ZLIB = -L../zlib -lz
-#ZLIB = ../../../zlib/libz.a
-
-XINC = -I/usr/include/X11 # old-style, stock X distributions
-XLIB = -L/usr/lib/X11 -lX11
-#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows)
-#XLIB = -L/usr/openwin/lib -lX11
-#XINC = -I/usr/X11R6/include # new X distributions (XFree86, etc.)
-#XLIB = -L/usr/X11R6/lib -lX11
-
-INCS = $(PNGINC) $(ZINC) $(XINC)
-RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm
-WLIBS = $(PNGLIB) $(ZLIB)
-
-CC = cc
-LD = cc
-RM = rm -f
-# ABI must be the same as that used to build libpng.
-ABI =
-CPPFLAGS =
-CFLAGS = $(ABI) -O -fullwarn $(INCS)
-LDFLAGS = $(ABI)
-O = .o
-E =
-
-RPNG = rpng-x
-RPNG2 = rpng2-x
-WPNG = wpng
-
-ROBJS = $(RPNG)$(O) readpng$(O)
-ROBJS2 = $(RPNG2)$(O) readpng2$(O)
-WOBJS = $(WPNG)$(O) writepng$(O)
-
-EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
-
-
-# implicit make rules -------------------------------------------------------
-
-.c$(O):
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-
-# dependencies --------------------------------------------------------------
-
-all: $(EXES)
-
-$(RPNG)$(E): $(ROBJS)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS)
-
-$(RPNG2)$(E): $(ROBJS2)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS)
-
-$(WPNG)$(E): $(WOBJS)
- $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS)
-
-$(RPNG)$(O): $(RPNG).c readpng.h
-$(RPNG2)$(O): $(RPNG2).c readpng2.h
-$(WPNG)$(O): $(WPNG).c writepng.h
-
-readpng$(O): readpng.c readpng.h
-readpng2$(O): readpng2.c readpng2.h
-writepng$(O): writepng.c writepng.h
-
-
-# maintenance ---------------------------------------------------------------
-
-clean:
- $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.unx b/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.unx
deleted file mode 100644
index 1a73e03bff4..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.unx
+++ /dev/null
@@ -1,134 +0,0 @@
-# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make.
-# Greg Roelofs
-# Last modified: 2 June 2007
-#
-# The programs built by this makefile are described in the book,
-# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
-# Associates, 1999). Go buy a copy, eh? Well, OK, it's not
-# generally for sale anymore, but it's the thought that counts,
-# right? (Hint: http://www.libpng.org/pub/png/book/ )
-#
-# Invoke this makefile from a shell prompt in the usual way; for example:
-#
-# make -f Makefile.unx
-#
-# This makefile assumes libpng and zlib have already been built or downloaded
-# and are installed in /usr/local/{include,lib} or as otherwise indicated by
-# the PNG* and Z* macros below. Edit as appropriate--choose only ONE each of
-# the PNGINC, PNGLIBd, PNGLIBs, ZINC, ZLIBd and ZLIBs lines.
-#
-# This makefile builds both dynamically and statically linked executables
-# (against libpng and zlib, that is), but that can be changed by modifying
-# the "EXES =" line. (You need only one set, but for testing it can be handy
-# to have both.)
-
-
-# macros --------------------------------------------------------------------
-
-#PNGDIR = /usr/local/lib
-#PNGINC = -I/usr/local/include/libpng16
-#PNGLIBd = -L$(PNGDIR) -lpng16 # dynamically linked, installed libpng
-#PNGLIBs = $(PNGDIR)/libpng16.a # statically linked, installed libpng
-# or:
-PNGDIR = ../..# this one is for libpng-x.y.z/contrib/gregbook builds
-#PNGDIR = ../libpng
-PNGINC = -I$(PNGDIR)
-PNGLIBd = -Wl,-rpath,$(PNGDIR) -L$(PNGDIR) -lpng16 # dynamically linked
-PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng
-
-ZDIR = /usr/local/lib
-#ZDIR = /usr/lib64
-ZINC = -I/usr/local/include
-ZLIBd = -L$(ZDIR) -lz # dynamically linked against zlib
-ZLIBs = $(ZDIR)/libz.a # statically linked against zlib
-# or:
-#ZDIR = ../zlib
-#ZINC = -I$(ZDIR)
-#ZLIBd = -Wl,-rpath,$(ZDIR) -L$(ZDIR) -lz # -rpath allows in-place testing
-#ZLIBs = $(ZDIR)/libz.a
-
-#XINC = -I/usr/include # old-style, stock X distributions
-#XLIB = -L/usr/lib/X11 -lX11 # (including SGI IRIX)
-#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows)
-#XLIB = -L/usr/openwin/lib -lX11
-XINC = -I/usr/X11R6/include # new X distributions (X.org, etc.)
-XLIB = -L/usr/X11R6/lib -lX11
-#XLIB = -L/usr/X11R6/lib64 -lX11 # e.g., Red Hat on AMD64
-
-INCS = $(PNGINC) $(ZINC) $(XINC)
-RLIBSd = $(PNGLIBd) $(ZLIBd) $(XLIB) -lm
-RLIBSs = $(PNGLIBs) $(ZLIBs) $(XLIB) -lm
-WLIBSd = $(PNGLIBd) $(ZLIBd) -lm
-WLIBSs = $(PNGLIBs) $(ZLIBs) -lm
-
-CC = gcc
-LD = gcc
-RM = rm -f
-CPPFLAGS = $(INCS) -DFEATURE_LOOP
-CFLAGS = -O -Wall
-#CFLAGS = -O -W -Wall -Wextra -pedantic -ansi
-# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
-# [-ansi, -pedantic, -Wextra, and -W can also be used]
-LDFLAGS =
-O = .o
-E =
-
-RPNG = rpng-x
-RPNG2 = rpng2-x
-WPNG = wpng
-
-RPNGs = $(RPNG)-static
-RPNG2s = $(RPNG2)-static
-WPNGs = $(WPNG)-static
-
-ROBJS = $(RPNG)$(O) readpng$(O)
-ROBJS2 = $(RPNG2)$(O) readpng2$(O)
-WOBJS = $(WPNG)$(O) writepng$(O)
-
-STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E)
-DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
-
-EXES = $(STATIC_EXES) $(DYNAMIC_EXES)
-
-
-# implicit make rules -------------------------------------------------------
-
-.c$(O):
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-
-# dependencies --------------------------------------------------------------
-
-all: $(EXES)
-
-$(RPNGs)$(E): $(ROBJS)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSs)
-
-$(RPNG)$(E): $(ROBJS)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSd)
-
-$(RPNG2s)$(E): $(ROBJS2)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSs)
-
-$(RPNG2)$(E): $(ROBJS2)
- $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSd)
-
-$(WPNGs)$(E): $(WOBJS)
- $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSs)
-
-$(WPNG)$(E): $(WOBJS)
- $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSd)
-
-$(RPNG)$(O): $(RPNG).c readpng.h
-$(RPNG2)$(O): $(RPNG2).c readpng2.h
-$(WPNG)$(O): $(WPNG).c writepng.h
-
-readpng$(O): readpng.c readpng.h
-readpng2$(O): readpng2.c readpng2.h
-writepng$(O): writepng.c writepng.h
-
-
-# maintenance ---------------------------------------------------------------
-
-clean:
- $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.w32 b/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.w32
deleted file mode 100644
index ab7dcf7cae7..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/Makefile.w32
+++ /dev/null
@@ -1,114 +0,0 @@
-# Sample makefile for rpng-win / rpng2-win / wpng using MSVC and NMAKE.
-# Greg Roelofs
-# Last modified: 2 June 2007
-#
-# The programs built by this makefile are described in the book,
-# "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and
-# Associates, 1999). Go buy a copy, eh? Well, OK, it's not
-# generally for sale anymore, but it's the thought that counts,
-# right? (Hint: http://www.libpng.org/pub/png/book/ )
-#
-# Invoke this makefile from a DOS prompt window via:
-#
-# %devstudio%\vc\bin\vcvars32.bat
-# nmake -nologo -f Makefile.w32
-#
-# where %devstudio% is the installation directory for MSVC / DevStudio. If
-# you get "environment out of space" errors, create a desktop shortcut with
-# "c:\windows\command.com /e:4096" as the program command line and set the
-# working directory to this directory. Then double-click to open the new
-# DOS-prompt window with a bigger environment and retry the commands above.
-#
-# This makefile assumes libpng and zlib have already been built or downloaded
-# and are in subdirectories at the same level as the current subdirectory
-# (as indicated by the PNGPATH and ZPATH macros below). Edit as appropriate.
-#
-# Note that the names of the dynamic and static libpng and zlib libraries
-# used below may change in later releases of the libraries. This makefile
-# builds statically linked executables, but that can be changed by uncom-
-# menting the appropriate PNGLIB and ZLIB lines.
-
-!include <ntwin32.mak>
-
-
-# macros --------------------------------------------------------------------
-
-PNGPATH = ../libpng
-PNGINC = -I$(PNGPATH)
-#PNGLIB = $(PNGPATH)/pngdll.lib
-PNGLIB = $(PNGPATH)/libpng.lib
-
-ZPATH = ../zlib
-ZINC = -I$(ZPATH)
-#ZLIB = $(ZPATH)/zlibdll.lib
-ZLIB = $(ZPATH)/zlibstat.lib
-
-WINLIBS = -defaultlib:user32.lib gdi32.lib
-# ["real" apps may also need comctl32.lib, comdlg32.lib, winmm.lib, etc.]
-
-INCS = $(PNGINC) $(ZINC)
-RLIBS = $(PNGLIB) $(ZLIB) $(WINLIBS)
-WLIBS = $(PNGLIB) $(ZLIB)
-
-CC = cl
-LD = link
-RM = del
-CPPFLAGS = $(INCS)
-CFLAGS = -nologo -O -W3 $(cvars)
-# [note that -W3 is an MSVC-specific compilation flag ("all warnings on")]
-# [see %devstudio%\vc\include\win32.mak for cvars macro definition]
-O = .obj
-E = .exe
-
-RLDFLAGS = -nologo -subsystem:windows
-WLDFLAGS = -nologo
-
-RPNG = rpng-win
-RPNG2 = rpng2-win
-WPNG = wpng
-
-ROBJS = $(RPNG)$(O) readpng$(O)
-ROBJS2 = $(RPNG2)$(O) readpng2$(O)
-WOBJS = $(WPNG)$(O) writepng$(O)
-
-EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E)
-
-
-# implicit make rules -------------------------------------------------------
-
-.c$(O):
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-
-# dependencies --------------------------------------------------------------
-
-all: $(EXES)
-
-$(RPNG)$(E): $(ROBJS)
- $(LD) $(RLDFLAGS) -out:$@ $(ROBJS) $(RLIBS)
-
-$(RPNG2)$(E): $(ROBJS2)
- $(LD) $(RLDFLAGS) -out:$@ $(ROBJS2) $(RLIBS)
-
-$(WPNG)$(E): $(WOBJS)
- $(LD) $(WLDFLAGS) -out:$@ $(WOBJS) $(WLIBS)
-
-$(RPNG)$(O): $(RPNG).c readpng.h
-$(RPNG2)$(O): $(RPNG2).c readpng2.h
-$(WPNG)$(O): $(WPNG).c writepng.h
-
-readpng$(O): readpng.c readpng.h
-readpng2$(O): readpng2.c readpng2.h
-writepng$(O): writepng.c writepng.h
-
-
-# maintenance ---------------------------------------------------------------
-
-clean:
-# ideally we could just do this:
-# $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS)
-# ...but the Windows "DEL" command is none too bright, so:
- $(RM) r*$(E)
- $(RM) w*$(E)
- $(RM) r*$(O)
- $(RM) w*$(O)
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/README b/Build/source/libs/libpng/libpng-src/contrib/gregbook/README
deleted file mode 100644
index 90e28f7ce53..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/README
+++ /dev/null
@@ -1,186 +0,0 @@
- ===========================
- PNG: The Definitive Guide
- ===========================
-
- Source Code
-
-Chapters 13, 14 and 15 of "PNG: The Definitive Guide" discuss three free,
-cross-platform demo programs that show how to use the libpng reference
-library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is
-a very simple example that that shows how a standard file-viewer might use
-libpng, while the second is designed to process streaming data and shows
-how a web browser might be written. wpng is a simple command-line program
-that reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets
-of PBMPLUS/NetPBM) and converts them to PNG.
-
-The source code for all three demo programs currently compiles under
-Unix, OpenVMS, and 32-bit Windows. (Special thanks to Martin Zinser,
-zinser at decus.de, for making the necessary changes for OpenVMS and for
-providing an appropriate build script.) Build instructions can be found
-below.
-
-Files:
-
- README this file
- LICENSE terms of distribution and reuse (BSD-like or GNU GPL)
- COPYING GNU General Public License (GPL)
-
- Makefile.unx Unix makefile
- Makefile.w32 Windows (MSVC) makefile
- makevms.com OpenVMS build script
-
- rpng-win.c Windows front end for the basic viewer
- rpng-x.c X Window System (Unix, OpenVMS) front end
- readpng.c generic back end for the basic viewer
- readpng.h header file for the basic viewer
-
- rpng2-win.c Windows front end for the progressive viewer
- rpng2-x.c X front end for the progressive viewer
- readpng2.c generic back end for the progressive viewer
- readpng2.h header file for the progressive viewer
-
- wpng.c generic (text) front end for the converter
- writepng.c generic back end for the converter
- writepng.h header file for the converter
-
- toucan.png transparent PNG for testing (by Stefan Schneider)
-
-Note that, although the programs are designed to be functional, their
-primary purpose is to illustrate how to use libpng to add PNG support to
-other programs. As such, their user interfaces are crude and definitely
-are not intended for everyday use.
-
-Please see http://www.libpng.org/pub/png/pngbook.html for further infor-
-mation and links to the latest version of the source code, and Chapters
-13-15 of the book for detailed discussion of the three programs.
-
-Greg Roelofs
-https://pobox.com/~newt/greg_contact.html
-16 March 2008
-
-
-BUILD INSTRUCTIONS
-
- - Prerequisites (in order of compilation):
-
- - zlib https://zlib.net/
- - libpng http://www.libpng.org/pub/png/libpng.html
- - pngbook http://www.libpng.org/pub/png/book/sources.html
-
- The pngbook demo programs are explicitly designed to demonstrate proper
- coding techniques for using the libpng reference library. As a result,
- you need to download and build both zlib (on which libpng depends) and
- libpng. A common build setup is to place the zlib, libpng and pngbook
- subdirectory trees ("folders") in the same parent directory. Then the
- libpng build can refer to files in ../zlib (or ..\zlib or [-.zlib]),
- and similarly for the pngbook build.
-
- Note that all three packages are designed to be built from a command
- line by default; those who wish to use a graphical or other integrated
- development environments are on their own.
-
-
- - Unix:
-
- Unpack the latest pngbook sources (which should correspond to this
- README file) into a directory and change into that directory.
-
- Copy Makefile.unx to Makefile and edit the PNG* and Z* variables
- appropriately (possibly also the X* variables if necessary).
-
- make
-
- There is no "install" target, so copy the three executables somewhere
- in your path or run them from the current directory. All three will
- print a basic usage screen when run without any command-line arguments;
- see the book for more details.
-
-
- - Windows:
-
- Unpack the latest pngbook sources (which should correspond to this
- README file) into a folder, open a "DOS shell" or "command prompt"
- or equivalent command-line window, and cd into the folder where you
- unpacked the source code.
-
- For MSVC, set up the necessary environment variables by invoking
-
- %devstudio%\vc\bin\vcvars32.bat
-
- where where %devstudio% is the installation directory for MSVC /
- DevStudio. If you get "environment out of space" errors under 95/98,
- create a desktop shortcut with "c:\windows\command.com /e:4096" as
- the program command line and set the working directory to the pngbook
- directory. Then double-click to open the new DOS-prompt window with
- a bigger environment and retry the commands above.
-
- Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables
- appropriately (possibly also the "INC" and "LIB" variables if needed).
- Note that the names of the dynamic and static libpng and zlib libraries
- used in the makefile may change in later releases of the libraries.
- Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work.
- This makefile therefore builds statically linked executables, but if
- the DLL problems ever get fixed, uncommenting the appropriate PNGLIB
- and ZLIB lines will build dynamically linked executables instead.
-
- Do the build by typing
-
- nmake
-
- The result should be three executables: rpng-win.exe, rpng2-win.exe,
- and wpng.exe. Copy them somewhere in your PATH or run them from the
- current folder. Like the Unix versions, the two windowed programs
- (rpng and rpng2) now display a usage screen in a console window when
- invoked without command-line arguments; this is new behavior as of
- the June 2001 release. Note that the programs use the Unix-style "-"
- character to specify options, instead of the more common DOS/Windows
- "/" character. (For example: "rpng2-win -bgpat 4 foo.png", not
- "rpng2-win /bgpat 4 foo.png")
-
-
- - OpenVMS:
-
- Unpack the pngbook sources into a subdirectory and change into that
- subdirectory.
-
- Edit makevms.com appropriately, specifically the zpath and pngpath
- variables.
-
- @makevms
-
- To run the programs, they probably first need to be set up as "foreign
- symbols," with "disk" and "dir" set appropriately:
-
- $ rpng == "$disk:[dir]rpng-x.exe"
- $ rpng2 == "$disk:[dir]rpng2-x.exe"
- $ wpng == "$disk:[dir]wpng.exe"
-
- All three will print a basic usage screen when run without any command-
- line arguments; see the book for more details. Note that the options
- style is Unix-like, i.e., preceded by "-" rather than "/".
-
-
-RUNNING THE PROGRAMS: (VERY) BRIEF INTRO
-
- rpng is a simple PNG viewer that can display transparent PNGs with a
- specified background color; for example,
-
- rpng -bgcolor \#ff0000 toucan.png
-
- would display the image with a red background. rpng2 is a progressive
- viewer that simulates a web browser in some respects; it can display
- images against either a background color or a dynamically generated
- background image. For example:
-
- rpng2 -bgpat 16 toucan.png
-
- wpng is a purely command-line image converter from binary PBMPLUS/NetPBM
- format (.pgm or .ppm) to PNG; for example,
-
- wpng -time < toucan-notrans.ppm > toucan-notrans.png
-
- would convert the specified PPM file (using redirection) to PNG, auto-
- matically setting the PNG modification-time chunk.
-
- All options can be abbreviated to the shortest unique value; for example,
- "-bgc" for -bgcolor (versus "-bgp" for -bgpat), or "-g" for -gamma.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/makevms.com b/Build/source/libs/libpng/libpng-src/contrib/gregbook/makevms.com
deleted file mode 100644
index f32bcaba7f9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/makevms.com
+++ /dev/null
@@ -1,132 +0,0 @@
-$!------------------------------------------------------------------------------
-$! make "PNG: The Definitive Guide" demo programs (for X) under OpenVMS
-$!
-$! Script created by Martin Zinser for libpng; modified by Greg Roelofs
-$! for standalone pngbook source distribution.
-$!
-$!
-$! Set locations where zlib and libpng sources live.
-$!
-$ zpath = ""
-$ pngpath = ""
-$!
-$ if f$search("[---.zlib]zlib.h").nes."" then zpath = "[---.zlib]"
-$ if f$search("[--]png.h").nes."" then pngpath = "[--]"
-$!
-$ if f$search("[-.zlib]zlib.h").nes."" then zpath = "[-.zlib]"
-$ if f$search("[-.libpng]png.h").nes."" then pngpath = "[-.libpng]"
-$!
-$ if zpath .eqs. ""
-$ then
-$ write sys$output "zlib include not found. Exiting..."
-$ exit 2
-$ endif
-$!
-$ if pngpath .eqs. ""
-$ then
-$ write sys$output "libpng include not found. Exiting..."
-$ exit 2
-$ endif
-$!
-$! Look for the compiler used.
-$!
-$ ccopt="/include=(''zpath',''pngpath')"
-$ if f$getsyi("HW_MODEL").ge.1024
-$ then
-$ ccopt = "/prefix=all"+ccopt
-$ comp = "__decc__=1"
-$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
-$ else
-$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
-$ then
-$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
-$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs.""
-$ then
-$ comp = "__gcc__=1"
-$ CC :== GCC
-$ else
-$ comp = "__vaxc__=1"
-$ endif
-$ else
-$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
-$ ccopt = "/decc/prefix=all"+ccopt
-$ comp = "__decc__=1"
-$ endif
-$ endif
-$ open/write lopt lib.opt
-$ write lopt "''pngpath'libpng.olb/lib"
-$ write lopt "''zpath'libz.olb/lib"
-$ close lopt
-$ open/write xopt x11.opt
-$ write xopt "sys$library:decw$xlibshr.exe/share"
-$ close xopt
-$!
-$! Build 'em.
-$!
-$ write sys$output "Compiling PNG book programs ..."
-$ CALL MAKE readpng.OBJ "cc ''CCOPT' readpng" -
- readpng.c readpng.h
-$ CALL MAKE readpng2.OBJ "cc ''CCOPT' readpng2" -
- readpng2.c readpng2.h
-$ CALL MAKE writepng.OBJ "cc ''CCOPT' writepng" -
- writepng.c writepng.h
-$ write sys$output "Building rpng-x..."
-$ CALL MAKE rpng-x.OBJ "cc ''CCOPT' rpng-x" -
- rpng-x.c readpng.h
-$ call make rpng-x.exe -
- "LINK rpng-x,readpng,lib.opt/opt,x11.opt/opt" -
- rpng-x.obj readpng.obj
-$ write sys$output "Building rpng2-x..."
-$ CALL MAKE rpng2-x.OBJ "cc ''CCOPT' rpng2-x" -
- rpng2-x.c readpng2.h
-$ call make rpng2-x.exe -
- "LINK rpng2-x,readpng2,lib.opt/opt,x11.opt/opt" -
- rpng2-x.obj readpng2.obj
-$ write sys$output "Building wpng..."
-$ CALL MAKE wpng.OBJ "cc ''CCOPT' wpng" -
- wpng.c writepng.h
-$ call make wpng.exe -
- "LINK wpng,writepng,lib.opt/opt" -
- wpng.obj writepng.obj
-$ exit
-$!
-$!
-$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
-$ V = 'F$Verify(0)
-$! P1 = What we are trying to make
-$! P2 = Command to make it
-$! P3 - P8 What it depends on
-$
-$ If F$Search(P1) .Eqs. "" Then Goto Makeit
-$ Time = F$CvTime(F$File(P1,"RDT"))
-$arg=3
-$Loop:
-$ Argument = P'arg
-$ If Argument .Eqs. "" Then Goto Exit
-$ El=0
-$Loop2:
-$ File = F$Element(El," ",Argument)
-$ If File .Eqs. " " Then Goto Endl
-$ AFile = ""
-$Loop3:
-$ OFile = AFile
-$ AFile = F$Search(File)
-$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
-$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
-$ Goto Loop3
-$NextEL:
-$ El = El + 1
-$ Goto Loop2
-$EndL:
-$ arg=arg+1
-$ If arg .Le. 8 Then Goto Loop
-$ Goto Exit
-$
-$Makeit:
-$ VV=F$VERIFY(0)
-$ write sys$output P2
-$ 'P2
-$ VV='F$Verify(VV)
-$Exit:
-$ If V Then Set Verify
-$ENDSUBROUTINE
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.c
deleted file mode 100644
index fad9b536ab9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng - simple PNG display program readpng.c
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2007,2017 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <zlib.h>
-
-#include "png.h" /* libpng header */
-#include "readpng.h" /* typedefs, common macros, public prototypes */
-
-/* future versions of libpng will provide this macro: */
-#ifndef png_jmpbuf
-# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
-#endif
-
-
-static png_structp png_ptr = NULL;
-static png_infop info_ptr = NULL;
-
-png_uint_32 width, height;
-int bit_depth, color_type;
-uch *image_data = NULL;
-
-
-void readpng_version_info(void)
-{
- fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
- PNG_LIBPNG_VER_STRING, png_libpng_ver);
- fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
- ZLIB_VERSION, zlib_version);
-}
-
-
-/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
-
-int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
-{
- uch sig[8];
-
-
- /* first do a quick check that the file really is a PNG image; could
- * have used slightly more general png_sig_cmp() function instead */
-
- fread(sig, 1, 8, infile);
- if (png_sig_cmp(sig, 0, 8))
- return 1; /* bad signature */
-
-
- /* could pass pointers to user-defined error handlers instead of NULLs: */
-
- png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), NULL, NULL,
- NULL);
- if (!png_ptr)
- return 4; /* out of memory */
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- return 4; /* out of memory */
- }
-
-
- /* we could create a second info struct here (end_info), but it's only
- * useful if we want to keep pre- and post-IDAT chunk info separated
- * (mainly for PNG-aware image editors and converters) */
-
-
- /* setjmp() must be called in every function that calls a PNG-reading
- * libpng function */
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return 2;
- }
-
-
- png_init_io(png_ptr, infile);
- png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */
-
- png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */
-
-
- /* alternatively, could make separate calls to png_get_image_width(),
- * etc., but want bit_depth and color_type for later [don't care about
- * compression_type and filter_type => NULLs] */
-
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
- NULL, NULL, NULL);
- *pWidth = width;
- *pHeight = height;
-
-
- /* OK, that's all we need for now; return happy */
-
- return 0;
-}
-
-
-
-
-/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;
- * scales values to 8-bit if necessary */
-
-int readpng_get_bgcolor(uch *red, uch *green, uch *blue)
-{
- png_color_16p pBackground;
-
-
- /* setjmp() must be called in every function that calls a PNG-reading
- * libpng function */
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return 2;
- }
-
-
- if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
- return 1;
-
- /* it is not obvious from the libpng documentation, but this function
- * takes a pointer to a pointer, and it always returns valid red, green
- * and blue values, regardless of color_type: */
-
- png_get_bKGD(png_ptr, info_ptr, &pBackground);
-
-
- /* however, it always returns the raw bKGD data, regardless of any
- * bit-depth transformations, so check depth and adjust if necessary */
-
- if (bit_depth == 16) {
- *red = pBackground->red >> 8;
- *green = pBackground->green >> 8;
- *blue = pBackground->blue >> 8;
- } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
- if (bit_depth == 1)
- *red = *green = *blue = pBackground->gray? 255 : 0;
- else if (bit_depth == 2)
- *red = *green = *blue = (255/3) * pBackground->gray;
- else /* bit_depth == 4 */
- *red = *green = *blue = (255/15) * pBackground->gray;
- } else {
- *red = (uch)pBackground->red;
- *green = (uch)pBackground->green;
- *blue = (uch)pBackground->blue;
- }
-
- return 0;
-}
-
-
-
-
-/* display_exponent == LUT_exponent * CRT_exponent */
-
-uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
-{
- double gamma;
- png_uint_32 i, rowbytes;
- png_bytepp row_pointers = NULL;
-
-
- /* setjmp() must be called in every function that calls a PNG-reading
- * libpng function */
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- free(image_data);
- image_data = NULL;
- free(row_pointers);
- row_pointers = NULL;
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return NULL;
- }
-
-
- /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
- * transparency chunks to full alpha channel; strip 16-bit-per-sample
- * images to 8 bits per sample; and convert grayscale to RGB[A] */
-
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- png_set_expand(png_ptr);
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
- png_set_expand(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand(png_ptr);
-#ifdef PNG_READ_16_TO_8_SUPPORTED
- if (bit_depth == 16)
-# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
- png_set_scale_16(png_ptr);
-# else
- png_set_strip_16(png_ptr);
-# endif
-#endif
- if (color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
-
-
- /* unlike the example in the libpng documentation, we have *no* idea where
- * this file may have come from--so if it doesn't have a file gamma, don't
- * do any correction ("do no harm") */
-
- if (png_get_gAMA(png_ptr, info_ptr, &gamma))
- png_set_gamma(png_ptr, display_exponent, gamma);
-
-
- /* all transformations have been registered; now update info_ptr data,
- * get rowbytes and channels, and allocate image memory */
-
- png_read_update_info(png_ptr, info_ptr);
-
- *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
- *pChannels = (int)png_get_channels(png_ptr, info_ptr);
-
- /* Guard against integer overflow */
- if (height > ((size_t)(-1))/rowbytes) {
- fprintf(stderr, "readpng: image_data buffer would be too large\n",
- return NULL;
- }
-
- if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return NULL;
- }
- if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- free(image_data);
- image_data = NULL;
- return NULL;
- }
-
- Trace((stderr, "readpng_get_image: channels = %d, rowbytes = %ld, height = %ld\n",
- *pChannels, rowbytes, height));
-
-
- /* set the individual row_pointers to point at the correct offsets */
-
- for (i = 0; i < height; ++i)
- row_pointers[i] = image_data + i*rowbytes;
-
-
- /* now we can go ahead and just read the whole image */
-
- png_read_image(png_ptr, row_pointers);
-
-
- /* and we're done! (png_read_end() can be omitted if no processing of
- * post-IDAT text/time/etc. is desired) */
-
- free(row_pointers);
- row_pointers = NULL;
-
- png_read_end(png_ptr, NULL);
-
- return image_data;
-}
-
-
-void readpng_cleanup(int free_image_data)
-{
- if (free_image_data && image_data) {
- free(image_data);
- image_data = NULL;
- }
-
- if (png_ptr && info_ptr) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- png_ptr = NULL;
- info_ptr = NULL;
- }
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.h b/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.h
deleted file mode 100644
index fad9fe3b4c5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng - simple PNG display program readpng.h
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#ifndef TRUE
-# define TRUE 1
-# define FALSE 0
-#endif
-
-#ifndef MAX
-# define MAX(a,b) ((a) > (b)? (a) : (b))
-# define MIN(a,b) ((a) < (b)? (a) : (b))
-#endif
-
-#ifdef DEBUG
-# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
-#else
-# define Trace(x) ;
-#endif
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-
-/* prototypes for public functions in readpng.c */
-
-void readpng_version_info(void);
-
-int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight);
-
-int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue);
-
-uch *readpng_get_image(double display_exponent, int *pChannels,
- ulg *pRowbytes);
-
-void readpng_cleanup(int free_image_data);
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.c
deleted file mode 100644
index 610b3cd87e0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng2 - progressive-model PNG display program readpng2.c
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2015 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------
-
- Changelog:
- 2015-11-12 - Check return value of png_get_bKGD() (Glenn R-P)
- 2017-04-22 - Guard against integer overflow (Glenn R-P)
-
- ---------------------------------------------------------------------------*/
-
-
-#include <stdlib.h> /* for exit() prototype */
-#include <setjmp.h>
-
-#include <zlib.h>
-#include "png.h" /* libpng header from the local directory */
-#include "readpng2.h" /* typedefs, common macros, public prototypes */
-
-
-/* local prototypes */
-
-static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr);
-static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
- png_uint_32 row_num, int pass);
-static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);
-static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
-static void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg);
-
-
-
-
-void readpng2_version_info(void)
-{
- fprintf(stderr, " Compiled with libpng %s; using libpng %s\n",
- PNG_LIBPNG_VER_STRING, png_libpng_ver);
-
- fprintf(stderr, " and with zlib %s; using zlib %s.\n",
- ZLIB_VERSION, zlib_version);
-}
-
-
-
-
-int readpng2_check_sig(uch *sig, int num)
-{
- return !png_sig_cmp(sig, 0, num);
-}
-
-
-
-
-/* returns 0 for success, 2 for libpng problem, 4 for out of memory */
-
-int readpng2_init(mainprog_info *mainprog_ptr)
-{
- png_structp png_ptr; /* note: temporary variables! */
- png_infop info_ptr;
-
-
- /* could also replace libpng warning-handler (final NULL), but no need: */
-
- png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), mainprog_ptr,
- readpng2_error_handler, readpng2_warning_handler);
- if (!png_ptr)
- return 4; /* out of memory */
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- return 4; /* out of memory */
- }
-
-
- /* we could create a second info struct here (end_info), but it's only
- * useful if we want to keep pre- and post-IDAT chunk info separated
- * (mainly for PNG-aware image editors and converters) */
-
-
- /* setjmp() must be called in every function that calls a PNG-reading
- * libpng function, unless an alternate error handler was installed--
- * but compatible error handlers must either use longjmp() themselves
- * (as in this program) or exit immediately, so here we are: */
-
- if (setjmp(mainprog_ptr->jmpbuf)) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return 2;
- }
-
-
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- /* prepare the reader to ignore all recognized chunks whose data won't be
- * used, i.e., all chunks recognized by libpng except for IHDR, PLTE, IDAT,
- * IEND, tRNS, bKGD, gAMA, and sRGB (small performance improvement) */
- {
- /* These byte strings were copied from png.h. If a future version
- * of readpng2.c recognizes more chunks, add them to this list.
- */
- static const png_byte chunks_to_process[] = {
- 98, 75, 71, 68, '\0', /* bKGD */
- 103, 65, 77, 65, '\0', /* gAMA */
- 115, 82, 71, 66, '\0', /* sRGB */
- };
-
- /* Ignore all chunks except for IHDR, PLTE, tRNS, IDAT, and IEND */
- png_set_keep_unknown_chunks(png_ptr, -1 /* PNG_HANDLE_CHUNK_NEVER */,
- NULL, -1);
-
- /* But do not ignore chunks in the "chunks_to_process" list */
- png_set_keep_unknown_chunks(png_ptr,
- 0 /* PNG_HANDLE_CHUNK_AS_DEFAULT */, chunks_to_process,
- sizeof(chunks_to_process)/5);
- }
-#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */
-
-
- /* instead of doing png_init_io() here, now we set up our callback
- * functions for progressive decoding */
-
- png_set_progressive_read_fn(png_ptr, mainprog_ptr,
- readpng2_info_callback, readpng2_row_callback, readpng2_end_callback);
-
-
- /* make sure we save our pointers for use in readpng2_decode_data() */
-
- mainprog_ptr->png_ptr = png_ptr;
- mainprog_ptr->info_ptr = info_ptr;
-
-
- /* and that's all there is to initialization */
-
- return 0;
-}
-
-
-
-
-/* returns 0 for success, 2 for libpng (longjmp) problem */
-
-int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length)
-{
- png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
- png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
-
-
- /* setjmp() must be called in every function that calls a PNG-reading
- * libpng function */
-
- if (setjmp(mainprog_ptr->jmpbuf)) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- mainprog_ptr->png_ptr = NULL;
- mainprog_ptr->info_ptr = NULL;
- return 2;
- }
-
-
- /* hand off the next chunk of input data to libpng for decoding */
-
- png_process_data(png_ptr, info_ptr, rawbuf, length);
-
- return 0;
-}
-
-
-
-
-static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr)
-{
- mainprog_info *mainprog_ptr;
- int color_type, bit_depth;
- png_uint_32 width, height;
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- double gamma;
-#else
- png_fixed_point gamma;
-#endif
-
-
- /* setjmp() doesn't make sense here, because we'd either have to exit(),
- * longjmp() ourselves, or return control to libpng, which doesn't want
- * to see us again. By not doing anything here, libpng will instead jump
- * to readpng2_decode_data(), which can return an error value to the main
- * program. */
-
-
- /* retrieve the pointer to our special-purpose struct, using the png_ptr
- * that libpng passed back to us (i.e., not a global this time--there's
- * no real difference for a single image, but for a multithreaded browser
- * decoding several PNG images at the same time, one needs to avoid mixing
- * up different images' structs) */
-
- mainprog_ptr = png_get_progressive_ptr(png_ptr);
-
- if (mainprog_ptr == NULL) { /* we be hosed */
- fprintf(stderr,
- "readpng2 error: main struct not recoverable in info_callback.\n");
- fflush(stderr);
- return;
- /*
- * Alternatively, we could call our error-handler just like libpng
- * does, which would effectively terminate the program. Since this
- * can only happen if png_ptr gets redirected somewhere odd or the
- * main PNG struct gets wiped, we're probably toast anyway. (If
- * png_ptr itself is NULL, we would not have been called.)
- */
- }
-
-
- /* this is just like in the non-progressive case */
-
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
- NULL, NULL, NULL);
- mainprog_ptr->width = (ulg)width;
- mainprog_ptr->height = (ulg)height;
-
-
- /* since we know we've read all of the PNG file's "header" (i.e., up
- * to IDAT), we can check for a background color here */
-
- if (mainprog_ptr->need_bgcolor)
- {
- png_color_16p pBackground;
-
- /* it is not obvious from the libpng documentation, but this function
- * takes a pointer to a pointer, and it always returns valid red,
- * green and blue values, regardless of color_type: */
- if (png_get_bKGD(png_ptr, info_ptr, &pBackground))
- {
-
- /* however, it always returns the raw bKGD data, regardless of any
- * bit-depth transformations, so check depth and adjust if necessary
- */
- if (bit_depth == 16) {
- mainprog_ptr->bg_red = pBackground->red >> 8;
- mainprog_ptr->bg_green = pBackground->green >> 8;
- mainprog_ptr->bg_blue = pBackground->blue >> 8;
- } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
- if (bit_depth == 1)
- mainprog_ptr->bg_red = mainprog_ptr->bg_green =
- mainprog_ptr->bg_blue = pBackground->gray? 255 : 0;
- else if (bit_depth == 2)
- mainprog_ptr->bg_red = mainprog_ptr->bg_green =
- mainprog_ptr->bg_blue = (255/3) * pBackground->gray;
- else /* bit_depth == 4 */
- mainprog_ptr->bg_red = mainprog_ptr->bg_green =
- mainprog_ptr->bg_blue = (255/15) * pBackground->gray;
- } else {
- mainprog_ptr->bg_red = (uch)pBackground->red;
- mainprog_ptr->bg_green = (uch)pBackground->green;
- mainprog_ptr->bg_blue = (uch)pBackground->blue;
- }
- }
- }
-
-
- /* as before, let libpng expand palette images to RGB, low-bit-depth
- * grayscale images to 8 bits, transparency chunks to full alpha channel;
- * strip 16-bit-per-sample images to 8 bits per sample; and convert
- * grayscale to RGB[A] */
-
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- png_set_expand(png_ptr);
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
- png_set_expand(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand(png_ptr);
-#ifdef PNG_READ_16_TO_8_SUPPORTED
- if (bit_depth == 16)
-# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
- png_set_scale_16(png_ptr);
-# else
- png_set_strip_16(png_ptr);
-# endif
-#endif
- if (color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
-
-
- /* Unlike the basic viewer, which was designed to operate on local files,
- * this program is intended to simulate a web browser--even though we
- * actually read from a local file, too. But because we are pretending
- * that most of the images originate on the Internet, we follow the recom-
- * mendation of the sRGB proposal and treat unlabelled images (no gAMA
- * chunk) as existing in the sRGB color space. That is, we assume that
- * such images have a file gamma of 0.45455, which corresponds to a PC-like
- * display system. This change in assumptions will have no effect on a
- * PC-like system, but on a Mac, SGI, NeXT or other system with a non-
- * identity lookup table, it will darken unlabelled images, which effec-
- * tively favors images from PC-like systems over those originating on
- * the local platform. Note that mainprog_ptr->display_exponent is the
- * "gamma" value for the entire display system, i.e., the product of
- * LUT_exponent and CRT_exponent. */
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- if (png_get_gAMA(png_ptr, info_ptr, &gamma))
- png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma);
- else
- png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455);
-#else
- if (png_get_gAMA_fixed(png_ptr, info_ptr, &gamma))
- png_set_gamma_fixed(png_ptr,
- (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), gamma);
- else
- png_set_gamma_fixed(png_ptr,
- (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), 45455);
-#endif
-
- /* we'll let libpng expand interlaced images, too */
-
- mainprog_ptr->passes = png_set_interlace_handling(png_ptr);
-
-
- /* all transformations have been registered; now update info_ptr data and
- * then get rowbytes and channels */
-
- png_read_update_info(png_ptr, info_ptr);
-
- mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);
- mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr);
-
-
- /* Call the main program to allocate memory for the image buffer and
- * initialize windows and whatnot. (The old-style function-pointer
- * invocation is used for compatibility with a few supposedly ANSI
- * compilers that nevertheless barf on "fn_ptr()"-style syntax.) */
-
- (*mainprog_ptr->mainprog_init)();
-
-
- /* and that takes care of initialization */
-
- return;
-}
-
-
-
-
-
-static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
- png_uint_32 row_num, int pass)
-{
- mainprog_info *mainprog_ptr;
-
-
- /* first check whether the row differs from the previous pass; if not,
- * nothing to combine or display */
-
- if (!new_row)
- return;
-
-
- /* retrieve the pointer to our special-purpose struct so we can access
- * the old rows and image-display callback function */
-
- mainprog_ptr = png_get_progressive_ptr(png_ptr);
-
-
- /* save the pass number for optional use by the front end */
-
- mainprog_ptr->pass = pass;
-
-
- /* have libpng either combine the new row data with the existing row data
- * from previous passes (if interlaced) or else just copy the new row
- * into the main program's image buffer */
-
- png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num],
- new_row);
-
-
- /* finally, call the display routine in the main program with the number
- * of the row we just updated */
-
- (*mainprog_ptr->mainprog_display_row)(row_num);
-
-
- /* and we're ready for more */
-
- return;
-}
-
-
-
-
-
-static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr)
-{
- mainprog_info *mainprog_ptr;
-
-
- /* retrieve the pointer to our special-purpose struct */
-
- mainprog_ptr = png_get_progressive_ptr(png_ptr);
-
-
- /* let the main program know that it should flush any buffered image
- * data to the display now and set a "done" flag or whatever, but note
- * that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do
- * NOT call readpng2_cleanup() either here or in the finish_display()
- * routine; wait until control returns to the main program via
- * readpng2_decode_data() */
-
- (*mainprog_ptr->mainprog_finish_display)();
-
-
- /* all done */
-
- (void)info_ptr; /* Unused */
-
- return;
-}
-
-
-
-
-
-void readpng2_cleanup(mainprog_info *mainprog_ptr)
-{
- png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
- png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
-
- if (png_ptr && info_ptr)
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-
- mainprog_ptr->png_ptr = NULL;
- mainprog_ptr->info_ptr = NULL;
-}
-
-
-static void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg)
-{
- fprintf(stderr, "readpng2 libpng warning: %s\n", msg);
- fflush(stderr);
- (void)png_ptr; /* Unused */
-}
-
-
-static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
-{
- mainprog_info *mainprog_ptr;
-
- /* This function, aside from the extra step of retrieving the "error
- * pointer" (below) and the fact that it exists within the application
- * rather than within libpng, is essentially identical to libpng's
- * default error handler. The second point is critical: since both
- * setjmp() and longjmp() are called from the same code, they are
- * guaranteed to have compatible notions of how big a jmp_buf is,
- * regardless of whether _BSD_SOURCE or anything else has (or has not)
- * been defined. */
-
- fprintf(stderr, "readpng2 libpng error: %s\n", msg);
- fflush(stderr);
-
- mainprog_ptr = png_get_error_ptr(png_ptr);
- if (mainprog_ptr == NULL) { /* we are completely hosed now */
- fprintf(stderr,
- "readpng2 severe error: jmpbuf not recoverable; terminating.\n");
- fflush(stderr);
- exit(99);
- }
-
- /* Now we have our data structure we can use the information in it
- * to return control to our own higher level code (all the points
- * where 'setjmp' is called in this file.) This will work with other
- * error handling mechanisms as well - libpng always calls png_error
- * when it can proceed no further, thus, so long as the error handler
- * is intercepted, application code can do its own error recovery.
- */
- longjmp(mainprog_ptr->jmpbuf, 1);
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.h b/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.h
deleted file mode 100644
index 6b3660d7c17..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readpng2.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng2 - progressive-model PNG display program readpng2.h
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2008 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#ifndef TRUE
-# define TRUE 1
-# define FALSE 0
-#endif
-
-#ifndef MAX
-# define MAX(a,b) ((a) > (b)? (a) : (b))
-# define MIN(a,b) ((a) < (b)? (a) : (b))
-#endif
-
-#ifdef DEBUG
-# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
-#else
-# define Trace(x) ;
-#endif
-
-enum rpng2_states {
- kPreInit = 0,
- kWindowInit,
- kDone
-};
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-typedef struct _mainprog_info {
- double display_exponent;
- ulg width;
- ulg height;
- void *png_ptr;
- void *info_ptr;
- void (*mainprog_init)(void);
- void (*mainprog_display_row)(ulg row_num);
- void (*mainprog_finish_display)(void);
- uch *image_data;
- uch **row_pointers;
- jmp_buf jmpbuf;
- int passes; /* not used */
- int pass;
- int rowbytes;
- int channels;
- int need_bgcolor;
- int state;
- uch bg_red;
- uch bg_green;
- uch bg_blue;
-} mainprog_info;
-
-
-/* prototypes for public functions in readpng2.c */
-
-void readpng2_version_info(void);
-
-int readpng2_check_sig(uch *sig, int num);
-
-int readpng2_init(mainprog_info *mainprog_ptr);
-
-int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length);
-
-void readpng2_cleanup(mainprog_info *mainprog_ptr);
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readppm.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/readppm.c
deleted file mode 100644
index 52e70277713..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/readppm.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng - simple PNG display program readppm.c
-
- ---------------------------------------------------------------------------
-
- This is a special-purpose replacement for readpng.c that allows binary
- PPM files to be used in place of PNG images.
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2007,2017 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "readpng.h" /* typedefs, common macros, public prototypes */
-
-
-ulg width, height;
-int bit_depth, color_type, channels;
-uch *image_data = NULL;
-FILE *saved_infile;
-
-
-void readpng_version_info()
-{
- fprintf(stderr, " Compiled without libpng, zlib or PBMPLUS/NetPBM.\n");
-}
-
-
-/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
-
-int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
-{
- static uch ppmline[256];
- int maxval;
-
-
- saved_infile = infile;
-
- fgets(ppmline, 256, infile);
- if (ppmline[0] != 'P' || ppmline[1] != '6') {
- fprintf(stderr, "ERROR: not a PPM file\n");
- return 1;
- }
- /* possible color types: P5 = grayscale (0), P6 = RGB (2), P8 = RGBA (6) */
- if (ppmline[1] == '6') {
- color_type = 2;
- channels = 3;
- } else if (ppmline[1] == '8') {
- color_type = 6;
- channels = 4;
- } else /* if (ppmline[1] == '5') */ {
- color_type = 0;
- channels = 1;
- }
-
- do {
- fgets(ppmline, 256, infile);
- } while (ppmline[0] == '#');
- sscanf(ppmline, "%lu %lu", &width, &height);
-
- do {
- fgets(ppmline, 256, infile);
- } while (ppmline[0] == '#');
- sscanf(ppmline, "%d", &maxval);
- if (maxval != 255) {
- fprintf(stderr, "ERROR: maxval = %d\n", maxval);
- return 2;
- }
- bit_depth = 8;
-
- *pWidth = width;
- *pHeight = height;
-
- return 0;
-}
-
-
-
-
-/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;
- * scales values to 8-bit if necessary */
-
-int readpng_get_bgcolor(uch *red, uch *green, uch *blue)
-{
- return 1;
-}
-
-
-
-
-/* display_exponent == LUT_exponent * CRT_exponent */
-
-uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
-{
- ulg rowbytes;
-
-
- /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
- * transparency chunks to full alpha channel; strip 16-bit-per-sample
- * images to 8 bits per sample; and convert grayscale to RGB[A] */
-
- /* GRR WARNING: grayscale needs to be expanded and channels reset! */
-
- *pRowbytes = rowbytes = channels*width;
- *pChannels = channels;
-
- Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height));
-
- /* Guard against integer overflow */
- if (height > ((size_t)(-1))/rowbytes) {
- fprintf(stderr, PROGNAME ": image_data buffer would be too large\n",
- return NULL;
- }
-
- if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
- return NULL;
- }
-
- /* now we can go ahead and just read the whole image */
-
- if (fread(image_data, 1L, rowbytes*height, saved_infile) <
- rowbytes*height) {
- free (image_data);
- image_data = NULL;
- return NULL;
- }
-
- return image_data;
-}
-
-
-void readpng_cleanup(int free_image_data)
-{
- if (free_image_data && image_data) {
- free(image_data);
- image_data = NULL;
- }
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-win.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-win.c
deleted file mode 100644
index 1a6f876154d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-win.c
+++ /dev/null
@@ -1,735 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng - simple PNG display program rpng-win.c
-
- This program decodes and displays PNG images, with gamma correction and
- optionally with a user-specified background color (in case the image has
- transparency). It is very nearly the most basic PNG viewer possible.
- This version is for 32-bit Windows; it may compile under 16-bit Windows
- with a little tweaking (or maybe not).
-
- to do:
- - handle quoted command-line args (especially filenames with spaces)
- - have minimum window width: oh well
- - use %.1023s to simplify truncation of title-bar string?
-
- ---------------------------------------------------------------------------
-
- Changelog:
- - 1.00: initial public release
- - 1.01: modified to allow abbreviated options; fixed long/ulong mis-
- match; switched to png_jmpbuf() macro
- - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed
- command-line parsing bug
- - 1.10: enabled "message window"/console (thanks to David Geldreich)
- - 2.00: dual-licensed (added GNU GPL)
- - 2.01: fixed improper display of usage screen on PNG error(s)
- - 2.02: check for integer overflow (Glenn R-P)
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2008, 2017 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#define PROGNAME "rpng-win"
-#define LONGNAME "Simple PNG Viewer for Windows"
-#define VERSION "2.01 of 16 March 2008"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <windows.h>
-#ifdef __CYGWIN__
-/* getch replacement. Turns out, we don't really need this,
- * but leave it here if we ever enable any of the uses of
- * _getch in the main code
- */
-#include <unistd.h>
-#include <termio.h>
-#include <sys/ioctl.h>
-int repl_getch( void )
-{
- char ch;
- int fd = fileno(stdin);
- struct termio old_tty, new_tty;
-
- ioctl(fd, TCGETA, &old_tty);
- new_tty = old_tty;
- new_tty.c_lflag &= ~(ICANON | ECHO | ISIG);
- ioctl(fd, TCSETA, &new_tty);
- fread(&ch, 1, sizeof(ch), stdin);
- ioctl(fd, TCSETA, &old_tty);
-
- return ch;
-}
-#define _getch repl_getch
-#else
-#include <conio.h> /* only for _getch() */
-#endif
-
-/* #define DEBUG : this enables the Trace() macros */
-
-#include "readpng.h" /* typedefs, common macros, readpng prototypes */
-
-
-/* could just include png.h, but this macro is the only thing we need
- * (name and typedefs changed to local versions); note that side effects
- * only happen with alpha (which could easily be avoided with
- * "ush acopy = (alpha);") */
-
-#define alpha_composite(composite, fg, alpha, bg) { \
- ush temp = ((ush)(fg)*(ush)(alpha) + \
- (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
- (composite) = (uch)((temp + (temp >> 8)) >> 8); \
-}
-
-
-/* local prototypes */
-static int rpng_win_create_window(HINSTANCE hInst, int showmode);
-static int rpng_win_display_image(void);
-static void rpng_win_cleanup(void);
-LRESULT CALLBACK rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM);
-
-
-static char titlebar[1024];
-static char *progname = PROGNAME;
-static char *appname = LONGNAME;
-static char *filename;
-static FILE *infile;
-
-static char *bgstr;
-static uch bg_red=0, bg_green=0, bg_blue=0;
-
-static double display_exponent;
-
-static ulg image_width, image_height, image_rowbytes;
-static int image_channels;
-static uch *image_data;
-
-/* Windows-specific variables */
-static ulg wimage_rowbytes;
-static uch *dib;
-static uch *wimage_data;
-static BITMAPINFOHEADER *bmih;
-
-static HWND global_hwnd;
-
-
-
-
-int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
-{
- char *args[1024]; /* arbitrary limit, but should suffice */
- char *p, *q, **argv = args;
- int argc = 0;
- int rc, alen, flen;
- int error = 0;
- int have_bg = FALSE;
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
- MSG msg;
-
-
- filename = (char *)NULL;
-
-#ifndef __CYGWIN__
- /* First reenable console output, which normally goes to the bit bucket
- * for windowed apps. Closing the console window will terminate the
- * app. Thanks to David.Geldreich at realviz.com for supplying the magical
- * incantation. */
-
- AllocConsole();
- freopen("CONOUT$", "a", stderr);
- freopen("CONOUT$", "a", stdout);
-#endif
-
-
- /* Next set the default value for our display-system exponent, i.e.,
- * the product of the CRT exponent and the exponent corresponding to
- * the frame-buffer's lookup table (LUT), if any. This is not an
- * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
- * ones), but it should cover 99% of the current possibilities. And
- * yes, these ifdefs are completely wasted in a Windows program... */
-
-#if defined(NeXT)
- LUT_exponent = 1.0 / 2.2;
- /*
- if (some_next_function_that_returns_gamma(&next_gamma))
- LUT_exponent = 1.0 / next_gamma;
- */
-#elif defined(sgi)
- LUT_exponent = 1.0 / 1.7;
- /* there doesn't seem to be any documented function to get the
- * "gamma" value, so we do it the hard way */
- infile = fopen("/etc/config/system.glGammaVal", "r");
- if (infile) {
- double sgi_gamma;
-
- fgets(tmpline, 80, infile);
- fclose(infile);
- sgi_gamma = atof(tmpline);
- if (sgi_gamma > 0.0)
- LUT_exponent = 1.0 / sgi_gamma;
- }
-#elif defined(Macintosh)
- LUT_exponent = 1.8 / 2.61;
- /*
- if (some_mac_function_that_returns_gamma(&mac_gamma))
- LUT_exponent = mac_gamma / 2.61;
- */
-#else
- LUT_exponent = 1.0; /* assume no LUT: most PCs */
-#endif
-
- /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
- default_display_exponent = LUT_exponent * CRT_exponent;
-
-
- /* If the user has set the SCREEN_GAMMA environment variable as suggested
- * (somewhat imprecisely) in the libpng documentation, use that; otherwise
- * use the default value we just calculated. Either way, the user may
- * override this via a command-line option. */
-
- if ((p = getenv("SCREEN_GAMMA")) != NULL)
- display_exponent = atof(p);
- else
- display_exponent = default_display_exponent;
-
-
- /* Windows really hates command lines, so we have to set up our own argv.
- * Note that we do NOT bother with quoted arguments here, so don't use
- * filenames with spaces in 'em! */
-
- argv[argc++] = PROGNAME;
- p = cmd;
- for (;;) {
- if (*p == ' ')
- while (*++p == ' ')
- ;
- /* now p points at the first non-space after some spaces */
- if (*p == '\0')
- break; /* nothing after the spaces: done */
- argv[argc++] = q = p;
- while (*q && *q != ' ')
- ++q;
- /* now q points at a space or the end of the string */
- if (*q == '\0')
- break; /* last argv already terminated; quit */
- *q = '\0'; /* change space to terminator */
- p = q + 1;
- }
- argv[argc] = NULL; /* terminate the argv array itself */
-
-
- /* Now parse the command line for options and the PNG filename. */
-
- while (*++argv && !error) {
- if (!strncmp(*argv, "-gamma", 2)) {
- if (!*++argv)
- ++error;
- else {
- display_exponent = atof(*argv);
- if (display_exponent <= 0.0)
- ++error;
- }
- } else if (!strncmp(*argv, "-bgcolor", 2)) {
- if (!*++argv)
- ++error;
- else {
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
- else
- have_bg = TRUE;
- }
- } else {
- if (**argv != '-') {
- filename = *argv;
- if (argv[1]) /* shouldn't be any more args after filename */
- ++error;
- } else
- ++error; /* not expecting any other options */
- }
- }
-
- if (!filename)
- ++error;
-
-
- /* print usage screen if any errors up to this point */
-
- if (error) {
-#ifndef __CYGWIN__
- int ch;
-#endif
-
- fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
- readpng_version_info();
- fprintf(stderr, "\n"
- "Usage: %s [-gamma exp] [-bgcolor bg] file.png\n"
- " exp \ttransfer-function exponent (``gamma'') of the display\n"
- "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
- "\t\t to the product of the lookup-table exponent (varies)\n"
- "\t\t and the CRT exponent (usually 2.2); must be positive\n"
- " bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
- "\t\t used with transparent images\n"
- "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
-#ifndef __CYGWIN__
- "Press Q or Esc to quit this usage screen.\n"
-#endif
- "\n", PROGNAME, default_display_exponent);
-#ifndef __CYGWIN__
- do
- ch = _getch();
- while (ch != 'q' && ch != 'Q' && ch != 0x1B);
-#endif
- exit(1);
- }
-
-
- if (!(infile = fopen(filename, "rb"))) {
- fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
- ++error;
- } else {
- if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
- switch (rc) {
- case 1:
- fprintf(stderr, PROGNAME
- ": [%s] is not a PNG file: incorrect signature\n",
- filename);
- break;
- case 2:
- fprintf(stderr, PROGNAME
- ": [%s] has bad IHDR (libpng longjmp)\n", filename);
- break;
- case 4:
- fprintf(stderr, PROGNAME ": insufficient memory\n");
- break;
- default:
- fprintf(stderr, PROGNAME
- ": unknown readpng_init() error\n");
- break;
- }
- ++error;
- }
- if (error)
- fclose(infile);
- }
-
-
- if (error) {
-#ifndef __CYGWIN__
- int ch;
-#endif
-
- fprintf(stderr, PROGNAME ": aborting.\n");
-#ifndef __CYGWIN__
- do
- ch = _getch();
- while (ch != 'q' && ch != 'Q' && ch != 0x1B);
-#endif
- exit(2);
- } else {
- fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
-#ifndef __CYGWIN__
- fprintf(stderr,
- "\n [console window: closing this window will terminate %s]\n\n",
- PROGNAME);
-#endif
- }
-
-
- /* set the title-bar string, but make sure buffer doesn't overflow */
-
- alen = strlen(appname);
- flen = strlen(filename);
- if (alen + flen + 3 > 1023)
- sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
- else
- sprintf(titlebar, "%s: %s", appname, filename);
-
-
- /* if the user didn't specify a background color on the command line,
- * check for one in the PNG file--if not, the initialized values of 0
- * (black) will be used */
-
- if (have_bg) {
- unsigned r, g, b; /* this approach quiets compiler warnings */
-
- sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
- bg_red = (uch)r;
- bg_green = (uch)g;
- bg_blue = (uch)b;
- } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {
- readpng_cleanup(TRUE);
- fprintf(stderr, PROGNAME
- ": libpng error while checking for background color\n");
- exit(2);
- }
-
-
- /* do the basic Windows initialization stuff, make the window and fill it
- * with the background color */
-
- if (rpng_win_create_window(hInst, showmode))
- exit(2);
-
-
- /* decode the image, all at once */
-
- Trace((stderr, "calling readpng_get_image()\n"))
- image_data = readpng_get_image(display_exponent, &image_channels,
- &image_rowbytes);
- Trace((stderr, "done with readpng_get_image()\n"))
-
-
- /* done with PNG file, so clean up to minimize memory usage (but do NOT
- * nuke image_data!) */
-
- readpng_cleanup(FALSE);
- fclose(infile);
-
- if (!image_data) {
- fprintf(stderr, PROGNAME ": unable to decode PNG image\n");
- exit(3);
- }
-
-
- /* display image (composite with background if requested) */
-
- Trace((stderr, "calling rpng_win_display_image()\n"))
- if (rpng_win_display_image()) {
- free(image_data);
- exit(4);
- }
- Trace((stderr, "done with rpng_win_display_image()\n"))
-
-
- /* wait for the user to tell us when to quit */
-
- printf(
-#ifndef __CYGWIN__
- "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"
-#else
- "Done. Press mouse button 1 (within image window) to quit.\n"
-#endif
- );
- fflush(stdout);
-
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
-
- /* OK, we're done: clean up all image and Windows resources and go away */
-
- rpng_win_cleanup();
-
- return msg.wParam;
-}
-
-
-
-
-
-static int rpng_win_create_window(HINSTANCE hInst, int showmode)
-{
- uch *dest;
- int extra_width, extra_height;
- ulg i, j;
- WNDCLASSEX wndclass;
-
-
-/*---------------------------------------------------------------------------
- Allocate memory for the display-specific version of the image (round up
- to multiple of 4 for Windows DIB).
- ---------------------------------------------------------------------------*/
-
- wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2;
-
- /* Guard against integer overflow */
- if (image_height > ((size_t)(-1))/wimage_rowbytes) {
- fprintf(stderr, PROGNAME ": image_data buffer would be too large\n");
- return 4; /* fail */
- }
-
- if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
- wimage_rowbytes*image_height)))
- {
- return 4; /* fail */
- }
-
-/*---------------------------------------------------------------------------
- Initialize the DIB. Negative height means to use top-down BMP ordering
- (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8
- implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values
- directly => wimage_data begins immediately after BMP header.
- ---------------------------------------------------------------------------*/
-
- memset(dib, 0, sizeof(BITMAPINFOHEADER));
- bmih = (BITMAPINFOHEADER *)dib;
- bmih->biSize = sizeof(BITMAPINFOHEADER);
- bmih->biWidth = image_width;
- bmih->biHeight = -((long)image_height);
- bmih->biPlanes = 1;
- bmih->biBitCount = 24;
- bmih->biCompression = 0;
- wimage_data = dib + sizeof(BITMAPINFOHEADER);
-
-/*---------------------------------------------------------------------------
- Fill in background color (black by default); data are in BGR order.
- ---------------------------------------------------------------------------*/
-
- for (j = 0; j < image_height; ++j) {
- dest = wimage_data + j*wimage_rowbytes;
- for (i = image_width; i > 0; --i) {
- *dest++ = bg_blue;
- *dest++ = bg_green;
- *dest++ = bg_red;
- }
- }
-
-/*---------------------------------------------------------------------------
- Set the window parameters.
- ---------------------------------------------------------------------------*/
-
- memset(&wndclass, 0, sizeof(wndclass));
-
- wndclass.cbSize = sizeof(wndclass);
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = rpng_win_wndproc;
- wndclass.hInstance = hInst;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = progname;
- wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
-
- RegisterClassEx(&wndclass);
-
-/*---------------------------------------------------------------------------
- Finally, create the window.
- ---------------------------------------------------------------------------*/
-
- extra_width = 2*(GetSystemMetrics(SM_CXBORDER) +
- GetSystemMetrics(SM_CXDLGFRAME));
- extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +
- GetSystemMetrics(SM_CYDLGFRAME)) +
- GetSystemMetrics(SM_CYCAPTION);
-
- global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width,
- image_height+extra_height, NULL, NULL, hInst, NULL);
-
- ShowWindow(global_hwnd, showmode);
- UpdateWindow(global_hwnd);
-
- return 0;
-
-} /* end function rpng_win_create_window() */
-
-
-
-
-
-static int rpng_win_display_image()
-{
- uch *src, *dest;
- uch r, g, b, a;
- ulg i, row, lastrow;
- RECT rect;
-
-
- Trace((stderr, "beginning display loop (image_channels == %d)\n",
- image_channels))
- Trace((stderr, "(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n",
- image_width, image_rowbytes, wimage_rowbytes))
-
-
-/*---------------------------------------------------------------------------
- Blast image data to buffer. This whole routine takes place before the
- message loop begins, so there's no real point in any pseudo-progressive
- display...
- ---------------------------------------------------------------------------*/
-
- for (lastrow = row = 0; row < image_height; ++row) {
- src = image_data + row*image_rowbytes;
- dest = wimage_data + row*wimage_rowbytes;
- if (image_channels == 3) {
- for (i = image_width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- *dest++ = b;
- *dest++ = g; /* note reverse order */
- *dest++ = r;
- }
- } else /* if (image_channels == 4) */ {
- for (i = image_width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (a == 255) {
- *dest++ = b;
- *dest++ = g;
- *dest++ = r;
- } else if (a == 0) {
- *dest++ = bg_blue;
- *dest++ = bg_green;
- *dest++ = bg_red;
- } else {
- /* this macro (copied from png.h) composites the
- * foreground and background values and puts the
- * result into the first argument; there are no
- * side effects with the first argument */
- alpha_composite(*dest++, b, a, bg_blue);
- alpha_composite(*dest++, g, a, bg_green);
- alpha_composite(*dest++, r, a, bg_red);
- }
- }
- }
- /* display after every 16 lines */
- if (((row+1) & 0xf) == 0) {
- rect.left = 0L;
- rect.top = (LONG)lastrow;
- rect.right = (LONG)image_width; /* possibly off by one? */
- rect.bottom = (LONG)lastrow + 16L; /* possibly off by one? */
- InvalidateRect(global_hwnd, &rect, FALSE);
- UpdateWindow(global_hwnd); /* similar to XFlush() */
- lastrow = row + 1;
- }
- }
-
- Trace((stderr, "calling final image-flush routine\n"))
- if (lastrow < image_height) {
- rect.left = 0L;
- rect.top = (LONG)lastrow;
- rect.right = (LONG)image_width; /* possibly off by one? */
- rect.bottom = (LONG)image_height; /* possibly off by one? */
- InvalidateRect(global_hwnd, &rect, FALSE);
- UpdateWindow(global_hwnd); /* similar to XFlush() */
- }
-
-/*
- last param determines whether or not background is wiped before paint
- InvalidateRect(global_hwnd, NULL, TRUE);
- UpdateWindow(global_hwnd);
- */
-
- return 0;
-}
-
-
-
-
-
-static void rpng_win_cleanup()
-{
- if (image_data) {
- free(image_data);
- image_data = NULL;
- }
-
- if (dib) {
- free(dib);
- dib = NULL;
- }
-}
-
-
-
-
-
-LRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
-{
- HDC hdc;
- PAINTSTRUCT ps;
- int rc;
-
- switch (iMsg) {
- case WM_CREATE:
- /* one-time processing here, if any */
- return 0;
-
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- /* dest */
- rc = StretchDIBits(hdc, 0, 0, image_width, image_height,
- /* source */
- 0, 0, image_width, image_height,
- wimage_data, (BITMAPINFO *)bmih,
- /* iUsage: no clue */
- 0, SRCCOPY);
- EndPaint(hwnd, &ps);
- return 0;
-
- /* wait for the user to tell us when to quit */
- case WM_CHAR:
- switch (wP) { /* only need one, so ignore repeat count */
- case 'q':
- case 'Q':
- case 0x1B: /* Esc key */
- PostQuitMessage(0);
- }
- return 0;
-
- case WM_LBUTTONDOWN: /* another way of quitting */
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
-
- return DefWindowProc(hwnd, iMsg, wP, lP);
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-x.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-x.c
deleted file mode 100644
index 92effaa6d29..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng-x.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng - simple PNG display program rpng-x.c
-
- This program decodes and displays PNG images, with gamma correction and
- optionally with a user-specified background color (in case the image has
- transparency). It is very nearly the most basic PNG viewer possible.
- This version is for the X Window System (tested by author under Unix and
- by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking).
-
- to do:
- - 8-bit (colormapped) X support
- - use %.1023s to simplify truncation of title-bar string?
-
- ---------------------------------------------------------------------------
-
- Changelog:
- - 1.01: initial public release
- - 1.02: modified to allow abbreviated options; fixed long/ulong mis-
- match; switched to png_jmpbuf() macro
- - 1.10: added support for non-default visuals; fixed X pixel-conversion
- - 1.11: added extra set of parentheses to png_jmpbuf() macro; fixed
- command-line parsing bug
- - 1.12: fixed some small X memory leaks (thanks to François Petitjean)
- - 1.13: fixed XFreeGC() crash bug (thanks to Patrick Welche)
- - 1.14: added support for X resources (thanks to Gerhard Niklasch)
- - 2.00: dual-licensed (added GNU GPL)
- - 2.01: fixed improper display of usage screen on PNG error(s)
- - 2.02: Added "void(argc);" statement to quiet pedantic compiler warnings
- about unused variable (GR-P)
- - 2.03: check for integer overflow (Glenn R-P)
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2008, 2017 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#define PROGNAME "rpng-x"
-#define LONGNAME "Simple PNG Viewer for X"
-#define VERSION "2.02 of 15 June 2014"
-#define RESNAME "rpng" /* our X resource application name */
-#define RESCLASS "Rpng" /* our X resource class name */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#include <X11/keysym.h>
-
-/* #define DEBUG : this enables the Trace() macros */
-
-#include "readpng.h" /* typedefs, common macros, readpng prototypes */
-
-
-/* could just include png.h, but this macro is the only thing we need
- * (name and typedefs changed to local versions); note that side effects
- * only happen with alpha (which could easily be avoided with
- * "ush acopy = (alpha);") */
-
-#define alpha_composite(composite, fg, alpha, bg) { \
- ush temp = ((ush)(fg)*(ush)(alpha) + \
- (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
- (composite) = (uch)((temp + (temp >> 8)) >> 8); \
-}
-
-
-/* local prototypes */
-static int rpng_x_create_window(void);
-static int rpng_x_display_image(void);
-static void rpng_x_cleanup(void);
-static int rpng_x_msb(ulg u32val);
-
-
-static char titlebar[1024], *window_name = titlebar;
-static char *appname = LONGNAME;
-static char *icon_name = PROGNAME;
-static char *res_name = RESNAME;
-static char *res_class = RESCLASS;
-static char *filename;
-static FILE *infile;
-
-static char *bgstr;
-static uch bg_red=0, bg_green=0, bg_blue=0;
-
-static double display_exponent;
-
-static ulg image_width, image_height, image_rowbytes;
-static int image_channels;
-static uch *image_data;
-
-/* X-specific variables */
-static char *displayname;
-static XImage *ximage;
-static Display *display;
-static int depth;
-static Visual *visual;
-static XVisualInfo *visual_list;
-static int RShift, GShift, BShift;
-static ulg RMask, GMask, BMask;
-static Window window;
-static GC gc;
-static Colormap colormap;
-
-static int have_nondefault_visual = FALSE;
-static int have_colormap = FALSE;
-static int have_window = FALSE;
-static int have_gc = FALSE;
-/*
-ulg numcolors=0, pixels[256];
-ush reds[256], greens[256], blues[256];
- */
-
-
-
-
-int main(int argc, char **argv)
-{
-#ifdef sgi
- char tmpline[80];
-#endif
- char *p;
- int rc, alen, flen;
- int error = 0;
- int have_bg = FALSE;
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
- XEvent e;
- KeySym k;
-
-
- displayname = (char *)NULL;
- filename = (char *)NULL;
-
-
- /* First set the default value for our display-system exponent, i.e.,
- * the product of the CRT exponent and the exponent corresponding to
- * the frame-buffer's lookup table (LUT), if any. This is not an
- * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
- * ones), but it should cover 99% of the current possibilities. */
-
-#if defined(NeXT)
- LUT_exponent = 1.0 / 2.2;
- /*
- if (some_next_function_that_returns_gamma(&next_gamma))
- LUT_exponent = 1.0 / next_gamma;
- */
-#elif defined(sgi)
- LUT_exponent = 1.0 / 1.7;
- /* there doesn't seem to be any documented function to get the
- * "gamma" value, so we do it the hard way */
- infile = fopen("/etc/config/system.glGammaVal", "r");
- if (infile) {
- double sgi_gamma;
-
- fgets(tmpline, 80, infile);
- fclose(infile);
- sgi_gamma = atof(tmpline);
- if (sgi_gamma > 0.0)
- LUT_exponent = 1.0 / sgi_gamma;
- }
-#elif defined(Macintosh)
- LUT_exponent = 1.8 / 2.61;
- /*
- if (some_mac_function_that_returns_gamma(&mac_gamma))
- LUT_exponent = mac_gamma / 2.61;
- */
-#else
- LUT_exponent = 1.0; /* assume no LUT: most PCs */
-#endif
-
- /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
- default_display_exponent = LUT_exponent * CRT_exponent;
-
-
- /* If the user has set the SCREEN_GAMMA environment variable as suggested
- * (somewhat imprecisely) in the libpng documentation, use that; otherwise
- * use the default value we just calculated. Either way, the user may
- * override this via a command-line option. */
-
- if ((p = getenv("SCREEN_GAMMA")) != NULL)
- display_exponent = atof(p);
- else
- display_exponent = default_display_exponent;
-
-
- /* Now parse the command line for options and the PNG filename. */
-
- while (*++argv && !error) {
- if (!strncmp(*argv, "-display", 2)) {
- if (!*++argv)
- ++error;
- else
- displayname = *argv;
- } else if (!strncmp(*argv, "-gamma", 2)) {
- if (!*++argv)
- ++error;
- else {
- display_exponent = atof(*argv);
- if (display_exponent <= 0.0)
- ++error;
- }
- } else if (!strncmp(*argv, "-bgcolor", 2)) {
- if (!*++argv)
- ++error;
- else {
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
- else
- have_bg = TRUE;
- }
- } else {
- if (**argv != '-') {
- filename = *argv;
- if (argv[1]) /* shouldn't be any more args after filename */
- ++error;
- } else
- ++error; /* not expecting any other options */
- }
- }
-
- if (!filename)
- ++error;
-
-
- /* print usage screen if any errors up to this point */
-
- if (error) {
- fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
- readpng_version_info();
- fprintf(stderr, "\n"
- "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n"
- " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
- " exp \ttransfer-function exponent (``gamma'') of the display\n"
- "\t\t system in floating-point format (e.g., ``%.1f''); equal\n",
- PROGNAME, default_display_exponent);
-
- fprintf(stderr, "\n"
- "\t\t to the product of the lookup-table exponent (varies)\n"
- "\t\t and the CRT exponent (usually 2.2); must be positive\n"
- " bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
- "\t\t used with transparent images\n"
- "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
- "is displayed) to quit.\n");
- exit(1);
- }
-
-
- if (!(infile = fopen(filename, "rb"))) {
- fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
- ++error;
- } else {
- if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
- switch (rc) {
- case 1:
- fprintf(stderr, PROGNAME
- ": [%s] is not a PNG file: incorrect signature\n",
- filename);
- break;
- case 2:
- fprintf(stderr, PROGNAME
- ": [%s] has bad IHDR (libpng longjmp)\n", filename);
- break;
- case 4:
- fprintf(stderr, PROGNAME ": insufficient memory\n");
- break;
- default:
- fprintf(stderr, PROGNAME
- ": unknown readpng_init() error\n");
- break;
- }
- ++error;
- } else {
- display = XOpenDisplay(displayname);
- if (!display) {
- readpng_cleanup(TRUE);
- fprintf(stderr, PROGNAME ": can't open X display [%s]\n",
- displayname? displayname : "default");
- ++error;
- }
- }
- if (error)
- fclose(infile);
- }
-
-
- if (error) {
- fprintf(stderr, PROGNAME ": aborting.\n");
- exit(2);
- }
-
-
- /* set the title-bar string, but make sure buffer doesn't overflow */
-
- alen = strlen(appname);
- flen = strlen(filename);
- if (alen + flen + 3 > 1023)
- sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
- else
- sprintf(titlebar, "%s: %s", appname, filename);
-
-
- /* if the user didn't specify a background color on the command line,
- * check for one in the PNG file--if not, the initialized values of 0
- * (black) will be used */
-
- if (have_bg) {
- unsigned r, g, b; /* this approach quiets compiler warnings */
-
- sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
- bg_red = (uch)r;
- bg_green = (uch)g;
- bg_blue = (uch)b;
- } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) {
- readpng_cleanup(TRUE);
- fprintf(stderr, PROGNAME
- ": libpng error while checking for background color\n");
- exit(2);
- }
-
-
- /* do the basic X initialization stuff, make the window and fill it
- * with the background color */
-
- if (rpng_x_create_window())
- exit(2);
-
-
- /* decode the image, all at once */
-
- Trace((stderr, "calling readpng_get_image()\n"))
- image_data = readpng_get_image(display_exponent, &image_channels,
- &image_rowbytes);
- Trace((stderr, "done with readpng_get_image()\n"))
-
-
- /* done with PNG file, so clean up to minimize memory usage (but do NOT
- * nuke image_data!) */
-
- readpng_cleanup(FALSE);
- fclose(infile);
-
- if (!image_data) {
- fprintf(stderr, PROGNAME ": unable to decode PNG image\n");
- exit(3);
- }
-
-
- /* display image (composite with background if requested) */
-
- Trace((stderr, "calling rpng_x_display_image()\n"))
- if (rpng_x_display_image()) {
- free(image_data);
- exit(4);
- }
- Trace((stderr, "done with rpng_x_display_image()\n"))
-
-
- /* wait for the user to tell us when to quit */
-
- printf(
- "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
- fflush(stdout);
-
- do
- XNextEvent(display, &e);
- while (!(e.type == ButtonPress && e.xbutton.button == Button1) &&
- !(e.type == KeyPress && /* v--- or 1 for shifted keys */
- ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) ));
-
-
- /* OK, we're done: clean up all image and X resources and go away */
-
- rpng_x_cleanup();
-
- (void)argc; /* Unused */
-
- return 0;
-}
-
-
-
-
-
-static int rpng_x_create_window(void)
-{
- uch *xdata;
- int need_colormap = FALSE;
- int screen, pad;
- ulg bg_pixel = 0L;
- ulg attrmask;
- Window root;
- XEvent e;
- XGCValues gcvalues;
- XSetWindowAttributes attr;
- XTextProperty windowName, *pWindowName = &windowName;
- XTextProperty iconName, *pIconName = &iconName;
- XVisualInfo visual_info;
- XSizeHints *size_hints;
- XWMHints *wm_hints;
- XClassHint *class_hints;
-
-
- screen = DefaultScreen(display);
- depth = DisplayPlanes(display, screen);
- root = RootWindow(display, screen);
-
-#ifdef DEBUG
- XSynchronize(display, True);
-#endif
-
-#if 0
-/* GRR: add 8-bit support */
- if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {
- fprintf(stderr,
- "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n",
- depth);
- return 2;
- }
-
- XMatchVisualInfo(display, screen, depth,
- (depth == 8)? PseudoColor : TrueColor, &visual_info);
- visual = visual_info.visual;
-#else
- if (depth != 16 && depth != 24 && depth != 32) {
- int visuals_matched = 0;
-
- Trace((stderr, "default depth is %d: checking other visuals\n",
- depth))
-
- /* 24-bit first */
- visual_info.screen = screen;
- visual_info.depth = 24;
- visual_list = XGetVisualInfo(display,
- VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
- if (visuals_matched == 0) {
-/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
- fprintf(stderr, "default screen depth %d not supported, and no"
- " 24-bit visuals found\n", depth);
- return 2;
- }
- Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
- visuals_matched))
- visual = visual_list[0].visual;
- depth = visual_list[0].depth;
-/*
- colormap_size = visual_list[0].colormap_size;
- visual_class = visual->class;
- visualID = XVisualIDFromVisual(visual);
- */
- have_nondefault_visual = TRUE;
- need_colormap = TRUE;
- } else {
- XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
- visual = visual_info.visual;
- }
-#endif
-
- RMask = visual->red_mask;
- GMask = visual->green_mask;
- BMask = visual->blue_mask;
-
-/* GRR: add/check 8-bit support */
- if (depth == 8 || need_colormap) {
- colormap = XCreateColormap(display, root, visual, AllocNone);
- if (!colormap) {
- fprintf(stderr, "XCreateColormap() failed\n");
- return 2;
- }
- have_colormap = TRUE;
- }
- if (depth == 15 || depth == 16) {
- RShift = 15 - rpng_x_msb(RMask); /* these are right-shifts */
- GShift = 15 - rpng_x_msb(GMask);
- BShift = 15 - rpng_x_msb(BMask);
- } else if (depth > 16) {
-#define NO_24BIT_MASKS
-#ifdef NO_24BIT_MASKS
- RShift = rpng_x_msb(RMask) - 7; /* these are left-shifts */
- GShift = rpng_x_msb(GMask) - 7;
- BShift = rpng_x_msb(BMask) - 7;
-#else
- RShift = 7 - rpng_x_msb(RMask); /* these are right-shifts, too */
- GShift = 7 - rpng_x_msb(GMask);
- BShift = 7 - rpng_x_msb(BMask);
-#endif
- }
- if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
- fprintf(stderr, "rpng internal logic error: negative X shift(s)!\n");
- return 2;
- }
-
-/*---------------------------------------------------------------------------
- Finally, create the window.
- ---------------------------------------------------------------------------*/
-
- attr.backing_store = Always;
- attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
- attrmask = CWBackingStore | CWEventMask;
- if (have_nondefault_visual) {
- attr.colormap = colormap;
- attr.background_pixel = 0;
- attr.border_pixel = 1;
- attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
- }
-
- window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0,
- depth, InputOutput, visual, attrmask, &attr);
-
- if (window == None) {
- fprintf(stderr, "XCreateWindow() failed\n");
- return 2;
- } else
- have_window = TRUE;
-
- if (depth == 8)
- XSetWindowColormap(display, window, colormap);
-
- if (!XStringListToTextProperty(&window_name, 1, pWindowName))
- pWindowName = NULL;
- if (!XStringListToTextProperty(&icon_name, 1, pIconName))
- pIconName = NULL;
-
- /* OK if any hints allocation fails; XSetWMProperties() allows NULLs */
-
- if ((size_hints = XAllocSizeHints()) != NULL) {
- /* window will not be resizable */
- size_hints->flags = PMinSize | PMaxSize;
- size_hints->min_width = size_hints->max_width = (int)image_width;
- size_hints->min_height = size_hints->max_height = (int)image_height;
- }
-
- if ((wm_hints = XAllocWMHints()) != NULL) {
- wm_hints->initial_state = NormalState;
- wm_hints->input = True;
- /* wm_hints->icon_pixmap = icon_pixmap; */
- wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ;
- }
-
- if ((class_hints = XAllocClassHint()) != NULL) {
- class_hints->res_name = res_name;
- class_hints->res_class = res_class;
- }
-
- XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
- size_hints, wm_hints, class_hints);
-
- /* various properties and hints no longer needed; free memory */
- if (pWindowName)
- XFree(pWindowName->value);
- if (pIconName)
- XFree(pIconName->value);
- if (size_hints)
- XFree(size_hints);
- if (wm_hints)
- XFree(wm_hints);
- if (class_hints)
- XFree(class_hints);
-
- XMapWindow(display, window);
-
- gc = XCreateGC(display, window, 0, &gcvalues);
- have_gc = TRUE;
-
-/*---------------------------------------------------------------------------
- Fill window with the specified background color.
- ---------------------------------------------------------------------------*/
-
- if (depth == 24 || depth == 32) {
- bg_pixel = ((ulg)bg_red << RShift) |
- ((ulg)bg_green << GShift) |
- ((ulg)bg_blue << BShift);
- } else if (depth == 16) {
- bg_pixel = ((((ulg)bg_red << 8) >> RShift) & RMask) |
- ((((ulg)bg_green << 8) >> GShift) & GMask) |
- ((((ulg)bg_blue << 8) >> BShift) & BMask);
- } else /* depth == 8 */ {
-
- /* GRR: add 8-bit support */
-
- }
-
- XSetForeground(display, gc, bg_pixel);
- XFillRectangle(display, window, gc, 0, 0, image_width, image_height);
-
-/*---------------------------------------------------------------------------
- Wait for first Expose event to do any drawing, then flush.
- ---------------------------------------------------------------------------*/
-
- do
- XNextEvent(display, &e);
- while (e.type != Expose || e.xexpose.count);
-
- XFlush(display);
-
-/*---------------------------------------------------------------------------
- Allocate memory for the X- and display-specific version of the image.
- ---------------------------------------------------------------------------*/
-
- if (depth == 24 || depth == 32) {
- xdata = (uch *)malloc(4*image_width*image_height);
- pad = 32;
- } else if (depth == 16) {
- xdata = (uch *)malloc(2*image_width*image_height);
- pad = 16;
- } else /* depth == 8 */ {
- xdata = (uch *)malloc(image_width*image_height);
- pad = 8;
- }
-
- if (!xdata) {
- fprintf(stderr, PROGNAME ": unable to allocate image memory\n");
- return 4;
- }
-
- ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
- (char *)xdata, image_width, image_height, pad, 0);
-
- if (!ximage) {
- fprintf(stderr, PROGNAME ": XCreateImage() failed\n");
- free(xdata);
- return 3;
- }
-
- /* to avoid testing the byte order every pixel (or doubling the size of
- * the drawing routine with a giant if-test), we arbitrarily set the byte
- * order to MSBFirst and let Xlib worry about inverting things on little-
- * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most
- * efficient approach (the giant if-test would be better), but in the
- * interest of clarity, we take the easy way out... */
-
- ximage->byte_order = MSBFirst;
-
- return 0;
-
-} /* end function rpng_x_create_window() */
-
-
-
-
-
-static int rpng_x_display_image(void)
-{
- uch *src;
- char *dest;
- uch r, g, b, a;
- ulg i, row, lastrow = 0;
- ulg pixel;
- int ximage_rowbytes = ximage->bytes_per_line;
-/* int bpp = ximage->bits_per_pixel; */
-
-
- Trace((stderr, "beginning display loop (image_channels == %d)\n",
- image_channels))
- Trace((stderr, " (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
- image_width, image_rowbytes, ximage_rowbytes))
- Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel))
- Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst?
- "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
-
- if (depth == 24 || depth == 32) {
- ulg red, green, blue;
-
- for (lastrow = row = 0; row < image_height; ++row) {
- src = image_data + row*image_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- if (image_channels == 3) {
- for (i = image_width; i > 0; --i) {
- red = *src++;
- green = *src++;
- blue = *src++;
-#ifdef NO_24BIT_MASKS
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- /* GRR BUG: this assumes bpp == 32, but may be 24: */
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
-#else
- red = (RShift < 0)? red << (-RShift) : red >> RShift;
- green = (GShift < 0)? green << (-GShift) : green >> GShift;
- blue = (BShift < 0)? blue << (-BShift) : blue >> BShift;
- pixel = (red & RMask) | (green & GMask) | (blue & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
-#endif
- }
- } else /* if (image_channels == 4) */ {
- for (i = image_width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (a == 255) {
- red = r;
- green = g;
- blue = b;
- } else if (a == 0) {
- red = bg_red;
- green = bg_green;
- blue = bg_blue;
- } else {
- /* this macro (from png.h) composites the foreground
- * and background values and puts the result into the
- * first argument */
- alpha_composite(red, r, a, bg_red);
- alpha_composite(green, g, a, bg_green);
- alpha_composite(blue, b, a, bg_blue);
- }
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
- /* display after every 16 lines */
- if (((row+1) & 0xf) == 0) {
- XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
- (int)lastrow, image_width, 16);
- XFlush(display);
- lastrow = row + 1;
- }
- }
-
- } else if (depth == 16) {
- ush red, green, blue;
-
- for (lastrow = row = 0; row < image_height; ++row) {
- src = image_data + row*image_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- if (image_channels == 3) {
- for (i = image_width; i > 0; --i) {
- red = ((ush)(*src) << 8);
- ++src;
- green = ((ush)(*src) << 8);
- ++src;
- blue = ((ush)(*src) << 8);
- ++src;
- pixel = ((red >> RShift) & RMask) |
- ((green >> GShift) & GMask) |
- ((blue >> BShift) & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- } else /* if (image_channels == 4) */ {
- for (i = image_width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (a == 255) {
- red = ((ush)r << 8);
- green = ((ush)g << 8);
- blue = ((ush)b << 8);
- } else if (a == 0) {
- red = ((ush)bg_red << 8);
- green = ((ush)bg_green << 8);
- blue = ((ush)bg_blue << 8);
- } else {
- /* this macro (from png.h) composites the foreground
- * and background values and puts the result back into
- * the first argument (== fg byte here: safe) */
- alpha_composite(r, r, a, bg_red);
- alpha_composite(g, g, a, bg_green);
- alpha_composite(b, b, a, bg_blue);
- red = ((ush)r << 8);
- green = ((ush)g << 8);
- blue = ((ush)b << 8);
- }
- pixel = ((red >> RShift) & RMask) |
- ((green >> GShift) & GMask) |
- ((blue >> BShift) & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
- /* display after every 16 lines */
- if (((row+1) & 0xf) == 0) {
- XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
- (int)lastrow, image_width, 16);
- XFlush(display);
- lastrow = row + 1;
- }
- }
-
- } else /* depth == 8 */ {
-
- /* GRR: add 8-bit support */
-
- }
-
- Trace((stderr, "calling final XPutImage()\n"))
- if (lastrow < image_height) {
- XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
- (int)lastrow, image_width, image_height-lastrow);
- XFlush(display);
- }
-
- return 0;
-}
-
-
-
-
-static void rpng_x_cleanup(void)
-{
- if (image_data) {
- free(image_data);
- image_data = NULL;
- }
-
- if (ximage) {
- if (ximage->data) {
- free(ximage->data); /* we allocated it, so we free it */
- ximage->data = (char *)NULL; /* instead of XDestroyImage() */
- }
- XDestroyImage(ximage);
- ximage = NULL;
- }
-
- if (have_gc)
- XFreeGC(display, gc);
-
- if (have_window)
- XDestroyWindow(display, window);
-
- if (have_colormap)
- XFreeColormap(display, colormap);
-
- if (have_nondefault_visual)
- XFree(visual_list);
-}
-
-
-
-
-
-static int rpng_x_msb(ulg u32val)
-{
- int i;
-
- for (i = 31; i >= 0; --i) {
- if (u32val & 0x80000000L)
- break;
- u32val <<= 1;
- }
- return i;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-win.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-win.c
deleted file mode 100644
index ed6b526ecb9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-win.c
+++ /dev/null
@@ -1,1261 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng2 - progressive-model PNG display program rpng2-win.c
-
- This program decodes and displays PNG files progressively, as if it were
- a web browser (though the front end is only set up to read from files).
- It supports gamma correction, user-specified background colors, and user-
- specified background patterns (for transparent images). This version is
- for 32-bit Windows; it may compile under 16-bit Windows with a little
- tweaking (or maybe not). Thanks to Adam Costello and Pieter S. van der
- Meulen for the "diamond" and "radial waves" patterns, respectively.
-
- to do (someday, maybe):
- - handle quoted command-line args (especially filenames with spaces)
- - finish resizable checkerboard-gradient (sizes 4-128?)
- - use %.1023s to simplify truncation of title-bar string?
- - have minimum window width: oh well
-
- ---------------------------------------------------------------------------
-
- Changelog:
- - 1.01: initial public release
- - 1.02: fixed cut-and-paste error in usage screen (oops...)
- - 1.03: modified to allow abbreviated options
- - 1.04: removed bogus extra argument from usage fprintf() [Glenn R-P?];
- fixed command-line parsing bug
- - 1.10: enabled "message window"/console (thanks to David Geldreich)
- - 1.20: added runtime MMX-enabling/disabling and new -mmx* options
- - 1.21: made minor tweak to usage screen to fit within 25-line console
- - 1.22: added AMD64/EM64T support (__x86_64__)
- - 2.00: dual-licensed (added GNU GPL)
- - 2.01: fixed 64-bit typo in readpng2.c
- - 2.02: fixed improper display of usage screen on PNG error(s); fixed
- unexpected-EOF and file-read-error cases
- - 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options
- - 2.04: check for integer overflow (Glenn R-P)
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2008, 2017 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#define PROGNAME "rpng2-win"
-#define LONGNAME "Progressive PNG Viewer for Windows"
-#define VERSION "2.02 of 16 March 2008"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
-#include <time.h>
-#include <math.h> /* only for PvdM background code */
-#include <windows.h>
-#ifdef __CYGWIN__
-/* getch replacement. Turns out, we don't really need this,
- * but leave it here if we ever enable any of the uses of
- * _getch in the main code
- */
-#include <unistd.h>
-#include <termio.h>
-#include <sys/ioctl.h>
-int repl_getch( void )
-{
- char ch;
- int fd = fileno(stdin);
- struct termio old_tty, new_tty;
-
- ioctl(fd, TCGETA, &old_tty);
- new_tty = old_tty;
- new_tty.c_lflag &= ~(ICANON | ECHO | ISIG);
- ioctl(fd, TCSETA, &new_tty);
- fread(&ch, 1, sizeof(ch), stdin);
- ioctl(fd, TCSETA, &old_tty);
-
- return ch;
-}
-#define _getch repl_getch
-#else
-#include <conio.h> /* only for _getch() */
-#endif
-
-/* all for PvdM background code: */
-#ifndef PI
-# define PI 3.141592653589793238
-#endif
-#define PI_2 (PI*0.5)
-#define INV_PI_360 (360.0 / PI)
-#define MAX(a,b) (a>b?a:b)
-#define MIN(a,b) (a<b?a:b)
-#define CLIP(a,min,max) MAX(min,MIN((a),max))
-#define ABS(a) ((a)<0?-(a):(a))
-#define CLIP8P(c) MAX(0,(MIN((c),255))) /* 8-bit pos. integer (uch) */
-#define ROUNDF(f) ((int)(f + 0.5))
-
-#define rgb1_max bg_freq
-#define rgb1_min bg_gray
-#define rgb2_max bg_bsat
-#define rgb2_min bg_brot
-
-/* #define DEBUG */ /* this enables the Trace() macros */
-
-#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
-
-
-/* could just include png.h, but this macro is the only thing we need
- * (name and typedefs changed to local versions); note that side effects
- * only happen with alpha (which could easily be avoided with
- * "ush acopy = (alpha);") */
-
-#define alpha_composite(composite, fg, alpha, bg) { \
- ush temp = ((ush)(fg)*(ush)(alpha) + \
- (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
- (composite) = (uch)((temp + (temp >> 8)) >> 8); \
-}
-
-
-#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
- * block size corresponds roughly to a download
- * speed 10% faster than theoretical 33.6K maximum
- * (assuming 8 data bits, 1 stop bit and no other
- * overhead) */
-
-/* local prototypes */
-static void rpng2_win_init(void);
-static int rpng2_win_create_window(void);
-static int rpng2_win_load_bg_image(void);
-static void rpng2_win_display_row(ulg row);
-static void rpng2_win_finish_display(void);
-static void rpng2_win_cleanup(void);
-LRESULT CALLBACK rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM);
-
-
-static char titlebar[1024];
-static char *progname = PROGNAME;
-static char *appname = LONGNAME;
-static char *filename;
-static FILE *infile;
-
-static mainprog_info rpng2_info;
-
-static uch inbuf[INBUFSIZE];
-static int incount;
-
-static int pat = 6; /* must be less than num_bgpat */
-static int bg_image = 0;
-static int bgscale = 16;
-static ulg bg_rowbytes;
-static uch *bg_data;
-
-static struct rgb_color {
- uch r, g, b;
-} rgb[] = {
- { 0, 0, 0}, /* 0: black */
- {255, 255, 255}, /* 1: white */
- {173, 132, 57}, /* 2: tan */
- { 64, 132, 0}, /* 3: medium green */
- {189, 117, 1}, /* 4: gold */
- {253, 249, 1}, /* 5: yellow */
- { 0, 0, 255}, /* 6: blue */
- { 0, 0, 120}, /* 7: medium blue */
- {255, 0, 255}, /* 8: magenta */
- { 64, 0, 64}, /* 9: dark magenta */
- {255, 0, 0}, /* 10: red */
- { 64, 0, 0}, /* 11: dark red */
- {255, 127, 0}, /* 12: orange */
- {192, 96, 0}, /* 13: darker orange */
- { 24, 60, 0}, /* 14: dark green-yellow */
- { 85, 125, 200} /* 15: ice blue */
-};
-/* not used for now, but should be for error-checking:
-static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
- */
-
-/*
- This whole struct is a fairly cheesy way to keep the number of
- command-line options to a minimum. The radial-waves background
- type is a particularly poor fit to the integer elements of the
- struct...but a few macros and a little fixed-point math will do
- wonders for ya.
-
- type bits:
- F E D C B A 9 8 7 6 5 4 3 2 1 0
- | | | | |
- | | +-+-+-- 0 = sharp-edged checkerboard
- | | 1 = soft diamonds
- | | 2 = radial waves
- | | 3-7 = undefined
- | +-- gradient #2 inverted?
- +-- alternating columns inverted?
- */
-static struct background_pattern {
- ush type;
- int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */
- int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/
-} bg[] = {
- {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */
- {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */
- {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */
- {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */
- {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */
- {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */
- {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */
- {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */
- {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */
- {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */
- {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */
- {1, 3,0, 0,0}, /* diamonds: medium green vs. black */
- {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */
- {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */
- {2, 16, 256, 100, 250}, /* radial: very tight spiral */
- {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */
-};
-static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
-
-
-/* Windows-specific global variables (could go in struct, but messy...) */
-static ulg wimage_rowbytes;
-static uch *dib;
-static uch *wimage_data;
-static BITMAPINFOHEADER *bmih;
-
-static HWND global_hwnd;
-static HINSTANCE global_hInst;
-static int global_showmode;
-
-
-
-
-int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
-{
- char *args[1024]; /* arbitrary limit, but should suffice */
- char **argv = args;
- char *p, *q, *bgstr = NULL;
- int argc = 0;
- int rc, alen, flen;
- int error = 0;
- int timing = FALSE;
- int have_bg = FALSE;
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
- MSG msg;
-
-
- /* First initialize a few things, just to be sure--memset takes care of
- * default background color (black), booleans (FALSE), pointers (NULL),
- * etc. */
-
- global_hInst = hInst;
- global_showmode = showmode;
- filename = (char *)NULL;
- memset(&rpng2_info, 0, sizeof(mainprog_info));
-
-#ifndef __CYGWIN__
- /* Next reenable console output, which normally goes to the bit bucket
- * for windowed apps. Closing the console window will terminate the
- * app. Thanks to David.Geldreich at realviz.com for supplying the magical
- * incantation. */
-
- AllocConsole();
- freopen("CONOUT$", "a", stderr);
- freopen("CONOUT$", "a", stdout);
-#endif
-
- /* Set the default value for our display-system exponent, i.e., the
- * product of the CRT exponent and the exponent corresponding to
- * the frame-buffer's lookup table (LUT), if any. This is not an
- * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
- * ones), but it should cover 99% of the current possibilities. And
- * yes, these ifdefs are completely wasted in a Windows program... */
-
-#if defined(NeXT)
- /* third-party utilities can modify the default LUT exponent */
- LUT_exponent = 1.0 / 2.2;
- /*
- if (some_next_function_that_returns_gamma(&next_gamma))
- LUT_exponent = 1.0 / next_gamma;
- */
-#elif defined(sgi)
- LUT_exponent = 1.0 / 1.7;
- /* there doesn't seem to be any documented function to
- * get the "gamma" value, so we do it the hard way */
- infile = fopen("/etc/config/system.glGammaVal", "r");
- if (infile) {
- double sgi_gamma;
-
- fgets(tmpline, 80, infile);
- fclose(infile);
- sgi_gamma = atof(tmpline);
- if (sgi_gamma > 0.0)
- LUT_exponent = 1.0 / sgi_gamma;
- }
-#elif defined(Macintosh)
- LUT_exponent = 1.8 / 2.61;
- /*
- if (some_mac_function_that_returns_gamma(&mac_gamma))
- LUT_exponent = mac_gamma / 2.61;
- */
-#else
- LUT_exponent = 1.0; /* assume no LUT: most PCs */
-#endif
-
- /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
- default_display_exponent = LUT_exponent * CRT_exponent;
-
-
- /* If the user has set the SCREEN_GAMMA environment variable as suggested
- * (somewhat imprecisely) in the libpng documentation, use that; otherwise
- * use the default value we just calculated. Either way, the user may
- * override this via a command-line option. */
-
- if ((p = getenv("SCREEN_GAMMA")) != NULL)
- rpng2_info.display_exponent = atof(p);
- else
- rpng2_info.display_exponent = default_display_exponent;
-
-
- /* Windows really hates command lines, so we have to set up our own argv.
- * Note that we do NOT bother with quoted arguments here, so don't use
- * filenames with spaces in 'em! */
-
- argv[argc++] = PROGNAME;
- p = cmd;
- for (;;) {
- if (*p == ' ')
- while (*++p == ' ')
- ;
- /* now p points at the first non-space after some spaces */
- if (*p == '\0')
- break; /* nothing after the spaces: done */
- argv[argc++] = q = p;
- while (*q && *q != ' ')
- ++q;
- /* now q points at a space or the end of the string */
- if (*q == '\0')
- break; /* last argv already terminated; quit */
- *q = '\0'; /* change space to terminator */
- p = q + 1;
- }
- argv[argc] = NULL; /* terminate the argv array itself */
-
-
- /* Now parse the command line for options and the PNG filename. */
-
- while (*++argv && !error) {
- if (!strncmp(*argv, "-gamma", 2)) {
- if (!*++argv)
- ++error;
- else {
- rpng2_info.display_exponent = atof(*argv);
- if (rpng2_info.display_exponent <= 0.0)
- ++error;
- }
- } else if (!strncmp(*argv, "-bgcolor", 4)) {
- if (!*++argv)
- ++error;
- else {
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
- else {
- have_bg = TRUE;
- bg_image = FALSE;
- }
- }
- } else if (!strncmp(*argv, "-bgpat", 4)) {
- if (!*++argv)
- ++error;
- else {
- pat = atoi(*argv) - 1;
- if (pat < 0 || pat >= num_bgpat)
- ++error;
- else {
- bg_image = TRUE;
- have_bg = FALSE;
- }
- }
- } else if (!strncmp(*argv, "-timing", 2)) {
- timing = TRUE;
- } else {
- if (**argv != '-') {
- filename = *argv;
- if (argv[1]) /* shouldn't be any more args after filename */
- ++error;
- } else
- ++error; /* not expecting any other options */
- }
- }
-
- if (!filename)
- ++error;
-
-
- /* print usage screen if any errors up to this point */
-
- if (error) {
-#ifndef __CYGWIN__
- int ch;
-#endif
-
- fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
- readpng2_version_info();
- fprintf(stderr, "\n"
- "Usage: %s [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing]\n"
- " %*s file.png\n\n"
- " exp \ttransfer-function exponent (``gamma'') of the display\n"
- "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
- "\t\t to the product of the lookup-table exponent (varies)\n"
- "\t\t and the CRT exponent (usually 2.2); must be positive\n"
- " bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
- "\t\t used with transparent images; overrides -bgpat option\n"
- " pat \tdesired background pattern number (1-%d); used with\n"
- "\t\t transparent images; overrides -bgcolor option\n"
- " -timing\tenables delay for every block read, to simulate modem\n"
- "\t\t download of image (~36 Kbps)\n"
- "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
-#ifndef __CYGWIN__
- "Press Q or Esc to quit this usage screen. ",
-#else
- ,
-#endif
- PROGNAME,
-#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \
- !(defined(__CYGWIN__) || defined(__MINGW32__))
- (int)strlen(PROGNAME), " ",
-#endif
- (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat);
- fflush(stderr);
-#ifndef __CYGWIN__
- do
- ch = _getch();
- while (ch != 'q' && ch != 'Q' && ch != 0x1B);
-#endif
- exit(1);
- }
-
-
- if (!(infile = fopen(filename, "rb"))) {
- fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
- ++error;
- } else {
- incount = fread(inbuf, 1, INBUFSIZE, infile);
- if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {
- fprintf(stderr, PROGNAME
- ": [%s] is not a PNG file: incorrect signature\n",
- filename);
- ++error;
- } else if ((rc = readpng2_init(&rpng2_info)) != 0) {
- switch (rc) {
- case 2:
- fprintf(stderr, PROGNAME
- ": [%s] has bad IHDR (libpng longjmp)\n", filename);
- break;
- case 4:
- fprintf(stderr, PROGNAME ": insufficient memory\n");
- break;
- default:
- fprintf(stderr, PROGNAME
- ": unknown readpng2_init() error\n");
- break;
- }
- ++error;
- }
- if (error)
- fclose(infile);
- }
-
-
- if (error) {
-#ifndef __CYGWIN__
- int ch;
-#endif
-
- fprintf(stderr, PROGNAME ": aborting.\n");
-#ifndef __CYGWIN__
- do
- ch = _getch();
- while (ch != 'q' && ch != 'Q' && ch != 0x1B);
-#endif
- exit(2);
- } else {
- fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname);
-#ifndef __CYGWIN__
- fprintf(stderr,
- "\n [console window: closing this window will terminate %s]\n\n",
- PROGNAME);
-#endif
- fflush(stderr);
- }
-
-
- /* set the title-bar string, but make sure buffer doesn't overflow */
-
- alen = strlen(appname);
- flen = strlen(filename);
- if (alen + flen + 3 > 1023)
- sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
- else
- sprintf(titlebar, "%s: %s", appname, filename);
-
-
- /* set some final rpng2_info variables before entering main data loop */
-
- if (have_bg) {
- unsigned r, g, b; /* this approach quiets compiler warnings */
-
- sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
- rpng2_info.bg_red = (uch)r;
- rpng2_info.bg_green = (uch)g;
- rpng2_info.bg_blue = (uch)b;
- } else
- rpng2_info.need_bgcolor = TRUE;
-
- rpng2_info.state = kPreInit;
- rpng2_info.mainprog_init = rpng2_win_init;
- rpng2_info.mainprog_display_row = rpng2_win_display_row;
- rpng2_info.mainprog_finish_display = rpng2_win_finish_display;
-
-
- /* OK, this is the fun part: call readpng2_decode_data() at the start of
- * the loop to deal with our first buffer of data (read in above to verify
- * that the file is a PNG image), then loop through the file and continue
- * calling the same routine to handle each chunk of data. It in turn
- * passes the data to libpng, which will invoke one or more of our call-
- * backs as decoded data become available. We optionally call Sleep() for
- * one second per iteration to simulate downloading the image via an analog
- * modem. */
-
- for (;;) {
- Trace((stderr, "about to call readpng2_decode_data()\n"))
- if (readpng2_decode_data(&rpng2_info, inbuf, incount))
- ++error;
- Trace((stderr, "done with readpng2_decode_data()\n"))
-
- if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {
- if (rpng2_info.state == kDone) {
- Trace((stderr, "done decoding PNG image\n"))
- } else if (ferror(infile)) {
- fprintf(stderr, PROGNAME
- ": error while reading PNG image file\n");
- exit(3);
- } else if (feof(infile)) {
- fprintf(stderr, PROGNAME ": end of file reached "
- "(unexpectedly) while reading PNG image file\n");
- exit(3);
- } else /* if (error) */ {
- /* will print error message below */
- }
- break;
- }
-
- if (timing)
- Sleep(1000L);
-
- incount = fread(inbuf, 1, INBUFSIZE, infile);
- }
-
-
- /* clean up PNG stuff and report any decoding errors */
-
- fclose(infile);
- Trace((stderr, "about to call readpng2_cleanup()\n"))
- readpng2_cleanup(&rpng2_info);
-
- if (error) {
- fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n");
- exit(3);
- }
-
-
- /* wait for the user to tell us when to quit */
-
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
-
- /* we're done: clean up all image and Windows resources and go away */
-
- Trace((stderr, "about to call rpng2_win_cleanup()\n"))
- rpng2_win_cleanup();
-
- return msg.wParam;
-}
-
-
-
-
-
-/* this function is called by readpng2_info_callback() in readpng2.c, which
- * in turn is called by libpng after all of the pre-IDAT chunks have been
- * read and processed--i.e., we now have enough info to finish initializing */
-
-static void rpng2_win_init()
-{
- ulg i;
- ulg rowbytes = rpng2_info.rowbytes;
-
- Trace((stderr, "beginning rpng2_win_init()\n"))
- Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes))
- Trace((stderr, " width = %ld\n", rpng2_info.width))
- Trace((stderr, " height = %ld\n", rpng2_info.height))
-
- /* Guard against integer overflow */
- if (rpng2_info.height > ((size_t)(-1))/rowbytes) {
- fprintf(stderr, PROGNAME ": image_data buffer would be too large\n",
- readpng2_cleanup(&rpng2_info);
- return;
- }
-
- rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
- if (!rpng2_info.image_data) {
- readpng2_cleanup(&rpng2_info);
- return;
- }
-
- rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));
- if (!rpng2_info.row_pointers) {
- free(rpng2_info.image_data);
- rpng2_info.image_data = NULL;
- readpng2_cleanup(&rpng2_info);
- return;
- }
-
- for (i = 0; i < rpng2_info.height; ++i)
- rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;
-
-/*---------------------------------------------------------------------------
- Do the basic Windows initialization stuff, make the window, and fill it
- with the user-specified, file-specified or default background color.
- ---------------------------------------------------------------------------*/
-
- if (rpng2_win_create_window()) {
- readpng2_cleanup(&rpng2_info);
- return;
- }
-
- rpng2_info.state = kWindowInit;
-}
-
-
-
-
-
-static int rpng2_win_create_window()
-{
- uch bg_red = rpng2_info.bg_red;
- uch bg_green = rpng2_info.bg_green;
- uch bg_blue = rpng2_info.bg_blue;
- uch *dest;
- int extra_width, extra_height;
- ulg i, j;
- WNDCLASSEX wndclass;
- RECT rect;
-
-
-/*---------------------------------------------------------------------------
- Allocate memory for the display-specific version of the image (round up
- to multiple of 4 for Windows DIB).
- ---------------------------------------------------------------------------*/
-
- wimage_rowbytes = ((3*rpng2_info.width + 3L) >> 2) << 2;
-
- if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
- wimage_rowbytes*rpng2_info.height)))
- {
- return 4; /* fail */
- }
-
-/*---------------------------------------------------------------------------
- Initialize the DIB. Negative height means to use top-down BMP ordering
- (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8
- implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values
- directly => wimage_data begins immediately after BMP header.
- ---------------------------------------------------------------------------*/
-
- memset(dib, 0, sizeof(BITMAPINFOHEADER));
- bmih = (BITMAPINFOHEADER *)dib;
- bmih->biSize = sizeof(BITMAPINFOHEADER);
- bmih->biWidth = rpng2_info.width;
- bmih->biHeight = -((long)rpng2_info.height);
- bmih->biPlanes = 1;
- bmih->biBitCount = 24;
- bmih->biCompression = 0;
- wimage_data = dib + sizeof(BITMAPINFOHEADER);
-
-/*---------------------------------------------------------------------------
- Fill window with the specified background color (default is black), but
- defer loading faked "background image" until window is displayed (may be
- slow to compute). Data are in BGR order.
- ---------------------------------------------------------------------------*/
-
- if (bg_image) { /* just fill with black for now */
- memset(wimage_data, 0, wimage_rowbytes*rpng2_info.height);
- } else {
- for (j = 0; j < rpng2_info.height; ++j) {
- dest = wimage_data + j*wimage_rowbytes;
- for (i = rpng2_info.width; i > 0; --i) {
- *dest++ = bg_blue;
- *dest++ = bg_green;
- *dest++ = bg_red;
- }
- }
- }
-
-/*---------------------------------------------------------------------------
- Set the window parameters.
- ---------------------------------------------------------------------------*/
-
- memset(&wndclass, 0, sizeof(wndclass));
-
- wndclass.cbSize = sizeof(wndclass);
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = rpng2_win_wndproc;
- wndclass.hInstance = global_hInst;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = progname;
- wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
-
- RegisterClassEx(&wndclass);
-
-/*---------------------------------------------------------------------------
- Finally, create the window.
- ---------------------------------------------------------------------------*/
-
- extra_width = 2*(GetSystemMetrics(SM_CXBORDER) +
- GetSystemMetrics(SM_CXDLGFRAME));
- extra_height = 2*(GetSystemMetrics(SM_CYBORDER) +
- GetSystemMetrics(SM_CYDLGFRAME)) +
- GetSystemMetrics(SM_CYCAPTION);
-
- global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, rpng2_info.width+extra_width,
- rpng2_info.height+extra_height, NULL, NULL, global_hInst, NULL);
-
- ShowWindow(global_hwnd, global_showmode);
- UpdateWindow(global_hwnd);
-
-/*---------------------------------------------------------------------------
- Now compute the background image and display it. If it fails (memory
- allocation), revert to a plain background color.
- ---------------------------------------------------------------------------*/
-
- if (bg_image) {
- static const char *msg = "Computing background image...";
- int x, y, len = strlen(msg);
- HDC hdc = GetDC(global_hwnd);
- TEXTMETRIC tm;
-
- GetTextMetrics(hdc, &tm);
- x = (rpng2_info.width - len*tm.tmAveCharWidth)/2;
- y = (rpng2_info.height - tm.tmHeight)/2;
- SetBkMode(hdc, TRANSPARENT);
- SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
- /* this can still begin out of bounds even if x is positive (???): */
- TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len);
- ReleaseDC(global_hwnd, hdc);
-
- rpng2_win_load_bg_image(); /* resets bg_image if fails */
- }
-
- if (!bg_image) {
- for (j = 0; j < rpng2_info.height; ++j) {
- dest = wimage_data + j*wimage_rowbytes;
- for (i = rpng2_info.width; i > 0; --i) {
- *dest++ = bg_blue;
- *dest++ = bg_green;
- *dest++ = bg_red;
- }
- }
- }
-
- rect.left = 0L;
- rect.top = 0L;
- rect.right = (LONG)rpng2_info.width; /* possibly off by one? */
- rect.bottom = (LONG)rpng2_info.height; /* possibly off by one? */
- InvalidateRect(global_hwnd, &rect, FALSE);
- UpdateWindow(global_hwnd); /* similar to XFlush() */
-
- return 0;
-
-} /* end function rpng2_win_create_window() */
-
-
-
-
-
-static int rpng2_win_load_bg_image()
-{
- uch *src, *dest;
- uch r1, r2, g1, g2, b1, b2;
- uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
- int k, hmax, max;
- int xidx, yidx, yidx_max = (bgscale-1);
- int even_odd_vert, even_odd_horiz, even_odd;
- int invert_gradient2 = (bg[pat].type & 0x08);
- int invert_column;
- ulg i, row;
-
-/*---------------------------------------------------------------------------
- Allocate buffer for fake background image to be used with transparent
- images; if this fails, revert to plain background color.
- ---------------------------------------------------------------------------*/
-
- bg_rowbytes = 3 * rpng2_info.width;
- bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);
- if (!bg_data) {
- fprintf(stderr, PROGNAME
- ": unable to allocate memory for background image\n");
- bg_image = 0;
- return 1;
- }
-
-/*---------------------------------------------------------------------------
- Vertical gradients (ramps) in NxN squares, alternating direction and
- colors (N == bgscale).
- ---------------------------------------------------------------------------*/
-
- if ((bg[pat].type & 0x07) == 0) {
- uch r1_min = rgb[bg[pat].rgb1_min].r;
- uch g1_min = rgb[bg[pat].rgb1_min].g;
- uch b1_min = rgb[bg[pat].rgb1_min].b;
- uch r2_min = rgb[bg[pat].rgb2_min].r;
- uch g2_min = rgb[bg[pat].rgb2_min].g;
- uch b2_min = rgb[bg[pat].rgb2_min].b;
- int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
- int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
- int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
- int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
- int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
- int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- yidx = row % bgscale;
- even_odd_vert = (row / bgscale) & 1;
-
- r1 = r1_min + (r1_diff * yidx) / yidx_max;
- g1 = g1_min + (g1_diff * yidx) / yidx_max;
- b1 = b1_min + (b1_diff * yidx) / yidx_max;
- r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
- g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
- b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
-
- r2 = r2_min + (r2_diff * yidx) / yidx_max;
- g2 = g2_min + (g2_diff * yidx) / yidx_max;
- b2 = b2_min + (b2_diff * yidx) / yidx_max;
- r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
- g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
- b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
-
- dest = bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- even_odd_horiz = (i / bgscale) & 1;
- even_odd = even_odd_vert ^ even_odd_horiz;
- invert_column =
- (even_odd_horiz && (bg[pat].type & 0x10));
- if (even_odd == 0) { /* gradient #1 */
- if (invert_column) {
- *dest++ = r1_inv;
- *dest++ = g1_inv;
- *dest++ = b1_inv;
- } else {
- *dest++ = r1;
- *dest++ = g1;
- *dest++ = b1;
- }
- } else { /* gradient #2 */
- if ((invert_column && invert_gradient2) ||
- (!invert_column && !invert_gradient2))
- {
- *dest++ = r2; /* not inverted or */
- *dest++ = g2; /* doubly inverted */
- *dest++ = b2;
- } else {
- *dest++ = r2_inv;
- *dest++ = g2_inv; /* singly inverted */
- *dest++ = b2_inv;
- }
- }
- }
- }
-
-/*---------------------------------------------------------------------------
- Soft gradient-diamonds with scale = bgscale. Code contributed by Adam
- M. Costello.
- ---------------------------------------------------------------------------*/
-
- } else if ((bg[pat].type & 0x07) == 1) {
-
- hmax = (bgscale-1)/2; /* half the max weight of a color */
- max = 2*hmax; /* the max weight of a color */
-
- r1 = rgb[bg[pat].rgb1_max].r;
- g1 = rgb[bg[pat].rgb1_max].g;
- b1 = rgb[bg[pat].rgb1_max].b;
- r2 = rgb[bg[pat].rgb2_max].r;
- g2 = rgb[bg[pat].rgb2_max].g;
- b2 = rgb[bg[pat].rgb2_max].b;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- yidx = row % bgscale;
- if (yidx > hmax)
- yidx = bgscale-1 - yidx;
- dest = bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- xidx = i % bgscale;
- if (xidx > hmax)
- xidx = bgscale-1 - xidx;
- k = xidx + yidx;
- *dest++ = (k*r1 + (max-k)*r2) / max;
- *dest++ = (k*g1 + (max-k)*g2) / max;
- *dest++ = (k*b1 + (max-k)*b2) / max;
- }
- }
-
-/*---------------------------------------------------------------------------
- Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
- soids will equal bgscale?]. This one is slow but very cool. Code con-
- tributed by Pieter S. van der Meulen (originally in Smalltalk).
- ---------------------------------------------------------------------------*/
-
- } else if ((bg[pat].type & 0x07) == 2) {
- uch ch;
- int ii, x, y, hw, hh, grayspot;
- double freq, rotate, saturate, gray, intensity;
- double angle=0.0, aoffset=0.0, maxDist, dist;
- double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
-
- fprintf(stderr, "%s: computing radial background...",
- PROGNAME);
- fflush(stderr);
-
- hh = rpng2_info.height / 2;
- hw = rpng2_info.width / 2;
-
- /* variables for radial waves:
- * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED]
- * freq: number of color beams originating from the center
- * grayspot: size of the graying center area (anti-alias)
- * rotate: rotation of the beams as a function of radius
- * saturate: saturation of beams' shape azimuthally
- */
- angle = CLIP(angle, 0.0, 360.0);
- grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
- freq = MAX((double)bg[pat].bg_freq, 0.0);
- saturate = (double)bg[pat].bg_bsat * 0.1;
- rotate = (double)bg[pat].bg_brot * 0.1;
- gray = 0.0;
- intensity = 0.0;
- maxDist = (double)((hw*hw) + (hh*hh));
-
- for (row = 0; row < rpng2_info.height; ++row) {
- y = row - hh;
- dest = bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- x = i - hw;
- angle = (x == 0)? PI_2 : atan((double)y / (double)x);
- gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
- gray = MIN(1.0, gray);
- dist = (double)((x*x) + (y*y)) / maxDist;
- intensity = cos((angle+(rotate*dist*PI)) * freq) *
- gray * saturate;
- intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
- hue = (angle + PI) * INV_PI_360 + aoffset;
- s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
- s = MIN(MAX(s,0.0), 1.0);
- v = MIN(MAX(intensity,0.0), 1.0);
-
- if (s == 0.0) {
- ch = (uch)(v * 255.0);
- *dest++ = ch;
- *dest++ = ch;
- *dest++ = ch;
- } else {
- if ((hue < 0.0) || (hue >= 360.0))
- hue -= (((int)(hue / 360.0)) * 360.0);
- hue /= 60.0;
- ii = (int)hue;
- f = hue - (double)ii;
- p = (1.0 - s) * v;
- q = (1.0 - (s * f)) * v;
- t = (1.0 - (s * (1.0 - f))) * v;
- if (ii == 0) { red = v; green = t; blue = p; }
- else if (ii == 1) { red = q; green = v; blue = p; }
- else if (ii == 2) { red = p; green = v; blue = t; }
- else if (ii == 3) { red = p; green = q; blue = v; }
- else if (ii == 4) { red = t; green = p; blue = v; }
- else if (ii == 5) { red = v; green = p; blue = q; }
- *dest++ = (uch)(red * 255.0);
- *dest++ = (uch)(green * 255.0);
- *dest++ = (uch)(blue * 255.0);
- }
- }
- }
- fprintf(stderr, "done.\n");
- fflush(stderr);
- }
-
-/*---------------------------------------------------------------------------
- Blast background image to display buffer before beginning PNG decode;
- calling function will handle invalidation and UpdateWindow() call.
- ---------------------------------------------------------------------------*/
-
- for (row = 0; row < rpng2_info.height; ++row) {
- src = bg_data + row*bg_rowbytes;
- dest = wimage_data + row*wimage_rowbytes;
- for (i = rpng2_info.width; i > 0; --i) {
- r1 = *src++;
- g1 = *src++;
- b1 = *src++;
- *dest++ = b1;
- *dest++ = g1; /* note reverse order */
- *dest++ = r1;
- }
- }
-
- return 0;
-
-} /* end function rpng2_win_load_bg_image() */
-
-
-
-
-
-static void rpng2_win_display_row(ulg row)
-{
- uch bg_red = rpng2_info.bg_red;
- uch bg_green = rpng2_info.bg_green;
- uch bg_blue = rpng2_info.bg_blue;
- uch *src, *src2=NULL, *dest;
- uch r, g, b, a;
- ulg i;
- static int rows=0;
- static ulg firstrow;
-
-/*---------------------------------------------------------------------------
- rows and firstrow simply track how many rows (and which ones) have not
- yet been displayed; alternatively, we could call InvalidateRect() for
- every row and not bother with the records-keeping.
- ---------------------------------------------------------------------------*/
-
- Trace((stderr, "beginning rpng2_win_display_row()\n"))
-
- if (rows == 0)
- firstrow = row; /* first row not yet displayed */
-
- ++rows; /* count of rows received but not yet displayed */
-
-/*---------------------------------------------------------------------------
- Aside from the use of the rpng2_info struct and the lack of an outer
- loop (over rows), this routine is identical to rpng_win_display_image()
- in the non-progressive version of the program.
- ---------------------------------------------------------------------------*/
-
- src = rpng2_info.image_data + row*rpng2_info.rowbytes;
- if (bg_image)
- src2 = bg_data + row*bg_rowbytes;
- dest = wimage_data + row*wimage_rowbytes;
-
- if (rpng2_info.channels == 3) {
- for (i = rpng2_info.width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- *dest++ = b;
- *dest++ = g; /* note reverse order */
- *dest++ = r;
- }
- } else /* if (rpng2_info.channels == 4) */ {
- for (i = rpng2_info.width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (bg_image) {
- bg_red = *src2++;
- bg_green = *src2++;
- bg_blue = *src2++;
- }
- if (a == 255) {
- *dest++ = b;
- *dest++ = g;
- *dest++ = r;
- } else if (a == 0) {
- *dest++ = bg_blue;
- *dest++ = bg_green;
- *dest++ = bg_red;
- } else {
- /* this macro (copied from png.h) composites the
- * foreground and background values and puts the
- * result into the first argument; there are no
- * side effects with the first argument */
- alpha_composite(*dest++, b, a, bg_blue);
- alpha_composite(*dest++, g, a, bg_green);
- alpha_composite(*dest++, r, a, bg_red);
- }
- }
- }
-
-/*---------------------------------------------------------------------------
- Display after every 16 rows or when on last row. (Region may include
- previously displayed lines due to interlacing--i.e., not contiguous.)
- ---------------------------------------------------------------------------*/
-
- if ((rows & 0xf) == 0 || row == rpng2_info.height-1) {
- RECT rect;
-
- rect.left = 0L;
- rect.top = (LONG)firstrow;
- rect.right = (LONG)rpng2_info.width; /* possibly off by one? */
- rect.bottom = (LONG)row + 1L; /* possibly off by one? */
- InvalidateRect(global_hwnd, &rect, FALSE);
- UpdateWindow(global_hwnd); /* similar to XFlush() */
- rows = 0;
- }
-
-} /* end function rpng2_win_display_row() */
-
-
-
-
-
-static void rpng2_win_finish_display()
-{
- Trace((stderr, "beginning rpng2_win_finish_display()\n"))
-
- /* last row has already been displayed by rpng2_win_display_row(), so
- * we have nothing to do here except set a flag and let the user know
- * that the image is done */
-
- rpng2_info.state = kDone;
- printf(
-#ifndef __CYGWIN__
- "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"
-#else
- "Done. Press mouse button 1 (within image window) to quit.\n"
-#endif
- );
- fflush(stdout);
-}
-
-
-
-
-
-static void rpng2_win_cleanup()
-{
- if (bg_image && bg_data) {
- free(bg_data);
- bg_data = NULL;
- }
-
- if (rpng2_info.image_data) {
- free(rpng2_info.image_data);
- rpng2_info.image_data = NULL;
- }
-
- if (rpng2_info.row_pointers) {
- free(rpng2_info.row_pointers);
- rpng2_info.row_pointers = NULL;
- }
-
- if (dib) {
- free(dib);
- dib = NULL;
- }
-}
-
-
-
-
-
-LRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP)
-{
- HDC hdc;
- PAINTSTRUCT ps;
- int rc;
-
- switch (iMsg) {
- case WM_CREATE:
- /* one-time processing here, if any */
- return 0;
-
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- rc = StretchDIBits(hdc, 0, 0, rpng2_info.width, rpng2_info.height,
- 0, 0, rpng2_info.width, rpng2_info.height,
- wimage_data, (BITMAPINFO *)bmih,
- 0, SRCCOPY);
- EndPaint(hwnd, &ps);
- return 0;
-
- /* wait for the user to tell us when to quit */
- case WM_CHAR:
- switch (wP) { /* only need one, so ignore repeat count */
- case 'q':
- case 'Q':
- case 0x1B: /* Esc key */
- PostQuitMessage(0);
- }
- return 0;
-
- case WM_LBUTTONDOWN: /* another way of quitting */
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
-
- return DefWindowProc(hwnd, iMsg, wP, lP);
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-x.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-x.c
deleted file mode 100644
index af944c0f2bf..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/rpng2-x.c
+++ /dev/null
@@ -1,2143 +0,0 @@
-/*---------------------------------------------------------------------------
-
- rpng2 - progressive-model PNG display program rpng2-x.c
-
- This program decodes and displays PNG files progressively, as if it were
- a web browser (though the front end is only set up to read from files).
- It supports gamma correction, user-specified background colors, and user-
- specified background patterns (for transparent images). This version is
- for the X Window System (tested by the author under Unix and by Martin
- Zinser under OpenVMS; may work under OS/2 with a little tweaking).
-
- Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond"
- and "radial waves" patterns, respectively.
-
- to do (someday, maybe):
- - fix expose/redraw code: don't draw entire row if only part exposed
- - 8-bit (colormapped) X support
- - finish resizable checkerboard-gradient (sizes 4-128?)
- - use %.1023s to simplify truncation of title-bar string?
-
- ---------------------------------------------------------------------------
-
- Changelog:
- - 1.01: initial public release
- - 1.02: modified to allow abbreviated options; fixed char/uchar mismatch
- - 1.10: added support for non-default visuals; fixed X pixel-conversion
- - 1.11: added -usleep option for demos; fixed command-line parsing bug
- - 1.12: added -pause option for demos and testing
- - 1.20: added runtime MMX-enabling/disabling and new -mmx* options
- - 1.21: fixed some small X memory leaks (thanks to François Petitjean)
- - 1.22: fixed XFreeGC() crash bug (thanks to Patrick Welche)
- - 1.23: added -bgpat 0 mode (std white/gray checkerboard, 8x8 squares)
- - 1.30: added -loop option for -bgpat (ifdef FEATURE_LOOP); fixed bpp =
- 24; added support for X resources (thanks to Gerhard Niklasch)
- - 1.31: added code to skip unused chunks (thanks to Glenn Randers-Pehrson)
- - 1.32: added AMD64/EM64T support (__x86_64__); added basic expose/redraw
- handling
- - 2.00: dual-licensed (added GNU GPL)
- - 2.01: fixed 64-bit typo in readpng2.c; fixed -pause usage description
- - 2.02: fixed improper display of usage screen on PNG error(s); fixed
- unexpected-EOF and file-read-error cases; fixed Trace() cut-and-
- paste bugs
- - 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options
- - 2.04: Added "void(foo);" statements to quiet pedantic compiler warnings
- about unused variables (GR-P)
- - 2.05: Use nanosleep() instead of usleep(), which is deprecated (GR-P).
- - 2.06: check for integer overflow (Glenn R-P)
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2010, 2014-2015, 2017 Greg Roelofs. All rights
- reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#define PROGNAME "rpng2-x"
-#define LONGNAME "Progressive PNG Viewer for X"
-#define VERSION "2.04 of 15 June 2014"
-#define RESNAME "rpng2" /* our X resource application name */
-#define RESCLASS "Rpng" /* our X resource class name */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
-#include <time.h>
-#include <math.h> /* only for PvdM background code */
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#include <X11/keysym.h> /* defines XK_* macros */
-
-#if _POSIX_C_SOURCE >= 199309L /* have nanosleep() */
-# undef usleep
-# define usleep(usec) { \
- struct timespec ts; \
- ts.tv_sec = 0; \
- ts.tv_nsec = (usec) * 1000; \
- nanosleep(&ts, NULL); }
-# endif
-
-#ifndef usleep /* have neither nanosleep() nor usleep() */
-# define usleep(x) sleep(((x)+499999)/1000000)
-#endif
-
-#ifdef VMS
-# include <unistd.h>
-#endif
-
-/* all for PvdM background code: */
-#ifndef PI
-# define PI 3.141592653589793238
-#endif
-#define PI_2 (PI*0.5)
-#define INV_PI_360 (360.0 / PI)
-#define MAX(a,b) (a>b?a:b)
-#define MIN(a,b) (a<b?a:b)
-#define CLIP(a,min,max) MAX(min,MIN((a),max))
-#define ABS(a) ((a)<0?-(a):(a))
-#define CLIP8P(c) MAX(0,(MIN((c),255))) /* 8-bit pos. integer (uch) */
-#define ROUNDF(f) ((int)(f + 0.5))
-
-#define QUIT(e,k) ((e.type == ButtonPress && e.xbutton.button == Button1) || \
- (e.type == KeyPress && /* v--- or 1 for shifted keys */ \
- ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape)))
-
-#define NO_24BIT_MASKS /* undef case not fully written--only for redisplay() */
-
-#define rgb1_max bg_freq
-#define rgb1_min bg_gray
-#define rgb2_max bg_bsat
-#define rgb2_min bg_brot
-
-/* #define DEBUG */ /* this enables the Trace() macros */
-
-#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
-
-
-/* could just include png.h, but this macro is the only thing we need
- * (name and typedefs changed to local versions); note that side effects
- * only happen with alpha (which could easily be avoided with
- * "ush acopy = (alpha);") */
-
-#define alpha_composite(composite, fg, alpha, bg) { \
- ush temp = ((ush)(fg)*(ush)(alpha) + \
- (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \
- (composite) = (uch)((temp + (temp >> 8)) >> 8); \
-}
-
-
-#define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
- * block size corresponds roughly to a download
- * speed 10% faster than theoretical 33.6K maximum
- * (assuming 8 data bits, 1 stop bit and no other
- * overhead) */
-
-/* local prototypes */
-static void rpng2_x_init (void);
-static int rpng2_x_create_window (void);
-static int rpng2_x_load_bg_image (void);
-static void rpng2_x_display_row (ulg row);
-static void rpng2_x_finish_display (void);
-static void rpng2_x_redisplay_image (ulg startcol, ulg startrow,
- ulg width, ulg height);
-#ifdef FEATURE_LOOP
-static void rpng2_x_reload_bg_image (void);
-static int is_number (char *p);
-#endif
-static void rpng2_x_cleanup (void);
-static int rpng2_x_msb (ulg u32val);
-
-
-static char titlebar[1024], *window_name = titlebar;
-static char *appname = LONGNAME;
-static char *icon_name = PROGNAME;
-static char *res_name = RESNAME;
-static char *res_class = RESCLASS;
-static char *filename;
-static FILE *infile;
-
-static mainprog_info rpng2_info;
-
-static uch inbuf[INBUFSIZE];
-static int incount;
-
-static int pat = 6; /* must be less than num_bgpat */
-static int bg_image = 0;
-static int bgscale, bgscale_default = 16;
-static ulg bg_rowbytes;
-static uch *bg_data;
-
-int pause_after_pass = FALSE;
-int demo_timing = FALSE;
-ulg usleep_duration = 0L;
-
-static struct rgb_color {
- uch r, g, b;
-} rgb[] = {
- { 0, 0, 0}, /* 0: black */
- {255, 255, 255}, /* 1: white */
- {173, 132, 57}, /* 2: tan */
- { 64, 132, 0}, /* 3: medium green */
- {189, 117, 1}, /* 4: gold */
- {253, 249, 1}, /* 5: yellow */
- { 0, 0, 255}, /* 6: blue */
- { 0, 0, 120}, /* 7: medium blue */
- {255, 0, 255}, /* 8: magenta */
- { 64, 0, 64}, /* 9: dark magenta */
- {255, 0, 0}, /* 10: red */
- { 64, 0, 0}, /* 11: dark red */
- {255, 127, 0}, /* 12: orange */
- {192, 96, 0}, /* 13: darker orange */
- { 24, 60, 0}, /* 14: dark green-yellow */
- { 85, 125, 200}, /* 15: ice blue */
- {192, 192, 192} /* 16: Netscape/Mosaic gray */
-};
-/* not used for now, but should be for error-checking:
-static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
- */
-
-/*
- This whole struct is a fairly cheesy way to keep the number of
- command-line options to a minimum. The radial-waves background
- type is a particularly poor fit to the integer elements of the
- struct...but a few macros and a little fixed-point math will do
- wonders for ya.
-
- type bits:
- F E D C B A 9 8 7 6 5 4 3 2 1 0
- | | | | |
- | | +-+-+-- 0 = sharp-edged checkerboard
- | | 1 = soft diamonds
- | | 2 = radial waves
- | | 3-7 = undefined
- | +-- gradient #2 inverted?
- +-- alternating columns inverted?
- */
-static struct background_pattern {
- ush type;
- int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */
- int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/
-} bg[] = {
- {0, 1,1, 16,16}, /* checkered: white vs. light gray (basic) */
- {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */
- {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */
- {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */
- {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */
- {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */
- {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */
- {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */
- {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */
- {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */
- {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */
- {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */
- {1, 3,0, 0,0}, /* diamonds: medium green vs. black */
- {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */
- {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */
- {2, 16, 256, 100, 250}, /* radial: very tight spiral */
- {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */
-};
-static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
-
-
-/* X-specific variables */
-static char *displayname;
-static XImage *ximage;
-static Display *display;
-static int depth;
-static Visual *visual;
-static XVisualInfo *visual_list;
-static int RShift, GShift, BShift;
-static ulg RMask, GMask, BMask;
-static Window window;
-static GC gc;
-static Colormap colormap;
-
-static int have_nondefault_visual = FALSE;
-static int have_colormap = FALSE;
-static int have_window = FALSE;
-static int have_gc = FALSE;
-
-
-
-
-int main(int argc, char **argv)
-{
-#ifdef sgi
- char tmpline[80];
-#endif
- char *p, *bgstr = NULL;
- int rc, alen, flen;
- int error = 0;
- int timing = FALSE;
- int have_bg = FALSE;
-#ifdef FEATURE_LOOP
- int loop = FALSE;
- long loop_interval = -1; /* seconds (100,000 max) */
-#endif
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
- XEvent e;
- KeySym k;
-
-
- /* First initialize a few things, just to be sure--memset takes care of
- * default background color (black), booleans (FALSE), pointers (NULL),
- * etc. */
-
- displayname = (char *)NULL;
- filename = (char *)NULL;
- memset(&rpng2_info, 0, sizeof(mainprog_info));
-
-
- /* Set the default value for our display-system exponent, i.e., the
- * product of the CRT exponent and the exponent corresponding to
- * the frame-buffer's lookup table (LUT), if any. This is not an
- * exhaustive list of LUT values (e.g., OpenStep has a lot of weird
- * ones), but it should cover 99% of the current possibilities. */
-
-#if defined(NeXT)
- /* third-party utilities can modify the default LUT exponent */
- LUT_exponent = 1.0 / 2.2;
- /*
- if (some_next_function_that_returns_gamma(&next_gamma))
- LUT_exponent = 1.0 / next_gamma;
- */
-#elif defined(sgi)
- LUT_exponent = 1.0 / 1.7;
- /* there doesn't seem to be any documented function to
- * get the "gamma" value, so we do it the hard way */
- infile = fopen("/etc/config/system.glGammaVal", "r");
- if (infile) {
- double sgi_gamma;
-
- fgets(tmpline, 80, infile);
- fclose(infile);
- sgi_gamma = atof(tmpline);
- if (sgi_gamma > 0.0)
- LUT_exponent = 1.0 / sgi_gamma;
- }
-#elif defined(Macintosh)
- LUT_exponent = 1.8 / 2.61;
- /*
- if (some_mac_function_that_returns_gamma(&mac_gamma))
- LUT_exponent = mac_gamma / 2.61;
- */
-#else
- LUT_exponent = 1.0; /* assume no LUT: most PCs */
-#endif
-
- /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
- default_display_exponent = LUT_exponent * CRT_exponent;
-
-
- /* If the user has set the SCREEN_GAMMA environment variable as suggested
- * (somewhat imprecisely) in the libpng documentation, use that; otherwise
- * use the default value we just calculated. Either way, the user may
- * override this via a command-line option. */
-
- if ((p = getenv("SCREEN_GAMMA")) != NULL)
- rpng2_info.display_exponent = atof(p);
- else
- rpng2_info.display_exponent = default_display_exponent;
-
-
- /* Now parse the command line for options and the PNG filename. */
-
- while (*++argv && !error) {
- if (!strncmp(*argv, "-display", 2)) {
- if (!*++argv)
- ++error;
- else
- displayname = *argv;
- } else if (!strncmp(*argv, "-gamma", 2)) {
- if (!*++argv)
- ++error;
- else {
- rpng2_info.display_exponent = atof(*argv);
- if (rpng2_info.display_exponent <= 0.0)
- ++error;
- }
- } else if (!strncmp(*argv, "-bgcolor", 4)) {
- if (!*++argv)
- ++error;
- else {
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
- else {
- have_bg = TRUE;
- bg_image = FALSE;
- }
- }
- } else if (!strncmp(*argv, "-bgpat", 4)) {
- if (!*++argv)
- ++error;
- else {
- pat = atoi(*argv);
- if (pat >= 0 && pat < num_bgpat) {
- bg_image = TRUE;
- have_bg = FALSE;
- } else
- ++error;
- }
- } else if (!strncmp(*argv, "-usleep", 2)) {
- if (!*++argv)
- ++error;
- else {
- usleep_duration = (ulg)atol(*argv);
- demo_timing = TRUE;
- }
- } else if (!strncmp(*argv, "-pause", 2)) {
- pause_after_pass = TRUE;
- } else if (!strncmp(*argv, "-timing", 2)) {
- timing = TRUE;
-#ifdef FEATURE_LOOP
- } else if (!strncmp(*argv, "-loop", 2)) {
- loop = TRUE;
- if (!argv[1] || !is_number(argv[1]))
- loop_interval = 2;
- else {
- ++argv;
- loop_interval = atol(*argv);
- if (loop_interval < 0)
- loop_interval = 2;
- else if (loop_interval > 100000) /* bit more than one day */
- loop_interval = 100000;
- }
-#endif
- } else {
- if (**argv != '-') {
- filename = *argv;
- if (argv[1]) /* shouldn't be any more args after filename */
- ++error;
- } else
- ++error; /* not expecting any other options */
- }
- }
-
- if (!filename)
- ++error;
-
-
- /* print usage screen if any errors up to this point */
-
- if (error) {
- fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname);
- readpng2_version_info();
- fprintf(stderr, "\n"
- "Usage: ");
- fprintf(stderr,
- "%s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
- " %*s [-usleep dur | -timing] [-pause]\n",
- PROGNAME, (int)strlen(PROGNAME), " ");
- fprintf(stderr,
-#ifdef FEATURE_LOOP
- " [-loop [sec]]"
-#endif
- " file.png\n\n");
- fprintf(stderr,
- " xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
- " exp \ttransfer-function exponent (``gamma'') of the display\n"
- "\t\t system in floating-point format (e.g., ``%.1f''); equal\n"
- "\t\t to the product of the lookup-table exponent (varies)\n",
- default_display_exponent);
- fprintf(stderr,
- "\t\t and the CRT exponent (usually 2.2); must be positive\n"
- " bg \tdesired background color in 7-character hex RGB format\n"
- "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n"
- "\t\t used with transparent images; overrides -bgpat\n"
- " pat \tdesired background pattern number (0-%d); used with\n"
- "\t\t transparent images; overrides -bgcolor\n",
- num_bgpat-1);
-#ifdef FEATURE_LOOP
- fprintf(stderr,
- " -loop\tloops through background images after initial display\n"
- "\t\t is complete (depends on -bgpat)\n"
- " sec \tseconds to display each background image (default = 2)\n");
-#endif
- fprintf(stderr,
- " dur \tduration in microseconds to wait after displaying each\n"
- "\t\t row (for demo purposes)\n"
- " -timing\tenables delay for every block read, to simulate modem\n"
- "\t\t download of image (~36 Kbps)\n"
- " -pause\tpauses after displaying each pass until mouse clicked\n"
- "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
- "is displayed) to quit.\n");
- exit(1);
- }
-
- if (!(infile = fopen(filename, "rb"))) {
- fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename);
- ++error;
- } else {
- incount = fread(inbuf, 1, INBUFSIZE, infile);
- if (incount < 8 || !readpng2_check_sig(inbuf, 8)) {
- fprintf(stderr, PROGNAME
- ": [%s] is not a PNG file: incorrect signature\n",
- filename);
- ++error;
- } else if ((rc = readpng2_init(&rpng2_info)) != 0) {
- switch (rc) {
- case 2:
- fprintf(stderr, PROGNAME
- ": [%s] has bad IHDR (libpng longjmp)\n", filename);
- break;
- case 4:
- fprintf(stderr, PROGNAME ": insufficient memory\n");
- break;
- default:
- fprintf(stderr, PROGNAME
- ": unknown readpng2_init() error\n");
- break;
- }
- ++error;
- } else {
- Trace((stderr, "about to call XOpenDisplay()\n"))
- display = XOpenDisplay(displayname);
- if (!display) {
- readpng2_cleanup(&rpng2_info);
- fprintf(stderr, PROGNAME ": can't open X display [%s]\n",
- displayname? displayname : "default");
- ++error;
- }
- }
- if (error)
- fclose(infile);
- }
-
-
- if (error) {
- fprintf(stderr, PROGNAME ": aborting.\n");
- exit(2);
- }
-
-
- /* set the title-bar string, but make sure buffer doesn't overflow */
-
- alen = strlen(appname);
- flen = strlen(filename);
- if (alen + flen + 3 > 1023)
- sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023));
- else
- sprintf(titlebar, "%s: %s", appname, filename);
-
-
- /* set some final rpng2_info variables before entering main data loop */
-
- if (have_bg) {
- unsigned r, g, b; /* this approach quiets compiler warnings */
-
- sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
- rpng2_info.bg_red = (uch)r;
- rpng2_info.bg_green = (uch)g;
- rpng2_info.bg_blue = (uch)b;
- } else
- rpng2_info.need_bgcolor = TRUE;
-
- rpng2_info.state = kPreInit;
- rpng2_info.mainprog_init = rpng2_x_init;
- rpng2_info.mainprog_display_row = rpng2_x_display_row;
- rpng2_info.mainprog_finish_display = rpng2_x_finish_display;
-
-
- /* OK, this is the fun part: call readpng2_decode_data() at the start of
- * the loop to deal with our first buffer of data (read in above to verify
- * that the file is a PNG image), then loop through the file and continue
- * calling the same routine to handle each chunk of data. It in turn
- * passes the data to libpng, which will invoke one or more of our call-
- * backs as decoded data become available. We optionally call sleep() for
- * one second per iteration to simulate downloading the image via an analog
- * modem. */
-
- for (;;) {
- Trace((stderr, "about to call readpng2_decode_data()\n"))
- if (readpng2_decode_data(&rpng2_info, inbuf, incount))
- ++error;
- Trace((stderr, "done with readpng2_decode_data()\n"))
-
- if (error || incount != INBUFSIZE || rpng2_info.state == kDone) {
- if (rpng2_info.state == kDone) {
- Trace((stderr, "done decoding PNG image\n"))
- } else if (ferror(infile)) {
- fprintf(stderr, PROGNAME
- ": error while reading PNG image file\n");
- exit(3);
- } else if (feof(infile)) {
- fprintf(stderr, PROGNAME ": end of file reached "
- "(unexpectedly) while reading PNG image file\n");
- exit(3);
- } else /* if (error) */ {
- /* will print error message below */
- }
- break;
- }
-
- if (timing)
- sleep(1);
-
- incount = fread(inbuf, 1, INBUFSIZE, infile);
- }
-
-
- /* clean up PNG stuff and report any decoding errors */
-
- fclose(infile);
- Trace((stderr, "about to call readpng2_cleanup()\n"))
- readpng2_cleanup(&rpng2_info);
-
- if (error) {
- fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n");
- exit(3);
- }
-
-
-#ifdef FEATURE_LOOP
-
- if (loop && bg_image) {
- Trace((stderr, "entering -loop loop (FEATURE_LOOP)\n"))
- for (;;) {
- int i, use_sleep;
- struct timeval now, then;
-
- /* get current time and add loop_interval to get target time */
- if (gettimeofday(&then, NULL) == 0) {
- then.tv_sec += loop_interval;
- use_sleep = FALSE;
- } else
- use_sleep = TRUE;
-
- /* do quick check for a quit event but don't wait for it */
- /* GRR BUG: should also check for Expose events and redraw... */
- if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e))
- if (QUIT(e,k))
- break;
-
- /* generate next background image */
- if (++pat >= num_bgpat)
- pat = 0;
- rpng2_x_reload_bg_image();
-
- /* wait for timeout, using whatever means are available */
- if (use_sleep || gettimeofday(&now, NULL) != 0) {
- for (i = loop_interval; i > 0; --i) {
- sleep(1);
- /* GRR BUG: also need to check for Expose (and redraw!) */
- if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask,
- &e) && QUIT(e,k))
- break;
- }
- } else {
- /* Y2038 BUG! */
- if (now.tv_sec < then.tv_sec ||
- (now.tv_sec == then.tv_sec && now.tv_usec < then.tv_usec))
- {
- int quit = FALSE;
- long seconds_to_go = then.tv_sec - now.tv_sec;
- long usleep_usec;
-
- /* basically chew up most of remaining loop-interval with
- * calls to sleep(1) interleaved with checks for quit
- * events, but also recalc time-to-go periodically; when
- * done, clean up any remaining time with usleep() call
- * (could also use SIGALRM, but signals are a pain...) */
- while (seconds_to_go-- > 1) {
- int seconds_done = 0;
-
- for (i = seconds_to_go; i > 0 && !quit; --i) {
- sleep(1);
- /* GRR BUG: need to check for Expose and redraw */
- if (XCheckMaskEvent(display, KeyPressMask |
- ButtonPressMask, &e) && QUIT(e,k))
- quit = TRUE;
- if (++seconds_done > 1000)
- break; /* time to redo seconds_to_go meas. */
- }
- if (quit)
- break;
-
- /* OK, more than 1000 seconds since last check:
- * correct the time-to-go measurement for drift */
- if (gettimeofday(&now, NULL) == 0) {
- if (now.tv_sec >= then.tv_sec)
- break;
- seconds_to_go = then.tv_sec - now.tv_sec;
- } else
- ++seconds_to_go; /* restore what we subtracted */
- }
- if (quit)
- break; /* breaks outer do-loop, skips redisplay */
-
- /* since difference between "now" and "then" is already
- * eaten up to within a couple of seconds, don't need to
- * worry about overflow--but might have overshot (neg.) */
- if (gettimeofday(&now, NULL) == 0) {
- usleep_usec = 1000000L*(then.tv_sec - now.tv_sec) +
- then.tv_usec - now.tv_usec;
- if (usleep_usec > 0)
- usleep((ulg)usleep_usec);
- }
- }
- }
-
- /* composite image against new background and display (note that
- * we do not take into account the time spent doing this...) */
- rpng2_x_redisplay_image (0, 0, rpng2_info.width, rpng2_info.height);
- }
-
- } else /* FALL THROUGH and do the normal thing */
-
-#endif /* FEATURE_LOOP */
-
- /* wait for the user to tell us when to quit */
-
- if (rpng2_info.state >= kWindowInit) {
- Trace((stderr, "entering final wait-for-quit-event loop\n"))
- do {
- XNextEvent(display, &e);
- if (e.type == Expose) {
- XExposeEvent *ex = (XExposeEvent *)&e;
- rpng2_x_redisplay_image (ex->x, ex->y, ex->width, ex->height);
- }
- } while (!QUIT(e,k));
- } else {
- fprintf(stderr, PROGNAME ": init callback never called: probable "
- "libpng error while decoding PNG metadata\n");
- exit(4);
- }
-
-
- /* we're done: clean up all image and X resources and go away */
-
- Trace((stderr, "about to call rpng2_x_cleanup()\n"))
- rpng2_x_cleanup();
-
- (void)argc; /* Unused */
-
- return 0;
-}
-
-
-
-
-
-/* this function is called by readpng2_info_callback() in readpng2.c, which
- * in turn is called by libpng after all of the pre-IDAT chunks have been
- * read and processed--i.e., we now have enough info to finish initializing */
-
-static void rpng2_x_init(void)
-{
- ulg i;
- ulg rowbytes = rpng2_info.rowbytes;
-
- Trace((stderr, "beginning rpng2_x_init()\n"))
- Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes))
- Trace((stderr, " width = %ld\n", rpng2_info.width))
- Trace((stderr, " height = %ld\n", rpng2_info.height))
-
- /* Guard against integer overflow */
- if (rpng2_info.height > ((size_t)(-1))/rpng2_info.rowbytes) {
- fprintf(stderr, PROGNAME ": image_data buffer would be too large\n");
- readpng2_cleanup(&rpng2_info);
- return;
- }
-
- rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
- if (!rpng2_info.image_data) {
- readpng2_cleanup(&rpng2_info);
- return;
- }
-
- rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *));
- if (!rpng2_info.row_pointers) {
- free(rpng2_info.image_data);
- rpng2_info.image_data = NULL;
- readpng2_cleanup(&rpng2_info);
- return;
- }
-
- for (i = 0; i < rpng2_info.height; ++i)
- rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes;
-
-
- /* do the basic X initialization stuff, make the window, and fill it with
- * the user-specified, file-specified or default background color or
- * pattern */
-
- if (rpng2_x_create_window()) {
-
- /* GRR TEMPORARY HACK: this is fundamentally no different from cases
- * above; libpng should call our error handler to longjmp() back to us
- * when png_ptr goes away. If we/it segfault instead, seems like a
- * libpng bug... */
-
- /* we're here via libpng callback, so if window fails, clean and bail */
- readpng2_cleanup(&rpng2_info);
- rpng2_x_cleanup();
- exit(2);
- }
-
- rpng2_info.state = kWindowInit;
-}
-
-
-
-
-
-static int rpng2_x_create_window(void)
-{
- ulg bg_red = rpng2_info.bg_red;
- ulg bg_green = rpng2_info.bg_green;
- ulg bg_blue = rpng2_info.bg_blue;
- ulg bg_pixel = 0L;
- ulg attrmask;
- int need_colormap = FALSE;
- int screen, pad;
- uch *xdata;
- Window root;
- XEvent e;
- XGCValues gcvalues;
- XSetWindowAttributes attr;
- XTextProperty windowName, *pWindowName = &windowName;
- XTextProperty iconName, *pIconName = &iconName;
- XVisualInfo visual_info;
- XSizeHints *size_hints;
- XWMHints *wm_hints;
- XClassHint *class_hints;
-
-
- Trace((stderr, "beginning rpng2_x_create_window()\n"))
-
- screen = DefaultScreen(display);
- depth = DisplayPlanes(display, screen);
- root = RootWindow(display, screen);
-
-#ifdef DEBUG
- XSynchronize(display, True);
-#endif
-
- if (depth != 16 && depth != 24 && depth != 32) {
- int visuals_matched = 0;
-
- Trace((stderr, "default depth is %d: checking other visuals\n",
- depth))
-
- /* 24-bit first */
- visual_info.screen = screen;
- visual_info.depth = 24;
- visual_list = XGetVisualInfo(display,
- VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
- if (visuals_matched == 0) {
-/* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
- fprintf(stderr, "default screen depth %d not supported, and no"
- " 24-bit visuals found\n", depth);
- return 2;
- }
- Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
- visuals_matched))
- visual = visual_list[0].visual;
- depth = visual_list[0].depth;
-/*
- colormap_size = visual_list[0].colormap_size;
- visual_class = visual->class;
- visualID = XVisualIDFromVisual(visual);
- */
- have_nondefault_visual = TRUE;
- need_colormap = TRUE;
- } else {
- XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
- visual = visual_info.visual;
- }
-
- RMask = visual->red_mask;
- GMask = visual->green_mask;
- BMask = visual->blue_mask;
-
-/* GRR: add/check 8-bit support */
- if (depth == 8 || need_colormap) {
- colormap = XCreateColormap(display, root, visual, AllocNone);
- if (!colormap) {
- fprintf(stderr, "XCreateColormap() failed\n");
- return 2;
- }
- have_colormap = TRUE;
- if (depth == 8)
- bg_image = FALSE; /* gradient just wastes palette entries */
- }
- if (depth == 15 || depth == 16) {
- RShift = 15 - rpng2_x_msb(RMask); /* these are right-shifts */
- GShift = 15 - rpng2_x_msb(GMask);
- BShift = 15 - rpng2_x_msb(BMask);
- } else if (depth > 16) {
- RShift = rpng2_x_msb(RMask) - 7; /* these are left-shifts */
- GShift = rpng2_x_msb(GMask) - 7;
- BShift = rpng2_x_msb(BMask) - 7;
- }
- if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
- fprintf(stderr, "rpng2 internal logic error: negative X shift(s)!\n");
- return 2;
- }
-
-/*---------------------------------------------------------------------------
- Finally, create the window.
- ---------------------------------------------------------------------------*/
-
- attr.backing_store = Always;
- attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
- attrmask = CWBackingStore | CWEventMask;
- if (have_nondefault_visual) {
- attr.colormap = colormap;
- attr.background_pixel = 0;
- attr.border_pixel = 1;
- attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
- }
-
- window = XCreateWindow(display, root, 0, 0, rpng2_info.width,
- rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr);
-
- if (window == None) {
- fprintf(stderr, "XCreateWindow() failed\n");
- return 2;
- } else
- have_window = TRUE;
-
- if (depth == 8)
- XSetWindowColormap(display, window, colormap);
-
- if (!XStringListToTextProperty(&window_name, 1, pWindowName))
- pWindowName = NULL;
- if (!XStringListToTextProperty(&icon_name, 1, pIconName))
- pIconName = NULL;
-
- /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */
-
- if ((size_hints = XAllocSizeHints()) != NULL) {
- /* window will not be resizable */
- size_hints->flags = PMinSize | PMaxSize;
- size_hints->min_width = size_hints->max_width = (int)rpng2_info.width;
- size_hints->min_height = size_hints->max_height =
- (int)rpng2_info.height;
- }
-
- if ((wm_hints = XAllocWMHints()) != NULL) {
- wm_hints->initial_state = NormalState;
- wm_hints->input = True;
- /* wm_hints->icon_pixmap = icon_pixmap; */
- wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ;
- }
-
- if ((class_hints = XAllocClassHint()) != NULL) {
- class_hints->res_name = res_name;
- class_hints->res_class = res_class;
- }
-
- XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0,
- size_hints, wm_hints, class_hints);
-
- /* various properties and hints no longer needed; free memory */
- if (pWindowName)
- XFree(pWindowName->value);
- if (pIconName)
- XFree(pIconName->value);
- if (size_hints)
- XFree(size_hints);
- if (wm_hints)
- XFree(wm_hints);
- if (class_hints)
- XFree(class_hints);
-
- XMapWindow(display, window);
-
- gc = XCreateGC(display, window, 0, &gcvalues);
- have_gc = TRUE;
-
-/*---------------------------------------------------------------------------
- Allocate memory for the X- and display-specific version of the image.
- ---------------------------------------------------------------------------*/
-
- if (depth == 24 || depth == 32) {
- xdata = (uch *)malloc(4*rpng2_info.width*rpng2_info.height);
- pad = 32;
- } else if (depth == 16) {
- xdata = (uch *)malloc(2*rpng2_info.width*rpng2_info.height);
- pad = 16;
- } else /* depth == 8 */ {
- xdata = (uch *)malloc(rpng2_info.width*rpng2_info.height);
- pad = 8;
- }
-
- if (!xdata) {
- fprintf(stderr, PROGNAME ": unable to allocate image memory\n");
- return 4;
- }
-
- ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
- (char *)xdata, rpng2_info.width, rpng2_info.height, pad, 0);
-
- if (!ximage) {
- fprintf(stderr, PROGNAME ": XCreateImage() failed\n");
- free(xdata);
- return 3;
- }
-
- /* to avoid testing the byte order every pixel (or doubling the size of
- * the drawing routine with a giant if-test), we arbitrarily set the byte
- * order to MSBFirst and let Xlib worry about inverting things on little-
- * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the
- * most efficient approach (the giant if-test would be better), but in
- * the interest of clarity, we'll take the easy way out... */
-
- ximage->byte_order = MSBFirst;
-
-/*---------------------------------------------------------------------------
- Fill window with the specified background color (default is black) or
- faked "background image" (but latter is disabled if 8-bit; gradients
- just waste palette entries).
- ---------------------------------------------------------------------------*/
-
- if (bg_image)
- rpng2_x_load_bg_image(); /* resets bg_image if fails */
-
- if (!bg_image) {
- if (depth == 24 || depth == 32) {
- bg_pixel = (bg_red << RShift) |
- (bg_green << GShift) |
- (bg_blue << BShift);
- } else if (depth == 16) {
- bg_pixel = (((bg_red << 8) >> RShift) & RMask) |
- (((bg_green << 8) >> GShift) & GMask) |
- (((bg_blue << 8) >> BShift) & BMask);
- } else /* depth == 8 */ {
-
- /* GRR: add 8-bit support */
-
- }
- XSetForeground(display, gc, bg_pixel);
- XFillRectangle(display, window, gc, 0, 0, rpng2_info.width,
- rpng2_info.height);
- }
-
-/*---------------------------------------------------------------------------
- Wait for first Expose event to do any drawing, then flush and return.
- ---------------------------------------------------------------------------*/
-
- do
- XNextEvent(display, &e);
- while (e.type != Expose || e.xexpose.count);
-
- XFlush(display);
-
- return 0;
-
-} /* end function rpng2_x_create_window() */
-
-
-
-
-
-static int rpng2_x_load_bg_image(void)
-{
- uch *src;
- char *dest;
- uch r1, r2, g1, g2, b1, b2;
- uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
- int k, hmax, max;
- int xidx, yidx, yidx_max;
- int even_odd_vert, even_odd_horiz, even_odd;
- int invert_gradient2 = (bg[pat].type & 0x08);
- int invert_column;
- int ximage_rowbytes = ximage->bytes_per_line;
- ulg i, row;
- ulg pixel;
-
-/*---------------------------------------------------------------------------
- Allocate buffer for fake background image to be used with transparent
- images; if this fails, revert to plain background color.
- ---------------------------------------------------------------------------*/
-
- bg_rowbytes = 3 * rpng2_info.width;
- bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height);
- if (!bg_data) {
- fprintf(stderr, PROGNAME
- ": unable to allocate memory for background image\n");
- bg_image = 0;
- return 1;
- }
-
- bgscale = (pat == 0)? 8 : bgscale_default;
- yidx_max = bgscale - 1;
-
-/*---------------------------------------------------------------------------
- Vertical gradients (ramps) in NxN squares, alternating direction and
- colors (N == bgscale).
- ---------------------------------------------------------------------------*/
-
- if ((bg[pat].type & 0x07) == 0) {
- uch r1_min = rgb[bg[pat].rgb1_min].r;
- uch g1_min = rgb[bg[pat].rgb1_min].g;
- uch b1_min = rgb[bg[pat].rgb1_min].b;
- uch r2_min = rgb[bg[pat].rgb2_min].r;
- uch g2_min = rgb[bg[pat].rgb2_min].g;
- uch b2_min = rgb[bg[pat].rgb2_min].b;
- int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
- int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
- int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
- int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
- int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
- int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- yidx = (int)(row % bgscale);
- even_odd_vert = (int)((row / bgscale) & 1);
-
- r1 = r1_min + (r1_diff * yidx) / yidx_max;
- g1 = g1_min + (g1_diff * yidx) / yidx_max;
- b1 = b1_min + (b1_diff * yidx) / yidx_max;
- r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
- g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
- b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
-
- r2 = r2_min + (r2_diff * yidx) / yidx_max;
- g2 = g2_min + (g2_diff * yidx) / yidx_max;
- b2 = b2_min + (b2_diff * yidx) / yidx_max;
- r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
- g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
- b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
-
- dest = (char *)bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- even_odd_horiz = (int)((i / bgscale) & 1);
- even_odd = even_odd_vert ^ even_odd_horiz;
- invert_column =
- (even_odd_horiz && (bg[pat].type & 0x10));
- if (even_odd == 0) { /* gradient #1 */
- if (invert_column) {
- *dest++ = r1_inv;
- *dest++ = g1_inv;
- *dest++ = b1_inv;
- } else {
- *dest++ = r1;
- *dest++ = g1;
- *dest++ = b1;
- }
- } else { /* gradient #2 */
- if ((invert_column && invert_gradient2) ||
- (!invert_column && !invert_gradient2))
- {
- *dest++ = r2; /* not inverted or */
- *dest++ = g2; /* doubly inverted */
- *dest++ = b2;
- } else {
- *dest++ = r2_inv;
- *dest++ = g2_inv; /* singly inverted */
- *dest++ = b2_inv;
- }
- }
- }
- }
-
-/*---------------------------------------------------------------------------
- Soft gradient-diamonds with scale = bgscale. Code contributed by Adam
- M. Costello.
- ---------------------------------------------------------------------------*/
-
- } else if ((bg[pat].type & 0x07) == 1) {
-
- hmax = (bgscale-1)/2; /* half the max weight of a color */
- max = 2*hmax; /* the max weight of a color */
-
- r1 = rgb[bg[pat].rgb1_max].r;
- g1 = rgb[bg[pat].rgb1_max].g;
- b1 = rgb[bg[pat].rgb1_max].b;
- r2 = rgb[bg[pat].rgb2_max].r;
- g2 = rgb[bg[pat].rgb2_max].g;
- b2 = rgb[bg[pat].rgb2_max].b;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- yidx = (int)(row % bgscale);
- if (yidx > hmax)
- yidx = bgscale-1 - yidx;
- dest = (char *)bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- xidx = (int)(i % bgscale);
- if (xidx > hmax)
- xidx = bgscale-1 - xidx;
- k = xidx + yidx;
- *dest++ = (k*r1 + (max-k)*r2) / max;
- *dest++ = (k*g1 + (max-k)*g2) / max;
- *dest++ = (k*b1 + (max-k)*b2) / max;
- }
- }
-
-/*---------------------------------------------------------------------------
- Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
- soids will equal bgscale?]. This one is slow but very cool. Code con-
- tributed by Pieter S. van der Meulen (originally in Smalltalk).
- ---------------------------------------------------------------------------*/
-
- } else if ((bg[pat].type & 0x07) == 2) {
- uch ch;
- int ii, x, y, hw, hh, grayspot;
- double freq, rotate, saturate, gray, intensity;
- double angle=0.0, aoffset=0.0, maxDist, dist;
- double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
-
- fprintf(stderr, "%s: computing radial background...",
- PROGNAME);
- fflush(stderr);
-
- hh = (int)(rpng2_info.height / 2);
- hw = (int)(rpng2_info.width / 2);
-
- /* variables for radial waves:
- * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED]
- * freq: number of color beams originating from the center
- * grayspot: size of the graying center area (anti-alias)
- * rotate: rotation of the beams as a function of radius
- * saturate: saturation of beams' shape azimuthally
- */
- angle = CLIP(angle, 0.0, 360.0);
- grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
- freq = MAX((double)bg[pat].bg_freq, 0.0);
- saturate = (double)bg[pat].bg_bsat * 0.1;
- rotate = (double)bg[pat].bg_brot * 0.1;
- gray = 0.0;
- intensity = 0.0;
- maxDist = (double)((hw*hw) + (hh*hh));
-
- for (row = 0; row < rpng2_info.height; ++row) {
- y = (int)(row - hh);
- dest = (char *)bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- x = (int)(i - hw);
- angle = (x == 0)? PI_2 : atan((double)y / (double)x);
- gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
- gray = MIN(1.0, gray);
- dist = (double)((x*x) + (y*y)) / maxDist;
- intensity = cos((angle+(rotate*dist*PI)) * freq) *
- gray * saturate;
- intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
- hue = (angle + PI) * INV_PI_360 + aoffset;
- s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
- s = MIN(MAX(s,0.0), 1.0);
- v = MIN(MAX(intensity,0.0), 1.0);
-
- if (s == 0.0) {
- ch = (uch)(v * 255.0);
- *dest++ = ch;
- *dest++ = ch;
- *dest++ = ch;
- } else {
- if ((hue < 0.0) || (hue >= 360.0))
- hue -= (((int)(hue / 360.0)) * 360.0);
- hue /= 60.0;
- ii = (int)hue;
- f = hue - (double)ii;
- p = (1.0 - s) * v;
- q = (1.0 - (s * f)) * v;
- t = (1.0 - (s * (1.0 - f))) * v;
- if (ii == 0) { red = v; green = t; blue = p; }
- else if (ii == 1) { red = q; green = v; blue = p; }
- else if (ii == 2) { red = p; green = v; blue = t; }
- else if (ii == 3) { red = p; green = q; blue = v; }
- else if (ii == 4) { red = t; green = p; blue = v; }
- else if (ii == 5) { red = v; green = p; blue = q; }
- *dest++ = (uch)(red * 255.0);
- *dest++ = (uch)(green * 255.0);
- *dest++ = (uch)(blue * 255.0);
- }
- }
- }
- fprintf(stderr, "done.\n");
- fflush(stderr);
- }
-
-/*---------------------------------------------------------------------------
- Blast background image to display buffer before beginning PNG decode.
- ---------------------------------------------------------------------------*/
-
- if (depth == 24 || depth == 32) {
- ulg red, green, blue;
- int bpp = ximage->bits_per_pixel;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- src = bg_data + row*bg_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- if (bpp == 32) { /* slightly optimized version */
- for (i = rpng2_info.width; i > 0; --i) {
- red = *src++;
- green = *src++;
- blue = *src++;
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- } else {
- for (i = rpng2_info.width; i > 0; --i) {
- red = *src++;
- green = *src++;
- blue = *src++;
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- /* GRR BUG? this assumes bpp == 24 & bits are packed low */
- /* (probably need to use RShift, RMask, etc.) */
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
- }
-
- } else if (depth == 16) {
- ush red, green, blue;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- src = bg_data + row*bg_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- for (i = rpng2_info.width; i > 0; --i) {
- red = ((ush)(*src) << 8); ++src;
- green = ((ush)(*src) << 8); ++src;
- blue = ((ush)(*src) << 8); ++src;
- pixel = ((red >> RShift) & RMask) |
- ((green >> GShift) & GMask) |
- ((blue >> BShift) & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
-
- } else /* depth == 8 */ {
-
- /* GRR: add 8-bit support */
-
- }
-
- XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width,
- rpng2_info.height);
-
- return 0;
-
-} /* end function rpng2_x_load_bg_image() */
-
-
-
-
-
-static void rpng2_x_display_row(ulg row)
-{
- uch bg_red = rpng2_info.bg_red;
- uch bg_green = rpng2_info.bg_green;
- uch bg_blue = rpng2_info.bg_blue;
- uch *src, *src2=NULL;
- char *dest;
- uch r, g, b, a;
- int ximage_rowbytes = ximage->bytes_per_line;
- ulg i, pixel;
- static int rows=0, prevpass=(-1);
- static ulg firstrow;
-
-/*---------------------------------------------------------------------------
- rows and firstrow simply track how many rows (and which ones) have not
- yet been displayed; alternatively, we could call XPutImage() for every
- row and not bother with the records-keeping.
- ---------------------------------------------------------------------------*/
-
- Trace((stderr, "beginning rpng2_x_display_row()\n"))
-
- if (rpng2_info.pass != prevpass) {
- if (pause_after_pass && rpng2_info.pass > 0) {
- XEvent e;
- KeySym k;
-
- fprintf(stderr,
- "%s: end of pass %d of 7; click in image window to continue\n",
- PROGNAME, prevpass + 1);
- do
- XNextEvent(display, &e);
- while (!QUIT(e,k));
- }
- fprintf(stderr, "%s: pass %d of 7\r", PROGNAME, rpng2_info.pass + 1);
- fflush(stderr);
- prevpass = rpng2_info.pass;
- }
-
- if (rows == 0)
- firstrow = row; /* first row that is not yet displayed */
-
- ++rows; /* count of rows received but not yet displayed */
-
-/*---------------------------------------------------------------------------
- Aside from the use of the rpng2_info struct, the lack of an outer loop
- (over rows) and moving the XPutImage() call outside the "if (depth)"
- tests, this routine is identical to rpng_x_display_image() in the non-
- progressive version of the program.
- ---------------------------------------------------------------------------*/
-
- if (depth == 24 || depth == 32) {
- ulg red, green, blue;
- int bpp = ximage->bits_per_pixel;
-
- src = rpng2_info.image_data + row*rpng2_info.rowbytes;
- if (bg_image)
- src2 = bg_data + row*bg_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- if (rpng2_info.channels == 3) {
- for (i = rpng2_info.width; i > 0; --i) {
- red = *src++;
- green = *src++;
- blue = *src++;
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- if (bpp == 32) {
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- } else {
- /* GRR BUG? this assumes bpp == 24 & bits are packed low */
- /* (probably need to use RShift, RMask, etc.) */
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
- } else /* if (rpng2_info.channels == 4) */ {
- for (i = rpng2_info.width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (bg_image) {
- bg_red = *src2++;
- bg_green = *src2++;
- bg_blue = *src2++;
- }
- if (a == 255) {
- red = r;
- green = g;
- blue = b;
- } else if (a == 0) {
- red = bg_red;
- green = bg_green;
- blue = bg_blue;
- } else {
- /* this macro (from png.h) composites the foreground
- * and background values and puts the result into the
- * first argument */
- alpha_composite(red, r, a, bg_red);
- alpha_composite(green, g, a, bg_green);
- alpha_composite(blue, b, a, bg_blue);
- }
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- if (bpp == 32) {
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- } else {
- /* GRR BUG? this assumes bpp == 24 & bits are packed low */
- /* (probably need to use RShift, RMask, etc.) */
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
- }
-
- } else if (depth == 16) {
- ush red, green, blue;
-
- src = rpng2_info.row_pointers[row];
- if (bg_image)
- src2 = bg_data + row*bg_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- if (rpng2_info.channels == 3) {
- for (i = rpng2_info.width; i > 0; --i) {
- red = ((ush)(*src) << 8);
- ++src;
- green = ((ush)(*src) << 8);
- ++src;
- blue = ((ush)(*src) << 8);
- ++src;
- pixel = ((red >> RShift) & RMask) |
- ((green >> GShift) & GMask) |
- ((blue >> BShift) & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- } else /* if (rpng2_info.channels == 4) */ {
- for (i = rpng2_info.width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (bg_image) {
- bg_red = *src2++;
- bg_green = *src2++;
- bg_blue = *src2++;
- }
- if (a == 255) {
- red = ((ush)r << 8);
- green = ((ush)g << 8);
- blue = ((ush)b << 8);
- } else if (a == 0) {
- red = ((ush)bg_red << 8);
- green = ((ush)bg_green << 8);
- blue = ((ush)bg_blue << 8);
- } else {
- /* this macro (from png.h) composites the foreground
- * and background values and puts the result back into
- * the first argument (== fg byte here: safe) */
- alpha_composite(r, r, a, bg_red);
- alpha_composite(g, g, a, bg_green);
- alpha_composite(b, b, a, bg_blue);
- red = ((ush)r << 8);
- green = ((ush)g << 8);
- blue = ((ush)b << 8);
- }
- pixel = ((red >> RShift) & RMask) |
- ((green >> GShift) & GMask) |
- ((blue >> BShift) & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
-
- } else /* depth == 8 */ {
-
- /* GRR: add 8-bit support */
-
- }
-
-
-/*---------------------------------------------------------------------------
- Display after every 16 rows or when on one of last two rows. (Region
- may include previously displayed lines due to interlacing--i.e., not
- contiguous. Also, second-to-last row is final one in interlaced images
- with odd number of rows.) For demos, flush (and delay) after every 16th
- row so "sparse" passes don't go twice as fast.
- ---------------------------------------------------------------------------*/
-
- if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) {
- XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
- (int)firstrow, rpng2_info.width, row - firstrow + 1);
- XFlush(display);
- rows = 0;
- usleep(usleep_duration);
- } else
- if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) {
- XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
- (int)firstrow, rpng2_info.width, row - firstrow + 1);
- XFlush(display);
- rows = 0;
- }
-
-}
-
-
-
-
-
-static void rpng2_x_finish_display(void)
-{
- Trace((stderr, "beginning rpng2_x_finish_display()\n"))
-
- /* last row has already been displayed by rpng2_x_display_row(), so we
- * have nothing to do here except set a flag and let the user know that
- * the image is done */
-
- rpng2_info.state = kDone;
- printf(
- "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n");
- fflush(stdout);
-}
-
-
-
-
-
-static void rpng2_x_redisplay_image(ulg startcol, ulg startrow,
- ulg width, ulg height)
-{
- uch bg_red = rpng2_info.bg_red;
- uch bg_green = rpng2_info.bg_green;
- uch bg_blue = rpng2_info.bg_blue;
- uch *src, *src2=NULL;
- char *dest;
- uch r, g, b, a;
- ulg i, row, lastrow = 0;
- ulg pixel;
- int ximage_rowbytes = ximage->bytes_per_line;
-
-
- Trace((stderr, "beginning display loop (image_channels == %d)\n",
- rpng2_info.channels))
- Trace((stderr, " (width = %ld, rowbytes = %d, ximage_rowbytes = %d)\n",
- rpng2_info.width, rpng2_info.rowbytes, ximage_rowbytes))
- Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel))
- Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst?
- "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
-
-/*---------------------------------------------------------------------------
- Aside from the use of the rpng2_info struct and of src2 (for background
- image), this routine is identical to rpng_x_display_image() in the non-
- progressive version of the program--for the simple reason that redisplay
- of the image against a new background happens after the image is fully
- decoded and therefore is, by definition, non-progressive.
- ---------------------------------------------------------------------------*/
-
- if (depth == 24 || depth == 32) {
- ulg red, green, blue;
- int bpp = ximage->bits_per_pixel;
-
- for (lastrow = row = startrow; row < startrow+height; ++row) {
- src = rpng2_info.image_data + row*rpng2_info.rowbytes;
- if (bg_image)
- src2 = bg_data + row*bg_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- if (rpng2_info.channels == 3) {
- for (i = rpng2_info.width; i > 0; --i) {
- red = *src++;
- green = *src++;
- blue = *src++;
-#ifdef NO_24BIT_MASKS
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- if (bpp == 32) {
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- } else {
- /* this assumes bpp == 24 & bits are packed low */
- /* (probably need to use RShift, RMask, etc.) */
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
-#else
- red = (RShift < 0)? red << (-RShift) : red >> RShift;
- green = (GShift < 0)? green << (-GShift) : green >> GShift;
- blue = (BShift < 0)? blue << (-BShift) : blue >> BShift;
- pixel = (red & RMask) | (green & GMask) | (blue & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- if (bpp == 32) {
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- } else {
- /* GRR BUG */
- /* this assumes bpp == 24 & bits are packed low */
- /* (probably need to use RShift/RMask/etc. here, too) */
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
-#endif
- }
-
- } else /* if (rpng2_info.channels == 4) */ {
- for (i = rpng2_info.width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (bg_image) {
- bg_red = *src2++;
- bg_green = *src2++;
- bg_blue = *src2++;
- }
- if (a == 255) {
- red = r;
- green = g;
- blue = b;
- } else if (a == 0) {
- red = bg_red;
- green = bg_green;
- blue = bg_blue;
- } else {
- /* this macro (from png.h) composites the foreground
- * and background values and puts the result into the
- * first argument */
- alpha_composite(red, r, a, bg_red);
- alpha_composite(green, g, a, bg_green);
- alpha_composite(blue, b, a, bg_blue);
- }
-#ifdef NO_24BIT_MASKS
- pixel = (red << RShift) |
- (green << GShift) |
- (blue << BShift);
- /* recall that we set ximage->byte_order = MSBFirst above */
- if (bpp == 32) {
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- } else {
- /* this assumes bpp == 24 & bits are packed low */
- /* (probably need to use RShift, RMask, etc.) */
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
-#else
- red = (RShift < 0)? red << (-RShift) : red >> RShift;
- green = (GShift < 0)? green << (-GShift) : green >> GShift;
- blue = (BShift < 0)? blue << (-BShift) : blue >> BShift;
- pixel = (red & RMask) | (green & GMask) | (blue & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- if (bpp == 32) {
- *dest++ = (char)((pixel >> 24) & 0xff);
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- } else {
- /* GRR BUG */
- /* this assumes bpp == 24 & bits are packed low */
- /* (probably need to use RShift/RMask/etc. here, too) */
- *dest++ = (char)((pixel >> 16) & 0xff);
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
-#endif
- }
- }
- /* display after every 16 lines */
- if (((row+1) & 0xf) == 0) {
- XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
- (int)lastrow, rpng2_info.width, 16);
- XFlush(display);
- lastrow = row + 1;
- }
- }
-
- } else if (depth == 16) {
- ush red, green, blue;
-
- for (lastrow = row = startrow; row < startrow+height; ++row) {
- src = rpng2_info.row_pointers[row];
- if (bg_image)
- src2 = bg_data + row*bg_rowbytes;
- dest = ximage->data + row*ximage_rowbytes;
- if (rpng2_info.channels == 3) {
- for (i = rpng2_info.width; i > 0; --i) {
- red = ((ush)(*src) << 8);
- ++src;
- green = ((ush)(*src) << 8);
- ++src;
- blue = ((ush)(*src) << 8);
- ++src;
- pixel = ((red >> RShift) & RMask) |
- ((green >> GShift) & GMask) |
- ((blue >> BShift) & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- } else /* if (rpng2_info.channels == 4) */ {
- for (i = rpng2_info.width; i > 0; --i) {
- r = *src++;
- g = *src++;
- b = *src++;
- a = *src++;
- if (bg_image) {
- bg_red = *src2++;
- bg_green = *src2++;
- bg_blue = *src2++;
- }
- if (a == 255) {
- red = ((ush)r << 8);
- green = ((ush)g << 8);
- blue = ((ush)b << 8);
- } else if (a == 0) {
- red = ((ush)bg_red << 8);
- green = ((ush)bg_green << 8);
- blue = ((ush)bg_blue << 8);
- } else {
- /* this macro (from png.h) composites the foreground
- * and background values and puts the result back into
- * the first argument (== fg byte here: safe) */
- alpha_composite(r, r, a, bg_red);
- alpha_composite(g, g, a, bg_green);
- alpha_composite(b, b, a, bg_blue);
- red = ((ush)r << 8);
- green = ((ush)g << 8);
- blue = ((ush)b << 8);
- }
- pixel = ((red >> RShift) & RMask) |
- ((green >> GShift) & GMask) |
- ((blue >> BShift) & BMask);
- /* recall that we set ximage->byte_order = MSBFirst above */
- *dest++ = (char)((pixel >> 8) & 0xff);
- *dest++ = (char)( pixel & 0xff);
- }
- }
- /* display after every 16 lines */
- if (((row+1) & 0xf) == 0) {
- XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
- (int)lastrow, rpng2_info.width, 16);
- XFlush(display);
- lastrow = row + 1;
- }
- }
-
- } else /* depth == 8 */ {
-
- /* GRR: add 8-bit support */
-
- }
-
- Trace((stderr, "calling final XPutImage()\n"))
- if (lastrow < startrow+height) {
- XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
- (int)lastrow, rpng2_info.width, rpng2_info.height-lastrow);
- XFlush(display);
- }
-
- (void)startcol;
- (void)width;
-
-} /* end function rpng2_x_redisplay_image() */
-
-
-
-
-
-#ifdef FEATURE_LOOP
-
-static void rpng2_x_reload_bg_image(void)
-{
- char *dest;
- uch r1, r2, g1, g2, b1, b2;
- uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv;
- int k, hmax, max;
- int xidx, yidx, yidx_max;
- int even_odd_vert, even_odd_horiz, even_odd;
- int invert_gradient2 = (bg[pat].type & 0x08);
- int invert_column;
- ulg i, row;
-
-
- bgscale = (pat == 0)? 8 : bgscale_default;
- yidx_max = bgscale - 1;
-
-/*---------------------------------------------------------------------------
- Vertical gradients (ramps) in NxN squares, alternating direction and
- colors (N == bgscale).
- ---------------------------------------------------------------------------*/
-
- if ((bg[pat].type & 0x07) == 0) {
- uch r1_min = rgb[bg[pat].rgb1_min].r;
- uch g1_min = rgb[bg[pat].rgb1_min].g;
- uch b1_min = rgb[bg[pat].rgb1_min].b;
- uch r2_min = rgb[bg[pat].rgb2_min].r;
- uch g2_min = rgb[bg[pat].rgb2_min].g;
- uch b2_min = rgb[bg[pat].rgb2_min].b;
- int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min;
- int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min;
- int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min;
- int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min;
- int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min;
- int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- yidx = (int)(row % bgscale);
- even_odd_vert = (int)((row / bgscale) & 1);
-
- r1 = r1_min + (r1_diff * yidx) / yidx_max;
- g1 = g1_min + (g1_diff * yidx) / yidx_max;
- b1 = b1_min + (b1_diff * yidx) / yidx_max;
- r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max;
- g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max;
- b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max;
-
- r2 = r2_min + (r2_diff * yidx) / yidx_max;
- g2 = g2_min + (g2_diff * yidx) / yidx_max;
- b2 = b2_min + (b2_diff * yidx) / yidx_max;
- r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max;
- g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
- b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
-
- dest = (char *)bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- even_odd_horiz = (int)((i / bgscale) & 1);
- even_odd = even_odd_vert ^ even_odd_horiz;
- invert_column =
- (even_odd_horiz && (bg[pat].type & 0x10));
- if (even_odd == 0) { /* gradient #1 */
- if (invert_column) {
- *dest++ = r1_inv;
- *dest++ = g1_inv;
- *dest++ = b1_inv;
- } else {
- *dest++ = r1;
- *dest++ = g1;
- *dest++ = b1;
- }
- } else { /* gradient #2 */
- if ((invert_column && invert_gradient2) ||
- (!invert_column && !invert_gradient2))
- {
- *dest++ = r2; /* not inverted or */
- *dest++ = g2; /* doubly inverted */
- *dest++ = b2;
- } else {
- *dest++ = r2_inv;
- *dest++ = g2_inv; /* singly inverted */
- *dest++ = b2_inv;
- }
- }
- }
- }
-
-/*---------------------------------------------------------------------------
- Soft gradient-diamonds with scale = bgscale. Code contributed by Adam
- M. Costello.
- ---------------------------------------------------------------------------*/
-
- } else if ((bg[pat].type & 0x07) == 1) {
-
- hmax = (bgscale-1)/2; /* half the max weight of a color */
- max = 2*hmax; /* the max weight of a color */
-
- r1 = rgb[bg[pat].rgb1_max].r;
- g1 = rgb[bg[pat].rgb1_max].g;
- b1 = rgb[bg[pat].rgb1_max].b;
- r2 = rgb[bg[pat].rgb2_max].r;
- g2 = rgb[bg[pat].rgb2_max].g;
- b2 = rgb[bg[pat].rgb2_max].b;
-
- for (row = 0; row < rpng2_info.height; ++row) {
- yidx = (int)(row % bgscale);
- if (yidx > hmax)
- yidx = bgscale-1 - yidx;
- dest = (char *)bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- xidx = (int)(i % bgscale);
- if (xidx > hmax)
- xidx = bgscale-1 - xidx;
- k = xidx + yidx;
- *dest++ = (k*r1 + (max-k)*r2) / max;
- *dest++ = (k*g1 + (max-k)*g2) / max;
- *dest++ = (k*b1 + (max-k)*b2) / max;
- }
- }
-
-/*---------------------------------------------------------------------------
- Radial "starburst" with azimuthal sinusoids; [eventually number of sinu-
- soids will equal bgscale?]. This one is slow but very cool. Code con-
- tributed by Pieter S. van der Meulen (originally in Smalltalk).
- ---------------------------------------------------------------------------*/
-
- } else if ((bg[pat].type & 0x07) == 2) {
- uch ch;
- int ii, x, y, hw, hh, grayspot;
- double freq, rotate, saturate, gray, intensity;
- double angle=0.0, aoffset=0.0, maxDist, dist;
- double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t;
-
- hh = (int)(rpng2_info.height / 2);
- hw = (int)(rpng2_info.width / 2);
-
- /* variables for radial waves:
- * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED]
- * freq: number of color beams originating from the center
- * grayspot: size of the graying center area (anti-alias)
- * rotate: rotation of the beams as a function of radius
- * saturate: saturation of beams' shape azimuthally
- */
- angle = CLIP(angle, 0.0, 360.0);
- grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw));
- freq = MAX((double)bg[pat].bg_freq, 0.0);
- saturate = (double)bg[pat].bg_bsat * 0.1;
- rotate = (double)bg[pat].bg_brot * 0.1;
- gray = 0.0;
- intensity = 0.0;
- maxDist = (double)((hw*hw) + (hh*hh));
-
- for (row = 0; row < rpng2_info.height; ++row) {
- y = (int)(row - hh);
- dest = (char *)bg_data + row*bg_rowbytes;
- for (i = 0; i < rpng2_info.width; ++i) {
- x = (int)(i - hw);
- angle = (x == 0)? PI_2 : atan((double)y / (double)x);
- gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
- gray = MIN(1.0, gray);
- dist = (double)((x*x) + (y*y)) / maxDist;
- intensity = cos((angle+(rotate*dist*PI)) * freq) *
- gray * saturate;
- intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5;
- hue = (angle + PI) * INV_PI_360 + aoffset;
- s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh));
- s = MIN(MAX(s,0.0), 1.0);
- v = MIN(MAX(intensity,0.0), 1.0);
-
- if (s == 0.0) {
- ch = (uch)(v * 255.0);
- *dest++ = ch;
- *dest++ = ch;
- *dest++ = ch;
- } else {
- if ((hue < 0.0) || (hue >= 360.0))
- hue -= (((int)(hue / 360.0)) * 360.0);
- hue /= 60.0;
- ii = (int)hue;
- f = hue - (double)ii;
- p = (1.0 - s) * v;
- q = (1.0 - (s * f)) * v;
- t = (1.0 - (s * (1.0 - f))) * v;
- if (ii == 0) { red = v; green = t; blue = p; }
- else if (ii == 1) { red = q; green = v; blue = p; }
- else if (ii == 2) { red = p; green = v; blue = t; }
- else if (ii == 3) { red = p; green = q; blue = v; }
- else if (ii == 4) { red = t; green = p; blue = v; }
- else if (ii == 5) { red = v; green = p; blue = q; }
- *dest++ = (uch)(red * 255.0);
- *dest++ = (uch)(green * 255.0);
- *dest++ = (uch)(blue * 255.0);
- }
- }
- }
- }
-
-} /* end function rpng2_x_reload_bg_image() */
-
-
-
-
-
-static int is_number(char *p)
-{
- while (*p) {
- if (!isdigit(*p))
- return FALSE;
- ++p;
- }
- return TRUE;
-}
-
-#endif /* FEATURE_LOOP */
-
-
-
-
-
-static void rpng2_x_cleanup(void)
-{
- if (bg_image && bg_data) {
- free(bg_data);
- bg_data = NULL;
- }
-
- if (rpng2_info.image_data) {
- free(rpng2_info.image_data);
- rpng2_info.image_data = NULL;
- }
-
- if (rpng2_info.row_pointers) {
- free(rpng2_info.row_pointers);
- rpng2_info.row_pointers = NULL;
- }
-
- if (ximage) {
- if (ximage->data) {
- free(ximage->data); /* we allocated it, so we free it */
- ximage->data = (char *)NULL; /* instead of XDestroyImage() */
- }
- XDestroyImage(ximage);
- ximage = NULL;
- }
-
- if (have_gc)
- XFreeGC(display, gc);
-
- if (have_window)
- XDestroyWindow(display, window);
-
- if (have_colormap)
- XFreeColormap(display, colormap);
-
- if (have_nondefault_visual)
- XFree(visual_list);
-}
-
-
-
-
-
-static int rpng2_x_msb(ulg u32val)
-{
- int i;
-
- for (i = 31; i >= 0; --i) {
- if (u32val & 0x80000000L)
- break;
- u32val <<= 1;
- }
- return i;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/toucan.png b/Build/source/libs/libpng/libpng-src/contrib/gregbook/toucan.png
deleted file mode 100644
index 03960d49399..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/toucan.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/wpng.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/wpng.c
deleted file mode 100644
index a8f367fb84a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/wpng.c
+++ /dev/null
@@ -1,865 +0,0 @@
-/*---------------------------------------------------------------------------
-
- wpng - simple PNG-writing program wpng.c
-
- This program converts certain NetPBM binary files (grayscale and RGB,
- maxval = 255) to PNG. Non-interlaced PNGs are written progressively;
- interlaced PNGs are read and written in one memory-intensive blast.
-
- Thanks to Jean-loup Gailly for providing the necessary trick to read
- interactive text from the keyboard while stdin is redirected. Thanks
- to Cosmin Truta for Cygwin fixes.
-
- NOTE: includes provisional support for PNM type "8" (portable alphamap)
- images, presumed to be a 32-bit interleaved RGBA format; no pro-
- vision for possible interleaved grayscale+alpha (16-bit) format.
- THIS IS UNLIKELY TO BECOME AN OFFICIAL NETPBM ALPHA FORMAT!
-
- to do:
- - delete output file if quit before calling any writepng routines
- - process backspace with -text option under DOS/Win? (currently get ^H)
-
- ---------------------------------------------------------------------------
-
- Changelog:
- - 1.01: initial public release
- - 1.02: modified to allow abbreviated options
- - 1.03: removed extraneous character from usage screen; fixed bug in
- command-line parsing
- - 1.04: fixed DOS/OS2/Win32 detection, including partial Cygwin fix
- (see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff)
- - 2.00: dual-licensed (added GNU GPL)
- - 2.01: check for integer overflow (Glenn R-P)
-
- [REPORTED BUG (win32 only): "contrib/gregbook/wpng.c - cmd line
- dose not work! In order to do something useful I needed to redirect
- both input and output, with cygwin and with bcc32 as well. Under
- Linux, the same wpng appears to work fine. I don't know what is
- the problem."]
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2007, 2017 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#define PROGNAME "wpng"
-#define VERSION "2.00 of 2 June 2007"
-#define APPNAME "Simple PGM/PPM/PAM to PNG Converter"
-
-#if defined(__MSDOS__) || defined(__OS2__)
-# define DOS_OS2_W32
-#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
-# ifndef __GNUC__ /* treat Win32 native ports of gcc as Unix environments */
-# define DOS_OS2_W32
-# endif
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <setjmp.h> /* for jmpbuf declaration in writepng.h */
-#include <time.h>
-
-#ifdef DOS_OS2_W32
-# include <io.h> /* for isatty(), setmode() prototypes */
-# include <fcntl.h> /* O_BINARY for fdopen() without text translation */
-# ifdef __EMX__
-# ifndef getch
-# define getch() _read_kbd(0, 1, 0) /* need getche() */
-# endif
-# else /* !__EMX__ */
-# ifdef __GO32__
-# include <pc.h>
-# define getch() getkey() /* GRR: need getche() */
-# else
-# include <conio.h> /* for getche() console input */
-# endif
-# endif /* ?__EMX__ */
-# define FGETS(buf,len,stream) dos_kbd_gets(buf,len)
-#else
-# include <unistd.h> /* for isatty() prototype */
-# define FGETS fgets
-#endif
-
-/* #define DEBUG : this enables the Trace() macros */
-
-/* #define FORBID_LATIN1_CTRL : this requires the user to re-enter any
- text that includes control characters discouraged by the PNG spec; text
- that includes an escape character (27) must be re-entered regardless */
-
-#include "writepng.h" /* typedefs, common macros, writepng prototypes */
-
-
-
-/* local prototypes */
-
-static int wpng_isvalid_latin1(uch *p, int len);
-static void wpng_cleanup(void);
-
-#ifdef DOS_OS2_W32
- static char *dos_kbd_gets(char *buf, int len);
-#endif
-
-
-
-static mainprog_info wpng_info; /* lone global */
-
-
-
-int main(int argc, char **argv)
-{
-#ifndef DOS_OS2_W32
- FILE *keybd;
-#endif
-#ifdef sgi
- FILE *tmpfile; /* or we could just use keybd, since no overlap */
- char tmpline[80];
-#endif
- char *inname = NULL, outname[256];
- char *p, pnmchar, pnmline[256];
- char *bgstr, *textbuf = NULL;
- ulg rowbytes;
- int rc, len = 0;
- int error = 0;
- int text = FALSE;
- int maxval;
- double LUT_exponent; /* just the lookup table */
- double CRT_exponent = 2.2; /* just the monitor */
- double default_display_exponent; /* whole display system */
- double default_gamma = 0.0;
-
-
- wpng_info.infile = NULL;
- wpng_info.outfile = NULL;
- wpng_info.image_data = NULL;
- wpng_info.row_pointers = NULL;
- wpng_info.filter = FALSE;
- wpng_info.interlaced = FALSE;
- wpng_info.have_bg = FALSE;
- wpng_info.have_time = FALSE;
- wpng_info.have_text = 0;
- wpng_info.gamma = 0.0;
-
-
- /* First get the default value for our display-system exponent, i.e.,
- * the product of the CRT exponent and the exponent corresponding to
- * the frame-buffer's lookup table (LUT), if any. If the PNM image
- * looks correct on the user's display system, its file gamma is the
- * inverse of this value. (Note that this is not an exhaustive list
- * of LUT values--e.g., OpenStep has a lot of weird ones--but it should
- * cover 99% of the current possibilities. This section must ensure
- * that default_display_exponent is positive.) */
-
-#if defined(NeXT)
- /* third-party utilities can modify the default LUT exponent */
- LUT_exponent = 1.0 / 2.2;
- /*
- if (some_next_function_that_returns_gamma(&next_gamma))
- LUT_exponent = 1.0 / next_gamma;
- */
-#elif defined(sgi)
- LUT_exponent = 1.0 / 1.7;
- /* there doesn't seem to be any documented function to
- * get the "gamma" value, so we do it the hard way */
- tmpfile = fopen("/etc/config/system.glGammaVal", "r");
- if (tmpfile) {
- double sgi_gamma;
-
- fgets(tmpline, 80, tmpfile);
- fclose(tmpfile);
- sgi_gamma = atof(tmpline);
- if (sgi_gamma > 0.0)
- LUT_exponent = 1.0 / sgi_gamma;
- }
-#elif defined(Macintosh)
- LUT_exponent = 1.8 / 2.61;
- /*
- if (some_mac_function_that_returns_gamma(&mac_gamma))
- LUT_exponent = mac_gamma / 2.61;
- */
-#else
- LUT_exponent = 1.0; /* assume no LUT: most PCs */
-#endif
-
- /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */
- default_display_exponent = LUT_exponent * CRT_exponent;
-
-
- /* If the user has set the SCREEN_GAMMA environment variable as suggested
- * (somewhat imprecisely) in the libpng documentation, use that; otherwise
- * use the default value we just calculated. Either way, the user may
- * override this via a command-line option. */
-
- if ((p = getenv("SCREEN_GAMMA")) != NULL) {
- double exponent = atof(p);
-
- if (exponent > 0.0)
- default_gamma = 1.0 / exponent;
- }
-
- if (default_gamma == 0.0)
- default_gamma = 1.0 / default_display_exponent;
-
-
- /* Now parse the command line for options and the PNM filename. */
-
- while (*++argv && !error) {
- if (!strncmp(*argv, "-i", 2)) {
- wpng_info.interlaced = TRUE;
- } else if (!strncmp(*argv, "-time", 3)) {
- wpng_info.modtime = time(NULL);
- wpng_info.have_time = TRUE;
- } else if (!strncmp(*argv, "-text", 3)) {
- text = TRUE;
- } else if (!strncmp(*argv, "-gamma", 2)) {
- if (!*++argv)
- ++error;
- else {
- wpng_info.gamma = atof(*argv);
- if (wpng_info.gamma <= 0.0)
- ++error;
- else if (wpng_info.gamma > 1.01)
- fprintf(stderr, PROGNAME
- " warning: file gammas are usually less than 1.0\n");
- }
- } else if (!strncmp(*argv, "-bgcolor", 4)) {
- if (!*++argv)
- ++error;
- else {
- bgstr = *argv;
- if (strlen(bgstr) != 7 || bgstr[0] != '#')
- ++error;
- else {
- unsigned r, g, b; /* this way quiets compiler warnings */
-
- sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
- wpng_info.bg_red = (uch)r;
- wpng_info.bg_green = (uch)g;
- wpng_info.bg_blue = (uch)b;
- wpng_info.have_bg = TRUE;
- }
- }
- } else {
- if (**argv != '-') {
- inname = *argv;
- if (argv[1]) /* shouldn't be any more args after filename */
- ++error;
- } else
- ++error; /* not expecting any other options */
- }
- }
-
-
- /* open the input and output files, or register an error and abort */
-
- if (!inname) {
- if (isatty(0)) {
- fprintf(stderr, PROGNAME
- ": must give input filename or provide image data via stdin\n");
- ++error;
- } else {
-#ifdef DOS_OS2_W32
- /* some buggy C libraries require BOTH setmode() and fdopen(bin) */
- setmode(fileno(stdin), O_BINARY);
- setmode(fileno(stdout), O_BINARY);
-#endif
- if ((wpng_info.infile = fdopen(fileno(stdin), "rb")) == NULL) {
- fprintf(stderr, PROGNAME
- ": unable to reopen stdin in binary mode\n");
- ++error;
- } else
- if ((wpng_info.outfile = fdopen(fileno(stdout), "wb")) == NULL) {
- fprintf(stderr, PROGNAME
- ": unable to reopen stdout in binary mode\n");
- fclose(wpng_info.infile);
- ++error;
- } else
- wpng_info.filter = TRUE;
- }
- } else if ((len = strlen(inname)) > 250) {
- fprintf(stderr, PROGNAME ": input filename is too long [%d chars]\n",
- len);
- ++error;
- } else if (!(wpng_info.infile = fopen(inname, "rb"))) {
- fprintf(stderr, PROGNAME ": can't open input file [%s]\n", inname);
- ++error;
- }
-
- if (!error) {
- fgets(pnmline, 256, wpng_info.infile);
- if (pnmline[0] != 'P' || ((pnmchar = pnmline[1]) != '5' &&
- pnmchar != '6' && pnmchar != '8'))
- {
- fprintf(stderr, PROGNAME
- ": input file [%s] is not a binary PGM, PPM or PAM file\n",
- inname);
- ++error;
- } else {
- wpng_info.pnmtype = (int)(pnmchar - '0');
- if (wpng_info.pnmtype != 8)
- wpng_info.have_bg = FALSE; /* no need for bg if opaque */
- do {
- fgets(pnmline, 256, wpng_info.infile); /* lose any comments */
- } while (pnmline[0] == '#');
- sscanf(pnmline, "%ld %ld", &wpng_info.width, &wpng_info.height);
- do {
- fgets(pnmline, 256, wpng_info.infile); /* more comment lines */
- } while (pnmline[0] == '#');
- sscanf(pnmline, "%d", &maxval);
- if (wpng_info.width <= 0L || wpng_info.height <= 0L ||
- maxval != 255)
- {
- fprintf(stderr, PROGNAME
- ": only positive width/height, maxval == 255 allowed \n");
- ++error;
- }
- wpng_info.sample_depth = 8; /* <==> maxval 255 */
-
- if (!wpng_info.filter) {
- /* make outname from inname */
- if ((p = strrchr(inname, '.')) == NULL ||
- (p - inname) != (len - 4))
- {
- strcpy(outname, inname);
- strcpy(outname+len, ".png");
- } else {
- len -= 4;
- strncpy(outname, inname, len);
- strcpy(outname+len, ".png");
- }
- /* check if outname already exists; if not, open */
- if ((wpng_info.outfile = fopen(outname, "rb")) != NULL) {
- fprintf(stderr, PROGNAME ": output file exists [%s]\n",
- outname);
- fclose(wpng_info.outfile);
- ++error;
- } else if (!(wpng_info.outfile = fopen(outname, "wb"))) {
- fprintf(stderr, PROGNAME ": can't open output file [%s]\n",
- outname);
- ++error;
- }
- }
- }
- if (error) {
- fclose(wpng_info.infile);
- wpng_info.infile = NULL;
- if (wpng_info.filter) {
- fclose(wpng_info.outfile);
- wpng_info.outfile = NULL;
- }
- }
- }
-
-
- /* if we had any errors, print usage and die horrible death...arrr! */
-
- if (error) {
- fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, APPNAME);
- writepng_version_info();
- fprintf(stderr, "\n"
-"Usage: %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\n"
-"or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\n"
- " exp \ttransfer-function exponent (``gamma'') of the image in\n"
- "\t\t floating-point format (e.g., ``%.5f''); if image looks\n"
- "\t\t correct on given display system, image gamma is equal to\n"
- "\t\t inverse of display-system exponent, i.e., 1 / (LUT * CRT)\n"
- "\t\t (where LUT = lookup-table exponent and CRT = CRT exponent;\n"
- "\t\t first varies, second is usually 2.2, all are positive)\n"
- " bg \tdesired background color for alpha-channel images, in\n"
- "\t\t 7-character hex RGB format (e.g., ``#ff7700'' for orange:\n"
- "\t\t same as HTML colors)\n"
- " -text\tprompt interactively for text info (tEXt chunks)\n"
- " -time\tinclude a tIME chunk (last modification time)\n"
- " -interlace\twrite interlaced PNG image\n"
- "\n"
-"pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\n"
-"unofficial and unsupported!) PAM (`P8') file. Currently it is required\n"
-"to have maxval == 255 (i.e., no scaling). If pnmfile is specified, it\n"
-"is converted to the corresponding PNG file with the same base name but a\n"
-"``.png'' extension; files read from stdin are converted and sent to stdout.\n"
-"The conversion is progressive (low memory usage) unless interlacing is\n"
-"requested; in that case the whole image will be buffered in memory and\n"
-"written in one call.\n"
- "\n", PROGNAME, PROGNAME, default_gamma);
- exit(1);
- }
-
-
- /* prepare the text buffers for libpng's use; note that even though
- * PNG's png_text struct includes a length field, we don't have to fill
- * it out */
-
- if (text &&
-#ifndef DOS_OS2_W32
- (keybd = fdopen(fileno(stderr), "r")) != NULL &&
-#endif
- (textbuf = (char *)malloc((5 + 9)*75)) != NULL)
- {
- int i, valid, result;
-
- fprintf(stderr,
- "Enter text info (no more than 72 characters per line);\n");
- fprintf(stderr, "to skip a field, hit the <Enter> key.\n");
- /* note: just <Enter> leaves len == 1 */
-
- do {
- valid = TRUE;
- p = textbuf + TEXT_TITLE_OFFSET;
- fprintf(stderr, " Title: ");
- fflush(stderr);
- if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
- if (p[len-1] == '\n')
- p[--len] = '\0';
- wpng_info.title = p;
- wpng_info.have_text |= TEXT_TITLE;
- if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
- fprintf(stderr, " " PROGNAME " warning: character code"
- " %u is %sdiscouraged by the PNG\n specification "
- "[first occurrence was at character position #%d]\n",
- (unsigned)p[result], (p[result] == 27)? "strongly " : "",
- result+1);
- fflush(stderr);
-#ifdef FORBID_LATIN1_CTRL
- wpng_info.have_text &= ~TEXT_TITLE;
- valid = FALSE;
-#else
- if (p[result] == 27) { /* escape character */
- wpng_info.have_text &= ~TEXT_TITLE;
- valid = FALSE;
- }
-#endif
- }
- }
- } while (!valid);
-
- do {
- valid = TRUE;
- p = textbuf + TEXT_AUTHOR_OFFSET;
- fprintf(stderr, " Author: ");
- fflush(stderr);
- if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
- if (p[len-1] == '\n')
- p[--len] = '\0';
- wpng_info.author = p;
- wpng_info.have_text |= TEXT_AUTHOR;
- if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
- fprintf(stderr, " " PROGNAME " warning: character code"
- " %u is %sdiscouraged by the PNG\n specification "
- "[first occurrence was at character position #%d]\n",
- (unsigned)p[result], (p[result] == 27)? "strongly " : "",
- result+1);
- fflush(stderr);
-#ifdef FORBID_LATIN1_CTRL
- wpng_info.have_text &= ~TEXT_AUTHOR;
- valid = FALSE;
-#else
- if (p[result] == 27) { /* escape character */
- wpng_info.have_text &= ~TEXT_AUTHOR;
- valid = FALSE;
- }
-#endif
- }
- }
- } while (!valid);
-
- do {
- valid = TRUE;
- p = textbuf + TEXT_DESC_OFFSET;
- fprintf(stderr, " Description (up to 9 lines):\n");
- for (i = 1; i < 10; ++i) {
- fprintf(stderr, " [%d] ", i);
- fflush(stderr);
- if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1)
- p += len; /* now points at NULL; char before is newline */
- else
- break;
- }
- if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) {
- if (p[-1] == '\n') {
- p[-1] = '\0';
- --len;
- }
- wpng_info.desc = textbuf + TEXT_DESC_OFFSET;
- wpng_info.have_text |= TEXT_DESC;
- p = textbuf + TEXT_DESC_OFFSET;
- if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
- fprintf(stderr, " " PROGNAME " warning: character code"
- " %u is %sdiscouraged by the PNG\n specification "
- "[first occurrence was at character position #%d]\n",
- (unsigned)p[result], (p[result] == 27)? "strongly " : "",
- result+1);
- fflush(stderr);
-#ifdef FORBID_LATIN1_CTRL
- wpng_info.have_text &= ~TEXT_DESC;
- valid = FALSE;
-#else
- if (p[result] == 27) { /* escape character */
- wpng_info.have_text &= ~TEXT_DESC;
- valid = FALSE;
- }
-#endif
- }
- }
- } while (!valid);
-
- do {
- valid = TRUE;
- p = textbuf + TEXT_COPY_OFFSET;
- fprintf(stderr, " Copyright: ");
- fflush(stderr);
- if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
- if (p[len-1] == '\n')
- p[--len] = '\0';
- wpng_info.copyright = p;
- wpng_info.have_text |= TEXT_COPY;
- if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
- fprintf(stderr, " " PROGNAME " warning: character code"
- " %u is %sdiscouraged by the PNG\n specification "
- "[first occurrence was at character position #%d]\n",
- (unsigned)p[result], (p[result] == 27)? "strongly " : "",
- result+1);
- fflush(stderr);
-#ifdef FORBID_LATIN1_CTRL
- wpng_info.have_text &= ~TEXT_COPY;
- valid = FALSE;
-#else
- if (p[result] == 27) { /* escape character */
- wpng_info.have_text &= ~TEXT_COPY;
- valid = FALSE;
- }
-#endif
- }
- }
- } while (!valid);
-
- do {
- valid = TRUE;
- p = textbuf + TEXT_EMAIL_OFFSET;
- fprintf(stderr, " E-mail: ");
- fflush(stderr);
- if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
- if (p[len-1] == '\n')
- p[--len] = '\0';
- wpng_info.email = p;
- wpng_info.have_text |= TEXT_EMAIL;
- if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
- fprintf(stderr, " " PROGNAME " warning: character code"
- " %u is %sdiscouraged by the PNG\n specification "
- "[first occurrence was at character position #%d]\n",
- (unsigned)p[result], (p[result] == 27)? "strongly " : "",
- result+1);
- fflush(stderr);
-#ifdef FORBID_LATIN1_CTRL
- wpng_info.have_text &= ~TEXT_EMAIL;
- valid = FALSE;
-#else
- if (p[result] == 27) { /* escape character */
- wpng_info.have_text &= ~TEXT_EMAIL;
- valid = FALSE;
- }
-#endif
- }
- }
- } while (!valid);
-
- do {
- valid = TRUE;
- p = textbuf + TEXT_URL_OFFSET;
- fprintf(stderr, " URL: ");
- fflush(stderr);
- if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) {
- if (p[len-1] == '\n')
- p[--len] = '\0';
- wpng_info.url = p;
- wpng_info.have_text |= TEXT_URL;
- if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) {
- fprintf(stderr, " " PROGNAME " warning: character code"
- " %u is %sdiscouraged by the PNG\n specification "
- "[first occurrence was at character position #%d]\n",
- (unsigned)p[result], (p[result] == 27)? "strongly " : "",
- result+1);
- fflush(stderr);
-#ifdef FORBID_LATIN1_CTRL
- wpng_info.have_text &= ~TEXT_URL;
- valid = FALSE;
-#else
- if (p[result] == 27) { /* escape character */
- wpng_info.have_text &= ~TEXT_URL;
- valid = FALSE;
- }
-#endif
- }
- }
- } while (!valid);
-
-#ifndef DOS_OS2_W32
- fclose(keybd);
-#endif
-
- } else if (text) {
- fprintf(stderr, PROGNAME ": unable to allocate memory for text\n");
- text = FALSE;
- wpng_info.have_text = 0;
- }
-
-
- /* allocate libpng stuff, initialize transformations, write pre-IDAT data */
-
- if ((rc = writepng_init(&wpng_info)) != 0) {
- switch (rc) {
- case 2:
- fprintf(stderr, PROGNAME
- ": libpng initialization problem (longjmp)\n");
- break;
- case 4:
- fprintf(stderr, PROGNAME ": insufficient memory\n");
- break;
- case 11:
- fprintf(stderr, PROGNAME
- ": internal logic error (unexpected PNM type)\n");
- break;
- default:
- fprintf(stderr, PROGNAME
- ": unknown writepng_init() error\n");
- break;
- }
- exit(rc);
- }
-
-
- /* free textbuf, since it's a completely local variable and all text info
- * has just been written to the PNG file */
-
- if (text && textbuf) {
- free(textbuf);
- textbuf = NULL;
- }
-
-
- /* calculate rowbytes on basis of image type; note that this becomes much
- * more complicated if we choose to support PBM type, ASCII PNM types, or
- * 16-bit-per-sample binary data [currently not an official NetPBM type] */
-
- if (wpng_info.pnmtype == 5)
- rowbytes = wpng_info.width;
- else if (wpng_info.pnmtype == 6)
- rowbytes = wpng_info.width * 3;
- else /* if (wpng_info.pnmtype == 8) */
- rowbytes = wpng_info.width * 4;
-
-
- /* read and write the image, either in its entirety (if writing interlaced
- * PNG) or row by row (if non-interlaced) */
-
- fprintf(stderr, "Encoding image data...\n");
- fflush(stderr);
-
- if (wpng_info.interlaced) {
- long i;
- ulg bytes;
- ulg image_bytes;
-
- /* Guard against integer overflow */
- if (wpng_info_height > ((size_t)(-1)/rowbytes ||
- wpng_info_height > ((ulg)(-1)/rowbytes) {
- fprintf(stderr, PROGNAME ": image_data buffer too large\n");
- writepng_cleanup(&wpng_info);
- wpng_cleanup();
- exit(5);
- }
-
- image_bytes = rowbytes * wpng_info.height;
-
- wpng_info.image_data = (uch *)malloc(image_bytes);
- wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));
- if (wpng_info.image_data == NULL || wpng_info.row_pointers == NULL) {
- fprintf(stderr, PROGNAME ": insufficient memory for image data\n");
- writepng_cleanup(&wpng_info);
- wpng_cleanup();
- exit(5);
- }
- for (i = 0; i < wpng_info.height; ++i)
- wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes;
- bytes = fread(wpng_info.image_data, 1, image_bytes, wpng_info.infile);
- if (bytes != image_bytes) {
- fprintf(stderr, PROGNAME ": expected %lu bytes, got %lu bytes\n",
- image_bytes, bytes);
- fprintf(stderr, " (continuing anyway)\n");
- }
- if (writepng_encode_image(&wpng_info) != 0) {
- fprintf(stderr, PROGNAME
- ": libpng problem (longjmp) while writing image data\n");
- writepng_cleanup(&wpng_info);
- wpng_cleanup();
- exit(2);
- }
-
- } else /* not interlaced: write progressively (row by row) */ {
- long j;
- ulg bytes;
-
- wpng_info.image_data = (uch *)malloc(rowbytes);
- if (wpng_info.image_data == NULL) {
- fprintf(stderr, PROGNAME ": insufficient memory for row data\n");
- writepng_cleanup(&wpng_info);
- wpng_cleanup();
- exit(5);
- }
- error = 0;
- for (j = wpng_info.height; j > 0L; --j) {
- bytes = fread(wpng_info.image_data, 1, rowbytes, wpng_info.infile);
- if (bytes != rowbytes) {
- fprintf(stderr, PROGNAME
- ": expected %lu bytes, got %lu bytes (row %ld)\n", rowbytes,
- bytes, wpng_info.height-j);
- ++error;
- break;
- }
- if (writepng_encode_row(&wpng_info) != 0) {
- fprintf(stderr, PROGNAME
- ": libpng problem (longjmp) while writing row %ld\n",
- wpng_info.height-j);
- ++error;
- break;
- }
- }
- if (error) {
- writepng_cleanup(&wpng_info);
- wpng_cleanup();
- exit(2);
- }
- if (writepng_encode_finish(&wpng_info) != 0) {
- fprintf(stderr, PROGNAME ": error on final libpng call\n");
- writepng_cleanup(&wpng_info);
- wpng_cleanup();
- exit(2);
- }
- }
-
-
- /* OK, we're done (successfully): clean up all resources and quit */
-
- fprintf(stderr, "Done.\n");
- fflush(stderr);
-
- writepng_cleanup(&wpng_info);
- wpng_cleanup();
-
- return 0;
-}
-
-
-
-
-
-static int wpng_isvalid_latin1(uch *p, int len)
-{
- int i, result = -1;
-
- for (i = 0; i < len; ++i) {
- if (p[i] == 10 || (p[i] > 31 && p[i] < 127) || p[i] > 160)
- continue; /* character is completely OK */
- if (result < 0 || (p[result] != 27 && p[i] == 27))
- result = i; /* mark location of first questionable one */
- } /* or of first escape character (bad) */
-
- return result;
-}
-
-
-
-
-
-static void wpng_cleanup(void)
-{
- if (wpng_info.outfile) {
- fclose(wpng_info.outfile);
- wpng_info.outfile = NULL;
- }
-
- if (wpng_info.infile) {
- fclose(wpng_info.infile);
- wpng_info.infile = NULL;
- }
-
- if (wpng_info.image_data) {
- free(wpng_info.image_data);
- wpng_info.image_data = NULL;
- }
-
- if (wpng_info.row_pointers) {
- free(wpng_info.row_pointers);
- wpng_info.row_pointers = NULL;
- }
-}
-
-
-
-
-#ifdef DOS_OS2_W32
-
-static char *dos_kbd_gets(char *buf, int len)
-{
- int ch, count=0;
-
- do {
- buf[count++] = ch = getche();
- } while (ch != '\r' && count < len-1);
-
- buf[count--] = '\0'; /* terminate string */
- if (buf[count] == '\r') /* Enter key makes CR, so change to newline */
- buf[count] = '\n';
-
- fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */
- fflush(stderr);
-
- return buf;
-}
-
-#endif /* DOS_OS2_W32 */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.c b/Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.c
deleted file mode 100644
index 055c74374a6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*---------------------------------------------------------------------------
-
- wpng - simple PNG-writing program writepng.c
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2007, 2017 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-
-#include <stdlib.h> /* for exit() prototype */
-#include <zlib.h>
-
-#include "png.h" /* libpng header, includes setjmp.h */
-#include "writepng.h" /* typedefs, common macros, public prototypes */
-
-
-/* local prototype */
-
-static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
-
-
-
-void writepng_version_info(void)
-{
- fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
- PNG_LIBPNG_VER_STRING, png_libpng_ver);
- fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
- ZLIB_VERSION, zlib_version);
-}
-
-
-
-
-/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for
- * unexpected pnmtype; note that outfile might be stdout */
-
-int writepng_init(mainprog_info *mainprog_ptr)
-{
- png_structp png_ptr; /* note: temporary variables! */
- png_infop info_ptr;
- int color_type, interlace_type;
-
-
- /* could also replace libpng warning-handler (final NULL), but no need: */
-
- png_ptr = png_create_write_struct(png_get_libpng_ver(NULL), mainprog_ptr,
- writepng_error_handler, NULL);
- if (!png_ptr)
- return 4; /* out of memory */
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- png_destroy_write_struct(&png_ptr, NULL);
- return 4; /* out of memory */
- }
-
-
- /* setjmp() must be called in every function that calls a PNG-writing
- * libpng function, unless an alternate error handler was installed--
- * but compatible error handlers must either use longjmp() themselves
- * (as in this program) or some other method to return control to
- * application code, so here we go: */
-
- if (setjmp(mainprog_ptr->jmpbuf)) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- return 2;
- }
-
-
- /* make sure outfile is (re)opened in BINARY mode */
-
- png_init_io(png_ptr, mainprog_ptr->outfile);
-
-
- /* set the compression levels--in general, always want to leave filtering
- * turned on (except for palette images) and allow all of the filters,
- * which is the default; want 32K zlib window, unless entire image buffer
- * is 16K or smaller (unknown here)--also the default; usually want max
- * compression (NOT the default); and remaining compression flags should
- * be left alone */
-
- png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
-/*
- >> this is default for no filtering; Z_FILTERED is default otherwise:
- png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
- >> these are all defaults:
- png_set_compression_mem_level(png_ptr, 8);
- png_set_compression_window_bits(png_ptr, 15);
- png_set_compression_method(png_ptr, 8);
- */
-
-
- /* set the image parameters appropriately */
-
- if (mainprog_ptr->pnmtype == 5)
- color_type = PNG_COLOR_TYPE_GRAY;
- else if (mainprog_ptr->pnmtype == 6)
- color_type = PNG_COLOR_TYPE_RGB;
- else if (mainprog_ptr->pnmtype == 8)
- color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- else {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- return 11;
- }
-
- interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 :
- PNG_INTERLACE_NONE;
-
- png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,
- mainprog_ptr->sample_depth, color_type, interlace_type,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- if (mainprog_ptr->gamma > 0.0)
- png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma);
-
- if (mainprog_ptr->have_bg) { /* we know it's RGBA, not gray+alpha */
- png_color_16 background;
-
- background.red = mainprog_ptr->bg_red;
- background.green = mainprog_ptr->bg_green;
- background.blue = mainprog_ptr->bg_blue;
- png_set_bKGD(png_ptr, info_ptr, &background);
- }
-
- if (mainprog_ptr->have_time) {
- png_time modtime;
-
- png_convert_from_time_t(&modtime, mainprog_ptr->modtime);
- png_set_tIME(png_ptr, info_ptr, &modtime);
- }
-
- if (mainprog_ptr->have_text) {
- png_text text[6];
- int num_text = 0;
-
- if (mainprog_ptr->have_text & TEXT_TITLE) {
- text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- text[num_text].key = "Title";
- text[num_text].text = mainprog_ptr->title;
- ++num_text;
- }
- if (mainprog_ptr->have_text & TEXT_AUTHOR) {
- text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- text[num_text].key = "Author";
- text[num_text].text = mainprog_ptr->author;
- ++num_text;
- }
- if (mainprog_ptr->have_text & TEXT_DESC) {
- text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- text[num_text].key = "Description";
- text[num_text].text = mainprog_ptr->desc;
- ++num_text;
- }
- if (mainprog_ptr->have_text & TEXT_COPY) {
- text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- text[num_text].key = "Copyright";
- text[num_text].text = mainprog_ptr->copyright;
- ++num_text;
- }
- if (mainprog_ptr->have_text & TEXT_EMAIL) {
- text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- text[num_text].key = "E-mail";
- text[num_text].text = mainprog_ptr->email;
- ++num_text;
- }
- if (mainprog_ptr->have_text & TEXT_URL) {
- text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- text[num_text].key = "URL";
- text[num_text].text = mainprog_ptr->url;
- ++num_text;
- }
- png_set_text(png_ptr, info_ptr, text, num_text);
- }
-
-
- /* write all chunks up to (but not including) first IDAT */
-
- png_write_info(png_ptr, info_ptr);
-
-
- /* if we wanted to write any more text info *after* the image data, we
- * would set up text struct(s) here and call png_set_text() again, with
- * just the new data; png_set_tIME() could also go here, but it would
- * have no effect since we already called it above (only one tIME chunk
- * allowed) */
-
-
- /* set up the transformations: for now, just pack low-bit-depth pixels
- * into bytes (one, two or four pixels per byte) */
-
- png_set_packing(png_ptr);
-/* png_set_shift(png_ptr, &sig_bit); to scale low-bit-depth values */
-
-
- /* make sure we save our pointers for use in writepng_encode_image() */
-
- mainprog_ptr->png_ptr = png_ptr;
- mainprog_ptr->info_ptr = info_ptr;
-
-
- /* OK, that's all we need to do for now; return happy */
-
- return 0;
-}
-
-
-
-
-
-/* returns 0 for success, 2 for libpng (longjmp) problem */
-
-int writepng_encode_image(mainprog_info *mainprog_ptr)
-{
- png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
- png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
-
-
- /* as always, setjmp() must be called in every function that calls a
- * PNG-writing libpng function */
-
- if (setjmp(mainprog_ptr->jmpbuf)) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- mainprog_ptr->png_ptr = NULL;
- mainprog_ptr->info_ptr = NULL;
- return 2;
- }
-
-
- /* and now we just write the whole image; libpng takes care of interlacing
- * for us */
-
- png_write_image(png_ptr, mainprog_ptr->row_pointers);
-
-
- /* since that's it, we also close out the end of the PNG file now--if we
- * had any text or time info to write after the IDATs, second argument
- * would be info_ptr, but we optimize slightly by sending NULL pointer: */
-
- png_write_end(png_ptr, NULL);
-
- return 0;
-}
-
-
-
-
-
-/* returns 0 if succeeds, 2 if libpng problem */
-
-int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */
-{
- png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
- png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
-
-
- /* as always, setjmp() must be called in every function that calls a
- * PNG-writing libpng function */
-
- if (setjmp(mainprog_ptr->jmpbuf)) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- mainprog_ptr->png_ptr = NULL;
- mainprog_ptr->info_ptr = NULL;
- return 2;
- }
-
-
- /* image_data points at our one row of image data */
-
- png_write_row(png_ptr, mainprog_ptr->image_data);
-
- return 0;
-}
-
-
-
-
-
-/* returns 0 if succeeds, 2 if libpng problem */
-
-int writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */
-{
- png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
- png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
-
-
- /* as always, setjmp() must be called in every function that calls a
- * PNG-writing libpng function */
-
- if (setjmp(mainprog_ptr->jmpbuf)) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- mainprog_ptr->png_ptr = NULL;
- mainprog_ptr->info_ptr = NULL;
- return 2;
- }
-
-
- /* close out PNG file; if we had any text or time info to write after
- * the IDATs, second argument would be info_ptr: */
-
- png_write_end(png_ptr, NULL);
-
- return 0;
-}
-
-
-
-
-
-void writepng_cleanup(mainprog_info *mainprog_ptr)
-{
- png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
- png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
-
- if (png_ptr && info_ptr)
- png_destroy_write_struct(&png_ptr, &info_ptr);
-}
-
-
-
-
-
-static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
-{
- mainprog_info *mainprog_ptr;
-
- /* This function, aside from the extra step of retrieving the "error
- * pointer" (below) and the fact that it exists within the application
- * rather than within libpng, is essentially identical to libpng's
- * default error handler. The second point is critical: since both
- * setjmp() and longjmp() are called from the same code, they are
- * guaranteed to have compatible notions of how big a jmp_buf is,
- * regardless of whether _BSD_SOURCE or anything else has (or has not)
- * been defined. */
-
- fprintf(stderr, "writepng libpng error: %s\n", msg);
- fflush(stderr);
-
- mainprog_ptr = png_get_error_ptr(png_ptr);
- if (mainprog_ptr == NULL) { /* we are completely hosed now */
- fprintf(stderr,
- "writepng severe error: jmpbuf not recoverable; terminating.\n");
- fflush(stderr);
- exit(99);
- }
-
- /* Now we have our data structure we can use the information in it
- * to return control to our own higher level code (all the points
- * where 'setjmp' is called in this file.) This will work with other
- * error handling mechanisms as well - libpng always calls png_error
- * when it can proceed no further, thus, so long as the error handler
- * is intercepted, application code can do its own error recovery.
- */
- longjmp(mainprog_ptr->jmpbuf, 1);
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.h b/Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.h
deleted file mode 100644
index 78b966b5874..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/gregbook/writepng.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*---------------------------------------------------------------------------
-
- wpng - simple PNG-writing program writepng.h
-
- ---------------------------------------------------------------------------
-
- Copyright (c) 1998-2007 Greg Roelofs. All rights reserved.
-
- This software is provided "as is," without warranty of any kind,
- express or implied. In no event shall the author or contributors
- be held liable for any damages arising in any way from the use of
- this software.
-
- The contents of this file are DUAL-LICENSED. You may modify and/or
- redistribute this software according to the terms of one of the
- following two licenses (at your option):
-
-
- LICENSE 1 ("BSD-like with advertising clause"):
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute
- it freely, subject to the following restrictions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, disclaimer, and this list of conditions.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, disclaimer, and this list of conditions in the documenta-
- tion and/or other materials provided with the distribution.
- 3. All advertising materials mentioning features or use of this
- software must display the following acknowledgment:
-
- This product includes software developed by Greg Roelofs
- and contributors for the book, "PNG: The Definitive Guide,"
- published by O'Reilly and Associates.
-
-
- LICENSE 2 (GNU GPL v2 or later):
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- ---------------------------------------------------------------------------*/
-
-#ifndef TRUE
-# define TRUE 1
-# define FALSE 0
-#endif
-
-#ifndef MAX
-# define MAX(a,b) ((a) > (b)? (a) : (b))
-# define MIN(a,b) ((a) < (b)? (a) : (b))
-#endif
-
-#ifdef DEBUG
-# define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);}
-#else
-# define Trace(x) ;
-#endif
-
-#define TEXT_TITLE 0x01
-#define TEXT_AUTHOR 0x02
-#define TEXT_DESC 0x04
-#define TEXT_COPY 0x08
-#define TEXT_EMAIL 0x10
-#define TEXT_URL 0x20
-
-#define TEXT_TITLE_OFFSET 0
-#define TEXT_AUTHOR_OFFSET 72
-#define TEXT_COPY_OFFSET (2*72)
-#define TEXT_EMAIL_OFFSET (3*72)
-#define TEXT_URL_OFFSET (4*72)
-#define TEXT_DESC_OFFSET (5*72)
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-typedef struct _mainprog_info {
- double gamma;
- long width;
- long height;
- time_t modtime;
- FILE *infile;
- FILE *outfile;
- void *png_ptr;
- void *info_ptr;
- uch *image_data;
- uch **row_pointers;
- char *title;
- char *author;
- char *desc;
- char *copyright;
- char *email;
- char *url;
- int filter; /* command-line-filter flag, not PNG row filter! */
- int pnmtype;
- int sample_depth;
- int interlaced;
- int have_bg;
- int have_time;
- int have_text;
- jmp_buf jmpbuf;
- uch bg_red;
- uch bg_green;
- uch bg_blue;
-} mainprog_info;
-
-
-/* prototypes for public functions in writepng.c */
-
-void writepng_version_info(void);
-
-int writepng_init(mainprog_info *mainprog_ptr);
-
-int writepng_encode_image(mainprog_info *mainprog_ptr);
-
-int writepng_encode_row(mainprog_info *mainprog_ptr);
-
-int writepng_encode_finish(mainprog_info *mainprog_ptr);
-
-void writepng_cleanup(mainprog_info *mainprog_ptr);
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/fakepng.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/fakepng.c
deleted file mode 100644
index 6512c140104..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/fakepng.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Fake a PNG - just write it out directly.
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2014.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- */
-
-#include <stdio.h>
-#include <zlib.h> /* for crc32 */
-
-void
-put_uLong(uLong val)
-{
- putchar(val >> 24);
- putchar(val >> 16);
- putchar(val >> 8);
- putchar(val >> 0);
-}
-
-void
-put_chunk(const unsigned char *chunk, uInt length)
-{
- uLong crc;
-
- put_uLong(length-4); /* Exclude the tag */
-
- fwrite(chunk, length, 1, stdout);
-
- crc = crc32(0, Z_NULL, 0);
- put_uLong(crc32(crc, chunk, length));
-}
-
-const unsigned char signature[] =
-{
- 137, 80, 78, 71, 13, 10, 26, 10
-};
-
-const unsigned char IHDR[] =
-{
- 73, 72, 68, 82, /* IHDR */
- 0, 0, 0, 1, /* width */
- 0, 0, 0, 1, /* height */
- 1, /* bit depth */
- 0, /* color type: greyscale */
- 0, /* compression method */
- 0, /* filter method */
- 0 /* interlace method: none */
-};
-
-const unsigned char unknown[] =
-{
- 'u', 'n', 'K', 'n' /* "unKn" - private safe to copy */
-};
-
-int
-main(void)
-{
- fwrite(signature, sizeof signature, 1, stdout);
- put_chunk(IHDR, sizeof IHDR);
-
- for (;;)
- put_chunk(unknown, sizeof unknown);
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/gentests.sh b/Build/source/libs/libpng/libpng-src/contrib/libtests/gentests.sh
deleted file mode 100755
index f0f8d2395a5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/gentests.sh
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2013 John Cunningham Bowler
-#
-# Last changed in libpng 1.6.0 [February 14, 2013]
-#
-# This code is released under the libpng license.
-# For conditions of distribution and use, see the disclaimer
-# and license in png.h
-#
-# Generate a set of PNG test images. The images are generated in a
-# sub-directory called 'tests' by default, however a command line argument will
-# change that name. The generation requires a built version of makepng in the
-# current directory.
-#
-usage(){
- exec >&2
- echo "$0 [<directory>]"
- echo ' Generate a set of PNG test files in "directory" ("tests" by default)'
- exit 1
-}
-
-mp="$PWD/makepng"
-test -x "$mp" || {
- exec >&2
- echo "$0: the 'makepng' program must exist"
- echo " in the directory within which this program:"
- echo " $mp"
- echo " is executed"
- usage
-}
-
-# Just one argument: the directory
-testdir="tests"
-test $# -gt 1 && {
- testdir="$1"
- shift
-}
-test $# -eq 0 || usage
-
-# Take care not to clobber something
-if test -e "$testdir"
-then
- test -d "$testdir" || usage
-else
- # mkdir -p isn't portable, so do the following
- mkdir "$testdir" 2>/dev/null || mkdir -p "$testdir" || usage
-fi
-
-# This fails in a very satisfactory way if it's not accessible
-cd "$testdir"
-:>"test$$.png" || {
- exec >&2
- echo "$testdir: directory not writable"
- usage
-}
-rm "test$$.png" || {
- exec >&2
- echo "$testdir: you have create but not write privileges here."
- echo " This is unexpected. You have a spurion; "'"'"test$$.png"'"'"."
- echo " You need to remove this yourself. Try a different directory."
- exit 1
-}
-
-# Now call makepng ($mp) to create every file we can think of with a
-# reasonable name
-doit(){
- for gamma in "" --sRGB --linear --1.8
- do
- case "$gamma" in
- "")
- gname=;;
- --sRGB)
- gname="-srgb";;
- --linear)
- gname="-lin";;
- --1.8)
- gname="-18";;
- *)
- gname="-$gamma";;
- esac
- "$mp" $gamma "$1" "$2" "test-$1-$2$gname.png"
- done
-}
-#
-for ct in gray palette
-do
- for bd in 1 2 4 8
- do
- doit "$ct" "$bd"
- done
-done
-#
-doit "gray" "16"
-#
-for ct in gray-alpha rgb rgb-alpha
-do
- for bd in 8 16
- do
- doit "$ct" "$bd"
- done
-done
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/makepng.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/makepng.c
deleted file mode 100644
index 312062bda7f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/makepng.c
+++ /dev/null
@@ -1,1941 +0,0 @@
-/* makepng.c */
-#define _ISOC99_SOURCE
-/* Copyright: */
-#define COPYRIGHT "\251 2013,2015 John Cunningham Bowler"
-/*
- * Last changed in libpng 1.6.20 [November 24, 2015]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Make a test PNG image. The arguments are as follows:
- *
- * makepng [--sRGB|--linear|--1.8] [--tRNS] [--nofilters] \
- * color-type bit-depth [file-name]
- *
- * The color-type may be numeric (and must match the numbers used by the PNG
- * specification) or one of the format names listed below. The bit-depth is the
- * component bit depth, or the pixel bit-depth for a color-mapped image.
- *
- * Without any options no color-space information is written, with the options
- * an sRGB or the appropriate gAMA chunk is written. "1.8" refers to the
- * display system used on older Apple computers to correct for high ambient
- * light levels in the viewing environment; it applies a transform of
- * approximately value^(1/1.45) to the color values and so a gAMA chunk of 65909
- * is written (1.45/2.2).
- *
- * The image data is generated internally. Unless --color is given the images
- * used are as follows:
- *
- * 1 channel: a square image with a diamond, the least luminous colors are on
- * the edge of the image, the most luminous in the center.
- *
- * 2 channels: the color channel increases in luminosity from top to bottom, the
- * alpha channel increases in opacity from left to right.
- *
- * 3 channels: linear combinations of, from the top-left corner clockwise,
- * black, green, white, red.
- *
- * 4 channels: linear combinations of, from the top-left corner clockwise,
- * transparent, red, green, blue.
- *
- * For color-mapped images a four channel color-map is used and if --tRNS is
- * given the PNG file has a tRNS chunk, as follows:
- *
- * 1-bit: entry 0 is transparent-red, entry 1 is opaque-white
- * 2-bit: entry 0: transparent-green
- * entry 1: 40%-red
- * entry 2: 80%-blue
- * entry 3: opaque-white
- * 4-bit: the 16 combinations of the 2-bit case
- * 8-bit: the 256 combinations of the 4-bit case
- *
- * The palette always has 2^bit-depth entries and the tRNS chunk one fewer. The
- * image is the 1-channel diamond, but using palette index, not luminosity.
- *
- * For formats other than color-mapped ones if --tRNS is specified a tRNS chunk
- * is generated with all channels equal to the low bits of 0x0101.
- *
- * Image size is determined by the final pixel depth in bits, i.e. channels x
- * bit-depth, as follows:
- *
- * 8 bits or less: 64x64
- * 16 bits: 256x256
- * More than 16 bits: 1024x1024
- *
- * Row filtering is the libpng default but may be turned off (the 'none' filter
- * is used on every row) with the --nofilters option.
- *
- * The images are not interlaced.
- *
- * If file-name is given then the PNG is written to that file, else it is
- * written to stdout. Notice that stdout is not supported on systems where, by
- * default, it assumes text output; this program makes no attempt to change the
- * text mode of stdout!
- *
- * makepng --color=<color> ...
- *
- * If --color is given then the whole image has that color, color-mapped images
- * will have exactly one palette entry and all image files with be 16x16 in
- * size. The color value is 1 to 4 decimal numbers as appropriate for the color
- * type.
- *
- * makepng --small ...
- *
- * If --small is given the images are no larger than required to include every
- * possible pixel value for the format.
- *
- * For formats with pixels 8 bits or fewer in size the images consist of a
- * single row with 2^pixel-depth pixels, one of every possible value.
- *
- * For formats with 16-bit pixels a 256x256 image is generated containing every
- * possible pixel value.
- *
- * For larger pixel sizes a 256x256 image is generated where the first row
- * consists of each pixel that has identical byte values throughout the pixel
- * followed by rows where the byte values differ within the pixel.
- *
- * In all cases the pixel values are arranged in such a way that the SUB and UP
- * filters give byte sequences for maximal zlib compression. By default (if
- * --nofilters is not given) the SUB filter is used on the first row and the UP
- * filter on all following rows.
- *
- * The --small option is meant to provide good test-case coverage, however the
- * images are not easy to examine visually. Without the --small option the
- * images contain identical color values; the pixel values are adjusted
- * according to the gamma encoding with no gamma encoding being interpreted as
- * sRGB.
- *
- * LICENSING
- * =========
- *
- * This code is copyright of the authors, see the COPYRIGHT define above. The
- * code is licensed as above, using the libpng license. The code generates
- * images which are solely the product of the code; the options choose which of
- * the many possibilities to generate. The images that result (but not the code
- * which generates them) are licensed as defined here:
- *
- * IMPORTANT: the COPYRIGHT #define must contain ISO-Latin-1 characters, the
- * IMAGE_LICENSING #define must contain UTF-8 characters. The 'copyright'
- * symbol 0xA9U (\251) in ISO-Latin-1 encoding and 0xC20xA9 (\302\251) in UTF-8.
- */
-#define IMAGE_LICENSING "Dedicated to the public domain per Creative Commons "\
- "license \"CC0 1.0\"; https://creativecommons.org/publicdomain/zero/1.0/"
-
-#include <stddef.h> /* for offsetof */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <math.h>
-#include <errno.h>
-#include <assert.h>
-#include <stdint.h>
-
-#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
-# include <config.h>
-#endif
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-#include <zlib.h>
-
-/* Work round for GCC complaints about casting a (double) function result to
- * an unsigned:
- */
-static unsigned int
-flooru(double d)
-{
- d = floor(d);
- return (unsigned int)d;
-}
-
-static png_byte
-floorb(double d)
-{
- d = floor(d);
- return (png_byte)d;
-}
-
-/* This structure is used for inserting extra chunks (the --insert argument, not
- * documented above.)
- */
-typedef struct chunk_insert
-{
- struct chunk_insert *next;
- void (*insert)(png_structp, png_infop, int, png_charpp);
- int nparams;
- png_charp parameters[1];
-} chunk_insert;
-
-static unsigned int
-channels_of_type(int color_type)
-{
- if (color_type & PNG_COLOR_MASK_PALETTE)
- return 1;
-
- else
- {
- int channels = 1;
-
- if (color_type & PNG_COLOR_MASK_COLOR)
- channels = 3;
-
- if (color_type & PNG_COLOR_MASK_ALPHA)
- return channels + 1;
-
- else
- return channels;
- }
-}
-
-static unsigned int
-pixel_depth_of_type(int color_type, int bit_depth)
-{
- return channels_of_type(color_type) * bit_depth;
-}
-
-static unsigned int
-image_size_of_type(int color_type, int bit_depth, unsigned int *colors,
- int small)
-{
- if (*colors)
- return 16;
-
- else
- {
- int pixel_depth = pixel_depth_of_type(color_type, bit_depth);
-
- if (small)
- {
- if (pixel_depth <= 8) /* there will be one row */
- return 1 << pixel_depth;
-
- else
- return 256;
- }
-
- else if (pixel_depth < 8)
- return 64;
-
- else if (pixel_depth > 16)
- return 1024;
-
- else
- return 256;
- }
-}
-
-static void
-set_color(png_colorp color, png_bytep trans, unsigned int red,
- unsigned int green, unsigned int blue, unsigned int alpha,
- png_const_bytep gamma_table)
-{
- color->red = gamma_table[red];
- color->green = gamma_table[green];
- color->blue = gamma_table[blue];
- *trans = (png_byte)alpha;
-}
-
-static int
-generate_palette(png_colorp palette, png_bytep trans, int bit_depth,
- png_const_bytep gamma_table, unsigned int *colors)
-{
- /*
- * 1-bit: entry 0 is transparent-red, entry 1 is opaque-white
- * 2-bit: entry 0: transparent-green
- * entry 1: 40%-red
- * entry 2: 80%-blue
- * entry 3: opaque-white
- * 4-bit: the 16 combinations of the 2-bit case
- * 8-bit: the 256 combinations of the 4-bit case
- */
- switch (colors[0])
- {
- default:
- fprintf(stderr, "makepng: --colors=...: invalid count %u\n",
- colors[0]);
- exit(1);
-
- case 1:
- set_color(palette+0, trans+0, colors[1], colors[1], colors[1], 255,
- gamma_table);
- return 1;
-
- case 2:
- set_color(palette+0, trans+0, colors[1], colors[1], colors[1],
- colors[2], gamma_table);
- return 1;
-
- case 3:
- set_color(palette+0, trans+0, colors[1], colors[2], colors[3], 255,
- gamma_table);
- return 1;
-
- case 4:
- set_color(palette+0, trans+0, colors[1], colors[2], colors[3],
- colors[4], gamma_table);
- return 1;
-
- case 0:
- if (bit_depth == 1)
- {
- set_color(palette+0, trans+0, 255, 0, 0, 0, gamma_table);
- set_color(palette+1, trans+1, 255, 255, 255, 255, gamma_table);
- return 2;
- }
-
- else
- {
- unsigned int size = 1U << (bit_depth/2); /* 2, 4 or 16 */
- unsigned int x, y;
- volatile unsigned int ip = 0;
-
- for (x=0; x<size; ++x) for (y=0; y<size; ++y)
- {
- ip = x + (size * y);
-
- /* size is at most 16, so the scaled value below fits in 16 bits
- */
-# define interp(pos, c1, c2) ((pos * c1) + ((size-pos) * c2))
-# define xyinterp(x, y, c1, c2, c3, c4) (((size * size / 2) +\
- (interp(x, c1, c2) * y + (size-y) * interp(x, c3, c4))) /\
- (size*size))
-
- set_color(palette+ip, trans+ip,
- /* color: green, red,blue,white */
- xyinterp(x, y, 0, 255, 0, 255),
- xyinterp(x, y, 255, 0, 0, 255),
- xyinterp(x, y, 0, 0, 255, 255),
- /* alpha: 0, 102, 204, 255) */
- xyinterp(x, y, 0, 102, 204, 255),
- gamma_table);
- }
-
- return ip+1;
- }
- }
-}
-
-static void
-set_value(png_bytep row, size_t rowbytes, png_uint_32 x, unsigned int bit_depth,
- png_uint_32 value, png_const_bytep gamma_table, double conv)
-{
- unsigned int mask = (1U << bit_depth)-1;
-
- x *= bit_depth; /* Maximum x is 4*1024, maximum bit_depth is 16 */
-
- if (value <= mask)
- {
- png_uint_32 offset = x >> 3;
-
- if (offset < rowbytes && (bit_depth < 16 || offset+1 < rowbytes))
- {
- row += offset;
-
- switch (bit_depth)
- {
- case 1:
- case 2:
- case 4:
- /* Don't gamma correct - values get smashed */
- {
- unsigned int shift = (8 - bit_depth) - (x & 0x7U);
-
- mask <<= shift;
- value = (value << shift) & mask;
- *row = (png_byte)((*row & ~mask) | value);
- }
- return;
-
- default:
- fprintf(stderr, "makepng: bad bit depth (internal error)\n");
- exit(1);
-
- case 16:
- value = flooru(65535*pow(value/65535.,conv)+.5);
- *row++ = (png_byte)(value >> 8);
- *row = (png_byte)value;
- return;
-
- case 8:
- *row = gamma_table[value];
- return;
- }
- }
-
- else
- {
- fprintf(stderr, "makepng: row buffer overflow (internal error)\n");
- exit(1);
- }
- }
-
- else
- {
- fprintf(stderr, "makepng: component overflow (internal error)\n");
- exit(1);
- }
-}
-
-static int /* filter mask for row */
-generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
- int bit_depth, png_const_bytep gamma_table, double conv,
- unsigned int *colors, int small)
-{
- int filters = 0; /* file *MASK*, 0 means the default, not NONE */
- png_uint_32 size_max =
- image_size_of_type(color_type, bit_depth, colors, small)-1;
- png_uint_32 depth_max = (1U << bit_depth)-1; /* up to 65536 */
-
- if (colors[0] == 0) if (small)
- {
- unsigned int pixel_depth = pixel_depth_of_type(color_type, bit_depth);
-
- /* For pixel depths less than 16 generate a single row containing all the
- * possible pixel values. For 16 generate all 65536 byte pair
- * combinations in a 256x256 pixel array.
- */
- switch (pixel_depth)
- {
- case 1:
- assert(y == 0 && rowbytes == 1 && size_max == 1);
- row[0] = 0x6CU; /* binary: 01101100, only top 2 bits used */
- filters = PNG_FILTER_NONE;
- break;
-
- case 2:
- assert(y == 0 && rowbytes == 1 && size_max == 3);
- row[0] = 0x1BU; /* binary 00011011, all bits used */
- filters = PNG_FILTER_NONE;
- break;
-
- case 4:
- assert(y == 0 && rowbytes == 8 && size_max == 15);
- row[0] = 0x01U;
- row[1] = 0x23U; /* SUB gives 0x22U for all following bytes */
- row[2] = 0x45U;
- row[3] = 0x67U;
- row[4] = 0x89U;
- row[5] = 0xABU;
- row[6] = 0xCDU;
- row[7] = 0xEFU;
- filters = PNG_FILTER_SUB;
- break;
-
- case 8:
- /* The row will have all the pixel values in order starting with
- * '1', the SUB filter will change every byte into '1' (including
- * the last, which generates pixel value '0'). Since the SUB filter
- * has value 1 this should result in maximum compression.
- */
- assert(y == 0 && rowbytes == 256 && size_max == 255);
- for (;;)
- {
- row[size_max] = 0xFFU & (size_max+1);
- if (size_max == 0)
- break;
- --size_max;
- }
- filters = PNG_FILTER_SUB;
- break;
-
- case 16:
- /* Rows are generated such that each row has a constant difference
- * between the first and second byte of each pixel and so that the
- * difference increases by 1 at each row. The rows start with the
- * first byte value of 0 and the value increases to 255 across the
- * row.
- *
- * The difference starts at 1, so the first row is:
- *
- * 0 1 1 2 2 3 3 4 ... 254 255 255 0
- *
- * This means that running the SUB filter on the first row produces:
- *
- * [SUB==1] 0 1 0 1 0 1...
- *
- * Then the difference is 2 on the next row, giving:
- *
- * 0 2 1 3 2 4 3 5 ... 254 0 255 1
- *
- * When the UP filter is run on this libpng produces:
- *
- * [UP ==2] 0 1 0 1 0 1...
- *
- * And so on for all the remain rows to the final two * rows:
- *
- * row 254: 0 255 1 0 2 1 3 2 4 3 ... 254 253 255 254
- * row 255: 0 0 1 1 2 2 3 3 4 4 ... 254 254 255 255
- */
- assert(rowbytes == 512 && size_max == 255);
- for (;;)
- {
- row[2*size_max ] = 0xFFU & size_max;
- row[2*size_max+1] = 0xFFU & (size_max+y+1);
- if (size_max == 0)
- break;
- --size_max;
- }
- /* The first row must include PNG_FILTER_UP so that libpng knows we
- * need to keep it for the following row:
- */
- filters = (y == 0 ? PNG_FILTER_SUB+PNG_FILTER_UP : PNG_FILTER_UP);
- break;
-
- case 24:
- case 32:
- case 48:
- case 64:
- /* The rows are filled by an alogorithm similar to the above, in the
- * first row pixel bytes are all equal, increasing from 0 by 1 for
- * each pixel. In the second row the bytes within a pixel are
- * incremented 1,3,5,7,... from the previous row byte. Using an odd
- * number ensures all the possible byte values are used.
- */
- assert(size_max == 255 && rowbytes == 256*(pixel_depth>>3));
- pixel_depth >>= 3; /* now in bytes */
- while (rowbytes > 0)
- {
- const size_t pixel_index = --rowbytes/pixel_depth;
-
- if (y == 0)
- row[rowbytes] = 0xFFU & pixel_index;
-
- else
- {
- const size_t byte_offset =
- rowbytes - pixel_index * pixel_depth;
-
- row[rowbytes] =
- 0xFFU & (pixel_index + (byte_offset * 2*y) + 1);
- }
- }
- filters = (y == 0 ? PNG_FILTER_SUB+PNG_FILTER_UP : PNG_FILTER_UP);
- break;
-
- default:
- assert(0/*NOT REACHED*/);
- }
- }
-
- else switch (channels_of_type(color_type))
- {
- /* 1 channel: a square image with a diamond, the least luminous colors are on
- * the edge of the image, the most luminous in the center.
- */
- case 1:
- {
- png_uint_32 x;
- png_uint_32 base = 2*size_max - abs(2*y-size_max);
-
- for (x=0; x<=size_max; ++x)
- {
- png_uint_32 luma = base - abs(2*x-size_max);
-
- /* 'luma' is now in the range 0..2*size_max, we need
- * 0..depth_max
- */
- luma = (luma*depth_max + size_max) / (2*size_max);
- set_value(row, rowbytes, x, bit_depth, luma, gamma_table, conv);
- }
- }
- break;
-
- /* 2 channels: the color channel increases in luminosity from top to bottom,
- * the alpha channel increases in opacity from left to right.
- */
- case 2:
- {
- png_uint_32 alpha = (depth_max * y * 2 + size_max) / (2 * size_max);
- png_uint_32 x;
-
- for (x=0; x<=size_max; ++x)
- {
- set_value(row, rowbytes, 2*x, bit_depth,
- (depth_max * x * 2 + size_max) / (2 * size_max), gamma_table,
- conv);
- set_value(row, rowbytes, 2*x+1, bit_depth, alpha, gamma_table,
- conv);
- }
- }
- break;
-
- /* 3 channels: linear combinations of, from the top-left corner clockwise,
- * black, green, white, red.
- */
- case 3:
- {
- /* x0: the black->red scale (the value of the red component) at the
- * start of the row (blue and green are 0).
- * x1: the green->white scale (the value of the red and blue
- * components at the end of the row; green is depth_max).
- */
- png_uint_32 Y = (depth_max * y * 2 + size_max) / (2 * size_max);
- png_uint_32 x;
-
- /* Interpolate x/depth_max from start to end:
- *
- * start end difference
- * red: Y Y 0
- * green: 0 depth_max depth_max
- * blue: 0 Y Y
- */
- for (x=0; x<=size_max; ++x)
- {
- set_value(row, rowbytes, 3*x+0, bit_depth, /* red */ Y,
- gamma_table, conv);
- set_value(row, rowbytes, 3*x+1, bit_depth, /* green */
- (depth_max * x * 2 + size_max) / (2 * size_max),
- gamma_table, conv);
- set_value(row, rowbytes, 3*x+2, bit_depth, /* blue */
- (Y * x * 2 + size_max) / (2 * size_max),
- gamma_table, conv);
- }
- }
- break;
-
- /* 4 channels: linear combinations of, from the top-left corner clockwise,
- * transparent, red, green, blue.
- */
- case 4:
- {
- /* x0: the transparent->blue scale (the value of the blue and alpha
- * components) at the start of the row (red and green are 0).
- * x1: the red->green scale (the value of the red and green
- * components at the end of the row; blue is 0 and alpha is
- * depth_max).
- */
- png_uint_32 Y = (depth_max * y * 2 + size_max) / (2 * size_max);
- png_uint_32 x;
-
- /* Interpolate x/depth_max from start to end:
- *
- * start end difference
- * red: 0 depth_max-Y depth_max-Y
- * green: 0 Y Y
- * blue: Y 0 -Y
- * alpha: Y depth_max depth_max-Y
- */
- for (x=0; x<=size_max; ++x)
- {
- set_value(row, rowbytes, 4*x+0, bit_depth, /* red */
- ((depth_max-Y) * x * 2 + size_max) / (2 * size_max),
- gamma_table, conv);
- set_value(row, rowbytes, 4*x+1, bit_depth, /* green */
- (Y * x * 2 + size_max) / (2 * size_max),
- gamma_table, conv);
- set_value(row, rowbytes, 4*x+2, bit_depth, /* blue */
- Y - (Y * x * 2 + size_max) / (2 * size_max),
- gamma_table, conv);
- set_value(row, rowbytes, 4*x+3, bit_depth, /* alpha */
- Y + ((depth_max-Y) * x * 2 + size_max) / (2 * size_max),
- gamma_table, conv);
- }
- }
- break;
-
- default:
- fprintf(stderr, "makepng: internal bad channel count\n");
- exit(2);
- }
-
- else if (color_type & PNG_COLOR_MASK_PALETTE)
- {
- /* Palette with fixed color: the image rows are all 0 and the image width
- * is 16.
- */
- memset(row, 0, rowbytes);
- }
-
- else if (colors[0] == channels_of_type(color_type))
- switch (channels_of_type(color_type))
- {
- case 1:
- {
- png_uint_32 luma = colors[1];
- png_uint_32 x;
-
- for (x=0; x<=size_max; ++x)
- set_value(row, rowbytes, x, bit_depth, luma, gamma_table,
- conv);
- }
- break;
-
- case 2:
- {
- png_uint_32 luma = colors[1];
- png_uint_32 alpha = colors[2];
- png_uint_32 x;
-
- for (x=0; x<size_max; ++x)
- {
- set_value(row, rowbytes, 2*x, bit_depth, luma, gamma_table,
- conv);
- set_value(row, rowbytes, 2*x+1, bit_depth, alpha, gamma_table,
- conv);
- }
- }
- break;
-
- case 3:
- {
- png_uint_32 red = colors[1];
- png_uint_32 green = colors[2];
- png_uint_32 blue = colors[3];
- png_uint_32 x;
-
- for (x=0; x<=size_max; ++x)
- {
- set_value(row, rowbytes, 3*x+0, bit_depth, red, gamma_table,
- conv);
- set_value(row, rowbytes, 3*x+1, bit_depth, green, gamma_table,
- conv);
- set_value(row, rowbytes, 3*x+2, bit_depth, blue, gamma_table,
- conv);
- }
- }
- break;
-
- case 4:
- {
- png_uint_32 red = colors[1];
- png_uint_32 green = colors[2];
- png_uint_32 blue = colors[3];
- png_uint_32 alpha = colors[4];
- png_uint_32 x;
-
- for (x=0; x<=size_max; ++x)
- {
- set_value(row, rowbytes, 4*x+0, bit_depth, red, gamma_table,
- conv);
- set_value(row, rowbytes, 4*x+1, bit_depth, green, gamma_table,
- conv);
- set_value(row, rowbytes, 4*x+2, bit_depth, blue, gamma_table,
- conv);
- set_value(row, rowbytes, 4*x+3, bit_depth, alpha, gamma_table,
- conv);
- }
- }
- break;
-
- default:
- fprintf(stderr, "makepng: internal bad channel count\n");
- exit(2);
- }
-
- else
- {
- fprintf(stderr,
- "makepng: --color: count(%u) does not match channels(%u)\n",
- colors[0], channels_of_type(color_type));
- exit(1);
- }
-
- return filters;
-}
-
-
-static void PNGCBAPI
-makepng_warning(png_structp png_ptr, png_const_charp message)
-{
- const char **ep = png_get_error_ptr(png_ptr);
- const char *name;
-
- if (ep != NULL && *ep != NULL)
- name = *ep;
-
- else
- name = "makepng";
-
- fprintf(stderr, "%s: warning: %s\n", name, message);
-}
-
-static void PNGCBAPI
-makepng_error(png_structp png_ptr, png_const_charp message)
-{
- makepng_warning(png_ptr, message);
- png_longjmp(png_ptr, 1);
-}
-
-static int /* 0 on success, else an error code */
-write_png(const char **name, FILE *fp, int color_type, int bit_depth,
- volatile png_fixed_point gamma, chunk_insert * volatile insert,
- unsigned int filters, unsigned int *colors, int small, int tRNS)
-{
- png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- name, makepng_error, makepng_warning);
- volatile png_infop info_ptr = NULL;
- volatile png_bytep row = NULL;
-
- if (png_ptr == NULL)
- {
- fprintf(stderr, "makepng: OOM allocating write structure\n");
- return 1;
- }
-
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- png_structp nv_ptr = png_ptr;
- png_infop nv_info = info_ptr;
-
- png_ptr = NULL;
- info_ptr = NULL;
- png_destroy_write_struct(&nv_ptr, &nv_info);
- if (row != NULL) free(row);
- return 1;
- }
-
- /* Allow benign errors so that we can write PNGs with errors */
- png_set_benign_errors(png_ptr, 1/*allowed*/);
-
- /* Max out the text compression level in an attempt to make the license
- * small. If --small then do the same for the IDAT.
- */
- if (small)
- png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
-
- png_set_text_compression_level(png_ptr, Z_BEST_COMPRESSION);
-
- png_init_io(png_ptr, fp);
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- png_error(png_ptr, "OOM allocating info structure");
-
- {
- unsigned int size =
- image_size_of_type(color_type, bit_depth, colors, small);
- unsigned int ysize;
- png_fixed_point real_gamma = 45455; /* For sRGB */
- png_byte gamma_table[256];
- double conv;
-
- /* Normally images are square, but with 'small' we want to simply generate
- * all the pixel values, or all that we reasonably can:
- */
- if (small)
- {
- unsigned int pixel_depth =
- pixel_depth_of_type(color_type, bit_depth);
-
- if (pixel_depth <= 8U)
- {
- assert(size == (1U<<pixel_depth));
- ysize = 1U;
- }
-
- else
- {
- assert(size == 256U);
- ysize = 256U;
- }
- }
-
- else
- ysize = size;
-
- /* This function uses the libpng values used on read to carry extra
- * information about the gamma:
- */
- if (gamma == PNG_GAMMA_MAC_18)
- gamma = 65909;
-
- else if (gamma > 0 && gamma < 1000)
- gamma = PNG_FP_1;
-
- if (gamma > 0)
- real_gamma = gamma;
-
- {
- unsigned int i;
-
- if (real_gamma == 45455) for (i=0; i<256; ++i)
- {
- gamma_table[i] = (png_byte)i;
- conv = 1.;
- }
-
- else
- {
- /* Convert 'i' from sRGB (45455) to real_gamma, this makes
- * the images look the same regardless of the gAMA chunk.
- */
- conv = real_gamma;
- conv /= 45455;
-
- gamma_table[0] = 0;
-
- for (i=1; i<255; ++i)
- gamma_table[i] = floorb(pow(i/255.,conv) * 255 + .5);
-
- gamma_table[255] = 255;
- }
- }
-
- png_set_IHDR(png_ptr, info_ptr, size, ysize, bit_depth, color_type,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
- if (color_type & PNG_COLOR_MASK_PALETTE)
- {
- int npalette;
- png_color palette[256];
- png_byte trans[256];
-
- npalette = generate_palette(palette, trans, bit_depth, gamma_table,
- colors);
- png_set_PLTE(png_ptr, info_ptr, palette, npalette);
-
- if (tRNS)
- png_set_tRNS(png_ptr, info_ptr, trans, npalette-1,
- NULL/*transparent color*/);
-
- /* Reset gamma_table to prevent the image rows being changed */
- for (npalette=0; npalette<256; ++npalette)
- gamma_table[npalette] = (png_byte)npalette;
- }
-
- else if (tRNS)
- {
- png_color_16 col;
-
- col.red = col.green = col.blue = col.gray =
- 0x0101U & ((1U<<bit_depth)-1U);
- col.index = 0U;
- png_set_tRNS(png_ptr, info_ptr, NULL/*trans*/, 1U, &col);
- }
-
- if (gamma == PNG_DEFAULT_sRGB)
- png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_ABSOLUTE);
-
- else if (gamma > 0) /* Else don't set color space information */
- {
- png_set_gAMA_fixed(png_ptr, info_ptr, real_gamma);
-
- /* Just use the sRGB values here. */
- png_set_cHRM_fixed(png_ptr, info_ptr,
- /* color x y */
- /* white */ 31270, 32900,
- /* red */ 64000, 33000,
- /* green */ 30000, 60000,
- /* blue */ 15000, 6000
- );
- }
-
- /* Insert extra information. */
- while (insert != NULL)
- {
- insert->insert(png_ptr, info_ptr, insert->nparams, insert->parameters);
- insert = insert->next;
- }
-
- /* Write the file header. */
- png_write_info(png_ptr, info_ptr);
-
- /* Restrict the filters */
- png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters);
-
- {
-# ifdef PNG_WRITE_INTERLACING_SUPPORTED
- int passes = png_set_interlace_handling(png_ptr);
-# else /* !WRITE_INTERLACING */
- int passes = 1;
-# endif /* !WRITE_INTERLACING */
- int pass;
- size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
-
- row = malloc(rowbytes);
-
- if (row == NULL)
- png_error(png_ptr, "OOM allocating row buffer");
-
- for (pass = 0; pass < passes; ++pass)
- {
- unsigned int y;
-
- for (y=0; y<ysize; ++y)
- {
- unsigned int row_filters =
- generate_row(row, rowbytes, y, color_type, bit_depth,
- gamma_table, conv, colors, small);
-
- if (row_filters != 0 && filters == PNG_ALL_FILTERS)
- png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, row_filters);
-
- png_write_row(png_ptr, row);
- }
- }
- }
- }
-
- /* Finish writing the file. */
- png_write_end(png_ptr, info_ptr);
-
- {
- png_structp nv_ptr = png_ptr;
- png_infop nv_info = info_ptr;
-
- png_ptr = NULL;
- info_ptr = NULL;
- png_destroy_write_struct(&nv_ptr, &nv_info);
- }
- free(row);
- return 0;
-}
-
-
-static size_t
-load_file(png_const_charp name, png_bytepp result)
-{
- FILE *fp = tmpfile();
-
- if (fp != NULL)
- {
- FILE *ip = fopen(name, "rb");
-
- if (ip != NULL)
- {
- size_t total = 0;
- int ch;
-
- for (;;)
- {
- ch = getc(ip);
- if (ch == EOF) break;
- putc(ch, fp);
- ++total;
- }
-
- if (ferror(ip))
- {
- perror(name);
- fprintf(stderr, "%s: read error\n", name);
- (void)fclose(ip);
- }
-
- else
- {
- (void)fclose(ip);
-
- if (ferror(fp))
- {
- perror("temporary file");
- fprintf(stderr, "temporary file write error\n");
- }
-
- else
- {
- rewind(fp);
-
- if (total > 0)
- {
- /* Round up to a multiple of 4 here to allow an iCCP profile
- * to be padded to a 4x boundary.
- */
- png_bytep data = malloc((total+3)&~3);
-
- if (data != NULL)
- {
- size_t new_size = 0;
-
- for (;;)
- {
- ch = getc(fp);
- if (ch == EOF) break;
- data[new_size++] = (png_byte)ch;
- }
-
- if (ferror(fp) || new_size != total)
- {
- perror("temporary file");
- fprintf(stderr, "temporary file read error\n");
- free(data);
- }
-
- else
- {
- (void)fclose(fp);
- *result = data;
- return total;
- }
- }
-
- else
- fprintf(stderr, "%s: out of memory loading file\n", name);
- }
-
- else
- fprintf(stderr, "%s: empty file\n", name);
- }
- }
- }
-
- else
- {
- perror(name);
- fprintf(stderr, "%s: open failed\n", name);
- }
-
- fclose(fp);
- }
-
- else
- fprintf(stderr, "makepng: %s: could not open temporary file\n", name);
-
- exit(1);
- return 0;
-}
-
-static size_t
-load_fake(png_charp param, png_bytepp profile)
-{
- char *endptr = NULL;
- uint64_t size = strtoull(param, &endptr, 0/*base*/);
-
- /* The 'fake' format is <number>*[string] */
- if (endptr != NULL && *endptr == '*')
- {
- size_t len = strlen(++endptr);
- size_t result = (size_t)size;
-
- if (len == 0) len = 1; /* capture the terminating '\0' */
-
- /* Now repeat that string to fill 'size' bytes. */
- if (result == size && (*profile = malloc(result)) != NULL)
- {
- png_bytep out = *profile;
-
- if (len == 1)
- memset(out, *endptr, result);
-
- else
- {
- while (size >= len)
- {
- memcpy(out, endptr, len);
- out += len;
- size -= len;
- }
- memcpy(out, endptr, size);
- }
-
- return result;
- }
-
- else
- {
- fprintf(stderr, "%s: size exceeds system limits\n", param);
- exit(1);
- }
- }
-
- return 0;
-}
-
-static void
-check_param_count(int nparams, int expect)
-{
- if (nparams != expect)
- {
- fprintf(stderr, "bad parameter count (internal error)\n");
- exit(1);
- }
-}
-
-static void
-insert_iCCP(png_structp png_ptr, png_infop info_ptr, int nparams,
- png_charpp params)
-{
- png_bytep profile = NULL;
- png_uint_32 proflen = 0;
- int result;
-
- check_param_count(nparams, 2);
-
- switch (params[1][0])
- {
- case '<':
- {
- size_t filelen = load_file(params[1]+1, &profile);
- if (filelen > 0xfffffffc) /* Maximum profile length */
- {
- fprintf(stderr, "%s: file too long (%lu) for an ICC profile\n",
- params[1]+1, (unsigned long)filelen);
- exit(1);
- }
-
- proflen = (png_uint_32)filelen;
- }
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- size_t fake_len = load_fake(params[1], &profile);
-
- if (fake_len > 0) /* else a simple parameter */
- {
- if (fake_len > 0xffffffff) /* Maximum profile length */
- {
- fprintf(stderr,
- "%s: fake data too long (%lu) for an ICC profile\n",
- params[1], (unsigned long)fake_len);
- exit(1);
- }
- proflen = (png_uint_32)(fake_len & ~3U);
- /* Always fix up the profile length. */
- png_save_uint_32(profile, proflen);
- break;
- }
- }
-
- default:
- fprintf(stderr, "--insert iCCP \"%s\": unrecognized\n", params[1]);
- fprintf(stderr, " use '<' to read a file: \"<filename\"\n");
- exit(1);
- }
-
- result = 1;
-
- if (proflen & 3)
- {
- fprintf(stderr,
- "makepng: --insert iCCP %s: profile length made a multiple of 4\n",
- params[1]);
-
- /* load_file allocates extra space for this padding, the ICC spec requires
- * padding with zero bytes.
- */
- while (proflen & 3)
- profile[proflen++] = 0;
- }
-
- if (profile != NULL && proflen > 3)
- {
- png_uint_32 prof_header = png_get_uint_32(profile);
-
- if (prof_header != proflen)
- {
- fprintf(stderr, "--insert iCCP %s: profile length field wrong:\n",
- params[1]);
- fprintf(stderr, " actual %lu, recorded value %lu (corrected)\n",
- (unsigned long)proflen, (unsigned long)prof_header);
- png_save_uint_32(profile, proflen);
- }
- }
-
- if (result && profile != NULL && proflen >=4)
- png_set_iCCP(png_ptr, info_ptr, params[0], PNG_COMPRESSION_TYPE_BASE,
- profile, proflen);
-
- if (profile)
- free(profile);
-
- if (!result)
- exit(1);
-}
-
-static void
-clear_text(png_text *text, png_charp keyword)
-{
- text->compression = -1; /* none */
- text->key = keyword;
- text->text = NULL;
- text->text_length = 0; /* libpng calculates this */
- text->itxt_length = 0; /* libpng calculates this */
- text->lang = NULL;
- text->lang_key = NULL;
-}
-
-static void
-set_text(png_structp png_ptr, png_infop info_ptr, png_textp text,
- png_charp param)
-{
- switch (param[0])
- {
- case '<':
- {
- png_bytep file = NULL;
-
- text->text_length = load_file(param+1, &file);
- text->text = (png_charp)file;
- }
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- png_bytep data = NULL;
- size_t fake_len = load_fake(param, &data);
-
- if (fake_len > 0) /* else a simple parameter */
- {
- text->text_length = fake_len;
- text->text = (png_charp)data;
- break;
- }
- }
-
- default:
- text->text = param;
- break;
- }
-
- png_set_text(png_ptr, info_ptr, text, 1);
-
- if (text->text != param)
- free(text->text);
-}
-
-static void
-insert_tEXt(png_structp png_ptr, png_infop info_ptr, int nparams,
- png_charpp params)
-{
- png_text text;
-
- check_param_count(nparams, 2);
- clear_text(&text, params[0]);
- set_text(png_ptr, info_ptr, &text, params[1]);
-}
-
-static void
-insert_zTXt(png_structp png_ptr, png_infop info_ptr, int nparams,
- png_charpp params)
-{
- png_text text;
-
- check_param_count(nparams, 2);
- clear_text(&text, params[0]);
- text.compression = 0; /* deflate */
- set_text(png_ptr, info_ptr, &text, params[1]);
-}
-
-static void
-insert_iTXt(png_structp png_ptr, png_infop info_ptr, int nparams,
- png_charpp params)
-{
- png_text text;
-
- check_param_count(nparams, 4);
- clear_text(&text, params[0]);
- text.compression = 2; /* iTXt + deflate */
- text.lang = params[1];/* language tag */
- text.lang_key = params[2]; /* translated keyword */
- set_text(png_ptr, info_ptr, &text, params[3]);
-}
-
-static void
-insert_hIST(png_structp png_ptr, png_infop info_ptr, int nparams,
- png_charpp params)
-{
- int i;
- png_uint_16 freq[256];
-
- /* libpng takes the count from the PLTE count; we don't check it here but we
- * do set the array to 0 for unspecified entries.
- */
- memset(freq, 0, sizeof freq);
- for (i=0; i<nparams; ++i)
- {
- char *endptr = NULL;
- unsigned long int l = strtoul(params[i], &endptr, 0/*base*/);
-
- if (params[i][0] && *endptr == 0 && l <= 65535)
- freq[i] = (png_uint_16)l;
-
- else
- {
- fprintf(stderr, "hIST[%d]: %s: invalid frequency\n", i, params[i]);
- exit(1);
- }
- }
-
- png_set_hIST(png_ptr, info_ptr, freq);
-}
-
-static png_byte
-bval(png_const_structrp png_ptr, png_charp param, unsigned int maxval)
-{
- char *endptr = NULL;
- unsigned long int l = strtoul(param, &endptr, 0/*base*/);
-
- if (param[0] && *endptr == 0 && l <= maxval)
- return (png_byte)l;
-
- else
- png_error(png_ptr, "sBIT: invalid sBIT value");
-}
-
-static void
-insert_sBIT(png_structp png_ptr, png_infop info_ptr, int nparams,
- png_charpp params)
-{
- int ct = png_get_color_type(png_ptr, info_ptr);
- int c = (ct & PNG_COLOR_MASK_COLOR ? 3 : 1) +
- (ct & PNG_COLOR_MASK_ALPHA ? 1 : 0);
- unsigned int maxval =
- ct & PNG_COLOR_MASK_PALETTE ? 8U : png_get_bit_depth(png_ptr, info_ptr);
- png_color_8 sBIT;
-
- if (nparams != c)
- png_error(png_ptr, "sBIT: incorrect parameter count");
-
- if (ct & PNG_COLOR_MASK_COLOR)
- {
- sBIT.red = bval(png_ptr, params[0], maxval);
- sBIT.green = bval(png_ptr, params[1], maxval);
- sBIT.blue = bval(png_ptr, params[2], maxval);
- sBIT.gray = 42;
- }
-
- else
- {
- sBIT.red = sBIT.green = sBIT.blue = 42;
- sBIT.gray = bval(png_ptr, params[0], maxval);
- }
-
- if (ct & PNG_COLOR_MASK_ALPHA)
- sBIT.alpha = bval(png_ptr, params[nparams-1], maxval);
-
- else
- sBIT.alpha = 42;
-
- png_set_sBIT(png_ptr, info_ptr, &sBIT);
-}
-
-#if 0
-static void
-insert_sPLT(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params)
-{
- fprintf(stderr, "insert sPLT: NYI\n");
-}
-#endif
-
-static int
-find_parameters(png_const_charp what, png_charp param, png_charp *list,
- int nparams)
-{
- /* Parameters are separated by '\n' or ':' characters, up to nparams are
- * accepted (more is an error) and the number found is returned.
- */
- int i;
- for (i=0; *param && i<nparams; ++i)
- {
- list[i] = param;
- while (*++param) if (*param == '\n' || *param == ':')
- {
- *param++ = 0; /* Terminate last parameter */
- break; /* And start a new one. */
- }
- }
-
- if (*param)
- {
- fprintf(stderr, "--insert %s: too many parameters (%s)\n", what, param);
- exit(1);
- }
-
- list[i] = NULL; /* terminates list */
- return i; /* number of parameters filled in */
-}
-
-static void
-bad_parameter_count(png_const_charp what, int nparams)
-{
- fprintf(stderr, "--insert %s: bad parameter count %d\n", what, nparams);
- exit(1);
-}
-
-static chunk_insert *
-make_insert(png_const_charp what,
- void (*insert)(png_structp, png_infop, int, png_charpp),
- int nparams, png_charpp list)
-{
- int i;
- chunk_insert *cip;
-
- cip = malloc(offsetof(chunk_insert,parameters) +
- nparams * sizeof (png_charp));
-
- if (cip == NULL)
- {
- fprintf(stderr, "--insert %s: out of memory allocating %d parameters\n",
- what, nparams);
- exit(1);
- }
-
- cip->next = NULL;
- cip->insert = insert;
- cip->nparams = nparams;
- for (i=0; i<nparams; ++i)
- cip->parameters[i] = list[i];
-
- return cip;
-}
-
-static chunk_insert *
-find_insert(png_const_charp what, png_charp param)
-{
- png_uint_32 chunk = 0;
- png_charp parameter_list[1024];
- int i, nparams;
-
- /* Assemble the chunk name */
- for (i=0; i<4; ++i)
- {
- char ch = what[i];
-
- if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122))
- chunk = (chunk << 8) + what[i];
-
- else
- break;
- }
-
- if (i < 4 || what[4] != 0)
- {
- fprintf(stderr, "makepng --insert \"%s\": invalid chunk name\n", what);
- exit(1);
- }
-
- /* Assemble the parameter list. */
- nparams = find_parameters(what, param, parameter_list, 1024);
-
-# define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
-
- switch (chunk)
- {
- case CHUNK(105,67,67,80): /* iCCP */
- if (nparams == 2)
- return make_insert(what, insert_iCCP, nparams, parameter_list);
- break;
-
- case CHUNK(116,69,88,116): /* tEXt */
- if (nparams == 2)
- return make_insert(what, insert_tEXt, nparams, parameter_list);
- break;
-
- case CHUNK(122,84,88,116): /* zTXt */
- if (nparams == 2)
- return make_insert(what, insert_zTXt, nparams, parameter_list);
- break;
-
- case CHUNK(105,84,88,116): /* iTXt */
- if (nparams == 4)
- return make_insert(what, insert_iTXt, nparams, parameter_list);
- break;
-
- case CHUNK(104,73,83,84): /* hIST */
- if (nparams <= 256)
- return make_insert(what, insert_hIST, nparams, parameter_list);
- break;
-
- case CHUNK(115,66,73,84): /* sBIT */
- if (nparams <= 4)
- return make_insert(what, insert_sBIT, nparams, parameter_list);
- break;
-
-#if 0
- case CHUNK(115,80,76,84): /* sPLT */
- return make_insert(what, insert_sPLT, nparams, parameter_list);
-#endif
-
- default:
- fprintf(stderr, "makepng --insert \"%s\": unrecognized chunk name\n",
- what);
- exit(1);
- }
-
- bad_parameter_count(what, nparams);
- return NULL;
-}
-
-/* This is necessary because libpng expects writeable strings for things like
- * text chunks (maybe this should be fixed...)
- */
-static png_charp
-strstash(png_const_charp foo)
-{
- /* The program indicates a memory allocation error by crashing, this is by
- * design.
- */
- if (foo != NULL)
- {
- png_charp bar = malloc(strlen(foo)+1);
- return strcpy(bar, foo);
- }
-
- return NULL;
-}
-
-static png_charp
-strstash_list(const png_const_charp *text)
-{
- size_t foo = 0;
- png_charp result, bar;
- const png_const_charp *line = text;
-
- while (*line != NULL)
- foo += strlen(*line++);
-
- result = bar = malloc(foo+1);
-
- line = text;
- while (*line != NULL)
- {
- foo = strlen(*line);
- memcpy(bar, *line++, foo);
- bar += foo;
- }
-
- *bar = 0;
- return result;
-}
-
-/* These are used to insert Copyright and Licence fields, they allow the text to
- * have \n unlike the --insert option.
- */
-static chunk_insert *
-add_tEXt(const char *key, const png_const_charp *text)
-{
- static char what[5] = { 116, 69, 88, 116, 0 };
- png_charp parameter_list[3];
-
- parameter_list[0] = strstash(key);
- parameter_list[1] = strstash_list(text);
- parameter_list[2] = NULL;
-
- return make_insert(what, insert_tEXt, 2, parameter_list);
-}
-
-static chunk_insert *
-add_iTXt(const char *key, const char *language, const char *language_key,
- const png_const_charp *text)
-{
- static char what[5] = { 105, 84, 88, 116, 0 };
- png_charp parameter_list[5];
-
- parameter_list[0] = strstash(key);
- parameter_list[1] = strstash(language);
- parameter_list[2] = strstash(language_key);
- parameter_list[3] = strstash_list(text);
- parameter_list[4] = NULL;
-
- return make_insert(what, insert_iTXt, 4, parameter_list);
-}
-
-/* This is a not-very-good parser for a sequence of numbers (including 0). It
- * doesn't accept some apparently valid things, but it accepts all the sensible
- * combinations.
- */
-static void
-parse_color(char *arg, unsigned int *colors)
-{
- unsigned int ncolors = 0;
-
- while (*arg && ncolors < 4)
- {
- char *ep = arg;
-
- unsigned long ul = strtoul(arg, &ep, 0);
-
- if (ul > 65535)
- {
- fprintf(stderr, "makepng --color=...'%s': too big\n", arg);
- exit(1);
- }
-
- if (ep == arg)
- {
- fprintf(stderr, "makepng --color=...'%s': not a valid color\n", arg);
- exit(1);
- }
-
- if (*ep) ++ep; /* skip a separator */
- arg = ep;
-
- colors[++ncolors] = (unsigned int)ul; /* checked above */
- }
-
- if (*arg)
- {
- fprintf(stderr, "makepng --color=...'%s': too many values\n", arg);
- exit(1);
- }
-
- *colors = ncolors;
-}
-
-int
-main(int argc, char **argv)
-{
- FILE *fp = stdout;
- const char *file_name = NULL;
- int color_type = 8; /* invalid */
- int bit_depth = 32; /* invalid */
- int small = 0; /* make full size images */
- int tRNS = 0; /* don't output a tRNS chunk */
- unsigned int colors[5];
- unsigned int filters = PNG_ALL_FILTERS;
- png_fixed_point gamma = 0; /* not set */
- chunk_insert *head_insert = NULL;
- chunk_insert **insert_ptr = &head_insert;
-
- memset(colors, 0, sizeof colors);
-
- while (--argc > 0)
- {
- char *arg = *++argv;
-
- if (strcmp(arg, "--small") == 0)
- {
- small = 1;
- continue;
- }
-
- if (strcmp(arg, "--tRNS") == 0)
- {
- tRNS = 1;
- continue;
- }
-
- if (strcmp(arg, "--sRGB") == 0)
- {
- gamma = PNG_DEFAULT_sRGB;
- continue;
- }
-
- if (strcmp(arg, "--linear") == 0)
- {
- gamma = PNG_FP_1;
- continue;
- }
-
- if (strcmp(arg, "--1.8") == 0)
- {
- gamma = PNG_GAMMA_MAC_18;
- continue;
- }
-
- if (strcmp(arg, "--nofilters") == 0)
- {
- filters = PNG_FILTER_NONE;
- continue;
- }
-
- if (strncmp(arg, "--color=", 8) == 0)
- {
- parse_color(arg+8, colors);
- continue;
- }
-
- if (argc >= 3 && strcmp(arg, "--insert") == 0)
- {
- png_const_charp what = *++argv;
- png_charp param = *++argv;
- chunk_insert *new_insert;
-
- argc -= 2;
-
- new_insert = find_insert(what, param);
-
- if (new_insert != NULL)
- {
- *insert_ptr = new_insert;
- insert_ptr = &new_insert->next;
- }
-
- continue;
- }
-
- if (arg[0] == '-')
- {
- fprintf(stderr, "makepng: %s: invalid option\n", arg);
- exit(1);
- }
-
- if (strcmp(arg, "palette") == 0)
- {
- color_type = PNG_COLOR_TYPE_PALETTE;
- continue;
- }
-
- if (strncmp(arg, "gray", 4) == 0)
- {
- if (arg[4] == 0)
- {
- color_type = PNG_COLOR_TYPE_GRAY;
- continue;
- }
-
- else if (strcmp(arg+4, "a") == 0 ||
- strcmp(arg+4, "alpha") == 0 ||
- strcmp(arg+4, "-alpha") == 0)
- {
- color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- continue;
- }
- }
-
- if (strncmp(arg, "rgb", 3) == 0)
- {
- if (arg[3] == 0)
- {
- color_type = PNG_COLOR_TYPE_RGB;
- continue;
- }
-
- else if (strcmp(arg+3, "a") == 0 ||
- strcmp(arg+3, "alpha") == 0 ||
- strcmp(arg+3, "-alpha") == 0)
- {
- color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- continue;
- }
- }
-
- if (color_type == 8 && isdigit(arg[0]))
- {
- color_type = atoi(arg);
- if (color_type < 0 || color_type > 6 || color_type == 1 ||
- color_type == 5)
- {
- fprintf(stderr, "makepng: %s: not a valid color type\n", arg);
- exit(1);
- }
-
- continue;
- }
-
- if (bit_depth == 32 && isdigit(arg[0]))
- {
- bit_depth = atoi(arg);
- if (bit_depth <= 0 || bit_depth > 16 ||
- (bit_depth & -bit_depth) != bit_depth)
- {
- fprintf(stderr, "makepng: %s: not a valid bit depth\n", arg);
- exit(1);
- }
-
- continue;
- }
-
- if (argc == 1) /* It's the file name */
- {
- fp = fopen(arg, "wb");
- if (fp == NULL)
- {
- fprintf(stderr, "%s: %s: could not open\n", arg, strerror(errno));
- exit(1);
- }
-
- file_name = arg;
- continue;
- }
-
- fprintf(stderr, "makepng: %s: unknown argument\n", arg);
- exit(1);
- } /* argument while loop */
-
- if (color_type == 8 || bit_depth == 32)
- {
- fprintf(stderr, "usage: makepng [--small] [--sRGB|--linear|--1.8] "
- "[--color=...] color-type bit-depth [file-name]\n"
- " Make a test PNG file, by default writes to stdout.\n"
- " Other options are available, UTSL.\n");
- exit(1);
- }
-
- /* Check the colors */
- {
- unsigned int lim = (color_type == PNG_COLOR_TYPE_PALETTE ? 255U :
- (1U<<bit_depth)-1);
- unsigned int i;
-
- for (i=1; i<=colors[0]; ++i)
- if (colors[i] > lim)
- {
- fprintf(stderr, "makepng: --color=...: %u out of range [0..%u]\n",
- colors[i], lim);
- exit(1);
- }
- }
-
- /* small and colors are incomparible (will probably crash if both are used at
- * the same time!)
- */
- if (small && colors[0] != 0)
- {
- fprintf(stderr, "makepng: --color --small: only one at a time!\n");
- exit(1);
- }
-
- /* Restrict the filters for more speed to those we know are used for the
- * generated images.
- */
- if (filters == PNG_ALL_FILTERS && !small/*small provides defaults*/)
- {
- if ((color_type & PNG_COLOR_MASK_PALETTE) != 0 || bit_depth < 8)
- filters = PNG_FILTER_NONE;
-
- else if (color_type & PNG_COLOR_MASK_COLOR) /* rgb */
- {
- if (bit_depth == 8)
- filters &= ~(PNG_FILTER_NONE | PNG_FILTER_AVG);
-
- else
- filters = PNG_FILTER_SUB | PNG_FILTER_PAETH;
- }
-
- else /* gray 8 or 16-bit */
- filters &= ~PNG_FILTER_NONE;
- }
-
- /* Insert standard copyright and licence text. */
- {
- static png_const_charp copyright[] =
- {
- COPYRIGHT, /* ISO-Latin-1 */
- NULL
- };
- static png_const_charp licensing[] =
- {
- IMAGE_LICENSING, /* UTF-8 */
- NULL
- };
-
- chunk_insert *new_insert;
-
- new_insert = add_tEXt("Copyright", copyright);
- if (new_insert != NULL)
- {
- *insert_ptr = new_insert;
- insert_ptr = &new_insert->next;
- }
-
- new_insert = add_iTXt("Licensing", "en", NULL, licensing);
- if (new_insert != NULL)
- {
- *insert_ptr = new_insert;
- insert_ptr = &new_insert->next;
- }
- }
-
- {
- int ret = write_png(&file_name, fp, color_type, bit_depth, gamma,
- head_insert, filters, colors, small, tRNS);
-
- if (ret != 0 && file_name != NULL)
- remove(file_name);
-
- return ret;
- }
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c
deleted file mode 100644
index f130c043dff..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngimage.c
+++ /dev/null
@@ -1,1712 +0,0 @@
-/* pngimage.c
- *
- * Copyright (c) 2015,2016 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.24 [August 4, 2016]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Test the png_read_png and png_write_png interfaces. Given a PNG file load it
- * using png_read_png and then write with png_write_png. Test all possible
- * transforms.
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#include <assert.h>
-
-#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
-# include <config.h>
-#endif
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-#ifndef PNG_SETJMP_SUPPORTED
-# include <setjmp.h> /* because png.h did *not* include this */
-#endif
-
-/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
- * a skipped test, in earlier versions we need to succeed on a skipped test, so:
- */
-#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
-# define SKIP 77
-#else
-# define SKIP 0
-#endif
-
-#if PNG_LIBPNG_VER < 10700
- /* READ_PNG and WRITE_PNG were not defined, so: */
-# ifdef PNG_INFO_IMAGE_SUPPORTED
-# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-# define PNG_READ_PNG_SUPPORTED
-# endif /* SEQUENTIAL_READ */
-# ifdef PNG_WRITE_SUPPORTED
-# define PNG_WRITE_PNG_SUPPORTED
-# endif /* WRITE */
-# endif /* INFO_IMAGE */
-#endif /* pre 1.7.0 */
-
-#ifdef PNG_READ_PNG_SUPPORTED
-/* If a transform is valid on both read and write this implies that if the
- * transform is applied to read it must also be applied on write to produce
- * meaningful data. This is because these transforms when performed on read
- * produce data with a memory format that does not correspond to a PNG format.
- *
- * Most of these transforms are invertible; after applying the transform on
- * write the result is the original PNG data that would have would have been
- * read if no transform were applied.
- *
- * The exception is _SHIFT, which destroys the low order bits marked as not
- * significant in a PNG with the sBIT chunk.
- *
- * The following table lists, for each transform, the conditions under which it
- * is expected to do anything. Conditions are defined as follows:
- *
- * 1) Color mask bits required - simply a mask to AND with color_type; one of
- * these must be present for the transform to fire, except that 0 means
- * 'always'.
- * 2) Color mask bits which must be absent - another mask - none of these must
- * be present.
- * 3) Bit depths - a mask of component bit depths for the transform to fire.
- * 4) 'read' - the transform works in png_read_png.
- * 5) 'write' - the transform works in png_write_png.
- * 6) PNG_INFO_chunk; a mask of the chunks that must be present for the
- * transform to fire. All must be present - the requirement is that
- * png_get_valid() & mask == mask, so if mask is 0 there is no requirement.
- *
- * The condition refers to the original image state - if multiple transforms are
- * used together it is possible to cause a transform that wouldn't fire on the
- * original image to fire.
- */
-static struct transform_info
-{
- const char *name;
- int transform;
- png_uint_32 valid_chunks;
-# define CHUNK_NONE 0
-# define CHUNK_sBIT PNG_INFO_sBIT
-# define CHUNK_tRNS PNG_INFO_tRNS
- png_byte color_mask_required;
- png_byte color_mask_absent;
-# define COLOR_MASK_X 0
-# define COLOR_MASK_P PNG_COLOR_MASK_PALETTE
-# define COLOR_MASK_C PNG_COLOR_MASK_COLOR
-# define COLOR_MASK_A PNG_COLOR_MASK_ALPHA
-# define COLOR_MASK_ALL (PALETTE+COLOR+ALPHA) /* absent = gray, no alpha */
- png_byte bit_depths;
-# define BD_ALL (1 + 2 + 4 + 8 + 16)
-# define BD_PAL (1 + 2 + 4 + 8)
-# define BD_LOW (1 + 2 + 4)
-# define BD_16 16
-# define BD_TRUE (8+16) /* i.e. true-color depths */
- png_byte when;
-# define TRANSFORM_R 1
-# define TRANSFORM_W 2
-# define TRANSFORM_RW 3
- png_byte tested; /* the transform was tested somewhere */
-} transform_info[] =
-{
- /* List ALL the PNG_TRANSFORM_ macros here. Check for support using the READ
- * macros; even if the transform is supported on write it cannot be tested
- * without the read support.
- */
-# define T(name,chunk,cm_required,cm_absent,bd,when)\
- { #name, PNG_TRANSFORM_ ## name, CHUNK_ ## chunk,\
- COLOR_MASK_ ## cm_required, COLOR_MASK_ ## cm_absent, BD_ ## bd,\
- TRANSFORM_ ## when, 0/*!tested*/ }
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
- T(STRIP_16, NONE, X, X, 16, R),
- /* drops the bottom 8 bits when bit depth is 16 */
-#endif
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
- T(STRIP_ALPHA, NONE, A, X, ALL, R),
- /* removes the alpha channel if present */
-#endif
-#ifdef PNG_WRITE_PACK_SUPPORTED
-# define TRANSFORM_RW_PACK TRANSFORM_RW
-#else
-# define TRANSFORM_RW_PACK TRANSFORM_R
-#endif
-#ifdef PNG_READ_PACK_SUPPORTED
- T(PACKING, NONE, X, X, LOW, RW_PACK),
- /* unpacks low-bit-depth components into 1 byte per component on read,
- * reverses this on write.
- */
-#endif
-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
-# define TRANSFORM_RW_PACKSWAP TRANSFORM_RW
-#else
-# define TRANSFORM_RW_PACKSWAP TRANSFORM_R
-#endif
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
- T(PACKSWAP, NONE, X, X, LOW, RW_PACKSWAP),
- /* reverses the order of low-bit-depth components packed into a byte */
-#endif
-#ifdef PNG_READ_EXPAND_SUPPORTED
- T(EXPAND, NONE, P, X, ALL, R),
- /* expands PLTE PNG files to RGB (no tRNS) or RGBA (tRNS) *
- * Note that the 'EXPAND' transform does lots of different things: */
- T(EXPAND, NONE, X, C, ALL, R),
- /* expands grayscale PNG files to RGB, or RGBA */
- T(EXPAND, tRNS, X, A, ALL, R),
- /* expands the tRNS chunk in files without alpha */
-#endif
-#ifdef PNG_WRITE_INVERT_SUPPORTED
-# define TRANSFORM_RW_INVERT TRANSFORM_RW
-#else
-# define TRANSFORM_RW_INVERT TRANSFORM_R
-#endif
-#ifdef PNG_READ_INVERT_SUPPORTED
- T(INVERT_MONO, NONE, X, C, ALL, RW_INVERT),
- /* converts gray-scale components to 1..0 from 0..1 */
-#endif
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-# define TRANSFORM_RW_SHIFT TRANSFORM_RW
-#else
-# define TRANSFORM_RW_SHIFT TRANSFORM_R
-#endif
-#ifdef PNG_READ_SHIFT_SUPPORTED
- T(SHIFT, sBIT, X, X, ALL, RW_SHIFT),
- /* reduces component values to the original range based on the sBIT chunk,
- * this is only partially reversible - the low bits are lost and cannot be
- * recovered on write. In fact write code replicates the bits to generate
- * new low-order bits.
- */
-#endif
-#ifdef PNG_WRITE_BGR_SUPPORTED
-# define TRANSFORM_RW_BGR TRANSFORM_RW
-#else
-# define TRANSFORM_RW_BGR TRANSFORM_R
-#endif
-#ifdef PNG_READ_BGR_SUPPORTED
- T(BGR, NONE, C, P, TRUE, RW_BGR),
- /* reverses the rgb component values of true-color pixels */
-#endif
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-# define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_RW
-#else
-# define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_R
-#endif
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
- T(SWAP_ALPHA, NONE, A, X, TRUE, RW_SWAP_ALPHA),
- /* swaps the alpha channel of RGBA or GA pixels to the front - ARGB or
- * AG, on write reverses the process.
- */
-#endif
-#ifdef PNG_WRITE_SWAP_SUPPORTED
-# define TRANSFORM_RW_SWAP TRANSFORM_RW
-#else
-# define TRANSFORM_RW_SWAP TRANSFORM_R
-#endif
-#ifdef PNG_READ_SWAP_SUPPORTED
- T(SWAP_ENDIAN, NONE, X, P, 16, RW_SWAP),
- /* byte-swaps 16-bit component values */
-#endif
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-# define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_RW
-#else
-# define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_R
-#endif
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
- T(INVERT_ALPHA, NONE, A, X, TRUE, RW_INVERT_ALPHA),
- /* converts an alpha channel from 0..1 to 1..0 */
-#endif
-#ifdef PNG_WRITE_FILLER_SUPPORTED
- T(STRIP_FILLER_BEFORE, NONE, A, P, TRUE, W), /* 'A' for a filler! */
- /* on write skips a leading filler channel; testing requires data with a
- * filler channel so this is produced from RGBA or GA images by removing
- * the 'alpha' flag from the color type in place.
- */
- T(STRIP_FILLER_AFTER, NONE, A, P, TRUE, W),
- /* on write strips a trailing filler channel */
-#endif
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
- T(GRAY_TO_RGB, NONE, X, C, ALL, R),
- /* expands grayscale images to RGB, also causes the palette part of
- * 'EXPAND' to happen. Low bit depth grayscale images are expanded to
- * 8-bits per component and no attempt is made to convert the image to a
- * palette image. While this transform is partially reversible
- * png_write_png does not currently support this.
- */
- T(GRAY_TO_RGB, NONE, P, X, ALL, R),
- /* The 'palette' side effect mentioned above; a bit bogus but this is the
- * way the libpng code works.
- */
-#endif
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
- T(EXPAND_16, NONE, X, X, PAL, R),
- /* expands images to 16-bits per component, as a side effect expands
- * palette images to RGB and expands the tRNS chunk if present, so it can
- * modify 16-bit per component images as well:
- */
- T(EXPAND_16, tRNS, X, A, 16, R),
- /* side effect of EXPAND_16 - expands the tRNS chunk in an RGB or G 16-bit
- * image.
- */
-#endif
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
- T(SCALE_16, NONE, X, X, 16, R),
- /* scales 16-bit components to 8-bits. */
-#endif
-
- { NULL /*name*/, 0, 0, 0, 0, 0, 0, 0/*!tested*/ }
-
-#undef T
-};
-
-#define ARRAY_SIZE(a) ((sizeof a)/(sizeof a[0]))
-#define TTABLE_SIZE ARRAY_SIZE(transform_info)
-
-/* Some combinations of options that should be reversible are not; these cases
- * are bugs.
- */
-static int known_bad_combos[][2] =
-{
- /* problem, antidote */
- { PNG_TRANSFORM_SHIFT | PNG_TRANSFORM_INVERT_ALPHA, 0/*antidote*/ }
-};
-
-static int
-is_combo(int transforms)
-{
- return transforms & (transforms-1); /* non-zero if more than one set bit */
-}
-
-static int
-first_transform(int transforms)
-{
- return transforms & -transforms; /* lowest set bit */
-}
-
-static int
-is_bad_combo(int transforms)
-{
- unsigned int i;
-
- for (i=0; i<ARRAY_SIZE(known_bad_combos); ++i)
- {
- int combo = known_bad_combos[i][0];
-
- if ((combo & transforms) == combo &&
- (transforms & known_bad_combos[i][1]) == 0)
- return 1;
- }
-
- return 0; /* combo is ok */
-}
-
-static const char *
-transform_name(int t)
- /* The name, if 't' has multiple bits set the name of the lowest set bit is
- * returned.
- */
-{
- unsigned int i;
-
- t &= -t; /* first set bit */
-
- for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
- {
- if ((transform_info[i].transform & t) != 0)
- return transform_info[i].name;
- }
-
- return "invalid transform";
-}
-
-/* Variables calculated by validate_T below and used to record all the supported
- * transforms. Need (unsigned int) here because of the places where these
- * values are used (unsigned compares in the 'exhaustive' iterator.)
- */
-static unsigned int read_transforms, write_transforms, rw_transforms;
-
-static void
-validate_T(void)
- /* Validate the above table - this just builds the above values */
-{
- unsigned int i;
-
- for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
- {
- if (transform_info[i].when & TRANSFORM_R)
- read_transforms |= transform_info[i].transform;
-
- if (transform_info[i].when & TRANSFORM_W)
- write_transforms |= transform_info[i].transform;
- }
-
- /* Reversible transforms are those which are supported on both read and
- * write.
- */
- rw_transforms = read_transforms & write_transforms;
-}
-
-/* FILE DATA HANDLING
- * The original file is cached in memory. During write the output file is
- * written to memory.
- *
- * In both cases the file data is held in a linked list of buffers - not all
- * of these are in use at any time.
- */
-#define NEW(type) ((type *)malloc(sizeof (type)))
-#define DELETE(ptr) (free(ptr))
-
-struct buffer_list
-{
- struct buffer_list *next; /* next buffer in list */
- png_byte buffer[1024]; /* the actual buffer */
-};
-
-struct buffer
-{
- struct buffer_list *last; /* last buffer in use */
- size_t end_count; /* bytes in the last buffer */
- struct buffer_list *current; /* current buffer being read */
- size_t read_count; /* count of bytes read from current */
- struct buffer_list first; /* the very first buffer */
-};
-
-static void
-buffer_init(struct buffer *buffer)
- /* Call this only once for a given buffer */
-{
- buffer->first.next = NULL;
- buffer->last = NULL;
- buffer->current = NULL;
-}
-
-static void
-buffer_destroy_list(struct buffer_list *list)
-{
- if (list != NULL)
- {
- struct buffer_list *next = list->next;
- DELETE(list);
- buffer_destroy_list(next);
- }
-}
-
-static void
-buffer_destroy(struct buffer *buffer)
-{
- struct buffer_list *list = buffer->first.next;
- buffer_init(buffer);
- buffer_destroy_list(list);
-}
-
-#ifdef PNG_WRITE_PNG_SUPPORTED
-static void
-buffer_start_write(struct buffer *buffer)
-{
- buffer->last = &buffer->first;
- buffer->end_count = 0;
- buffer->current = NULL;
-}
-#endif
-
-static void
-buffer_start_read(struct buffer *buffer)
-{
- buffer->current = &buffer->first;
- buffer->read_count = 0;
-}
-
-#ifdef ENOMEM /* required by POSIX 1003.1 */
-# define MEMORY ENOMEM
-#else
-# define MEMORY ERANGE /* required by ANSI-C */
-#endif
-static struct buffer *
-get_buffer(png_structp pp)
- /* Used from libpng callbacks to get the current buffer */
-{
- return (struct buffer*)png_get_io_ptr(pp);
-}
-
-static struct buffer_list *
-buffer_extend(struct buffer_list *current)
-{
- struct buffer_list *add;
-
- assert(current->next == NULL);
-
- add = NEW(struct buffer_list);
- if (add == NULL)
- return NULL;
-
- add->next = NULL;
- current->next = add;
-
- return add;
-}
-
-/* Load a buffer from a file; does the equivalent of buffer_start_write. On a
- * read error returns an errno value, else returns 0.
- */
-static int
-buffer_from_file(struct buffer *buffer, FILE *fp)
-{
- struct buffer_list *last = &buffer->first;
- size_t count = 0;
-
- for (;;)
- {
- size_t r = fread(last->buffer+count, 1/*size*/,
- (sizeof last->buffer)-count, fp);
-
- if (r > 0)
- {
- count += r;
-
- if (count >= sizeof last->buffer)
- {
- assert(count == sizeof last->buffer);
- count = 0;
-
- if (last->next == NULL)
- {
- last = buffer_extend(last);
- if (last == NULL)
- return MEMORY;
- }
-
- else
- last = last->next;
- }
- }
-
- else /* fread failed - probably end of file */
- {
- if (feof(fp))
- {
- buffer->last = last;
- buffer->end_count = count;
- return 0; /* no error */
- }
-
- /* Some kind of funky error; errno should be non-zero */
- return errno == 0 ? ERANGE : errno;
- }
- }
-}
-
-/* This structure is used to control the test of a single file. */
-typedef enum
-{
- VERBOSE, /* switches on all messages */
- INFORMATION,
- WARNINGS, /* switches on warnings */
- LIBPNG_WARNING,
- APP_WARNING,
- ERRORS, /* just errors */
- APP_FAIL, /* continuable error - no need to longjmp */
- LIBPNG_ERROR, /* this and higher cause a longjmp */
- LIBPNG_BUG, /* erroneous behavior in libpng */
- APP_ERROR, /* such as out-of-memory in a callback */
- QUIET, /* no normal messages */
- USER_ERROR, /* such as file-not-found */
- INTERNAL_ERROR
-} error_level;
-#define LEVEL_MASK 0xf /* where the level is in 'options' */
-
-#define EXHAUSTIVE 0x010 /* Test all combinations of active options */
-#define STRICT 0x020 /* Fail on warnings as well as errors */
-#define LOG 0x040 /* Log pass/fail to stdout */
-#define CONTINUE 0x080 /* Continue on APP_FAIL errors */
-#define SKIP_BUGS 0x100 /* Skip over known bugs */
-#define LOG_SKIPPED 0x200 /* Log skipped bugs */
-#define FIND_BAD_COMBOS 0x400 /* Attempt to deduce bad combos */
-#define LIST_COMBOS 0x800 /* List combos by name */
-
-/* Result masks apply to the result bits in the 'results' field below; these
- * bits are simple 1U<<error_level. A pass requires either nothing worse than
- * warnings (--relaxes) or nothing worse than information (--strict)
- */
-#define RESULT_STRICT(r) (((r) & ~((1U<<WARNINGS)-1)) == 0)
-#define RESULT_RELAXED(r) (((r) & ~((1U<<ERRORS)-1)) == 0)
-
-struct display
-{
- jmp_buf error_return; /* Where to go to on error */
-
- const char *filename; /* The name of the original file */
- const char *operation; /* Operation being performed */
- int transforms; /* Transform used in operation */
- png_uint_32 options; /* See display_log below */
- png_uint_32 results; /* A mask of errors seen */
-
-
- png_structp original_pp; /* used on the original read */
- png_infop original_ip; /* set by the original read */
-
- size_t original_rowbytes; /* of the original rows: */
- png_bytepp original_rows; /* from the original read */
-
- /* Original chunks valid */
- png_uint_32 chunks;
-
- /* Original IHDR information */
- png_uint_32 width;
- png_uint_32 height;
- int bit_depth;
- int color_type;
- int interlace_method;
- int compression_method;
- int filter_method;
-
- /* Derived information for the original image. */
- int active_transforms; /* transforms that do something on read */
- int ignored_transforms; /* transforms that should do nothing */
-
- /* Used on a read, both the original read and when validating a written
- * image.
- */
- png_structp read_pp;
- png_infop read_ip;
-
-# ifdef PNG_WRITE_PNG_SUPPORTED
- /* Used to write a new image (the original info_ptr is used) */
- png_structp write_pp;
- struct buffer written_file; /* where the file gets written */
-# endif
-
- struct buffer original_file; /* Data read from the original file */
-};
-
-static void
-display_init(struct display *dp)
- /* Call this only once right at the start to initialize the control
- * structure, the (struct buffer) lists are maintained across calls - the
- * memory is not freed.
- */
-{
- memset(dp, 0, sizeof *dp);
- dp->options = WARNINGS; /* default to !verbose, !quiet */
- dp->filename = NULL;
- dp->operation = NULL;
- dp->original_pp = NULL;
- dp->original_ip = NULL;
- dp->original_rows = NULL;
- dp->read_pp = NULL;
- dp->read_ip = NULL;
- buffer_init(&dp->original_file);
-
-# ifdef PNG_WRITE_PNG_SUPPORTED
- dp->write_pp = NULL;
- buffer_init(&dp->written_file);
-# endif
-}
-
-static void
-display_clean_read(struct display *dp)
-{
- if (dp->read_pp != NULL)
- png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL);
-}
-
-#ifdef PNG_WRITE_PNG_SUPPORTED
-static void
-display_clean_write(struct display *dp)
-{
- if (dp->write_pp != NULL)
- png_destroy_write_struct(&dp->write_pp, NULL);
-}
-#endif
-
-static void
-display_clean(struct display *dp)
-{
-# ifdef PNG_WRITE_PNG_SUPPORTED
- display_clean_write(dp);
-# endif
- display_clean_read(dp);
-
- dp->original_rowbytes = 0;
- dp->original_rows = NULL;
- dp->chunks = 0;
-
- png_destroy_read_struct(&dp->original_pp, &dp->original_ip, NULL);
- /* leave the filename for error detection */
- dp->results = 0; /* reset for next time */
-}
-
-static void
-display_destroy(struct display *dp)
-{
- /* Release any memory held in the display. */
-# ifdef PNG_WRITE_PNG_SUPPORTED
- buffer_destroy(&dp->written_file);
-# endif
-
- buffer_destroy(&dp->original_file);
-}
-
-static struct display *
-get_dp(png_structp pp)
- /* The display pointer is always stored in the png_struct error pointer */
-{
- struct display *dp = (struct display*)png_get_error_ptr(pp);
-
- if (dp == NULL)
- {
- fprintf(stderr, "pngimage: internal error (no display)\n");
- exit(99); /* prevents a crash */
- }
-
- return dp;
-}
-
-/* error handling */
-#ifdef __GNUC__
-# define VGATTR __attribute__((__format__ (__printf__,3,4)))
- /* Required to quiet GNUC warnings when the compiler sees a stdarg function
- * that calls one of the stdio v APIs.
- */
-#else
-# define VGATTR
-#endif
-static void VGATTR
-display_log(struct display *dp, error_level level, const char *fmt, ...)
- /* 'level' is as above, fmt is a stdio style format string. This routine
- * does not return if level is above LIBPNG_WARNING
- */
-{
- dp->results |= 1U << level;
-
- if (level > (error_level)(dp->options & LEVEL_MASK))
- {
- const char *lp;
- va_list ap;
-
- switch (level)
- {
- case INFORMATION: lp = "information"; break;
- case LIBPNG_WARNING: lp = "warning(libpng)"; break;
- case APP_WARNING: lp = "warning(pngimage)"; break;
- case APP_FAIL: lp = "error(continuable)"; break;
- case LIBPNG_ERROR: lp = "error(libpng)"; break;
- case LIBPNG_BUG: lp = "bug(libpng)"; break;
- case APP_ERROR: lp = "error(pngimage)"; break;
- case USER_ERROR: lp = "error(user)"; break;
-
- case INTERNAL_ERROR: /* anything unexpected is an internal error: */
- case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
- default: lp = "bug(pngimage)"; break;
- }
-
- fprintf(stderr, "%s: %s: %s",
- dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);
-
- if (dp->transforms != 0)
- {
- int tr = dp->transforms;
-
- if (is_combo(tr))
- {
- if (dp->options & LIST_COMBOS)
- {
- int trx = tr;
-
- fprintf(stderr, "(");
- if (trx)
- {
- int start = 0;
-
- while (trx)
- {
- int trz = trx & -trx;
-
- if (start) fprintf(stderr, "+");
- fprintf(stderr, "%s", transform_name(trz));
- start = 1;
- trx &= ~trz;
- }
- }
-
- else
- fprintf(stderr, "-");
- fprintf(stderr, ")");
- }
-
- else
- fprintf(stderr, "(0x%x)", tr);
- }
-
- else
- fprintf(stderr, "(%s)", transform_name(tr));
- }
-
- fprintf(stderr, ": ");
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- fputc('\n', stderr);
- }
- /* else do not output any message */
-
- /* Errors cause this routine to exit to the fail code */
- if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
- longjmp(dp->error_return, level);
-}
-
-/* error handler callbacks for libpng */
-static void PNGCBAPI
-display_warning(png_structp pp, png_const_charp warning)
-{
- display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
-}
-
-static void PNGCBAPI
-display_error(png_structp pp, png_const_charp error)
-{
- struct display *dp = get_dp(pp);
-
- display_log(dp, LIBPNG_ERROR, "%s", error);
-}
-
-static void
-display_cache_file(struct display *dp, const char *filename)
- /* Does the initial cache of the file. */
-{
- FILE *fp;
- int ret;
-
- dp->filename = filename;
-
- if (filename != NULL)
- {
- fp = fopen(filename, "rb");
- if (fp == NULL)
- display_log(dp, USER_ERROR, "open failed: %s", strerror(errno));
- }
-
- else
- fp = stdin;
-
- ret = buffer_from_file(&dp->original_file, fp);
-
- fclose(fp);
-
- if (ret != 0)
- display_log(dp, APP_ERROR, "read failed: %s", strerror(ret));
-}
-
-static void
-buffer_read(struct display *dp, struct buffer *bp, png_bytep data,
- size_t size)
-{
- struct buffer_list *last = bp->current;
- size_t read_count = bp->read_count;
-
- while (size > 0)
- {
- size_t avail;
-
- if (last == NULL ||
- (last == bp->last && read_count >= bp->end_count))
- {
- display_log(dp, USER_ERROR, "file truncated (%lu bytes)",
- (unsigned long)size);
- /*NOTREACHED*/
- break;
- }
-
- else if (read_count >= sizeof last->buffer)
- {
- /* Move to the next buffer: */
- last = last->next;
- read_count = 0;
- bp->current = last; /* Avoid update outside the loop */
-
- /* And do a sanity check (the EOF case is caught above) */
- if (last == NULL)
- {
- display_log(dp, INTERNAL_ERROR, "damaged buffer list");
- /*NOTREACHED*/
- break;
- }
- }
-
- avail = (sizeof last->buffer) - read_count;
- if (avail > size)
- avail = size;
-
- memcpy(data, last->buffer + read_count, avail);
- read_count += avail;
- size -= avail;
- data += avail;
- }
-
- bp->read_count = read_count;
-}
-
-static void PNGCBAPI
-read_function(png_structp pp, png_bytep data, size_t size)
-{
- buffer_read(get_dp(pp), get_buffer(pp), data, size);
-}
-
-static void
-read_png(struct display *dp, struct buffer *bp, const char *operation,
- int transforms)
-{
- png_structp pp;
- png_infop ip;
-
- /* This cleans out any previous read and sets operation and transforms to
- * empty.
- */
- display_clean_read(dp);
-
- if (operation != NULL) /* else this is a verify and do not overwrite info */
- {
- dp->operation = operation;
- dp->transforms = transforms;
- }
-
- dp->read_pp = pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
- display_error, display_warning);
- if (pp == NULL)
- display_log(dp, LIBPNG_ERROR, "failed to create read struct");
-
- /* The png_read_png API requires us to make the info struct, but it does the
- * call to png_read_info.
- */
- dp->read_ip = ip = png_create_info_struct(pp);
- if (ip == NULL)
- display_log(dp, LIBPNG_ERROR, "failed to create info struct");
-
-# ifdef PNG_SET_USER_LIMITS_SUPPORTED
- /* Remove the user limits, if any */
- png_set_user_limits(pp, 0x7fffffff, 0x7fffffff);
-# endif
-
- /* Set the IO handling */
- buffer_start_read(bp);
- png_set_read_fn(pp, bp, read_function);
-
- png_read_png(pp, ip, transforms, NULL/*params*/);
-
-#if 0 /* crazy debugging */
- {
- png_bytep pr = png_get_rows(pp, ip)[0];
- size_t rb = png_get_rowbytes(pp, ip);
- size_t cb;
- char c = ' ';
-
- fprintf(stderr, "%.4x %2d (%3lu bytes):", transforms, png_get_bit_depth(pp,ip), (unsigned long)rb);
-
- for (cb=0; cb<rb; ++cb)
- fputc(c, stderr), fprintf(stderr, "%.2x", pr[cb]), c='.';
-
- fputc('\n', stderr);
- }
-#endif
-}
-
-static void
-update_display(struct display *dp)
- /* called once after the first read to update all the info, original_pp and
- * original_ip must have been filled in.
- */
-{
- png_structp pp;
- png_infop ip;
-
- /* Now perform the initial read with a 0 transform. */
- read_png(dp, &dp->original_file, "original read", 0/*no transform*/);
-
- /* Move the result to the 'original' fields */
- dp->original_pp = pp = dp->read_pp, dp->read_pp = NULL;
- dp->original_ip = ip = dp->read_ip, dp->read_ip = NULL;
-
- dp->original_rowbytes = png_get_rowbytes(pp, ip);
- if (dp->original_rowbytes == 0)
- display_log(dp, LIBPNG_BUG, "png_get_rowbytes returned 0");
-
- dp->chunks = png_get_valid(pp, ip, 0xffffffff);
- if ((dp->chunks & PNG_INFO_IDAT) == 0) /* set by png_read_png */
- display_log(dp, LIBPNG_BUG, "png_read_png did not set IDAT flag");
-
- dp->original_rows = png_get_rows(pp, ip);
- if (dp->original_rows == NULL)
- display_log(dp, LIBPNG_BUG, "png_read_png did not create row buffers");
-
- if (!png_get_IHDR(pp, ip,
- &dp->width, &dp->height, &dp->bit_depth, &dp->color_type,
- &dp->interlace_method, &dp->compression_method, &dp->filter_method))
- display_log(dp, LIBPNG_BUG, "png_get_IHDR failed");
-
- /* 'active' transforms are discovered based on the original image format;
- * running one active transform can activate others. At present the code
- * does not attempt to determine the closure.
- */
- {
- png_uint_32 chunks = dp->chunks;
- int active = 0, inactive = 0;
- int ct = dp->color_type;
- int bd = dp->bit_depth;
- unsigned int i;
-
- for (i=0; i<TTABLE_SIZE; ++i) if (transform_info[i].name != NULL)
- {
- int transform = transform_info[i].transform;
-
- if ((transform_info[i].valid_chunks == 0 ||
- (transform_info[i].valid_chunks & chunks) != 0) &&
- (transform_info[i].color_mask_required & ct) ==
- transform_info[i].color_mask_required &&
- (transform_info[i].color_mask_absent & ct) == 0 &&
- (transform_info[i].bit_depths & bd) != 0 &&
- (transform_info[i].when & TRANSFORM_R) != 0)
- active |= transform;
-
- else if ((transform_info[i].when & TRANSFORM_R) != 0)
- inactive |= transform;
- }
-
- /* Some transforms appear multiple times in the table; the 'active' status
- * is the logical OR of these and the inactive status must be adjusted to
- * take this into account.
- */
- inactive &= ~active;
-
- dp->active_transforms = active;
- dp->ignored_transforms = inactive; /* excluding write-only transforms */
- }
-}
-
-static int
-compare_read(struct display *dp, int applied_transforms)
-{
- /* Compare the png_info from read_ip with original_info */
- size_t rowbytes;
- png_uint_32 width, height;
- int bit_depth, color_type;
- int interlace_method, compression_method, filter_method;
- const char *e = NULL;
-
- png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth,
- &color_type, &interlace_method, &compression_method, &filter_method);
-
-# define C(item) if (item != dp->item) \
- display_log(dp, APP_WARNING, "IHDR " #item "(%lu) changed to %lu",\
- (unsigned long)dp->item, (unsigned long)item), e = #item
-
- /* The IHDR should be identical: */
- C(width);
- C(height);
- C(bit_depth);
- C(color_type);
- C(interlace_method);
- C(compression_method);
- C(filter_method);
-
- /* 'e' remains set to the name of the last thing changed: */
- if (e)
- display_log(dp, APP_ERROR, "IHDR changed (%s)", e);
-
- /* All the chunks from the original PNG should be preserved in the output PNG
- * because the PNG format has not been changed.
- */
- {
- unsigned long chunks =
- png_get_valid(dp->read_pp, dp->read_ip, 0xffffffff);
-
- if (chunks != dp->chunks)
- display_log(dp, APP_FAIL, "PNG chunks changed from 0x%lx to 0x%lx",
- (unsigned long)dp->chunks, chunks);
- }
-
- /* rowbytes should be the same */
- rowbytes = png_get_rowbytes(dp->read_pp, dp->read_ip);
-
- /* NOTE: on 64-bit systems this may trash the top bits of rowbytes,
- * which could lead to weird error messages.
- */
- if (rowbytes != dp->original_rowbytes)
- display_log(dp, APP_ERROR, "PNG rowbytes changed from %lu to %lu",
- (unsigned long)dp->original_rowbytes, (unsigned long)rowbytes);
-
- /* The rows should be the same too, unless the applied transforms includes
- * the shift transform, in which case low bits may have been lost.
- */
- {
- png_bytepp rows = png_get_rows(dp->read_pp, dp->read_ip);
- unsigned int mask; /* mask (if not zero) for the final byte */
-
- if (bit_depth < 8)
- {
- /* Need the stray bits at the end, this depends only on the low bits
- * of the image width; overflow does not matter. If the width is an
- * exact multiple of 8 bits this gives a mask of 0, not 0xff.
- */
- mask = 0xff & (0xff00 >> ((bit_depth * width) & 7));
- }
-
- else
- mask = 0;
-
- if (rows == NULL)
- display_log(dp, LIBPNG_BUG, "png_get_rows returned NULL");
-
- if ((applied_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
- (dp->active_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
- color_type == PNG_COLOR_TYPE_PALETTE)
- {
- unsigned long y;
-
- for (y=0; y<height; ++y)
- {
- png_bytep row = rows[y];
- png_bytep orig = dp->original_rows[y];
-
- if (memcmp(row, orig, rowbytes-(mask != 0)) != 0 || (mask != 0 &&
- ((row[rowbytes-1] & mask) != (orig[rowbytes-1] & mask))))
- {
- size_t x;
-
- /* Find the first error */
- for (x=0; x<rowbytes-1; ++x) if (row[x] != orig[x])
- break;
-
- display_log(dp, APP_FAIL,
- "byte(%lu,%lu) changed 0x%.2x -> 0x%.2x",
- (unsigned long)x, (unsigned long)y, orig[x], row[x]);
- return 0; /* don't keep reporting failed rows on 'continue' */
- }
- }
- }
-
- else
-# ifdef PNG_sBIT_SUPPORTED
- {
- unsigned long y;
- int bpp; /* bits-per-pixel then bytes-per-pixel */
- /* components are up to 8 bytes in size */
- png_byte sig_bits[8];
- png_color_8p sBIT;
-
- if (png_get_sBIT(dp->read_pp, dp->read_ip, &sBIT) != PNG_INFO_sBIT)
- display_log(dp, INTERNAL_ERROR,
- "active shift transform but no sBIT in file");
-
- switch (color_type)
- {
- case PNG_COLOR_TYPE_GRAY:
- sig_bits[0] = sBIT->gray;
- bpp = bit_depth;
- break;
-
- case PNG_COLOR_TYPE_GA:
- sig_bits[0] = sBIT->gray;
- sig_bits[1] = sBIT->alpha;
- bpp = 2 * bit_depth;
- break;
-
- case PNG_COLOR_TYPE_RGB:
- sig_bits[0] = sBIT->red;
- sig_bits[1] = sBIT->green;
- sig_bits[2] = sBIT->blue;
- bpp = 3 * bit_depth;
- break;
-
- case PNG_COLOR_TYPE_RGBA:
- sig_bits[0] = sBIT->red;
- sig_bits[1] = sBIT->green;
- sig_bits[2] = sBIT->blue;
- sig_bits[3] = sBIT->alpha;
- bpp = 4 * bit_depth;
- break;
-
- default:
- display_log(dp, LIBPNG_ERROR, "invalid colour type %d",
- color_type);
- /*NOTREACHED*/
- bpp = 0;
- break;
- }
-
- {
- int b;
-
- for (b=0; 8*b<bpp; ++b)
- {
- /* libpng should catch this; if not there is a security issue
- * because an app (like this one) may overflow an array. In fact
- * libpng doesn't catch this at present.
- */
- if (sig_bits[b] == 0 || sig_bits[b] > bit_depth/*!palette*/)
- display_log(dp, LIBPNG_BUG,
- "invalid sBIT[%u] value %d returned for PNG bit depth %d",
- b, sig_bits[b], bit_depth);
- }
- }
-
- if (bpp < 8 && bpp != bit_depth)
- {
- /* sanity check; this is a grayscale PNG; something is wrong in the
- * code above.
- */
- display_log(dp, INTERNAL_ERROR, "invalid bpp %u for bit_depth %u",
- bpp, bit_depth);
- }
-
- switch (bit_depth)
- {
- int b;
-
- case 16: /* Two bytes per component, big-endian */
- for (b = (bpp >> 4); b > 0; --b)
- {
- unsigned int sig = (unsigned int)(0xffff0000 >> sig_bits[b]);
-
- sig_bits[2*b+1] = (png_byte)sig;
- sig_bits[2*b+0] = (png_byte)(sig >> 8); /* big-endian */
- }
- break;
-
- case 8: /* One byte per component */
- for (b=0; b*8 < bpp; ++b)
- sig_bits[b] = (png_byte)(0xff00 >> sig_bits[b]);
- break;
-
- case 1: /* allowed, but dumb */
- /* Value is 1 */
- sig_bits[0] = 0xff;
- break;
-
- case 2: /* Replicate 4 times */
- /* Value is 1 or 2 */
- b = 0x3 & ((0x3<<2) >> sig_bits[0]);
- b |= b << 2;
- b |= b << 4;
- sig_bits[0] = (png_byte)b;
- break;
-
- case 4: /* Relicate twice */
- /* Value is 1, 2, 3 or 4 */
- b = 0xf & ((0xf << 4) >> sig_bits[0]);
- b |= b << 4;
- sig_bits[0] = (png_byte)b;
- break;
-
- default:
- display_log(dp, LIBPNG_BUG, "invalid bit depth %d", bit_depth);
- break;
- }
-
- /* Convert bpp to bytes; this gives '1' for low-bit depth grayscale,
- * where there are multiple pixels per byte.
- */
- bpp = (bpp+7) >> 3;
-
- /* The mask can be combined with sig_bits[0] */
- if (mask != 0)
- {
- mask &= sig_bits[0];
-
- if (bpp != 1 || mask == 0)
- display_log(dp, INTERNAL_ERROR, "mask calculation error %u, %u",
- bpp, mask);
- }
-
- for (y=0; y<height; ++y)
- {
- png_bytep row = rows[y];
- png_bytep orig = dp->original_rows[y];
- unsigned long x;
-
- for (x=0; x<(width-(mask!=0)); ++x)
- {
- int b;
-
- for (b=0; b<bpp; ++b)
- {
- if ((*row++ & sig_bits[b]) != (*orig++ & sig_bits[b]))
- {
- display_log(dp, APP_FAIL,
- "significant bits at (%lu[%u],%lu) changed %.2x->%.2x",
- x, b, y, orig[-1], row[-1]);
- return 0;
- }
- }
- }
-
- if (mask != 0 && (*row & mask) != (*orig & mask))
- {
- display_log(dp, APP_FAIL,
- "significant bits at (%lu[end],%lu) changed", x, y);
- return 0;
- }
- } /* for y */
- }
-# else /* !sBIT */
- display_log(dp, INTERNAL_ERROR,
- "active shift transform but no sBIT support");
-# endif /* !sBIT */
- }
-
- return 1; /* compare succeeded */
-}
-
-#ifdef PNG_WRITE_PNG_SUPPORTED
-static void
-buffer_write(struct display *dp, struct buffer *buffer, png_bytep data,
- size_t size)
- /* Generic write function used both from the write callback provided to
- * libpng and from the generic read code.
- */
-{
- /* Write the data into the buffer, adding buffers as required */
- struct buffer_list *last = buffer->last;
- size_t end_count = buffer->end_count;
-
- while (size > 0)
- {
- size_t avail;
-
- if (end_count >= sizeof last->buffer)
- {
- if (last->next == NULL)
- {
- last = buffer_extend(last);
-
- if (last == NULL)
- display_log(dp, APP_ERROR, "out of memory saving file");
- }
-
- else
- last = last->next;
-
- buffer->last = last; /* avoid the need to rewrite every time */
- end_count = 0;
- }
-
- avail = (sizeof last->buffer) - end_count;
- if (avail > size)
- avail = size;
-
- memcpy(last->buffer + end_count, data, avail);
- end_count += avail;
- size -= avail;
- data += avail;
- }
-
- buffer->end_count = end_count;
-}
-
-static void PNGCBAPI
-write_function(png_structp pp, png_bytep data, size_t size)
-{
- buffer_write(get_dp(pp), get_buffer(pp), data, size);
-}
-
-static void
-write_png(struct display *dp, png_infop ip, int transforms)
-{
- display_clean_write(dp); /* safety */
-
- buffer_start_write(&dp->written_file);
- dp->operation = "write";
- dp->transforms = transforms;
-
- dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
- display_error, display_warning);
-
- if (dp->write_pp == NULL)
- display_log(dp, APP_ERROR, "failed to create write png_struct");
-
- png_set_write_fn(dp->write_pp, &dp->written_file, write_function,
- NULL/*flush*/);
-
-# ifdef PNG_SET_USER_LIMITS_SUPPORTED
- /* Remove the user limits, if any */
- png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
-# endif
-
- /* Certain transforms require the png_info to be zapped to allow the
- * transform to work correctly.
- */
- if (transforms & (PNG_TRANSFORM_PACKING|
- PNG_TRANSFORM_STRIP_FILLER|
- PNG_TRANSFORM_STRIP_FILLER_BEFORE))
- {
- int ct = dp->color_type;
-
- if (transforms & (PNG_TRANSFORM_STRIP_FILLER|
- PNG_TRANSFORM_STRIP_FILLER_BEFORE))
- ct &= ~PNG_COLOR_MASK_ALPHA;
-
- png_set_IHDR(dp->write_pp, ip, dp->width, dp->height, dp->bit_depth, ct,
- dp->interlace_method, dp->compression_method, dp->filter_method);
- }
-
- png_write_png(dp->write_pp, ip, transforms, NULL/*params*/);
-
- /* Clean it on the way out - if control returns to the caller then the
- * written_file contains the required data.
- */
- display_clean_write(dp);
-}
-#endif /* WRITE_PNG */
-
-static int
-skip_transform(struct display *dp, int tr)
- /* Helper to test for a bad combo and log it if it is skipped */
-{
- if ((dp->options & SKIP_BUGS) != 0 && is_bad_combo(tr))
- {
- /* Log this to stdout if logging is on, otherwise just do an information
- * display_log.
- */
- if ((dp->options & LOG_SKIPPED) != 0)
- {
- printf("SKIP: %s transforms ", dp->filename);
-
- while (tr != 0)
- {
- int next = first_transform(tr);
- tr &= ~next;
-
- printf("%s", transform_name(next));
- if (tr != 0)
- putchar('+');
- }
-
- putchar('\n');
- }
-
- else
- display_log(dp, INFORMATION, "%s: skipped known bad combo 0x%x",
- dp->filename, tr);
-
- return 1; /* skip */
- }
-
- return 0; /* don't skip */
-}
-
-static void
-test_one_file(struct display *dp, const char *filename)
-{
- /* First cache the file and update the display original file
- * information for the new file.
- */
- dp->operation = "cache file";
- dp->transforms = 0;
- display_cache_file(dp, filename);
- update_display(dp);
-
- /* First test: if there are options that should be ignored for this file
- * verify that they really are ignored.
- */
- if (dp->ignored_transforms != 0)
- {
- read_png(dp, &dp->original_file, "ignored transforms",
- dp->ignored_transforms);
-
- /* The result should be identical to the original_rows */
- if (!compare_read(dp, 0/*transforms applied*/))
- return; /* no point testing more */
- }
-
-#ifdef PNG_WRITE_PNG_SUPPORTED
- /* Second test: write the original PNG data out to a new file (to test the
- * write side) then read the result back in and make sure that it hasn't
- * changed.
- */
- dp->operation = "write";
- write_png(dp, dp->original_ip, 0/*transforms*/);
- read_png(dp, &dp->written_file, NULL, 0/*transforms*/);
- if (!compare_read(dp, 0/*transforms applied*/))
- return;
-#endif
-
- /* Third test: the active options. Test each in turn, or, with the
- * EXHAUSTIVE option, test all possible combinations.
- */
- {
- /* Use unsigned int here because the code below to increment through all
- * the possibilities exhaustively has to use a compare and that must be
- * unsigned, because some transforms are negative on a 16-bit system.
- */
- unsigned int active = dp->active_transforms;
- int exhaustive = (dp->options & EXHAUSTIVE) != 0;
- unsigned int current = first_transform(active);
- unsigned int bad_transforms = 0;
- unsigned int bad_combo = ~0U; /* bitwise AND of failing transforms */
- unsigned int bad_combo_list = 0; /* bitwise OR of failures */
-
- for (;;)
- {
- read_png(dp, &dp->original_file, "active transforms", current);
-
- /* If this involved any irreversible transformations then if we write
- * it out with just the reversible transformations and read it in again
- * with the same transforms we should get the same thing. At present
- * this isn't done - it just seems like a waste of time and it would
- * require two sets of read png_struct/png_info.
- *
- * If there were no irreversible transformations then if we write it
- * out and read it back in again (without the reversible transforms)
- * we should get back to the place where we started.
- */
-#ifdef PNG_WRITE_PNG_SUPPORTED
- if ((current & write_transforms) == current)
- {
- /* All transforms reversible: write the PNG with the transformations
- * reversed, then read it back in with no transformations. The
- * result should be the same as the original apart from the loss of
- * low order bits because of the SHIFT/sBIT transform.
- */
- dp->operation = "reversible transforms";
- write_png(dp, dp->read_ip, current);
-
- /* And if this is read back in, because all the transformations were
- * reversible, the result should be the same.
- */
- read_png(dp, &dp->written_file, NULL, 0);
- if (!compare_read(dp, current/*for the SHIFT/sBIT transform*/))
- {
- /* This set of transforms failed. If a single bit is set - if
- * there is just one transform - don't include this in further
- * 'exhaustive' tests. Notice that each transform is tested on
- * its own before testing combos in the exhaustive case.
- */
- if (is_combo(current))
- {
- bad_combo &= current;
- bad_combo_list |= current;
- }
-
- else
- bad_transforms |= current;
- }
- }
-#endif
-
- /* Now move to the next transform */
- if (exhaustive) /* all combinations */
- {
- unsigned int next = current;
-
- do
- {
- if (next == read_transforms) /* Everything tested */
- goto combo;
-
- ++next;
- } /* skip known bad combos if the relevant option is set; skip
- * combos involving known bad single transforms in all cases.
- */
- while ( (next & read_transforms) <= current
- || (next & active) == 0 /* skip cases that do nothing */
- || (next & bad_transforms) != 0
- || skip_transform(dp, next));
-
- assert((next & read_transforms) == next);
- current = next;
- }
-
- else /* one at a time */
- {
- active &= ~current;
-
- if (active == 0)
- goto combo;
-
- current = first_transform(active);
- }
- }
-
-combo:
- if (dp->options & FIND_BAD_COMBOS)
- {
- /* bad_combos identifies the combos that occur in all failing cases;
- * bad_combo_list identifies transforms that do not prevent the
- * failure.
- */
- if (bad_combo != ~0U)
- printf("%s[0x%x]: PROBLEM: 0x%x[0x%x] ANTIDOTE: 0x%x\n",
- dp->filename, active, bad_combo, bad_combo_list,
- rw_transforms & ~bad_combo_list);
-
- else
- printf("%s: no %sbad combos found\n", dp->filename,
- (dp->options & SKIP_BUGS) ? "additional " : "");
- }
- }
-}
-
-static int
-do_test(struct display *dp, const char *file)
- /* Exists solely to isolate the setjmp clobbers */
-{
- int ret = setjmp(dp->error_return);
-
- if (ret == 0)
- {
- test_one_file(dp, file);
- return 0;
- }
-
- else if (ret < ERRORS) /* shouldn't longjmp on warnings */
- display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
-
- return ret;
-}
-
-int
-main(int argc, char **argv)
-{
- /* For each file on the command line test it with a range of transforms */
- int option_end, ilog = 0;
- struct display d;
-
- validate_T();
- display_init(&d);
-
- for (option_end=1; option_end<argc; ++option_end)
- {
- const char *name = argv[option_end];
-
- if (strcmp(name, "--verbose") == 0)
- d.options = (d.options & ~LEVEL_MASK) | VERBOSE;
-
- else if (strcmp(name, "--warnings") == 0)
- d.options = (d.options & ~LEVEL_MASK) | WARNINGS;
-
- else if (strcmp(name, "--errors") == 0)
- d.options = (d.options & ~LEVEL_MASK) | ERRORS;
-
- else if (strcmp(name, "--quiet") == 0)
- d.options = (d.options & ~LEVEL_MASK) | QUIET;
-
- else if (strcmp(name, "--exhaustive") == 0)
- d.options |= EXHAUSTIVE;
-
- else if (strcmp(name, "--fast") == 0)
- d.options &= ~EXHAUSTIVE;
-
- else if (strcmp(name, "--strict") == 0)
- d.options |= STRICT;
-
- else if (strcmp(name, "--relaxed") == 0)
- d.options &= ~STRICT;
-
- else if (strcmp(name, "--log") == 0)
- {
- ilog = option_end; /* prevent display */
- d.options |= LOG;
- }
-
- else if (strcmp(name, "--nolog") == 0)
- d.options &= ~LOG;
-
- else if (strcmp(name, "--continue") == 0)
- d.options |= CONTINUE;
-
- else if (strcmp(name, "--stop") == 0)
- d.options &= ~CONTINUE;
-
- else if (strcmp(name, "--skip-bugs") == 0)
- d.options |= SKIP_BUGS;
-
- else if (strcmp(name, "--test-all") == 0)
- d.options &= ~SKIP_BUGS;
-
- else if (strcmp(name, "--log-skipped") == 0)
- d.options |= LOG_SKIPPED;
-
- else if (strcmp(name, "--nolog-skipped") == 0)
- d.options &= ~LOG_SKIPPED;
-
- else if (strcmp(name, "--find-bad-combos") == 0)
- d.options |= FIND_BAD_COMBOS;
-
- else if (strcmp(name, "--nofind-bad-combos") == 0)
- d.options &= ~FIND_BAD_COMBOS;
-
- else if (strcmp(name, "--list-combos") == 0)
- d.options |= LIST_COMBOS;
-
- else if (strcmp(name, "--nolist-combos") == 0)
- d.options &= ~LIST_COMBOS;
-
- else if (name[0] == '-' && name[1] == '-')
- {
- fprintf(stderr, "pngimage: %s: unknown option\n", name);
- return 99;
- }
-
- else
- break; /* Not an option */
- }
-
- {
- int i;
- int errors = 0;
-
- for (i=option_end; i<argc; ++i)
- {
- {
- int ret = do_test(&d, argv[i]);
-
- if (ret > QUIET) /* abort on user or internal error */
- return 99;
- }
-
- /* Here on any return, including failures, except user/internal issues
- */
- {
- int pass = (d.options & STRICT) ?
- RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
-
- if (!pass)
- ++errors;
-
- if (d.options & LOG)
- {
- int j;
-
- printf("%s: pngimage ", pass ? "PASS" : "FAIL");
-
- for (j=1; j<option_end; ++j) if (j != ilog)
- printf("%s ", argv[j]);
-
- printf("%s\n", d.filename);
- }
- }
-
- display_clean(&d);
- }
-
- /* Release allocated memory */
- display_destroy(&d);
-
- return errors != 0;
- }
-}
-#else /* !READ_PNG */
-int
-main(void)
-{
- fprintf(stderr, "pngimage: no support for png_read/write_image\n");
- return SKIP;
-}
-#endif
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest-errors.h b/Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest-errors.h
deleted file mode 100644
index 3356f1c46ff..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest-errors.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* contrib/libtests/pngstest-errors.h
- *
- * BUILT USING: libpng version 1.6.19beta03 - September 25, 2015
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * THIS IS A MACHINE GENERATED FILE: do not edit it directly!
- * Instead run:
- *
- * pngstest --accumulate
- *
- * on as many PNG files as possible; at least PNGSuite and
- * contrib/libtests/testpngs.
- */
-static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] =
-{
- { /* input: sRGB-gray */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 372, 0 }, { 0, 0, 372, 0 }, { 0, 0, 372, 0 }, { 0, 0, 372, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: sRGB-gray+alpha */
- { 0, 19, 0, 0 }, { 0, 0, 0, 0 }, { 0, 20, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 897, 788, 0 }, { 0, 897, 788, 0 }, { 0, 897, 788, 0 }, { 0, 897, 788, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: sRGB-rgb */
- { 0, 0, 19, 0 }, { 0, 0, 19, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 893, 0 }, { 0, 0, 893, 0 }, { 0, 0, 811, 0 }, { 0, 0, 811, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: sRGB-rgb+alpha */
- { 0, 16, 17, 0 }, { 0, 17, 17, 0 }, { 0, 19, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 850, 875, 0 }, { 0, 850, 875, 0 }, { 0, 897, 788, 0 }, { 0, 897, 788, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: linear-gray */
- { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: linear-gray+alpha */
- { 0, 74, 9, 0 }, { 0, 20, 9, 0 }, { 0, 74, 9, 0 }, { 0, 20, 9, 0 },
- { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: linear-rgb */
- { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },
- { 0, 0, 4, 0 }, { 0, 0, 4, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: linear-rgb+alpha */
- { 0, 126, 143, 0 }, { 0, 11, 7, 0 }, { 0, 74, 9, 0 }, { 0, 17, 9, 0 },
- { 0, 4, 4, 0 }, { 0, 5, 4, 0 }, { 0, 0, 0, 0 }, { 0, 1, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-sRGB-gray */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-sRGB-gray+alpha */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-sRGB-rgb */
- { 0, 0, 13, 0 }, { 0, 0, 13, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },
- { 0, 0, 673, 0 }, { 0, 0, 673, 0 }, { 0, 0, 674, 0 }, { 0, 0, 674, 0 },
- { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 460, 0 }, { 0, 0, 460, 0 }, { 0, 0, 263, 0 }, { 0, 0, 263, 0 }
- }, { /* input: color-mapped-sRGB-rgb+alpha */
- { 0, 6, 8, 0 }, { 0, 7, 8, 0 }, { 0, 75, 9, 0 }, { 0, 9, 9, 0 },
- { 0, 585, 427, 0 }, { 0, 585, 427, 0 }, { 0, 717, 514, 0 }, { 0, 717, 514, 0 },
- { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 13323, 460, 0 }, { 0, 427, 460, 0 }, { 0, 16480, 263, 0 }, { 0, 243, 263, 0 }
- }, { /* input: color-mapped-linear-gray */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 282, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-linear-gray+alpha */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 253, 282, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-linear-rgb */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 265, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-linear-rgb+alpha */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 243, 265, 0 }
- }
-};
-static png_uint_16 gpc_error_via_linear[16][4/*out*/][4] =
-{
- { /* input: sRGB-gray */
- { 0, 0, 7, 0 }, { 0, 0, 7, 0 }, { 0, 0, 7, 0 }, { 0, 0, 7, 0 }
- }, { /* input: sRGB-gray+alpha */
- { 0, 15, 15, 0 }, { 0, 186, 15, 0 }, { 0, 15, 15, 0 }, { 0, 186, 15, 0 }
- }, { /* input: sRGB-rgb */
- { 0, 0, 20, 0 }, { 0, 0, 20, 0 }, { 0, 0, 15, 0 }, { 0, 0, 15, 0 }
- }, { /* input: sRGB-rgb+alpha */
- { 0, 16, 17, 0 }, { 0, 187, 17, 0 }, { 0, 15, 15, 0 }, { 0, 186, 15, 0 }
- }, { /* input: linear-gray */
- { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }
- }, { /* input: linear-gray+alpha */
- { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
- }, { /* input: linear-rgb */
- { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }
- }, { /* input: linear-rgb+alpha */
- { 0, 1, 1, 0 }, { 0, 9, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
- }, { /* input: color-mapped-sRGB-gray */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-sRGB-gray+alpha */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-sRGB-rgb */
- { 0, 0, 13, 0 }, { 0, 0, 13, 0 }, { 0, 0, 14, 0 }, { 0, 0, 14, 0 }
- }, { /* input: color-mapped-sRGB-rgb+alpha */
- { 0, 4, 8, 0 }, { 0, 9, 8, 0 }, { 0, 9, 5, 0 }, { 0, 32, 5, 0 }
- }, { /* input: color-mapped-linear-gray */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-linear-gray+alpha */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-linear-rgb */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }, { /* input: color-mapped-linear-rgb+alpha */
- { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
- }
-};
-static png_uint_16 gpc_error_to_colormap[8/*i*/][8/*o*/][4] =
-{
- { /* input: sRGB-gray */
- { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 }, { 0, 0, 9, 0 },
- { 0, 0, 560, 0 }, { 0, 0, 560, 0 }, { 0, 0, 560, 0 }, { 0, 0, 560, 0 }
- }, { /* input: sRGB-gray+alpha */
- { 0, 19, 9, 0 }, { 0, 255, 9, 25 }, { 0, 88, 9, 0 }, { 0, 255, 9, 25 },
- { 0, 1012, 928, 0 }, { 0, 16026, 928, 6425 }, { 0, 1012, 928, 0 }, { 0, 16026, 928, 6425 }
- }, { /* input: sRGB-rgb */
- { 0, 0, 19, 0 }, { 0, 0, 19, 0 }, { 0, 0, 25, 0 }, { 0, 0, 25, 0 },
- { 0, 0, 962, 0 }, { 0, 0, 962, 0 }, { 0, 0, 13677, 0 }, { 0, 0, 13677, 0 }
- }, { /* input: sRGB-rgb+alpha */
- { 0, 63, 77, 0 }, { 0, 255, 19, 25 }, { 0, 225, 25, 0 }, { 0, 255, 25, 67 },
- { 0, 17534, 18491, 0 }, { 0, 15736, 2824, 6425 }, { 0, 14019, 13677, 0 }, { 0, 50115, 13677, 17219 }
- }, { /* input: linear-gray */
- { 0, 0, 73, 0 }, { 0, 0, 73, 0 }, { 0, 0, 73, 0 }, { 0, 0, 73, 0 },
- { 0, 0, 18817, 0 }, { 0, 0, 18817, 0 }, { 0, 0, 18817, 0 }, { 0, 0, 18817, 0 }
- }, { /* input: linear-gray+alpha */
- { 0, 74, 74, 0 }, { 0, 255, 74, 25 }, { 0, 99, 74, 0 }, { 0, 255, 74, 25 },
- { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6553 }, { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6553 }
- }, { /* input: linear-rgb */
- { 0, 0, 73, 0 }, { 0, 0, 73, 0 }, { 0, 0, 98, 0 }, { 0, 0, 98, 0 },
- { 0, 0, 18664, 0 }, { 0, 0, 18664, 0 }, { 0, 0, 24998, 0 }, { 0, 0, 24998, 0 }
- }, { /* input: linear-rgb+alpha */
- { 0, 181, 196, 0 }, { 0, 255, 61, 25 }, { 206, 187, 98, 0 }, { 0, 255, 98, 67 },
- { 0, 18141, 18137, 0 }, { 0, 17494, 17504, 6553 }, { 0, 24979, 24992, 0 }, { 0, 49172, 24992, 17347 }
- }
-};
-/* END MACHINE GENERATED */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest.c
deleted file mode 100644
index a368bf0f4d7..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngstest.c
+++ /dev/null
@@ -1,3828 +0,0 @@
-/*-
- * pngstest.c
- *
- * Last changed in libpng 1.6.31 [July 27, 2017]
- * Copyright (c) 2013-2017 John Cunningham Bowler
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Test for the PNG 'simplified' APIs.
- */
-#define _ISOC90_SOURCE 1
-#define MALLOC_CHECK_ 2/*glibc facility: turn on debugging*/
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-#include <math.h>
-
-#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
-# include <config.h>
-#endif
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
- * a skipped test, in earlier versions we need to succeed on a skipped test, so:
- */
-#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
-# define SKIP 77
-#else
-# define SKIP 0
-#endif
-
-#ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */
-#include "../tools/sRGB.h"
-
-/* KNOWN ISSUES
- *
- * These defines switch on alternate algorithms for format conversions to match
- * the current libpng implementation; they are set to allow pngstest to pass
- * even though libpng is producing answers that are not as correct as they
- * should be.
- */
-#define ALLOW_UNUSED_GPC 0
- /* If true include unused static GPC functions and declare an external array
- * of them to hide the fact that they are unused. This is for development
- * use while testing the correct function to use to take into account libpng
- * misbehavior, such as using a simple power law to correct sRGB to linear.
- */
-
-/* The following is to support direct compilation of this file as C++ */
-#ifdef __cplusplus
-# define voidcast(type, value) static_cast<type>(value)
-# define aligncastconst(type, value) \
- static_cast<type>(static_cast<const void*>(value))
-#else
-# define voidcast(type, value) (value)
-# define aligncastconst(type, value) ((const void*)(value))
-#endif /* __cplusplus */
-
-/* During parallel runs of pngstest each temporary file needs a unique name,
- * this is used to permit uniqueness using a command line argument which can be
- * up to 22 characters long.
- */
-static char tmpf[23] = "TMP";
-
-/* Generate random bytes. This uses a boring repeatable algorithm and it
- * is implemented here so that it gives the same set of numbers on every
- * architecture. It's a linear congruential generator (Knuth or Sedgewick
- * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
- * Hill, "The Art of Electronics".
- */
-static void
-make_random_bytes(png_uint_32* seed, void* pv, size_t size)
-{
- png_uint_32 u0 = seed[0], u1 = seed[1];
- png_bytep bytes = voidcast(png_bytep, pv);
-
- /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
- * bit-20. The top 1 bit is in u1, the bottom 32 are in u0.
- */
- size_t i;
- for (i=0; i<size; ++i)
- {
- /* First generate 8 new bits then shift them in at the end. */
- png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
- u1 <<= 8;
- u1 |= u0 >> 24;
- u0 <<= 8;
- u0 |= u;
- *bytes++ = (png_byte)u;
- }
-
- seed[0] = u0;
- seed[1] = u1;
-}
-
-static png_uint_32 color_seed[2];
-
-static void
-reseed(void)
-{
- color_seed[0] = 0x12345678U;
- color_seed[1] = 0x9abcdefU;
-}
-
-static void
-random_color(png_colorp color)
-{
- make_random_bytes(color_seed, color, sizeof *color);
-}
-
-/* Math support - neither Cygwin nor Visual Studio have C99 support and we need
- * a predictable rounding function, so make one here:
- */
-static double
-closestinteger(double x)
-{
- return floor(x + .5);
-}
-
-/* Cast support: remove GCC whines. */
-static png_byte
-u8d(double d)
-{
- d = closestinteger(d);
- return (png_byte)d;
-}
-
-static png_uint_16
-u16d(double d)
-{
- d = closestinteger(d);
- return (png_uint_16)d;
-}
-
-/* sRGB support: use exact calculations rounded to the nearest int, see the
- * fesetround() call in main(). sRGB_to_d optimizes the 8 to 16-bit conversion.
- */
-static double sRGB_to_d[256];
-static double g22_to_d[256];
-
-static void
-init_sRGB_to_d(void)
-{
- int i;
-
- sRGB_to_d[0] = 0;
- for (i=1; i<255; ++i)
- sRGB_to_d[i] = linear_from_sRGB(i/255.);
- sRGB_to_d[255] = 1;
-
- g22_to_d[0] = 0;
- for (i=1; i<255; ++i)
- g22_to_d[i] = pow(i/255., 1/.45455);
- g22_to_d[255] = 1;
-}
-
-static png_byte
-sRGB(double linear /*range 0.0 .. 1.0*/)
-{
- return u8d(255 * sRGB_from_linear(linear));
-}
-
-static png_byte
-isRGB(int fixed_linear)
-{
- return sRGB(fixed_linear / 65535.);
-}
-
-#if 0 /* not used */
-static png_byte
-unpremultiply(int component, int alpha)
-{
- if (alpha <= component)
- return 255; /* Arbitrary, but consistent with the libpng code */
-
- else if (alpha >= 65535)
- return isRGB(component);
-
- else
- return sRGB((double)component / alpha);
-}
-#endif
-
-static png_uint_16
-ilinear(int fixed_srgb)
-{
- return u16d(65535 * sRGB_to_d[fixed_srgb]);
-}
-
-static png_uint_16
-ilineara(int fixed_srgb, int alpha)
-{
- return u16d((257 * alpha) * sRGB_to_d[fixed_srgb]);
-}
-
-static png_uint_16
-ilinear_g22(int fixed_srgb)
-{
- return u16d(65535 * g22_to_d[fixed_srgb]);
-}
-
-#if ALLOW_UNUSED_GPC
-static png_uint_16
-ilineara_g22(int fixed_srgb, int alpha)
-{
- return u16d((257 * alpha) * g22_to_d[fixed_srgb]);
-}
-#endif
-
-static double
-YfromRGBint(int ir, int ig, int ib)
-{
- double r = ir;
- double g = ig;
- double b = ib;
- return YfromRGB(r, g, b);
-}
-
-#if 0 /* unused */
-/* The error that results from using a 2.2 power law in place of the correct
- * sRGB transform, given an 8-bit value which might be either sRGB or power-law.
- */
-static int
-power_law_error8(int value)
-{
- if (value > 0 && value < 255)
- {
- double vd = value / 255.;
- double e = fabs(
- pow(sRGB_to_d[value], 1/2.2) - sRGB_from_linear(pow(vd, 2.2)));
-
- /* Always allow an extra 1 here for rounding errors */
- e = 1+floor(255 * e);
- return (int)e;
- }
-
- return 0;
-}
-
-static int error_in_sRGB_roundtrip = 56; /* by experiment */
-static int
-power_law_error16(int value)
-{
- if (value > 0 && value < 65535)
- {
- /* Round trip the value through an 8-bit representation but using
- * non-matching to/from conversions.
- */
- double vd = value / 65535.;
- double e = fabs(
- pow(sRGB_from_linear(vd), 2.2) - linear_from_sRGB(pow(vd, 1/2.2)));
-
- /* Always allow an extra 1 here for rounding errors */
- e = error_in_sRGB_roundtrip+floor(65535 * e);
- return (int)e;
- }
-
- return 0;
-}
-
-static int
-compare_8bit(int v1, int v2, int error_limit, int multiple_algorithms)
-{
- int e = abs(v1-v2);
- int ev1, ev2;
-
- if (e <= error_limit)
- return 1;
-
- if (!multiple_algorithms)
- return 0;
-
- ev1 = power_law_error8(v1);
- if (e <= ev1)
- return 1;
-
- ev2 = power_law_error8(v2);
- if (e <= ev2)
- return 1;
-
- return 0;
-}
-
-static int
-compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms)
-{
- int e = abs(v1-v2);
- int ev1, ev2;
-
- if (e <= error_limit)
- return 1;
-
- /* "multiple_algorithms" in this case means that a color-map has been
- * involved somewhere, so we can deduce that the values were forced to 8-bit
- * (like the via_linear case for 8-bit.)
- */
- if (!multiple_algorithms)
- return 0;
-
- ev1 = power_law_error16(v1);
- if (e <= ev1)
- return 1;
-
- ev2 = power_law_error16(v2);
- if (e <= ev2)
- return 1;
-
- return 0;
-}
-#endif /* unused */
-
-#define USE_FILE 1 /* else memory */
-#define USE_STDIO 2 /* else use file name */
-#define STRICT 4 /* fail on warnings too */
-#define VERBOSE 8
-#define KEEP_TMPFILES 16 /* else delete temporary files */
-#define KEEP_GOING 32
-#define ACCUMULATE 64
-#define FAST_WRITE 128
-#define sRGB_16BIT 256
-#define NO_RESEED 512 /* do not reseed on each new file */
-#define GBG_ERROR 1024 /* do not ignore the gamma+background_rgb_to_gray
- * libpng warning. */
-
-static void
-print_opts(png_uint_32 opts)
-{
- if (opts & USE_FILE)
- printf(" --file");
- if (opts & USE_STDIO)
- printf(" --stdio");
- if (!(opts & STRICT))
- printf(" --nostrict");
- if (opts & VERBOSE)
- printf(" --verbose");
- if (opts & KEEP_TMPFILES)
- printf(" --preserve");
- if (opts & KEEP_GOING)
- printf(" --keep-going");
- if (opts & ACCUMULATE)
- printf(" --accumulate");
- if (!(opts & FAST_WRITE)) /* --fast is currently the default */
- printf(" --slow");
- if (opts & sRGB_16BIT)
- printf(" --sRGB-16bit");
- if (opts & NO_RESEED)
- printf(" --noreseed");
-#if PNG_LIBPNG_VER < 10700 /* else on by default */
- if (opts & GBG_ERROR)
- printf(" --fault-gbg-warning");
-#endif
-}
-
-#define FORMAT_NO_CHANGE 0x80000000 /* additional flag */
-
-/* A name table for all the formats - defines the format of the '+' arguments to
- * pngstest.
- */
-#define FORMAT_COUNT 64
-#define FORMAT_MASK 0x3f
-static const char * const format_names[FORMAT_COUNT] =
-{
- "sRGB-gray",
- "sRGB-gray+alpha",
- "sRGB-rgb",
- "sRGB-rgb+alpha",
- "linear-gray",
- "linear-gray+alpha",
- "linear-rgb",
- "linear-rgb+alpha",
-
- "color-mapped-sRGB-gray",
- "color-mapped-sRGB-gray+alpha",
- "color-mapped-sRGB-rgb",
- "color-mapped-sRGB-rgb+alpha",
- "color-mapped-linear-gray",
- "color-mapped-linear-gray+alpha",
- "color-mapped-linear-rgb",
- "color-mapped-linear-rgb+alpha",
-
- "sRGB-gray",
- "sRGB-gray+alpha",
- "sRGB-bgr",
- "sRGB-bgr+alpha",
- "linear-gray",
- "linear-gray+alpha",
- "linear-bgr",
- "linear-bgr+alpha",
-
- "color-mapped-sRGB-gray",
- "color-mapped-sRGB-gray+alpha",
- "color-mapped-sRGB-bgr",
- "color-mapped-sRGB-bgr+alpha",
- "color-mapped-linear-gray",
- "color-mapped-linear-gray+alpha",
- "color-mapped-linear-bgr",
- "color-mapped-linear-bgr+alpha",
-
- "sRGB-gray",
- "alpha+sRGB-gray",
- "sRGB-rgb",
- "alpha+sRGB-rgb",
- "linear-gray",
- "alpha+linear-gray",
- "linear-rgb",
- "alpha+linear-rgb",
-
- "color-mapped-sRGB-gray",
- "color-mapped-alpha+sRGB-gray",
- "color-mapped-sRGB-rgb",
- "color-mapped-alpha+sRGB-rgb",
- "color-mapped-linear-gray",
- "color-mapped-alpha+linear-gray",
- "color-mapped-linear-rgb",
- "color-mapped-alpha+linear-rgb",
-
- "sRGB-gray",
- "alpha+sRGB-gray",
- "sRGB-bgr",
- "alpha+sRGB-bgr",
- "linear-gray",
- "alpha+linear-gray",
- "linear-bgr",
- "alpha+linear-bgr",
-
- "color-mapped-sRGB-gray",
- "color-mapped-alpha+sRGB-gray",
- "color-mapped-sRGB-bgr",
- "color-mapped-alpha+sRGB-bgr",
- "color-mapped-linear-gray",
- "color-mapped-alpha+linear-gray",
- "color-mapped-linear-bgr",
- "color-mapped-alpha+linear-bgr",
-};
-
-/* Decode an argument to a format number. */
-static png_uint_32
-formatof(const char *arg)
-{
- char *ep;
- unsigned long format = strtoul(arg, &ep, 0);
-
- if (ep > arg && *ep == 0 && format < FORMAT_COUNT)
- return (png_uint_32)format;
-
- else for (format=0; format < FORMAT_COUNT; ++format)
- {
- if (strcmp(format_names[format], arg) == 0)
- return (png_uint_32)format;
- }
-
- fprintf(stderr, "pngstest: format name '%s' invalid\n", arg);
- return FORMAT_COUNT;
-}
-
-/* Bitset/test functions for formats */
-#define FORMAT_SET_COUNT (FORMAT_COUNT / 32)
-typedef struct
-{
- png_uint_32 bits[FORMAT_SET_COUNT];
-}
-format_list;
-
-static void format_init(format_list *pf)
-{
- int i;
- for (i=0; i<FORMAT_SET_COUNT; ++i)
- pf->bits[i] = 0; /* All off */
-}
-
-#if 0 /* currently unused */
-static void format_clear(format_list *pf)
-{
- int i;
- for (i=0; i<FORMAT_SET_COUNT; ++i)
- pf->bits[i] = 0;
-}
-#endif
-
-static int format_is_initial(format_list *pf)
-{
- int i;
- for (i=0; i<FORMAT_SET_COUNT; ++i)
- if (pf->bits[i] != 0)
- return 0;
-
- return 1;
-}
-
-static int format_set(format_list *pf, png_uint_32 format)
-{
- if (format < FORMAT_COUNT)
- return pf->bits[format >> 5] |= ((png_uint_32)1) << (format & 31);
-
- return 0;
-}
-
-#if 0 /* currently unused */
-static int format_unset(format_list *pf, png_uint_32 format)
-{
- if (format < FORMAT_COUNT)
- return pf->bits[format >> 5] &= ~((png_uint_32)1) << (format & 31);
-
- return 0;
-}
-#endif
-
-static int format_isset(format_list *pf, png_uint_32 format)
-{
- return format < FORMAT_COUNT &&
- (pf->bits[format >> 5] & (((png_uint_32)1) << (format & 31))) != 0;
-}
-
-static void format_default(format_list *pf, int redundant)
-{
- if (redundant)
- {
- int i;
-
- /* set everything, including flags that are pointless */
- for (i=0; i<FORMAT_SET_COUNT; ++i)
- pf->bits[i] = ~(png_uint_32)0;
- }
-
- else
- {
- png_uint_32 f;
-
- for (f=0; f<FORMAT_COUNT; ++f)
- {
- /* Eliminate redundant and unsupported settings. */
-# ifdef PNG_FORMAT_BGR_SUPPORTED
- /* BGR is meaningless if no color: */
- if ((f & PNG_FORMAT_FLAG_COLOR) == 0 &&
- (f & PNG_FORMAT_FLAG_BGR) != 0)
-# else
- if ((f & 0x10U/*HACK: fixed value*/) != 0)
-# endif
- continue;
-
- /* AFIRST is meaningless if no alpha: */
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if ((f & PNG_FORMAT_FLAG_ALPHA) == 0 &&
- (f & PNG_FORMAT_FLAG_AFIRST) != 0)
-# else
- if ((f & 0x20U/*HACK: fixed value*/) != 0)
-# endif
- continue;
-
- format_set(pf, f);
- }
- }
-}
-
-/* THE Image STRUCTURE */
-/* The super-class of a png_image, contains the decoded image plus the input
- * data necessary to re-read the file with a different format.
- */
-typedef struct
-{
- png_image image;
- png_uint_32 opts;
- const char *file_name;
- int stride_extra;
- FILE *input_file;
- png_voidp input_memory;
- size_t input_memory_size;
- png_bytep buffer;
- ptrdiff_t stride;
- size_t bufsize;
- size_t allocsize;
- char tmpfile_name[32];
- png_uint_16 colormap[256*4];
-}
-Image;
-
-/* Initializer: also sets the permitted error limit for 16-bit operations. */
-static void
-newimage(Image *image)
-{
- memset(image, 0, sizeof *image);
-}
-
-/* Reset the image to be read again - only needs to rewind the FILE* at present.
- */
-static void
-resetimage(Image *image)
-{
- if (image->input_file != NULL)
- rewind(image->input_file);
-}
-
-/* Free the image buffer; the buffer is re-used on a re-read, this is just for
- * cleanup.
- */
-static void
-freebuffer(Image *image)
-{
- if (image->buffer) free(image->buffer);
- image->buffer = NULL;
- image->bufsize = 0;
- image->allocsize = 0;
-}
-
-/* Delete function; cleans out all the allocated data and the temporary file in
- * the image.
- */
-static void
-freeimage(Image *image)
-{
- freebuffer(image);
- png_image_free(&image->image);
-
- if (image->input_file != NULL)
- {
- fclose(image->input_file);
- image->input_file = NULL;
- }
-
- if (image->input_memory != NULL)
- {
- free(image->input_memory);
- image->input_memory = NULL;
- image->input_memory_size = 0;
- }
-
- if (image->tmpfile_name[0] != 0 && (image->opts & KEEP_TMPFILES) == 0)
- {
- (void)remove(image->tmpfile_name);
- image->tmpfile_name[0] = 0;
- }
-}
-
-/* This is actually a re-initializer; allows an image structure to be re-used by
- * freeing everything that relates to an old image.
- */
-static void initimage(Image *image, png_uint_32 opts, const char *file_name,
- int stride_extra)
-{
- freeimage(image);
- memset(&image->image, 0, sizeof image->image);
- image->opts = opts;
- image->file_name = file_name;
- image->stride_extra = stride_extra;
-}
-
-/* Make sure the image buffer is big enough; allows re-use of the buffer if the
- * image is re-read.
- */
-#define BUFFER_INIT8 73
-static void
-allocbuffer(Image *image)
-{
- size_t size = PNG_IMAGE_BUFFER_SIZE(image->image, image->stride);
-
- if (size+32 > image->bufsize)
- {
- freebuffer(image);
- image->buffer = voidcast(png_bytep, malloc(size+32));
- if (image->buffer == NULL)
- {
- fflush(stdout);
- fprintf(stderr,
- "simpletest: out of memory allocating %lu(+32) byte buffer\n",
- (unsigned long)size);
- exit(1);
- }
- image->bufsize = size+32;
- }
-
- memset(image->buffer, 95, image->bufsize);
- memset(image->buffer+16, BUFFER_INIT8, size);
- image->allocsize = size;
-}
-
-/* Make sure 16 bytes match the given byte. */
-static int
-check16(png_const_bytep bp, int b)
-{
- int i = 16;
-
- do
- if (*bp != b) return 1;
- while (--i);
-
- return 0;
-}
-
-/* Check for overwrite in the image buffer. */
-static void
-checkbuffer(Image *image, const char *arg)
-{
- if (check16(image->buffer, 95))
- {
- fflush(stdout);
- fprintf(stderr, "%s: overwrite at start of image buffer\n", arg);
- exit(1);
- }
-
- if (check16(image->buffer+16+image->allocsize, 95))
- {
- fflush(stdout);
- fprintf(stderr, "%s: overwrite at end of image buffer\n", arg);
- exit(1);
- }
-}
-
-/* ERROR HANDLING */
-/* Log a terminal error, also frees the libpng part of the image if necessary.
- */
-static int
-logerror(Image *image, const char *a1, const char *a2, const char *a3)
-{
- fflush(stdout);
- if (image->image.warning_or_error)
- fprintf(stderr, "%s%s%s: %s\n", a1, a2, a3, image->image.message);
-
- else
- fprintf(stderr, "%s%s%s\n", a1, a2, a3);
-
- if (image->image.opaque != NULL)
- {
- fprintf(stderr, "%s: image opaque pointer non-NULL on error\n",
- image->file_name);
- png_image_free(&image->image);
- }
-
- return 0;
-}
-
-/* Log an error and close a file (just a utility to do both things in one
- * function call.)
- */
-static int
-logclose(Image *image, FILE *f, const char *name, const char *operation)
-{
- int e = errno;
-
- fclose(f);
- return logerror(image, name, operation, strerror(e));
-}
-
-/* Make sure the png_image has been freed - validates that libpng is doing what
- * the spec says and freeing the image.
- */
-static int
-checkopaque(Image *image)
-{
- if (image->image.opaque != NULL)
- {
- png_image_free(&image->image);
- return logerror(image, image->file_name, ": opaque not NULL", "");
- }
-
- /* Separate out the gamma+background_rgb_to_gray warning because it may
- * produce opaque component errors:
- */
- else if (image->image.warning_or_error != 0 &&
- (strcmp(image->image.message,
- "libpng does not support gamma+background+rgb_to_gray") == 0 ?
- (image->opts & GBG_ERROR) != 0 : (image->opts & STRICT) != 0))
- return logerror(image, image->file_name, (image->opts & GBG_ERROR) != 0 ?
- " --fault-gbg-warning" : " --strict", "");
-
- else
- return 1;
-}
-
-/* IMAGE COMPARISON/CHECKING */
-/* Compare the pixels of two images, which should be the same but aren't. The
- * images must have been checked for a size match.
- */
-typedef struct
-{
- /* The components, for grayscale images the gray value is in 'g' and if alpha
- * is not present 'a' is set to 255 or 65535 according to format.
- */
- int r, g, b, a;
-} Pixel;
-
-typedef struct
-{
- /* The background as the original sRGB 8-bit value converted to the final
- * integer format and as a double precision linear value in the range 0..1
- * for with partially transparent pixels.
- */
- int ir, ig, ib;
- double dr, dg, db; /* linear r,g,b scaled to 0..1 */
-} Background;
-
-/* Basic image formats; control the data but not the layout thereof. */
-#define BASE_FORMATS\
- (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_LINEAR)
-
-/* Read a Pixel from a buffer. The code below stores the correct routine for
- * the format in a function pointer, these are the routines:
- */
-static void
-gp_g8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = p->g = p->b = pp[0];
- p->a = 255;
-}
-
-static void
-gp_ga8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = p->g = p->b = pp[0];
- p->a = pp[1];
-}
-
-#ifdef PNG_FORMAT_AFIRST_SUPPORTED
-static void
-gp_ag8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = p->g = p->b = pp[1];
- p->a = pp[0];
-}
-#endif
-
-static void
-gp_rgb8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = pp[0];
- p->g = pp[1];
- p->b = pp[2];
- p->a = 255;
-}
-
-#ifdef PNG_FORMAT_BGR_SUPPORTED
-static void
-gp_bgr8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = pp[2];
- p->g = pp[1];
- p->b = pp[0];
- p->a = 255;
-}
-#endif
-
-static void
-gp_rgba8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = pp[0];
- p->g = pp[1];
- p->b = pp[2];
- p->a = pp[3];
-}
-
-#ifdef PNG_FORMAT_BGR_SUPPORTED
-static void
-gp_bgra8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = pp[2];
- p->g = pp[1];
- p->b = pp[0];
- p->a = pp[3];
-}
-#endif
-
-#ifdef PNG_FORMAT_AFIRST_SUPPORTED
-static void
-gp_argb8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = pp[1];
- p->g = pp[2];
- p->b = pp[3];
- p->a = pp[0];
-}
-#endif
-
-#if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED)
-static void
-gp_abgr8(Pixel *p, png_const_voidp pb)
-{
- png_const_bytep pp = voidcast(png_const_bytep, pb);
-
- p->r = pp[3];
- p->g = pp[2];
- p->b = pp[1];
- p->a = pp[0];
-}
-#endif
-
-static void
-gp_g16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = p->g = p->b = pp[0];
- p->a = 65535;
-}
-
-static void
-gp_ga16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = p->g = p->b = pp[0];
- p->a = pp[1];
-}
-
-#ifdef PNG_FORMAT_AFIRST_SUPPORTED
-static void
-gp_ag16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = p->g = p->b = pp[1];
- p->a = pp[0];
-}
-#endif
-
-static void
-gp_rgb16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = pp[0];
- p->g = pp[1];
- p->b = pp[2];
- p->a = 65535;
-}
-
-#ifdef PNG_FORMAT_BGR_SUPPORTED
-static void
-gp_bgr16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = pp[2];
- p->g = pp[1];
- p->b = pp[0];
- p->a = 65535;
-}
-#endif
-
-static void
-gp_rgba16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = pp[0];
- p->g = pp[1];
- p->b = pp[2];
- p->a = pp[3];
-}
-
-#ifdef PNG_FORMAT_BGR_SUPPORTED
-static void
-gp_bgra16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = pp[2];
- p->g = pp[1];
- p->b = pp[0];
- p->a = pp[3];
-}
-#endif
-
-#ifdef PNG_FORMAT_AFIRST_SUPPORTED
-static void
-gp_argb16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = pp[1];
- p->g = pp[2];
- p->b = pp[3];
- p->a = pp[0];
-}
-#endif
-
-#if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED)
-static void
-gp_abgr16(Pixel *p, png_const_voidp pb)
-{
- png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
-
- p->r = pp[3];
- p->g = pp[2];
- p->b = pp[1];
- p->a = pp[0];
-}
-#endif
-
-/* Given a format, return the correct one of the above functions. */
-static void (*
-get_pixel(png_uint_32 format))(Pixel *p, png_const_voidp pb)
-{
- /* The color-map flag is irrelevant here - the caller of the function
- * returned must either pass the buffer or, for a color-mapped image, the
- * correct entry in the color-map.
- */
- if (format & PNG_FORMAT_FLAG_LINEAR)
- {
- if (format & PNG_FORMAT_FLAG_COLOR)
- {
-# ifdef PNG_FORMAT_BGR_SUPPORTED
- if (format & PNG_FORMAT_FLAG_BGR)
- {
- if (format & PNG_FORMAT_FLAG_ALPHA)
- {
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if (format & PNG_FORMAT_FLAG_AFIRST)
- return gp_abgr16;
-
- else
-# endif
- return gp_bgra16;
- }
-
- else
- return gp_bgr16;
- }
-
- else
-# endif
- {
- if (format & PNG_FORMAT_FLAG_ALPHA)
- {
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if (format & PNG_FORMAT_FLAG_AFIRST)
- return gp_argb16;
-
- else
-# endif
- return gp_rgba16;
- }
-
- else
- return gp_rgb16;
- }
- }
-
- else
- {
- if (format & PNG_FORMAT_FLAG_ALPHA)
- {
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if (format & PNG_FORMAT_FLAG_AFIRST)
- return gp_ag16;
-
- else
-# endif
- return gp_ga16;
- }
-
- else
- return gp_g16;
- }
- }
-
- else
- {
- if (format & PNG_FORMAT_FLAG_COLOR)
- {
-# ifdef PNG_FORMAT_BGR_SUPPORTED
- if (format & PNG_FORMAT_FLAG_BGR)
- {
- if (format & PNG_FORMAT_FLAG_ALPHA)
- {
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if (format & PNG_FORMAT_FLAG_AFIRST)
- return gp_abgr8;
-
- else
-# endif
- return gp_bgra8;
- }
-
- else
- return gp_bgr8;
- }
-
- else
-# endif
- {
- if (format & PNG_FORMAT_FLAG_ALPHA)
- {
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if (format & PNG_FORMAT_FLAG_AFIRST)
- return gp_argb8;
-
- else
-# endif
- return gp_rgba8;
- }
-
- else
- return gp_rgb8;
- }
- }
-
- else
- {
- if (format & PNG_FORMAT_FLAG_ALPHA)
- {
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if (format & PNG_FORMAT_FLAG_AFIRST)
- return gp_ag8;
-
- else
-# endif
- return gp_ga8;
- }
-
- else
- return gp_g8;
- }
- }
-}
-
-/* Conversion between pixel formats. The code above effectively eliminates the
- * component ordering changes leaving three basic changes:
- *
- * 1) Remove an alpha channel by pre-multiplication or compositing on a
- * background color. (Adding an alpha channel is a no-op.)
- *
- * 2) Remove color by mapping to grayscale. (Grayscale to color is a no-op.)
- *
- * 3) Convert between 8-bit and 16-bit components. (Both directtions are
- * relevant.)
- *
- * This gives the following base format conversion matrix:
- *
- * OUT: ----- 8-bit ----- ----- 16-bit -----
- * IN G GA RGB RGBA G GA RGB RGBA
- * 8 G . . . . lin lin lin lin
- * 8 GA bckg . bckc . pre' pre pre' pre
- * 8 RGB g8 g8 . . glin glin lin lin
- * 8 RGBA g8b g8 bckc . gpr' gpre pre' pre
- * 16 G sRGB sRGB sRGB sRGB . . . .
- * 16 GA b16g unpg b16c unpc A . A .
- * 16 RGB sG sG sRGB sRGB g16 g16 . .
- * 16 RGBA gb16 sGp cb16 sCp g16 g16' A .
- *
- * 8-bit to 8-bit:
- * bckg: composite on gray background
- * bckc: composite on color background
- * g8: convert sRGB components to sRGB grayscale
- * g8b: convert sRGB components to grayscale and composite on gray background
- *
- * 8-bit to 16-bit:
- * lin: make sRGB components linear, alpha := 65535
- * pre: make sRGB components linear and premultiply by alpha (scale alpha)
- * pre': as 'pre' but alpha := 65535
- * glin: make sRGB components linear, convert to grayscale, alpha := 65535
- * gpre: make sRGB components grayscale and linear and premultiply by alpha
- * gpr': as 'gpre' but alpha := 65535
- *
- * 16-bit to 8-bit:
- * sRGB: convert linear components to sRGB, alpha := 255
- * unpg: unpremultiply gray component and convert to sRGB (scale alpha)
- * unpc: unpremultiply color components and convert to sRGB (scale alpha)
- * b16g: composite linear onto gray background and convert the result to sRGB
- * b16c: composite linear onto color background and convert the result to sRGB
- * sG: convert linear RGB to sRGB grayscale
- * sGp: unpremultiply RGB then convert to sRGB grayscale
- * sCp: unpremultiply RGB then convert to sRGB
- * gb16: composite linear onto background and convert to sRGB grayscale
- * (order doesn't matter, the composite and grayscale operations permute)
- * cb16: composite linear onto background and convert to sRGB
- *
- * 16-bit to 16-bit:
- * A: set alpha to 65535
- * g16: convert linear RGB to linear grayscale (alpha := 65535)
- * g16': as 'g16' but alpha is unchanged
- */
-/* Simple copy: */
-static void
-gpc_noop(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
- out->r = in->r;
- out->g = in->g;
- out->b = in->b;
- out->a = in->a;
-}
-
-#if ALLOW_UNUSED_GPC
-static void
-gpc_nop8(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
- if (in->a == 0)
- out->r = out->g = out->b = 255;
-
- else
- {
- out->r = in->r;
- out->g = in->g;
- out->b = in->b;
- }
-
- out->a = in->a;
-}
-#endif
-
-#if ALLOW_UNUSED_GPC
-static void
-gpc_nop6(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
- if (in->a == 0)
- out->r = out->g = out->b = 65535;
-
- else
- {
- out->r = in->r;
- out->g = in->g;
- out->b = in->b;
- }
-
- out->a = in->a;
-}
-#endif
-
-/* 8-bit to 8-bit conversions */
-/* bckg: composite on gray background */
-static void
-gpc_bckg(Pixel *out, const Pixel *in, const Background *back)
-{
- if (in->a <= 0)
- out->r = out->g = out->b = back->ig;
-
- else if (in->a >= 255)
- out->r = out->g = out->b = in->g;
-
- else
- {
- double a = in->a / 255.;
-
- out->r = out->g = out->b = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a));
- }
-
- out->a = 255;
-}
-
-/* bckc: composite on color background */
-static void
-gpc_bckc(Pixel *out, const Pixel *in, const Background *back)
-{
- if (in->a <= 0)
- {
- out->r = back->ir;
- out->g = back->ig;
- out->b = back->ib;
- }
-
- else if (in->a >= 255)
- {
- out->r = in->r;
- out->g = in->g;
- out->b = in->b;
- }
-
- else
- {
- double a = in->a / 255.;
-
- out->r = sRGB(sRGB_to_d[in->r] * a + back->dr * (1-a));
- out->g = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a));
- out->b = sRGB(sRGB_to_d[in->b] * a + back->db * (1-a));
- }
-
- out->a = 255;
-}
-
-/* g8: convert sRGB components to sRGB grayscale */
-static void
-gpc_g8(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = in->g;
-
- else
- out->r = out->g = out->b =
- sRGB(YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
-
- out->a = in->a;
-}
-
-/* g8b: convert sRGB components to grayscale and composite on gray background */
-static void
-gpc_g8b(Pixel *out, const Pixel *in, const Background *back)
-{
- if (in->a <= 0)
- out->r = out->g = out->b = back->ig;
-
- else if (in->a >= 255)
- {
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = in->g;
-
- else
- out->r = out->g = out->b = sRGB(YfromRGB(
- sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
- }
-
- else
- {
- double a = in->a/255.;
-
- out->r = out->g = out->b = sRGB(a * YfromRGB(sRGB_to_d[in->r],
- sRGB_to_d[in->g], sRGB_to_d[in->b]) + back->dg * (1-a));
- }
-
- out->a = 255;
-}
-
-/* 8-bit to 16-bit conversions */
-/* lin: make sRGB components linear, alpha := 65535 */
-static void
-gpc_lin(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = ilinear(in->r);
-
- if (in->g == in->r)
- {
- out->g = out->r;
-
- if (in->b == in->r)
- out->b = out->r;
-
- else
- out->b = ilinear(in->b);
- }
-
- else
- {
- out->g = ilinear(in->g);
-
- if (in->b == in->r)
- out->b = out->r;
-
- else if (in->b == in->g)
- out->b = out->g;
-
- else
- out->b = ilinear(in->b);
- }
-
- out->a = 65535;
-}
-
-/* pre: make sRGB components linear and premultiply by alpha (scale alpha) */
-static void
-gpc_pre(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = ilineara(in->r, in->a);
-
- if (in->g == in->r)
- {
- out->g = out->r;
-
- if (in->b == in->r)
- out->b = out->r;
-
- else
- out->b = ilineara(in->b, in->a);
- }
-
- else
- {
- out->g = ilineara(in->g, in->a);
-
- if (in->b == in->r)
- out->b = out->r;
-
- else if (in->b == in->g)
- out->b = out->g;
-
- else
- out->b = ilineara(in->b, in->a);
- }
-
- out->a = in->a * 257;
-}
-
-/* pre': as 'pre' but alpha := 65535 */
-static void
-gpc_preq(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = ilineara(in->r, in->a);
-
- if (in->g == in->r)
- {
- out->g = out->r;
-
- if (in->b == in->r)
- out->b = out->r;
-
- else
- out->b = ilineara(in->b, in->a);
- }
-
- else
- {
- out->g = ilineara(in->g, in->a);
-
- if (in->b == in->r)
- out->b = out->r;
-
- else if (in->b == in->g)
- out->b = out->g;
-
- else
- out->b = ilineara(in->b, in->a);
- }
-
- out->a = 65535;
-}
-
-/* glin: make sRGB components linear, convert to grayscale, alpha := 65535 */
-static void
-gpc_glin(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = ilinear(in->g);
-
- else
- out->r = out->g = out->b = u16d(65535 *
- YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
-
- out->a = 65535;
-}
-
-/* gpre: make sRGB components grayscale and linear and premultiply by alpha */
-static void
-gpc_gpre(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = ilineara(in->g, in->a);
-
- else
- out->r = out->g = out->b = u16d(in->a * 257 *
- YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
-
- out->a = 257 * in->a;
-}
-
-/* gpr': as 'gpre' but alpha := 65535 */
-static void
-gpc_gprq(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = ilineara(in->g, in->a);
-
- else
- out->r = out->g = out->b = u16d(in->a * 257 *
- YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
-
- out->a = 65535;
-}
-
-/* 8-bit to 16-bit conversions for gAMA 45455 encoded values */
-/* Lin: make gAMA 45455 components linear, alpha := 65535 */
-static void
-gpc_Lin(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = ilinear_g22(in->r);
-
- if (in->g == in->r)
- {
- out->g = out->r;
-
- if (in->b == in->r)
- out->b = out->r;
-
- else
- out->b = ilinear_g22(in->b);
- }
-
- else
- {
- out->g = ilinear_g22(in->g);
-
- if (in->b == in->r)
- out->b = out->r;
-
- else if (in->b == in->g)
- out->b = out->g;
-
- else
- out->b = ilinear_g22(in->b);
- }
-
- out->a = 65535;
-}
-
-#if ALLOW_UNUSED_GPC
-/* Pre: make gAMA 45455 components linear and premultiply by alpha (scale alpha)
- */
-static void
-gpc_Pre(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = ilineara_g22(in->r, in->a);
-
- if (in->g == in->r)
- {
- out->g = out->r;
-
- if (in->b == in->r)
- out->b = out->r;
-
- else
- out->b = ilineara_g22(in->b, in->a);
- }
-
- else
- {
- out->g = ilineara_g22(in->g, in->a);
-
- if (in->b == in->r)
- out->b = out->r;
-
- else if (in->b == in->g)
- out->b = out->g;
-
- else
- out->b = ilineara_g22(in->b, in->a);
- }
-
- out->a = in->a * 257;
-}
-#endif
-
-#if ALLOW_UNUSED_GPC
-/* Pre': as 'Pre' but alpha := 65535 */
-static void
-gpc_Preq(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = ilineara_g22(in->r, in->a);
-
- if (in->g == in->r)
- {
- out->g = out->r;
-
- if (in->b == in->r)
- out->b = out->r;
-
- else
- out->b = ilineara_g22(in->b, in->a);
- }
-
- else
- {
- out->g = ilineara_g22(in->g, in->a);
-
- if (in->b == in->r)
- out->b = out->r;
-
- else if (in->b == in->g)
- out->b = out->g;
-
- else
- out->b = ilineara_g22(in->b, in->a);
- }
-
- out->a = 65535;
-}
-#endif
-
-#if ALLOW_UNUSED_GPC
-/* Glin: make gAMA 45455 components linear, convert to grayscale, alpha := 65535
- */
-static void
-gpc_Glin(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = ilinear_g22(in->g);
-
- else
- out->r = out->g = out->b = u16d(65535 *
- YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));
-
- out->a = 65535;
-}
-#endif
-
-#if ALLOW_UNUSED_GPC
-/* Gpre: make gAMA 45455 components grayscale and linear and premultiply by
- * alpha.
- */
-static void
-gpc_Gpre(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = ilineara_g22(in->g, in->a);
-
- else
- out->r = out->g = out->b = u16d(in->a * 257 *
- YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));
-
- out->a = 257 * in->a;
-}
-#endif
-
-#if ALLOW_UNUSED_GPC
-/* Gpr': as 'Gpre' but alpha := 65535 */
-static void
-gpc_Gprq(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->r == in->g && in->g == in->b)
- out->r = out->g = out->b = ilineara_g22(in->g, in->a);
-
- else
- out->r = out->g = out->b = u16d(in->a * 257 *
- YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));
-
- out->a = 65535;
-}
-#endif
-
-/* 16-bit to 8-bit conversions */
-/* sRGB: convert linear components to sRGB, alpha := 255 */
-static void
-gpc_sRGB(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = isRGB(in->r);
-
- if (in->g == in->r)
- {
- out->g = out->r;
-
- if (in->b == in->r)
- out->b = out->r;
-
- else
- out->b = isRGB(in->b);
- }
-
- else
- {
- out->g = isRGB(in->g);
-
- if (in->b == in->r)
- out->b = out->r;
-
- else if (in->b == in->g)
- out->b = out->g;
-
- else
- out->b = isRGB(in->b);
- }
-
- out->a = 255;
-}
-
-/* unpg: unpremultiply gray component and convert to sRGB (scale alpha) */
-static void
-gpc_unpg(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->a <= 128)
- {
- out->r = out->g = out->b = 255;
- out->a = 0;
- }
-
- else
- {
- out->r = out->g = out->b = sRGB((double)in->g / in->a);
- out->a = u8d(in->a / 257.);
- }
-}
-
-/* unpc: unpremultiply color components and convert to sRGB (scale alpha) */
-static void
-gpc_unpc(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->a <= 128)
- {
- out->r = out->g = out->b = 255;
- out->a = 0;
- }
-
- else
- {
- out->r = sRGB((double)in->r / in->a);
- out->g = sRGB((double)in->g / in->a);
- out->b = sRGB((double)in->b / in->a);
- out->a = u8d(in->a / 257.);
- }
-}
-
-/* b16g: composite linear onto gray background and convert the result to sRGB */
-static void
-gpc_b16g(Pixel *out, const Pixel *in, const Background *back)
-{
- if (in->a <= 0)
- out->r = out->g = out->b = back->ig;
-
- else
- {
- double a = in->a/65535.;
- double a1 = 1-a;
-
- a /= 65535;
- out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1);
- }
-
- out->a = 255;
-}
-
-/* b16c: composite linear onto color background and convert the result to sRGB*/
-static void
-gpc_b16c(Pixel *out, const Pixel *in, const Background *back)
-{
- if (in->a <= 0)
- {
- out->r = back->ir;
- out->g = back->ig;
- out->b = back->ib;
- }
-
- else
- {
- double a = in->a/65535.;
- double a1 = 1-a;
-
- a /= 65535;
- out->r = sRGB(in->r * a + back->dr * a1);
- out->g = sRGB(in->g * a + back->dg * a1);
- out->b = sRGB(in->b * a + back->db * a1);
- }
-
- out->a = 255;
-}
-
-/* sG: convert linear RGB to sRGB grayscale */
-static void
-gpc_sG(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/65535);
- out->a = 255;
-}
-
-/* sGp: unpremultiply RGB then convert to sRGB grayscale */
-static void
-gpc_sGp(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->a <= 128)
- {
- out->r = out->g = out->b = 255;
- out->a = 0;
- }
-
- else
- {
- out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/in->a);
- out->a = u8d(in->a / 257.);
- }
-}
-
-/* sCp: unpremultiply RGB then convert to sRGB */
-static void
-gpc_sCp(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
-
- if (in->a <= 128)
- {
- out->r = out->g = out->b = 255;
- out->a = 0;
- }
-
- else
- {
- out->r = sRGB((double)in->r / in->a);
- out->g = sRGB((double)in->g / in->a);
- out->b = sRGB((double)in->b / in->a);
- out->a = u8d(in->a / 257.);
- }
-}
-
-/* gb16: composite linear onto background and convert to sRGB grayscale */
-/* (order doesn't matter, the composite and grayscale operations permute) */
-static void
-gpc_gb16(Pixel *out, const Pixel *in, const Background *back)
-{
- if (in->a <= 0)
- out->r = out->g = out->b = back->ig;
-
- else if (in->a >= 65535)
- out->r = out->g = out->b = isRGB(in->g);
-
- else
- {
- double a = in->a / 65535.;
- double a1 = 1-a;
-
- a /= 65535;
- out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1);
- }
-
- out->a = 255;
-}
-
-/* cb16: composite linear onto background and convert to sRGB */
-static void
-gpc_cb16(Pixel *out, const Pixel *in, const Background *back)
-{
- if (in->a <= 0)
- {
- out->r = back->ir;
- out->g = back->ig;
- out->b = back->ib;
- }
-
- else if (in->a >= 65535)
- {
- out->r = isRGB(in->r);
- out->g = isRGB(in->g);
- out->b = isRGB(in->b);
- }
-
- else
- {
- double a = in->a / 65535.;
- double a1 = 1-a;
-
- a /= 65535;
- out->r = sRGB(in->r * a + back->dr * a1);
- out->g = sRGB(in->g * a + back->dg * a1);
- out->b = sRGB(in->b * a + back->db * a1);
- }
-
- out->a = 255;
-}
-
-/* 16-bit to 16-bit conversions */
-/* A: set alpha to 65535 */
-static void
-gpc_A(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
- out->r = in->r;
- out->g = in->g;
- out->b = in->b;
- out->a = 65535;
-}
-
-/* g16: convert linear RGB to linear grayscale (alpha := 65535) */
-static void
-gpc_g16(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
- out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b));
- out->a = 65535;
-}
-
-/* g16': as 'g16' but alpha is unchanged */
-static void
-gpc_g16q(Pixel *out, const Pixel *in, const Background *back)
-{
- (void)back;
- out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b));
- out->a = in->a;
-}
-
-#if ALLOW_UNUSED_GPC
-/* Unused functions (to hide them from GCC unused function warnings) */
-void (* const gpc_unused[])
- (Pixel *out, const Pixel *in, const Background *back) =
-{
- gpc_Pre, gpc_Preq, gpc_Glin, gpc_Gpre, gpc_Gprq, gpc_nop8, gpc_nop6
-};
-#endif
-
-/* OUT: ----- 8-bit ----- ----- 16-bit -----
- * IN G GA RGB RGBA G GA RGB RGBA
- * 8 G . . . . lin lin lin lin
- * 8 GA bckg . bckc . pre' pre pre' pre
- * 8 RGB g8 g8 . . glin glin lin lin
- * 8 RGBA g8b g8 bckc . gpr' gpre pre' pre
- * 16 G sRGB sRGB sRGB sRGB . . . .
- * 16 GA b16g unpg b16c unpc A . A .
- * 16 RGB sG sG sRGB sRGB g16 g16 . .
- * 16 RGBA gb16 sGp cb16 sCp g16 g16' A .
- *
- * The matrix is held in an array indexed thus:
- *
- * gpc_fn[out_format & BASE_FORMATS][in_format & BASE_FORMATS];
- */
-/* This will produce a compile time error if the FORMAT_FLAG values don't
- * match the above matrix!
- */
-#if PNG_FORMAT_FLAG_ALPHA == 1 && PNG_FORMAT_FLAG_COLOR == 2 &&\
- PNG_FORMAT_FLAG_LINEAR == 4
-static void (* const gpc_fn[8/*in*/][8/*out*/])
- (Pixel *out, const Pixel *in, const Background *back) =
-{
-/*out: G-8 GA-8 RGB-8 RGBA-8 G-16 GA-16 RGB-16 RGBA-16 */
- {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_Lin, gpc_Lin, gpc_Lin, gpc_Lin },
- {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre },
- {gpc_g8, gpc_g8, gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin },
- {gpc_g8b, gpc_g8, gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre },
- {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop},
- {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A, gpc_noop,gpc_A, gpc_noop},
- {gpc_sG, gpc_sG, gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop},
- {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp, gpc_g16, gpc_g16q,gpc_A, gpc_noop}
-};
-
-/* The array is repeated for the cases where both the input and output are color
- * mapped because then different algorithms are used.
- */
-static void (* const gpc_fn_colormapped[8/*in*/][8/*out*/])
- (Pixel *out, const Pixel *in, const Background *back) =
-{
-/*out: G-8 GA-8 RGB-8 RGBA-8 G-16 GA-16 RGB-16 RGBA-16 */
- {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_lin, gpc_lin, gpc_lin, gpc_lin },
- {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre },
- {gpc_g8, gpc_g8, gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin },
- {gpc_g8b, gpc_g8, gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre },
- {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop},
- {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A, gpc_noop,gpc_A, gpc_noop},
- {gpc_sG, gpc_sG, gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop},
- {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp, gpc_g16, gpc_g16q,gpc_A, gpc_noop}
-};
-
-/* The error arrays record the error in the same matrix; 64 entries, however
- * the different algorithms used in libpng for colormap and direct conversions
- * mean that four separate matrices are used (for each combination of
- * colormapped and direct.)
- *
- * In some cases the conversion between sRGB formats goes via a linear
- * intermediate; an sRGB to linear conversion (as above) is followed by a simple
- * linear to sRGB step with no other conversions. This is done by a separate
- * error array from an arbitrary 'in' format to one of the four basic outputs
- * (since final output is always sRGB not colormapped).
- *
- * These arrays may be modified if the --accumulate flag is set during the run;
- * then instead of logging errors they are simply added in.
- *
- * The three entries are currently for transparent, partially transparent and
- * opaque input pixel values. Notice that alpha should be exact in each case.
- *
- * Errors in alpha should only occur when converting from a direct format
- * to a colormapped format, when alpha is effectively smashed (so large
- * errors can occur.) There should be no error in the '0' and 'opaque'
- * values. The fourth entry in the array is used for the alpha error (and it
- * should always be zero for the 'via linear' case since this is never color
- * mapped.)
- *
- * Mapping to a colormap smashes the colors, it is necessary to have separate
- * values for these cases because they are much larger; it is very much
- * impossible to obtain a reasonable result, these are held in
- * gpc_error_to_colormap.
- */
-#if PNG_FORMAT_FLAG_COLORMAP == 8 /* extra check also required */
-# include "pngstest-errors.h" /* machine generated */
-#endif /* COLORMAP flag check */
-#endif /* flag checks */
-
-typedef struct
-{
- /* Basic pixel information: */
- Image* in_image; /* Input image */
- const Image* out_image; /* Output image */
-
- /* 'background' is the value passed to the gpc_ routines, it may be NULL if
- * it should not be used (*this* program has an error if it crashes as a
- * result!)
- */
- Background background_color;
- const Background* background;
-
- /* Precalculated values: */
- int in_opaque; /* Value of input alpha that is opaque */
- int is_palette; /* Sample values come from the palette */
- int accumulate; /* Accumulate component errors (don't log) */
- int output_8bit; /* Output is 8-bit (else 16-bit) */
-
- void (*in_gp)(Pixel*, png_const_voidp);
- void (*out_gp)(Pixel*, png_const_voidp);
-
- void (*transform)(Pixel *out, const Pixel *in, const Background *back);
- /* A function to perform the required transform */
-
- void (*from_linear)(Pixel *out, const Pixel *in, const Background *back);
- /* For 'via_linear' transforms the final, from linear, step, else NULL */
-
- png_uint_16 error[4];
- /* Three error values for transparent, partially transparent and opaque
- * input pixels (in turn).
- */
-
- png_uint_16 *error_ptr;
- /* Where these are stored in the static array (for 'accumulate') */
-}
-Transform;
-
-/* Return a 'transform' as above for the given format conversion. */
-static void
-transform_from_formats(Transform *result, Image *in_image,
- const Image *out_image, png_const_colorp background, int via_linear)
-{
- png_uint_32 in_format, out_format;
- png_uint_32 in_base, out_base;
-
- memset(result, 0, sizeof *result);
-
- /* Store the original images for error messages */
- result->in_image = in_image;
- result->out_image = out_image;
-
- in_format = in_image->image.format;
- out_format = out_image->image.format;
-
- if (in_format & PNG_FORMAT_FLAG_LINEAR)
- result->in_opaque = 65535;
- else
- result->in_opaque = 255;
-
- result->output_8bit = (out_format & PNG_FORMAT_FLAG_LINEAR) == 0;
-
- result->is_palette = 0; /* set by caller if required */
- result->accumulate = (in_image->opts & ACCUMULATE) != 0;
-
- /* The loaders (which need the ordering information) */
- result->in_gp = get_pixel(in_format);
- result->out_gp = get_pixel(out_format);
-
- /* Remove the ordering information: */
- in_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP;
- in_base = in_format & BASE_FORMATS;
- out_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP;
- out_base = out_format & BASE_FORMATS;
-
- if (via_linear)
- {
- /* Check for an error in this program: */
- if (out_format & (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLORMAP))
- {
- fprintf(stderr, "internal transform via linear error 0x%x->0x%x\n",
- in_format, out_format);
- exit(1);
- }
-
- result->transform = gpc_fn[in_base][out_base | PNG_FORMAT_FLAG_LINEAR];
- result->from_linear = gpc_fn[out_base | PNG_FORMAT_FLAG_LINEAR][out_base];
- result->error_ptr = gpc_error_via_linear[in_format][out_format];
- }
-
- else if (~in_format & out_format & PNG_FORMAT_FLAG_COLORMAP)
- {
- /* The input is not colormapped but the output is, the errors will
- * typically be large (only the grayscale-no-alpha case permits preserving
- * even 8-bit values.)
- */
- result->transform = gpc_fn[in_base][out_base];
- result->from_linear = NULL;
- result->error_ptr = gpc_error_to_colormap[in_base][out_base];
- }
-
- else
- {
- /* The caller handles the colormap->pixel value conversion, so the
- * transform function just gets a pixel value, however because libpng
- * currently contains a different implementation for mapping a colormap if
- * both input and output are colormapped we need different conversion
- * functions to deal with errors in the libpng implementation.
- */
- if (in_format & out_format & PNG_FORMAT_FLAG_COLORMAP)
- result->transform = gpc_fn_colormapped[in_base][out_base];
- else
- result->transform = gpc_fn[in_base][out_base];
- result->from_linear = NULL;
- result->error_ptr = gpc_error[in_format][out_format];
- }
-
- /* Follow the libpng simplified API rules to work out what to pass to the gpc
- * routines as a background value, if one is not required pass NULL so that
- * this program crashes in the even of a programming error.
- */
- result->background = NULL; /* default: not required */
-
- /* Rule 1: background only need be supplied if alpha is to be removed */
- if (in_format & ~out_format & PNG_FORMAT_FLAG_ALPHA)
- {
- /* The input value is 'NULL' to use the background and (otherwise) an sRGB
- * background color (to use a solid color). The code above uses a fixed
- * byte value, BUFFER_INIT8, for buffer even for 16-bit output. For
- * linear (16-bit) output the sRGB background color is ignored; the
- * composition is always on the background (so BUFFER_INIT8 * 257), except
- * that for the colormap (i.e. linear colormapped output) black is used.
- */
- result->background = &result->background_color;
-
- if (out_format & PNG_FORMAT_FLAG_LINEAR || via_linear)
- {
- if (out_format & PNG_FORMAT_FLAG_COLORMAP)
- {
- result->background_color.ir =
- result->background_color.ig =
- result->background_color.ib = 0;
- result->background_color.dr =
- result->background_color.dg =
- result->background_color.db = 0;
- }
-
- else
- {
- result->background_color.ir =
- result->background_color.ig =
- result->background_color.ib = BUFFER_INIT8 * 257;
- result->background_color.dr =
- result->background_color.dg =
- result->background_color.db = 0;
- }
- }
-
- else /* sRGB output */
- {
- if (background != NULL)
- {
- if (out_format & PNG_FORMAT_FLAG_COLOR)
- {
- result->background_color.ir = background->red;
- result->background_color.ig = background->green;
- result->background_color.ib = background->blue;
- /* TODO: sometimes libpng uses the power law conversion here, how
- * to handle this?
- */
- result->background_color.dr = sRGB_to_d[background->red];
- result->background_color.dg = sRGB_to_d[background->green];
- result->background_color.db = sRGB_to_d[background->blue];
- }
-
- else /* grayscale: libpng only looks at 'g' */
- {
- result->background_color.ir =
- result->background_color.ig =
- result->background_color.ib = background->green;
- /* TODO: sometimes libpng uses the power law conversion here, how
- * to handle this?
- */
- result->background_color.dr =
- result->background_color.dg =
- result->background_color.db = sRGB_to_d[background->green];
- }
- }
-
- else if ((out_format & PNG_FORMAT_FLAG_COLORMAP) == 0)
- {
- result->background_color.ir =
- result->background_color.ig =
- result->background_color.ib = BUFFER_INIT8;
- /* TODO: sometimes libpng uses the power law conversion here, how
- * to handle this?
- */
- result->background_color.dr =
- result->background_color.dg =
- result->background_color.db = sRGB_to_d[BUFFER_INIT8];
- }
-
- /* Else the output is colormapped and a background color must be
- * provided; if pngstest crashes then that is a bug in this program
- * (though libpng should png_error as well.)
- */
- else
- result->background = NULL;
- }
- }
-
- if (result->background == NULL)
- {
- result->background_color.ir =
- result->background_color.ig =
- result->background_color.ib = -1; /* not used */
- result->background_color.dr =
- result->background_color.dg =
- result->background_color.db = 1E30; /* not used */
- }
-
-
- /* Copy the error values into the Transform: */
- result->error[0] = result->error_ptr[0];
- result->error[1] = result->error_ptr[1];
- result->error[2] = result->error_ptr[2];
- result->error[3] = result->error_ptr[3];
-}
-
-
-/* Compare two pixels.
- *
- * OLD error values:
-static int error_to_linear = 811; * by experiment *
-static int error_to_linear_grayscale = 424; * by experiment *
-static int error_to_sRGB = 6; * by experiment *
-static int error_to_sRGB_grayscale = 17; * libpng error by calculation +
- 2 by experiment *
-static int error_in_compose = 2; * by experiment *
-static int error_in_premultiply = 1;
- *
- * The following is *just* the result of a round trip from 8-bit sRGB to linear
- * then back to 8-bit sRGB when it is done by libpng. There are two problems:
- *
- * 1) libpng currently uses a 2.2 power law with no linear segment, this results
- * in instability in the low values and even with 16-bit precision sRGB(1) ends
- * up mapping to sRGB(0) as a result of rounding in the 16-bit representation.
- * This gives an error of 1 in the handling of value 1 only.
- *
- * 2) libpng currently uses an intermediate 8-bit linear value in gamma
- * correction of 8-bit values. This results in many more errors, the worse of
- * which is mapping sRGB(14) to sRGB(0).
- *
- * The general 'error_via_linear' is more complex because of pre-multiplication,
- * this compounds the 8-bit errors according to the alpha value of the pixel.
- * As a result 256 values are pre-calculated for error_via_linear.
- */
-#if 0
-static int error_in_libpng_gamma;
-static int error_via_linear[256]; /* Indexed by 8-bit alpha */
-
-static void
-init_error_via_linear(void)
-{
- int alpha;
-
- error_via_linear[0] = 255; /* transparent pixel */
-
- for (alpha=1; alpha<=255; ++alpha)
- {
- /* 16-bit values less than 128.5 get rounded to 8-bit 0 and so the worst
- * case error arises with 16-bit 128.5, work out what sRGB
- * (non-associated) value generates 128.5; any value less than this is
- * going to map to 0, so the worst error is floor(value).
- *
- * Note that errors are considerably higher (more than a factor of 2)
- * because libpng uses a simple power law for sRGB data at present.
- *
- * Add .1 for arithmetic errors inside libpng.
- */
- double v = floor(255*pow(.5/*(128.5 * 255 / 65535)*/ / alpha, 1/2.2)+.1);
-
- error_via_linear[alpha] = (int)v;
- }
-
- /* This is actually 14.99, but, despite the closeness to 15, 14 seems to work
- * ok in this case.
- */
- error_in_libpng_gamma = 14;
-}
-#endif
-
-static void
-print_pixel(char string[64], const Pixel *pixel, png_uint_32 format)
-{
- switch (format & (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR))
- {
- case 0:
- sprintf(string, "%s(%d)", format_names[format], pixel->g);
- break;
-
- case PNG_FORMAT_FLAG_ALPHA:
- sprintf(string, "%s(%d,%d)", format_names[format], pixel->g,
- pixel->a);
- break;
-
- case PNG_FORMAT_FLAG_COLOR:
- sprintf(string, "%s(%d,%d,%d)", format_names[format],
- pixel->r, pixel->g, pixel->b);
- break;
-
- case PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA:
- sprintf(string, "%s(%d,%d,%d,%d)", format_names[format],
- pixel->r, pixel->g, pixel->b, pixel->a);
- break;
-
- default:
- sprintf(string, "invalid-format");
- break;
- }
-}
-
-static int
-logpixel(const Transform *transform, png_uint_32 x, png_uint_32 y,
- const Pixel *in, const Pixel *calc, const Pixel *out, const char *reason)
-{
- png_uint_32 in_format = transform->in_image->image.format;
- png_uint_32 out_format = transform->out_image->image.format;
-
- png_uint_32 back_format = out_format & ~PNG_FORMAT_FLAG_ALPHA;
- const char *via_linear = "";
-
- char pixel_in[64], pixel_calc[64], pixel_out[64], pixel_loc[64];
- char background_info[100];
-
- print_pixel(pixel_in, in, in_format);
- print_pixel(pixel_calc, calc, out_format);
- print_pixel(pixel_out, out, out_format);
-
- if (transform->is_palette)
- sprintf(pixel_loc, "palette: %lu", (unsigned long)y);
- else
- sprintf(pixel_loc, "%lu,%lu", (unsigned long)x, (unsigned long)y);
-
- if (transform->from_linear != NULL)
- {
- via_linear = " (via linear)";
- /* And as a result the *read* format which did any background processing
- * was itself linear, so the background color information is also
- * linear.
- */
- back_format |= PNG_FORMAT_FLAG_LINEAR;
- }
-
- if (transform->background != NULL)
- {
- Pixel back;
- char pixel_back[64];
-
- back.r = transform->background->ir;
- back.g = transform->background->ig;
- back.b = transform->background->ib;
- back.a = -1; /* not used */
-
- print_pixel(pixel_back, &back, back_format);
- sprintf(background_info, " on background %s", pixel_back);
- }
-
- else
- background_info[0] = 0;
-
- if (transform->in_image->file_name != transform->out_image->file_name)
- {
- char error_buffer[512];
- sprintf(error_buffer,
- "(%s) %s error%s:\n %s%s ->\n %s\n not: %s.\n"
- "Use --preserve and examine: ", pixel_loc, reason, via_linear,
- pixel_in, background_info, pixel_out, pixel_calc);
- return logerror(transform->in_image, transform->in_image->file_name,
- error_buffer, transform->out_image->file_name);
- }
-
- else
- {
- char error_buffer[512];
- sprintf(error_buffer,
- "(%s) %s error%s:\n %s%s ->\n %s\n not: %s.\n"
- " The error happened when reading the original file with this format.",
- pixel_loc, reason, via_linear, pixel_in, background_info, pixel_out,
- pixel_calc);
- return logerror(transform->in_image, transform->in_image->file_name,
- error_buffer, "");
- }
-}
-
-static int
-cmppixel(Transform *transform, png_const_voidp in, png_const_voidp out,
- png_uint_32 x, png_uint_32 y/*or palette index*/)
-{
- int maxerr;
- png_const_charp errmsg;
- Pixel pixel_in, pixel_calc, pixel_out;
-
- transform->in_gp(&pixel_in, in);
-
- if (transform->from_linear == NULL)
- transform->transform(&pixel_calc, &pixel_in, transform->background);
-
- else
- {
- transform->transform(&pixel_out, &pixel_in, transform->background);
- transform->from_linear(&pixel_calc, &pixel_out, NULL);
- }
-
- transform->out_gp(&pixel_out, out);
-
- /* Eliminate the case where the input and output values match exactly. */
- if (pixel_calc.a == pixel_out.a && pixel_calc.r == pixel_out.r &&
- pixel_calc.g == pixel_out.g && pixel_calc.b == pixel_out.b)
- return 1;
-
- /* Eliminate the case where the output pixel is transparent and the output
- * is 8-bit - any component values are valid. Don't check the input alpha
- * here to also skip the 16-bit small alpha cases.
- */
- if (transform->output_8bit && pixel_calc.a == 0 && pixel_out.a == 0)
- return 1;
-
- /* Check for alpha errors first; an alpha error can damage the components too
- * so avoid spurious checks on components if one is found.
- */
- errmsg = NULL;
- {
- int err_a = abs(pixel_calc.a-pixel_out.a);
-
- if (err_a > transform->error[3])
- {
- /* If accumulating check the components too */
- if (transform->accumulate)
- transform->error[3] = (png_uint_16)err_a;
-
- else
- errmsg = "alpha";
- }
- }
-
- /* Now if *either* of the output alphas are 0 but alpha is within tolerance
- * eliminate the 8-bit component comparison.
- */
- if (errmsg == NULL && transform->output_8bit &&
- (pixel_calc.a == 0 || pixel_out.a == 0))
- return 1;
-
- if (errmsg == NULL) /* else just signal an alpha error */
- {
- int err_r = abs(pixel_calc.r - pixel_out.r);
- int err_g = abs(pixel_calc.g - pixel_out.g);
- int err_b = abs(pixel_calc.b - pixel_out.b);
- int limit;
-
- if ((err_r | err_g | err_b) == 0)
- return 1; /* exact match */
-
- /* Mismatch on a component, check the input alpha */
- if (pixel_in.a >= transform->in_opaque)
- {
- errmsg = "opaque component";
- limit = 2; /* opaque */
- }
-
- else if (pixel_in.a > 0)
- {
- errmsg = "alpha component";
- limit = 1; /* partially transparent */
- }
-
- else
- {
- errmsg = "transparent component (background)";
- limit = 0; /* transparent */
- }
-
- maxerr = err_r;
- if (maxerr < err_g) maxerr = err_g;
- if (maxerr < err_b) maxerr = err_b;
-
- if (maxerr <= transform->error[limit])
- return 1; /* within the error limits */
-
- /* Handle a component mis-match; log it, just return an error code, or
- * accumulate it.
- */
- if (transform->accumulate)
- {
- transform->error[limit] = (png_uint_16)maxerr;
- return 1; /* to cause the caller to keep going */
- }
- }
-
- /* Failure to match and not accumulating, so the error must be logged. */
- return logpixel(transform, x, y, &pixel_in, &pixel_calc, &pixel_out, errmsg);
-}
-
-static png_byte
-component_loc(png_byte loc[4], png_uint_32 format)
-{
- /* Given a format return the number of channels and the location of
- * each channel.
- *
- * The mask 'loc' contains the component offset of the channels in the
- * following order. Note that if 'format' is grayscale the entries 1-3 must
- * all contain the location of the gray channel.
- *
- * 0: alpha
- * 1: red or gray
- * 2: green or gray
- * 3: blue or gray
- */
- png_byte channels;
-
- if (format & PNG_FORMAT_FLAG_COLOR)
- {
- channels = 3;
-
- loc[2] = 1;
-
-# ifdef PNG_FORMAT_BGR_SUPPORTED
- if (format & PNG_FORMAT_FLAG_BGR)
- {
- loc[1] = 2;
- loc[3] = 0;
- }
-
- else
-# endif
- {
- loc[1] = 0;
- loc[3] = 2;
- }
- }
-
- else
- {
- channels = 1;
- loc[1] = loc[2] = loc[3] = 0;
- }
-
- if (format & PNG_FORMAT_FLAG_ALPHA)
- {
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if (format & PNG_FORMAT_FLAG_AFIRST)
- {
- loc[0] = 0;
- ++loc[1];
- ++loc[2];
- ++loc[3];
- }
-
- else
-# endif
- loc[0] = channels;
-
- ++channels;
- }
-
- else
- loc[0] = 4; /* not present */
-
- return channels;
-}
-
-/* Compare two images, the original 'a', which was written out then read back in
- * to * give image 'b'. The formats may have been changed.
- */
-static int
-compare_two_images(Image *a, Image *b, int via_linear,
- png_const_colorp background)
-{
- ptrdiff_t stridea = a->stride;
- ptrdiff_t strideb = b->stride;
- png_const_bytep rowa = a->buffer+16;
- png_const_bytep rowb = b->buffer+16;
- png_uint_32 width = a->image.width;
- png_uint_32 height = a->image.height;
- png_uint_32 formata = a->image.format;
- png_uint_32 formatb = b->image.format;
- unsigned int a_sample = PNG_IMAGE_SAMPLE_SIZE(formata);
- unsigned int b_sample = PNG_IMAGE_SAMPLE_SIZE(formatb);
- int alpha_added, alpha_removed;
- int bchannels;
- png_uint_32 y;
- Transform tr;
- int btoa[4]={0,0,0,0};
-
- /* This should never happen: */
- if (width != b->image.width || height != b->image.height)
- return logerror(a, a->file_name, ": width x height changed: ",
- b->file_name);
-
- /* Set up the background and the transform */
- transform_from_formats(&tr, a, b, background, via_linear);
-
- /* Find the first row and inter-row space. */
- if (!(formata & PNG_FORMAT_FLAG_COLORMAP) &&
- (formata & PNG_FORMAT_FLAG_LINEAR))
- stridea *= 2;
-
- if (!(formatb & PNG_FORMAT_FLAG_COLORMAP) &&
- (formatb & PNG_FORMAT_FLAG_LINEAR))
- strideb *= 2;
-
- if (stridea < 0) rowa += (height-1) * (-stridea);
- if (strideb < 0) rowb += (height-1) * (-strideb);
-
- /* First shortcut the two colormap case by comparing the image data; if it
- * matches then we expect the colormaps to match, although this is not
- * absolutely necessary for an image match. If the colormaps fail to match
- * then there is a problem in libpng.
- */
- if (formata & formatb & PNG_FORMAT_FLAG_COLORMAP)
- {
- /* Only check colormap entries that actually exist; */
- png_const_bytep ppa, ppb;
- int match;
- png_byte in_use[256], amax = 0, bmax = 0;
-
- memset(in_use, 0, sizeof in_use);
-
- ppa = rowa;
- ppb = rowb;
-
- /* Do this the slow way to accumulate the 'in_use' flags, don't break out
- * of the loop until the end; this validates the color-mapped data to
- * ensure all pixels are valid color-map indexes.
- */
- for (y=0, match=1; y<height && match; ++y, ppa += stridea, ppb += strideb)
- {
- png_uint_32 x;
-
- for (x=0; x<width; ++x)
- {
- png_byte bval = ppb[x];
- png_byte aval = ppa[x];
-
- if (bval > bmax)
- bmax = bval;
-
- if (bval != aval)
- match = 0;
-
- in_use[aval] = 1;
- if (aval > amax)
- amax = aval;
- }
- }
-
- /* If the buffers match then the colormaps must too. */
- if (match)
- {
- /* Do the color-maps match, entry by entry? Only check the 'in_use'
- * entries. An error here should be logged as a color-map error.
- */
- png_const_bytep a_cmap = (png_const_bytep)a->colormap;
- png_const_bytep b_cmap = (png_const_bytep)b->colormap;
- int result = 1; /* match by default */
-
- /* This is used in logpixel to get the error message correct. */
- tr.is_palette = 1;
-
- for (y=0; y<256; ++y, a_cmap += a_sample, b_cmap += b_sample)
- if (in_use[y])
- {
- /* The colormap entries should be valid, but because libpng doesn't
- * do any checking at present the original image may contain invalid
- * pixel values. These cause an error here (at present) unless
- * accumulating errors in which case the program just ignores them.
- */
- if (y >= a->image.colormap_entries)
- {
- if ((a->opts & ACCUMULATE) == 0)
- {
- char pindex[9];
- sprintf(pindex, "%lu[%lu]", (unsigned long)y,
- (unsigned long)a->image.colormap_entries);
- logerror(a, a->file_name, ": bad pixel index: ", pindex);
- }
- result = 0;
- }
-
- else if (y >= b->image.colormap_entries)
- {
- if ((b->opts & ACCUMULATE) == 0)
- {
- char pindex[9];
- sprintf(pindex, "%lu[%lu]", (unsigned long)y,
- (unsigned long)b->image.colormap_entries);
- logerror(b, b->file_name, ": bad pixel index: ", pindex);
- }
- result = 0;
- }
-
- /* All the mismatches are logged here; there can only be 256! */
- else if (!cmppixel(&tr, a_cmap, b_cmap, 0, y))
- result = 0;
- }
-
- /* If requested, copy the error values back from the Transform. */
- if (a->opts & ACCUMULATE)
- {
- tr.error_ptr[0] = tr.error[0];
- tr.error_ptr[1] = tr.error[1];
- tr.error_ptr[2] = tr.error[2];
- tr.error_ptr[3] = tr.error[3];
- result = 1; /* force a continue */
- }
-
- return result;
- }
-
- /* else the image buffers don't match pixel-wise so compare sample values
- * instead, but first validate that the pixel indexes are in range (but
- * only if not accumulating, when the error is ignored.)
- */
- else if ((a->opts & ACCUMULATE) == 0)
- {
-# ifdef __GNUC__
-# define BYTE_CHARS 20 /* 2^32: GCC sprintf warning */
-# else
-# define BYTE_CHARS 3 /* 2^8: real maximum value */
-# endif
- /* Check the original image first,
- * TODO: deal with input images with bad pixel values?
- */
- if (amax >= a->image.colormap_entries)
- {
- char pindex[3+2*BYTE_CHARS];
- sprintf(pindex, "%d[%u]", amax,
- (png_byte)/*SAFE*/a->image.colormap_entries);
- return logerror(a, a->file_name, ": bad pixel index: ", pindex);
- }
-
- else if (bmax >= b->image.colormap_entries)
- {
- char pindex[3+2*BYTE_CHARS];
- sprintf(pindex, "%d[%u]", bmax,
- (png_byte)/*SAFE*/b->image.colormap_entries);
- return logerror(b, b->file_name, ": bad pixel index: ", pindex);
- }
- }
- }
-
- /* We can directly compare pixel values without the need to use the read
- * or transform support (i.e. a memory compare) if:
- *
- * 1) The bit depth has not changed.
- * 2) RGB to grayscale has not been done (the reverse is ok; we just compare
- * the three RGB values to the original grayscale.)
- * 3) An alpha channel has not been removed from an 8-bit format, or the
- * 8-bit alpha value of the pixel was 255 (opaque).
- *
- * If an alpha channel has been *added* then it must have the relevant opaque
- * value (255 or 65535).
- *
- * The fist two the tests (in the order given above) (using the boolean
- * equivalence !a && !b == !(a || b))
- */
- if (!(((formata ^ formatb) & PNG_FORMAT_FLAG_LINEAR) |
- (formata & (formatb ^ PNG_FORMAT_FLAG_COLOR) & PNG_FORMAT_FLAG_COLOR)))
- {
- /* Was an alpha channel changed? */
- png_uint_32 alpha_changed = (formata ^ formatb) & PNG_FORMAT_FLAG_ALPHA;
-
- /* Was an alpha channel removed? (The third test.) If so the direct
- * comparison is only possible if the input alpha is opaque.
- */
- alpha_removed = (formata & alpha_changed) != 0;
-
- /* Was an alpha channel added? */
- alpha_added = (formatb & alpha_changed) != 0;
-
- /* The channels may have been moved between input and output, this finds
- * out how, recording the result in the btoa array, which says where in
- * 'a' to find each channel of 'b'. If alpha was added then btoa[alpha]
- * ends up as 4 (and is not used.)
- */
- {
- int i;
- png_byte aloc[4];
- png_byte bloc[4];
-
- /* The following are used only if the formats match, except that
- * 'bchannels' is a flag for matching formats. btoa[x] says, for each
- * channel in b, where to find the corresponding value in a, for the
- * bchannels. achannels may be different for a gray to rgb transform
- * (a will be 1 or 2, b will be 3 or 4 channels.)
- */
- (void)component_loc(aloc, formata);
- bchannels = component_loc(bloc, formatb);
-
- /* Hence the btoa array. */
- for (i=0; i<4; ++i) if (bloc[i] < 4)
- btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */
-
- if (alpha_added)
- alpha_added = bloc[0]; /* location of alpha channel in image b */
-
- else
- alpha_added = 4; /* Won't match an image b channel */
-
- if (alpha_removed)
- alpha_removed = aloc[0]; /* location of alpha channel in image a */
-
- else
- alpha_removed = 4;
- }
- }
-
- else
- {
- /* Direct compare is not possible, cancel out all the corresponding local
- * variables.
- */
- bchannels = 0;
- alpha_removed = alpha_added = 4;
- btoa[3] = btoa[2] = btoa[1] = btoa[0] = 4; /* 4 == not present */
- }
-
- for (y=0; y<height; ++y, rowa += stridea, rowb += strideb)
- {
- png_const_bytep ppa, ppb;
- png_uint_32 x;
-
- for (x=0, ppa=rowa, ppb=rowb; x<width; ++x)
- {
- png_const_bytep psa, psb;
-
- if (formata & PNG_FORMAT_FLAG_COLORMAP)
- psa = (png_const_bytep)a->colormap + a_sample * *ppa++;
- else
- psa = ppa, ppa += a_sample;
-
- if (formatb & PNG_FORMAT_FLAG_COLORMAP)
- psb = (png_const_bytep)b->colormap + b_sample * *ppb++;
- else
- psb = ppb, ppb += b_sample;
-
- /* Do the fast test if possible. */
- if (bchannels)
- {
- /* Check each 'b' channel against either the corresponding 'a'
- * channel or the opaque alpha value, as appropriate. If
- * alpha_removed value is set (not 4) then also do this only if the
- * 'a' alpha channel (alpha_removed) is opaque; only relevant for
- * the 8-bit case.
- */
- if (formatb & PNG_FORMAT_FLAG_LINEAR) /* 16-bit checks */
- {
- png_const_uint_16p pua = aligncastconst(png_const_uint_16p, psa);
- png_const_uint_16p pub = aligncastconst(png_const_uint_16p, psb);
-
- switch (bchannels)
- {
- case 4:
- if (pua[btoa[3]] != pub[3]) break;
- /* FALLTHROUGH */
- case 3:
- if (pua[btoa[2]] != pub[2]) break;
- /* FALLTHROUGH */
- case 2:
- if (pua[btoa[1]] != pub[1]) break;
- /* FALLTHROUGH */
- case 1:
- if (pua[btoa[0]] != pub[0]) break;
- if (alpha_added != 4 && pub[alpha_added] != 65535) break;
- continue; /* x loop */
- default:
- break; /* impossible */
- }
- }
-
- else if (alpha_removed == 4 || psa[alpha_removed] == 255)
- {
- switch (bchannels)
- {
- case 4:
- if (psa[btoa[3]] != psb[3]) break;
- /* FALLTHROUGH */
- case 3:
- if (psa[btoa[2]] != psb[2]) break;
- /* FALLTHROUGH */
- case 2:
- if (psa[btoa[1]] != psb[1]) break;
- /* FALLTHROUGH */
- case 1:
- if (psa[btoa[0]] != psb[0]) break;
- if (alpha_added != 4 && psb[alpha_added] != 255) break;
- continue; /* x loop */
- default:
- break; /* impossible */
- }
- }
- }
-
- /* If we get to here the fast match failed; do the slow match for this
- * pixel.
- */
- if (!cmppixel(&tr, psa, psb, x, y) && (a->opts & KEEP_GOING) == 0)
- return 0; /* error case */
- }
- }
-
- /* If requested, copy the error values back from the Transform. */
- if (a->opts & ACCUMULATE)
- {
- tr.error_ptr[0] = tr.error[0];
- tr.error_ptr[1] = tr.error[1];
- tr.error_ptr[2] = tr.error[2];
- tr.error_ptr[3] = tr.error[3];
- }
-
- return 1;
-}
-
-/* Read the file; how the read gets done depends on which of input_file and
- * input_memory have been set.
- */
-static int
-read_file(Image *image, png_uint_32 format, png_const_colorp background)
-{
- memset(&image->image, 0, sizeof image->image);
- image->image.version = PNG_IMAGE_VERSION;
-
- if (image->input_memory != NULL)
- {
- if (!png_image_begin_read_from_memory(&image->image, image->input_memory,
- image->input_memory_size))
- return logerror(image, "memory init: ", image->file_name, "");
- }
-
-# ifdef PNG_STDIO_SUPPORTED
- else if (image->input_file != NULL)
- {
- if (!png_image_begin_read_from_stdio(&image->image, image->input_file))
- return logerror(image, "stdio init: ", image->file_name, "");
- }
-
- else
- {
- if (!png_image_begin_read_from_file(&image->image, image->file_name))
- return logerror(image, "file init: ", image->file_name, "");
- }
-# else
- else
- {
- return logerror(image, "unsupported file/stdio init: ",
- image->file_name, "");
- }
-# endif
-
- /* This must be set after the begin_read call: */
- if (image->opts & sRGB_16BIT)
- image->image.flags |= PNG_IMAGE_FLAG_16BIT_sRGB;
-
- /* Have an initialized image with all the data we need plus, maybe, an
- * allocated file (myfile) or buffer (mybuffer) that need to be freed.
- */
- {
- int result;
- png_uint_32 image_format;
-
- /* Print both original and output formats. */
- image_format = image->image.format;
-
- if (image->opts & VERBOSE)
- {
- printf("%s %lu x %lu %s -> %s", image->file_name,
- (unsigned long)image->image.width,
- (unsigned long)image->image.height,
- format_names[image_format & FORMAT_MASK],
- (format & FORMAT_NO_CHANGE) != 0 || image->image.format == format
- ? "no change" : format_names[format & FORMAT_MASK]);
-
- if (background != NULL)
- printf(" background(%d,%d,%d)\n", background->red,
- background->green, background->blue);
- else
- printf("\n");
-
- fflush(stdout);
- }
-
- /* 'NO_CHANGE' combined with the color-map flag forces the base format
- * flags to be set on read to ensure that the original representation is
- * not lost in the pass through a colormap format.
- */
- if ((format & FORMAT_NO_CHANGE) != 0)
- {
- if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
- (image_format & PNG_FORMAT_FLAG_COLORMAP) != 0)
- format = (image_format & ~BASE_FORMATS) | (format & BASE_FORMATS);
-
- else
- format = image_format;
- }
-
- image->image.format = format;
-
- image->stride = PNG_IMAGE_ROW_STRIDE(image->image) + image->stride_extra;
- allocbuffer(image);
-
- result = png_image_finish_read(&image->image, background,
- image->buffer+16, (png_int_32)image->stride, image->colormap);
-
- checkbuffer(image, image->file_name);
-
- if (result)
- return checkopaque(image);
-
- else
- return logerror(image, image->file_name, ": image read failed", "");
- }
-}
-
-/* Reads from a filename, which must be in image->file_name, but uses
- * image->opts to choose the method. The file is always read in its native
- * format (the one the simplified API suggests).
- */
-static int
-read_one_file(Image *image)
-{
- if (!(image->opts & USE_FILE) || (image->opts & USE_STDIO))
- {
- /* memory or stdio. */
- FILE *f = fopen(image->file_name, "rb");
-
- if (f != NULL)
- {
- if (image->opts & USE_FILE)
- image->input_file = f;
-
- else /* memory */
- {
- if (fseek(f, 0, SEEK_END) == 0)
- {
- long int cb = ftell(f);
-
- if (cb > 0)
- {
-#ifndef __COVERITY__
- if ((unsigned long int)cb <= (size_t)~(size_t)0)
-#endif
- {
- png_bytep b = voidcast(png_bytep, malloc((size_t)cb));
-
- if (b != NULL)
- {
- rewind(f);
-
- if (fread(b, (size_t)cb, 1, f) == 1)
- {
- fclose(f);
- image->input_memory_size = cb;
- image->input_memory = b;
- }
-
- else
- {
- free(b);
- return logclose(image, f, image->file_name,
- ": read failed: ");
- }
- }
-
- else
- return logclose(image, f, image->file_name,
- ": out of memory: ");
- }
-
- else
- return logclose(image, f, image->file_name,
- ": file too big for this architecture: ");
- /* cb is the length of the file as a (long) and
- * this is greater than the maximum amount of
- * memory that can be requested from malloc.
- */
- }
-
- else if (cb == 0)
- return logclose(image, f, image->file_name,
- ": zero length: ");
-
- else
- return logclose(image, f, image->file_name,
- ": tell failed: ");
- }
-
- else
- return logclose(image, f, image->file_name, ": seek failed: ");
- }
- }
-
- else
- return logerror(image, image->file_name, ": open failed: ",
- strerror(errno));
- }
-
- return read_file(image, FORMAT_NO_CHANGE, NULL);
-}
-
-#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
-static int
-write_one_file(Image *output, Image *image, int convert_to_8bit)
-{
- if (image->opts & FAST_WRITE)
- image->image.flags |= PNG_IMAGE_FLAG_FAST;
-
- if (image->opts & USE_STDIO)
- {
-#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
-#ifndef __COVERITY__
- FILE *f = tmpfile();
-#else
- /* Experimental. Coverity says tmpfile() is insecure because it
- * generates predictable names.
- *
- * It is possible to satisfy Coverity by using mkstemp(); however,
- * any platform supporting mkstemp() undoubtedly has a secure tmpfile()
- * implementation as well, and doesn't need the fix. Note that
- * the fix won't work on platforms that don't support mkstemp().
- *
- * https://www.securecoding.cert.org/confluence/display/c/
- * FIO21-C.+Do+not+create+temporary+files+in+shared+directories
- * says that most historic implementations of tmpfile() provide
- * only a limited number of possible temporary file names
- * (usually 26) before file names are recycled. That article also
- * provides a secure solution that unfortunately depends upon mkstemp().
- */
- char tmpfile[] = "pngstest-XXXXXX";
- int filedes;
- FILE *f;
- umask(0177);
- filedes = mkstemp(tmpfile);
- if (filedes < 0)
- f = NULL;
- else
- {
- f = fdopen(filedes,"w+");
- /* Hide the filename immediately and ensure that the file does
- * not exist after the program ends
- */
- (void) unlink(tmpfile);
- }
-#endif
-
- if (f != NULL)
- {
- if (png_image_write_to_stdio(&image->image, f, convert_to_8bit,
- image->buffer+16, (png_int_32)image->stride, image->colormap))
- {
- if (fflush(f) == 0)
- {
- rewind(f);
- initimage(output, image->opts, "tmpfile", image->stride_extra);
- output->input_file = f;
- if (!checkopaque(image))
- return 0;
- }
-
- else
- return logclose(image, f, "tmpfile", ": flush: ");
- }
-
- else
- {
- fclose(f);
- return logerror(image, "tmpfile", ": write failed", "");
- }
- }
-
- else
- return logerror(image, "tmpfile", ": open: ", strerror(errno));
-#else /* SIMPLIFIED_WRITE_STDIO */
- return logerror(image, "tmpfile", ": open: unsupported", "");
-#endif /* SIMPLIFIED_WRITE_STDIO */
- }
-
- else if (image->opts & USE_FILE)
- {
-#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
- static int counter = 0;
- char name[32];
-
- sprintf(name, "%s%d.png", tmpf, ++counter);
-
- if (png_image_write_to_file(&image->image, name, convert_to_8bit,
- image->buffer+16, (png_int_32)image->stride, image->colormap))
- {
- initimage(output, image->opts, output->tmpfile_name,
- image->stride_extra);
- /* Afterwards, or freeimage will delete it! */
- strcpy(output->tmpfile_name, name);
-
- if (!checkopaque(image))
- return 0;
- }
-
- else
- return logerror(image, name, ": write failed", "");
-#else /* SIMPLIFIED_WRITE_STDIO */
- return logerror(image, "stdio", ": open: unsupported", "");
-#endif /* SIMPLIFIED_WRITE_STDIO */
- }
-
- else /* use memory */
- {
- png_alloc_size_t size;
-
- if (png_image_write_get_memory_size(image->image, size, convert_to_8bit,
- image->buffer+16, (png_int_32)image->stride, image->colormap))
- {
- /* This is non-fatal but ignoring it was causing serious problems in
- * the macro to be ignored:
- */
- if (size > PNG_IMAGE_PNG_SIZE_MAX(image->image))
- return logerror(image, "memory", ": PNG_IMAGE_SIZE_MAX wrong", "");
-
- initimage(output, image->opts, "memory", image->stride_extra);
- output->input_memory = malloc(size);
-
- if (output->input_memory != NULL)
- {
- output->input_memory_size = size;
-
- if (png_image_write_to_memory(&image->image, output->input_memory,
- &output->input_memory_size, convert_to_8bit, image->buffer+16,
- (png_int_32)image->stride, image->colormap))
- {
- /* This is also non-fatal but it safes safer to error out anyway:
- */
- if (size != output->input_memory_size)
- return logerror(image, "memory", ": memory size wrong", "");
- }
-
- else
- return logerror(image, "memory", ": write failed", "");
- }
-
- else
- return logerror(image, "memory", ": out of memory", "");
- }
-
- else
- return logerror(image, "memory", ": get size:", "");
- }
-
- /* 'output' has an initialized temporary image, read this back in and compare
- * this against the original: there should be no change since the original
- * format was written unmodified unless 'convert_to_8bit' was specified.
- * However, if the original image was color-mapped, a simple read will zap
- * the linear, color and maybe alpha flags, this will cause spurious failures
- * under some circumstances.
- */
- if (read_file(output, image->image.format | FORMAT_NO_CHANGE, NULL))
- {
- png_uint_32 original_format = image->image.format;
-
- if (convert_to_8bit)
- original_format &= ~PNG_FORMAT_FLAG_LINEAR;
-
- if ((output->image.format & BASE_FORMATS) !=
- (original_format & BASE_FORMATS))
- return logerror(image, image->file_name, ": format changed on read: ",
- output->file_name);
-
- return compare_two_images(image, output, 0/*via linear*/, NULL);
- }
-
- else
- return logerror(output, output->tmpfile_name,
- ": read of new file failed", "");
-}
-#endif
-
-static int
-testimage(Image *image, png_uint_32 opts, format_list *pf)
-{
- int result;
- Image copy;
-
- /* Copy the original data, stealing it from 'image' */
- checkopaque(image);
- copy = *image;
-
- copy.opts = opts;
- copy.buffer = NULL;
- copy.bufsize = 0;
- copy.allocsize = 0;
-
- image->input_file = NULL;
- image->input_memory = NULL;
- image->input_memory_size = 0;
- image->tmpfile_name[0] = 0;
-
- {
- png_uint_32 counter;
- Image output;
-
- newimage(&output);
-
- result = 1;
-
- /* Use the low bit of 'counter' to indicate whether or not to do alpha
- * removal with a background color or by composting onto the image; this
- * step gets skipped if it isn't relevant
- */
- for (counter=0; counter<2*FORMAT_COUNT; ++counter)
- if (format_isset(pf, counter >> 1))
- {
- png_uint_32 format = counter >> 1;
-
- png_color background_color;
- png_colorp background = NULL;
-
- /* If there is a format change that removes the alpha channel then
- * the background is relevant. If the output is 8-bit color-mapped
- * then a background color *must* be provided, otherwise there are
- * two tests to do - one with a color, the other with NULL. The
- * NULL test happens second.
- */
- if ((counter & 1) == 0)
- {
- if ((format & PNG_FORMAT_FLAG_ALPHA) == 0 &&
- (image->image.format & PNG_FORMAT_FLAG_ALPHA) != 0)
- {
- /* Alpha/transparency will be removed, the background is
- * relevant: make it a color the first time
- */
- random_color(&background_color);
- background = &background_color;
-
- /* BUT if the output is to a color-mapped 8-bit format then
- * the background must always be a color, so increment 'counter'
- * to skip the NULL test.
- */
- if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
- (format & PNG_FORMAT_FLAG_LINEAR) == 0)
- ++counter;
- }
-
- /* Otherwise an alpha channel is not being eliminated, just leave
- * background NULL and skip the (counter & 1) NULL test.
- */
- else
- ++counter;
- }
- /* else just use NULL for background */
-
- resetimage(&copy);
- copy.opts = opts; /* in case read_file needs to change it */
-
- result = read_file(&copy, format, background);
- if (!result)
- break;
-
- /* Make sure the file just read matches the original file. */
- result = compare_two_images(image, &copy, 0/*via linear*/, background);
- if (!result)
- break;
-
-# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
- /* Write the *copy* just made to a new file to make sure the write
- * side works ok. Check the conversion to sRGB if the copy is
- * linear.
- */
- output.opts = opts;
- result = write_one_file(&output, &copy, 0/*convert to 8bit*/);
- if (!result)
- break;
-
- /* Validate against the original too; the background is needed here
- * as well so that compare_two_images knows what color was used.
- */
- result = compare_two_images(image, &output, 0, background);
- if (!result)
- break;
-
- if ((format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
- (format & PNG_FORMAT_FLAG_COLORMAP) == 0)
- {
- /* 'output' is linear, convert to the corresponding sRGB format.
- */
- output.opts = opts;
- result = write_one_file(&output, &copy, 1/*convert to 8bit*/);
- if (!result)
- break;
-
- /* This may involve a conversion via linear; in the ideal world
- * this would round-trip correctly, but libpng 1.5.7 is not the
- * ideal world so allow a drift (error_via_linear).
- *
- * 'image' has an alpha channel but 'output' does not then there
- * will a strip-alpha-channel operation (because 'output' is
- * linear), handle this by composing on black when doing the
- * comparison.
- */
- result = compare_two_images(image, &output, 1/*via_linear*/,
- background);
- if (!result)
- break;
- }
-# endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */
- }
-
- freeimage(&output);
- }
-
- freeimage(&copy);
-
- return result;
-}
-
-static int
-test_one_file(const char *file_name, format_list *formats, png_uint_32 opts,
- int stride_extra, int log_pass)
-{
- int result;
- Image image;
-
- if (!(opts & NO_RESEED))
- reseed(); /* ensure that the random numbers don't depend on file order */
- newimage(&image);
- initimage(&image, opts, file_name, stride_extra);
- result = read_one_file(&image);
- if (result)
- result = testimage(&image, opts, formats);
- freeimage(&image);
-
- /* Ensure that stderr is flushed into any log file */
- fflush(stderr);
-
- if (log_pass)
- {
- if (result)
- printf("PASS:");
-
- else
- printf("FAIL:");
-
-# ifndef PNG_SIMPLIFIED_WRITE_SUPPORTED
- printf(" (no write)");
-# endif
-
- print_opts(opts);
- printf(" %s\n", file_name);
- /* stdout may not be line-buffered if it is piped to a file, so: */
- fflush(stdout);
- }
-
- else if (!result)
- exit(1);
-
- return result;
-}
-
-int
-main(int argc, char **argv)
-{
- png_uint_32 opts = FAST_WRITE | STRICT;
- format_list formats;
- const char *touch = NULL;
- int log_pass = 0;
- int redundant = 0;
- int stride_extra = 0;
- int retval = 0;
- int c;
-
-#if PNG_LIBPNG_VER >= 10700
- /* This error should not exist in 1.7 or later: */
- opts |= GBG_ERROR;
-#endif
-
- init_sRGB_to_d();
-#if 0
- init_error_via_linear();
-#endif
- format_init(&formats);
- reseed(); /* initialize random number seeds */
-
- for (c=1; c<argc; ++c)
- {
- const char *arg = argv[c];
-
- if (strcmp(arg, "--log") == 0)
- log_pass = 1;
- else if (strcmp(arg, "--fresh") == 0)
- {
- memset(gpc_error, 0, sizeof gpc_error);
- memset(gpc_error_via_linear, 0, sizeof gpc_error_via_linear);
- }
- else if (strcmp(arg, "--file") == 0)
-# ifdef PNG_STDIO_SUPPORTED
- opts |= USE_FILE;
-# else
- return SKIP; /* skipped: no support */
-# endif
- else if (strcmp(arg, "--memory") == 0)
- opts &= ~USE_FILE;
- else if (strcmp(arg, "--stdio") == 0)
-# ifdef PNG_STDIO_SUPPORTED
- opts |= USE_STDIO;
-# else
- return SKIP; /* skipped: no support */
-# endif
- else if (strcmp(arg, "--name") == 0)
- opts &= ~USE_STDIO;
- else if (strcmp(arg, "--verbose") == 0)
- opts |= VERBOSE;
- else if (strcmp(arg, "--quiet") == 0)
- opts &= ~VERBOSE;
- else if (strcmp(arg, "--preserve") == 0)
- opts |= KEEP_TMPFILES;
- else if (strcmp(arg, "--nopreserve") == 0)
- opts &= ~KEEP_TMPFILES;
- else if (strcmp(arg, "--keep-going") == 0)
- opts |= KEEP_GOING;
- else if (strcmp(arg, "--fast") == 0)
- opts |= FAST_WRITE;
- else if (strcmp(arg, "--slow") == 0)
- opts &= ~FAST_WRITE;
- else if (strcmp(arg, "--accumulate") == 0)
- opts |= ACCUMULATE;
- else if (strcmp(arg, "--redundant") == 0)
- redundant = 1;
- else if (strcmp(arg, "--stop") == 0)
- opts &= ~KEEP_GOING;
- else if (strcmp(arg, "--strict") == 0)
- opts |= STRICT;
- else if (strcmp(arg, "--nostrict") == 0)
- opts &= ~STRICT;
- else if (strcmp(arg, "--sRGB-16bit") == 0)
- opts |= sRGB_16BIT;
- else if (strcmp(arg, "--linear-16bit") == 0)
- opts &= ~sRGB_16BIT;
- else if (strcmp(arg, "--noreseed") == 0)
- opts |= NO_RESEED;
- else if (strcmp(arg, "--fault-gbg-warning") == 0)
- opts |= GBG_ERROR;
- else if (strcmp(arg, "--tmpfile") == 0)
- {
- if (c+1 < argc)
- {
- if (strlen(argv[++c]) >= sizeof tmpf)
- {
- fflush(stdout);
- fprintf(stderr, "%s: %s is too long for a temp file prefix\n",
- argv[0], argv[c]);
- exit(99);
- }
-
- /* Safe: checked above */
- strncpy(tmpf, argv[c], sizeof (tmpf)-1);
- }
-
- else
- {
- fflush(stdout);
- fprintf(stderr, "%s: %s requires a temporary file prefix\n",
- argv[0], arg);
- exit(99);
- }
- }
- else if (strcmp(arg, "--touch") == 0)
- {
- if (c+1 < argc)
- touch = argv[++c];
-
- else
- {
- fflush(stdout);
- fprintf(stderr, "%s: %s requires a file name argument\n",
- argv[0], arg);
- exit(99);
- }
- }
- else if (arg[0] == '+')
- {
- png_uint_32 format = formatof(arg+1);
-
- if (format > FORMAT_COUNT)
- exit(99);
-
- format_set(&formats, format);
- }
- else if (arg[0] == '-' && arg[1] != 0 && (arg[1] != '0' || arg[2] != 0))
- {
- fflush(stdout);
- fprintf(stderr, "%s: unknown option: %s\n", argv[0], arg);
- exit(99);
- }
- else
- {
- if (format_is_initial(&formats))
- format_default(&formats, redundant);
-
- if (arg[0] == '-')
- {
- int term = (arg[1] == '0' ? 0 : '\n');
- unsigned int ich = 0;
-
- /* Loop reading files, use a static buffer to simplify this and just
- * stop if the name gets to long.
- */
- static char buffer[4096];
-
- do
- {
- int ch = getchar();
-
- /* Don't allow '\0' in file names, and terminate with '\n' or,
- * for -0, just '\0' (use -print0 to find to make this work!)
- */
- if (ch == EOF || ch == term || ch == 0)
- {
- buffer[ich] = 0;
-
- if (ich > 0 && !test_one_file(buffer, &formats, opts,
- stride_extra, log_pass))
- retval = 1;
-
- if (ch == EOF)
- break;
-
- ich = 0;
- --ich; /* so that the increment below sets it to 0 again */
- }
-
- else
- buffer[ich] = (char)ch;
- } while (++ich < sizeof buffer);
-
- if (ich)
- {
- buffer[32] = 0;
- buffer[4095] = 0;
- fprintf(stderr, "%s...%s: file name too long\n", buffer,
- buffer+(4096-32));
- exit(99);
- }
- }
-
- else if (!test_one_file(arg, &formats, opts, stride_extra, log_pass))
- retval = 1;
- }
- }
-
- if (opts & ACCUMULATE)
- {
- unsigned int in;
-
- printf("/* contrib/libtests/pngstest-errors.h\n");
- printf(" *\n");
- printf(" * BUILT USING:" PNG_HEADER_VERSION_STRING);
- printf(" *\n");
- printf(" * This code is released under the libpng license.\n");
- printf(" * For conditions of distribution and use, see the disclaimer\n");
- printf(" * and license in png.h\n");
- printf(" *\n");
- printf(" * THIS IS A MACHINE GENERATED FILE: do not edit it directly!\n");
- printf(" * Instead run:\n");
- printf(" *\n");
- printf(" * pngstest --accumulate\n");
- printf(" *\n");
- printf(" * on as many PNG files as possible; at least PNGSuite and\n");
- printf(" * contrib/libtests/testpngs.\n");
- printf(" */\n");
-
- printf("static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] =\n");
- printf("{\n");
- for (in=0; in<16; ++in)
- {
- unsigned int out;
- printf(" { /* input: %s */\n ", format_names[in]);
- for (out=0; out<16; ++out)
- {
- unsigned int alpha;
- printf(" {");
- for (alpha=0; alpha<4; ++alpha)
- {
- printf(" %d", gpc_error[in][out][alpha]);
- if (alpha < 3) putchar(',');
- }
- printf(" }");
- if (out < 15)
- {
- putchar(',');
- if (out % 4 == 3) printf("\n ");
- }
- }
- printf("\n }");
-
- if (in < 15)
- putchar(',');
- else
- putchar('\n');
- }
- printf("};\n");
-
- printf("static png_uint_16 gpc_error_via_linear[16][4/*out*/][4] =\n");
- printf("{\n");
- for (in=0; in<16; ++in)
- {
- unsigned int out;
- printf(" { /* input: %s */\n ", format_names[in]);
- for (out=0; out<4; ++out)
- {
- unsigned int alpha;
- printf(" {");
- for (alpha=0; alpha<4; ++alpha)
- {
- printf(" %d", gpc_error_via_linear[in][out][alpha]);
- if (alpha < 3) putchar(',');
- }
- printf(" }");
- if (out < 3)
- putchar(',');
- }
- printf("\n }");
-
- if (in < 15)
- putchar(',');
- else
- putchar('\n');
- }
- printf("};\n");
-
- printf("static png_uint_16 gpc_error_to_colormap[8/*i*/][8/*o*/][4] =\n");
- printf("{\n");
- for (in=0; in<8; ++in)
- {
- unsigned int out;
- printf(" { /* input: %s */\n ", format_names[in]);
- for (out=0; out<8; ++out)
- {
- unsigned int alpha;
- printf(" {");
- for (alpha=0; alpha<4; ++alpha)
- {
- printf(" %d", gpc_error_to_colormap[in][out][alpha]);
- if (alpha < 3) putchar(',');
- }
- printf(" }");
- if (out < 7)
- {
- putchar(',');
- if (out % 4 == 3) printf("\n ");
- }
- }
- printf("\n }");
-
- if (in < 7)
- putchar(',');
- else
- putchar('\n');
- }
- printf("};\n");
- printf("/* END MACHINE GENERATED */\n");
- }
-
- if (retval == 0 && touch != NULL)
- {
- FILE *fsuccess = fopen(touch, "wt");
-
- if (fsuccess != NULL)
- {
- int error = 0;
- fprintf(fsuccess, "PNG simple API tests succeeded\n");
- fflush(fsuccess);
- error = ferror(fsuccess);
-
- if (fclose(fsuccess) || error)
- {
- fflush(stdout);
- fprintf(stderr, "%s: write failed\n", touch);
- exit(99);
- }
- }
-
- else
- {
- fflush(stdout);
- fprintf(stderr, "%s: open failed\n", touch);
- exit(99);
- }
- }
-
- return retval;
-}
-
-#else /* !PNG_SIMPLIFIED_READ_SUPPORTED */
-int main(void)
-{
- fprintf(stderr, "pngstest: no read support in libpng, test skipped\n");
- /* So the test is skipped: */
- return SKIP;
-}
-#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngunknown.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/pngunknown.c
deleted file mode 100644
index 05bdd833dbc..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngunknown.c
+++ /dev/null
@@ -1,1294 +0,0 @@
-
-/* pngunknown.c - test the read side unknown chunk handling
- *
- * Last changed in libpng 1.6.32 [August 24, 2017]
- * Copyright (c) 2015,2017 Glenn Randers-Pehrson
- * Written by John Cunningham Bowler
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * NOTES:
- * This is a C program that is intended to be linked against libpng. It
- * allows the libpng unknown handling code to be tested by interpreting
- * arguments to save or discard combinations of chunks. The program is
- * currently just a minimal validation for the built-in libpng facilities.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <setjmp.h>
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
- * a skipped test, in earlier versions we need to succeed on a skipped test, so:
- */
-#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
-# define SKIP 77
-#else
-# define SKIP 0
-#endif
-
-
-/* Since this program tests the ability to change the unknown chunk handling
- * these must be defined:
- */
-#if defined(PNG_SET_UNKNOWN_CHUNKS_SUPPORTED) &&\
- defined(PNG_STDIO_SUPPORTED) &&\
- defined(PNG_READ_SUPPORTED)
-
-/* One of these must be defined to allow us to find out what happened. It is
- * still useful to set unknown chunk handling without either of these in order
- * to cause *known* chunks to be discarded. This can be a significant
- * efficiency gain, but it can't really be tested here.
- */
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) ||\
- defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)
-
-#if PNG_LIBPNG_VER < 10500
-/* This deliberately lacks the const. */
-typedef png_byte *png_const_bytep;
-
-/* This is copied from 1.5.1 png.h: */
-#define PNG_INTERLACE_ADAM7_PASSES 7
-#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
-#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
-#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
-#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
-#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
- -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
-#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
- -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
-#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
- (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
-#define PNG_COL_FROM_PASS_COL(xIn, pass) \
- (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
-#define PNG_PASS_MASK(pass,off) ( \
- ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
- ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
-#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
- ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
-#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
- ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
-
-/* These are needed too for the default build: */
-#define PNG_WRITE_16BIT_SUPPORTED
-#define PNG_READ_16BIT_SUPPORTED
-
-/* This comes from pnglibconf.h after 1.5: */
-#define PNG_FP_1 100000
-#define PNG_GAMMA_THRESHOLD_FIXED\
- ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
-#endif
-
-#if PNG_LIBPNG_VER < 10600
- /* 1.6.0 constifies many APIs. The following exists to allow pngvalid to be
- * compiled against earlier versions.
- */
-# define png_const_structp png_structp
-#endif
-
-#if PNG_LIBPNG_VER < 10700
- /* Copied from libpng 1.7.0 png.h */
-#define PNG_u2(b1, b2) (((unsigned int)(b1) << 8) + (b2))
-
-#define PNG_U16(b1, b2) ((png_uint_16)PNG_u2(b1, b2))
-#define PNG_U32(b1, b2, b3, b4)\
- (((png_uint_32)PNG_u2(b1, b2) << 16) + PNG_u2(b3, b4))
-
-/* Constants for known chunk types.
- */
-#define png_IDAT PNG_U32( 73, 68, 65, 84)
-#define png_IEND PNG_U32( 73, 69, 78, 68)
-#define png_IHDR PNG_U32( 73, 72, 68, 82)
-#define png_PLTE PNG_U32( 80, 76, 84, 69)
-#define png_bKGD PNG_U32( 98, 75, 71, 68)
-#define png_cHRM PNG_U32( 99, 72, 82, 77)
-#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */
-#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
-#define png_gAMA PNG_U32(103, 65, 77, 65)
-#define png_gIFg PNG_U32(103, 73, 70, 103)
-#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */
-#define png_gIFx PNG_U32(103, 73, 70, 120)
-#define png_hIST PNG_U32(104, 73, 83, 84)
-#define png_iCCP PNG_U32(105, 67, 67, 80)
-#define png_iTXt PNG_U32(105, 84, 88, 116)
-#define png_oFFs PNG_U32(111, 70, 70, 115)
-#define png_pCAL PNG_U32(112, 67, 65, 76)
-#define png_pHYs PNG_U32(112, 72, 89, 115)
-#define png_sBIT PNG_U32(115, 66, 73, 84)
-#define png_sCAL PNG_U32(115, 67, 65, 76)
-#define png_sPLT PNG_U32(115, 80, 76, 84)
-#define png_sRGB PNG_U32(115, 82, 71, 66)
-#define png_sTER PNG_U32(115, 84, 69, 82)
-#define png_tEXt PNG_U32(116, 69, 88, 116)
-#define png_tIME PNG_U32(116, 73, 77, 69)
-#define png_tRNS PNG_U32(116, 82, 78, 83)
-#define png_zTXt PNG_U32(122, 84, 88, 116)
-
-/* Test on flag values as defined in the spec (section 5.4): */
-#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29))
-#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c))
-#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21))
-#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13))
-#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5))
-
-#endif /* PNG_LIBPNG_VER < 10700 */
-
-#ifdef __cplusplus
-# define this not_the_cpp_this
-# define new not_the_cpp_new
-# define voidcast(type, value) static_cast<type>(value)
-#else
-# define voidcast(type, value) (value)
-#endif /* __cplusplus */
-
-/* Unused formal parameter errors are removed using the following macro which is
- * expected to have no bad effects on performance.
- */
-#ifndef UNUSED
-# if defined(__GNUC__) || defined(_MSC_VER)
-# define UNUSED(param) (void)param;
-# else
-# define UNUSED(param)
-# endif
-#endif
-
-/* Types of chunks not known to libpng */
-#define png_vpAg PNG_U32(118, 112, 65, 103)
-
-/* Chunk information */
-#define PNG_INFO_tEXt 0x10000000U
-#define PNG_INFO_iTXt 0x20000000U
-#define PNG_INFO_zTXt 0x40000000U
-
-#define PNG_INFO_sTER 0x01000000U
-#define PNG_INFO_vpAg 0x02000000U
-
-#define ABSENT 0
-#define START 1
-#define END 2
-
-static struct
-{
- char name[5];
- png_uint_32 flag;
- png_uint_32 tag;
- int unknown; /* Chunk not known to libpng */
- int all; /* Chunk set by the '-1' option */
- int position; /* position in pngtest.png */
- int keep; /* unknown handling setting */
-} chunk_info[] = {
- /* Critical chunks */
- { "IDAT", PNG_INFO_IDAT, png_IDAT, 0, 0, START, 0 }, /* must be [0] */
- { "PLTE", PNG_INFO_PLTE, png_PLTE, 0, 0, ABSENT, 0 },
-
- /* Non-critical chunks that libpng handles */
- /* This is a mess but it seems to be the only way to do it - there is no way
- * to check for a definition outside a #if.
- */
- { "bKGD", PNG_INFO_bKGD, png_bKGD,
-# ifdef PNG_READ_bKGD_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "cHRM", PNG_INFO_cHRM, png_cHRM,
-# ifdef PNG_READ_cHRM_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "eXIf", PNG_INFO_eXIf, png_eXIf,
-# ifdef PNG_READ_eXIf_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, END, 0 },
- { "gAMA", PNG_INFO_gAMA, png_gAMA,
-# ifdef PNG_READ_gAMA_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "hIST", PNG_INFO_hIST, png_hIST,
-# ifdef PNG_READ_hIST_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, ABSENT, 0 },
- { "iCCP", PNG_INFO_iCCP, png_iCCP,
-# ifdef PNG_READ_iCCP_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, ABSENT, 0 },
- { "iTXt", PNG_INFO_iTXt, png_iTXt,
-# ifdef PNG_READ_iTXt_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, ABSENT, 0 },
- { "oFFs", PNG_INFO_oFFs, png_oFFs,
-# ifdef PNG_READ_oFFs_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "pCAL", PNG_INFO_pCAL, png_pCAL,
-# ifdef PNG_READ_pCAL_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "pHYs", PNG_INFO_pHYs, png_pHYs,
-# ifdef PNG_READ_pHYs_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "sBIT", PNG_INFO_sBIT, png_sBIT,
-# ifdef PNG_READ_sBIT_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "sCAL", PNG_INFO_sCAL, png_sCAL,
-# ifdef PNG_READ_sCAL_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "sPLT", PNG_INFO_sPLT, png_sPLT,
-# ifdef PNG_READ_sPLT_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, ABSENT, 0 },
- { "sRGB", PNG_INFO_sRGB, png_sRGB,
-# ifdef PNG_READ_sRGB_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "tEXt", PNG_INFO_tEXt, png_tEXt,
-# ifdef PNG_READ_tEXt_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "tIME", PNG_INFO_tIME, png_tIME,
-# ifdef PNG_READ_tIME_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, START, 0 },
- { "tRNS", PNG_INFO_tRNS, png_tRNS,
-# ifdef PNG_READ_tRNS_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 0, ABSENT, 0 },
- { "zTXt", PNG_INFO_zTXt, png_zTXt,
-# ifdef PNG_READ_zTXt_SUPPORTED
- 0,
-# else
- 1,
-# endif
- 1, END, 0 },
-
- /* No libpng handling */
- { "sTER", PNG_INFO_sTER, png_sTER, 1, 1, START, 0 },
- { "vpAg", PNG_INFO_vpAg, png_vpAg, 1, 0, START, 0 },
-};
-
-#define NINFO ((int)((sizeof chunk_info)/(sizeof chunk_info[0])))
-
-static void
-clear_keep(void)
-{
- int i = NINFO;
- while (--i >= 0)
- chunk_info[i].keep = 0;
-}
-
-static int
-find(const char *name)
-{
- int i = NINFO;
- while (--i >= 0)
- {
- if (memcmp(chunk_info[i].name, name, 4) == 0)
- break;
- }
-
- return i;
-}
-
-static int
-findb(const png_byte *name)
-{
- int i = NINFO;
- while (--i >= 0)
- {
- if (memcmp(chunk_info[i].name, name, 4) == 0)
- break;
- }
-
- return i;
-}
-
-static int
-find_by_flag(png_uint_32 flag)
-{
- int i = NINFO;
-
- while (--i >= 0) if (chunk_info[i].flag == flag) return i;
-
- fprintf(stderr, "pngunknown: internal error\n");
- exit(4);
-}
-
-static int
-ancillary(const char *name)
-{
- return PNG_CHUNK_ANCILLARY(PNG_U32(name[0], name[1], name[2], name[3]));
-}
-
-#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
-static int
-ancillaryb(const png_byte *name)
-{
- return PNG_CHUNK_ANCILLARY(PNG_U32(name[0], name[1], name[2], name[3]));
-}
-#endif
-
-/* Type of an error_ptr */
-typedef struct
-{
- jmp_buf error_return;
- png_structp png_ptr;
- png_infop info_ptr, end_ptr;
- png_uint_32 before_IDAT;
- png_uint_32 after_IDAT;
- int error_count;
- int warning_count;
- int keep; /* the default value */
- const char *program;
- const char *file;
- const char *test;
-} display;
-
-static const char init[] = "initialization";
-static const char cmd[] = "command line";
-
-static void
-init_display(display *d, const char *program)
-{
- memset(d, 0, sizeof *d);
- d->png_ptr = NULL;
- d->info_ptr = d->end_ptr = NULL;
- d->error_count = d->warning_count = 0;
- d->program = program;
- d->file = program;
- d->test = init;
-}
-
-static void
-clean_display(display *d)
-{
- png_destroy_read_struct(&d->png_ptr, &d->info_ptr, &d->end_ptr);
-
- /* This must not happen - it might cause an app crash */
- if (d->png_ptr != NULL || d->info_ptr != NULL || d->end_ptr != NULL)
- {
- fprintf(stderr, "%s(%s): png_destroy_read_struct error\n", d->file,
- d->test);
- exit(1);
- }
-}
-
-PNG_FUNCTION(void, display_exit, (display *d), static PNG_NORETURN)
-{
- ++(d->error_count);
-
- if (d->png_ptr != NULL)
- clean_display(d);
-
- /* During initialization and if this is a single command line argument set
- * exit now - there is only one test, otherwise longjmp to do the next test.
- */
- if (d->test == init || d->test == cmd)
- exit(1);
-
- longjmp(d->error_return, 1);
-}
-
-static int
-display_rc(const display *d, int strict)
-{
- return d->error_count + (strict ? d->warning_count : 0);
-}
-
-/* libpng error and warning callbacks */
-PNG_FUNCTION(void, (PNGCBAPI error), (png_structp png_ptr, const char *message),
- static PNG_NORETURN)
-{
- display *d = (display*)png_get_error_ptr(png_ptr);
-
- fprintf(stderr, "%s(%s): libpng error: %s\n", d->file, d->test, message);
- display_exit(d);
-}
-
-static void PNGCBAPI
-warning(png_structp png_ptr, const char *message)
-{
- display *d = (display*)png_get_error_ptr(png_ptr);
-
- fprintf(stderr, "%s(%s): libpng warning: %s\n", d->file, d->test, message);
- ++(d->warning_count);
-}
-
-static png_uint_32
-get_valid(display *d, png_infop info_ptr)
-{
- png_uint_32 flags = png_get_valid(d->png_ptr, info_ptr, (png_uint_32)~0);
-
- /* Map the text chunks back into the flags */
- {
- png_textp text;
- png_uint_32 ntext = png_get_text(d->png_ptr, info_ptr, &text, NULL);
-
- while (ntext > 0) switch (text[--ntext].compression)
- {
- case -1:
- flags |= PNG_INFO_tEXt;
- break;
- case 0:
- flags |= PNG_INFO_zTXt;
- break;
- case 1:
- case 2:
- flags |= PNG_INFO_iTXt;
- break;
- default:
- fprintf(stderr, "%s(%s): unknown text compression %d\n", d->file,
- d->test, text[ntext].compression);
- display_exit(d);
- }
- }
-
- return flags;
-}
-
-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
-static int PNGCBAPI
-read_callback(png_structp pp, png_unknown_chunkp pc)
-{
- /* This function mimics the behavior of png_set_keep_unknown_chunks by
- * returning '0' to keep the chunk and '1' to discard it.
- */
- display *d = voidcast(display*, png_get_user_chunk_ptr(pp));
- int chunk = findb(pc->name);
- int keep, discard;
-
- if (chunk < 0) /* not one in our list, so not a known chunk */
- keep = d->keep;
-
- else
- {
- keep = chunk_info[chunk].keep;
- if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
- {
- /* See the comments in png.h - use the default for unknown chunks,
- * do not keep known chunks.
- */
- if (chunk_info[chunk].unknown)
- keep = d->keep;
-
- else
- keep = PNG_HANDLE_CHUNK_NEVER;
- }
- }
-
- switch (keep)
- {
- default:
- fprintf(stderr, "%s(%s): %d: unrecognized chunk option\n", d->file,
- d->test, chunk_info[chunk].keep);
- display_exit(d);
-
- case PNG_HANDLE_CHUNK_AS_DEFAULT:
- case PNG_HANDLE_CHUNK_NEVER:
- discard = 1/*handled; discard*/;
- break;
-
- case PNG_HANDLE_CHUNK_IF_SAFE:
- case PNG_HANDLE_CHUNK_ALWAYS:
- discard = 0/*not handled; keep*/;
- break;
- }
-
- /* Also store information about this chunk in the display, the relevant flag
- * is set if the chunk is to be kept ('not handled'.)
- */
- if (chunk >= 0) if (!discard) /* stupidity to stop a GCC warning */
- {
- png_uint_32 flag = chunk_info[chunk].flag;
-
- if (pc->location & PNG_AFTER_IDAT)
- d->after_IDAT |= flag;
-
- else
- d->before_IDAT |= flag;
- }
-
- /* However if there is no support to store unknown chunks don't ask libpng to
- * do it; there will be an png_error.
- */
-# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
- return discard;
-# else
- return 1; /*handled; discard*/
-# endif
-}
-#endif /* READ_USER_CHUNKS_SUPPORTED */
-
-#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
-static png_uint_32
-get_unknown(display *d, png_infop info_ptr, int after_IDAT)
-{
- /* Create corresponding 'unknown' flags */
- png_uint_32 flags = 0;
-
- UNUSED(after_IDAT)
-
- {
- png_unknown_chunkp unknown;
- int num_unknown = png_get_unknown_chunks(d->png_ptr, info_ptr, &unknown);
-
- while (--num_unknown >= 0)
- {
- int chunk = findb(unknown[num_unknown].name);
-
- /* Chunks not known to pngunknown must be validated here; since they
- * must also be unknown to libpng the 'display->keep' behavior should
- * have been used.
- */
- if (chunk < 0) switch (d->keep)
- {
- default: /* impossible */
- case PNG_HANDLE_CHUNK_AS_DEFAULT:
- case PNG_HANDLE_CHUNK_NEVER:
- fprintf(stderr, "%s(%s): %s: %s: unknown chunk saved\n",
- d->file, d->test, d->keep ? "discard" : "default",
- unknown[num_unknown].name);
- ++(d->error_count);
- break;
-
- case PNG_HANDLE_CHUNK_IF_SAFE:
- if (!ancillaryb(unknown[num_unknown].name))
- {
- fprintf(stderr,
- "%s(%s): if-safe: %s: unknown critical chunk saved\n",
- d->file, d->test, unknown[num_unknown].name);
- ++(d->error_count);
- break;
- }
- /* FALLTHROUGH */ /* (safe) */
- case PNG_HANDLE_CHUNK_ALWAYS:
- break;
- }
-
- else
- flags |= chunk_info[chunk].flag;
- }
- }
-
- return flags;
-}
-#else /* SAVE_UNKNOWN_CHUNKS */
-static png_uint_32
-get_unknown(display *d, png_infop info_ptr, int after_IDAT)
- /* Otherwise this will return the cached values set by any user callback */
-{
- UNUSED(info_ptr);
-
- if (after_IDAT)
- return d->after_IDAT;
-
- else
- return d->before_IDAT;
-}
-
-# ifndef PNG_READ_USER_CHUNKS_SUPPORTED
- /* The #defines above should mean this is never reached, it's just here as
- * a check to ensure the logic is correct.
- */
-# error No store support and no user chunk support, this will not work
-# endif /* READ_USER_CHUNKS */
-#endif /* SAVE_UNKNOWN_CHUNKS */
-
-static int
-check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/,
- display *d, int set_callback)
-{
- int i, npasses, ipass;
- png_uint_32 height;
-
- d->keep = PNG_HANDLE_CHUNK_AS_DEFAULT;
- d->before_IDAT = 0;
- d->after_IDAT = 0;
-
- /* Some of these errors are permanently fatal and cause an exit here, others
- * are per-test and cause an error return.
- */
- d->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, d, error,
- warning);
- if (d->png_ptr == NULL)
- {
- fprintf(stderr, "%s(%s): could not allocate png struct\n", d->file,
- d->test);
- /* Terminate here, this error is not test specific. */
- exit(1);
- }
-
- d->info_ptr = png_create_info_struct(d->png_ptr);
- d->end_ptr = png_create_info_struct(d->png_ptr);
- if (d->info_ptr == NULL || d->end_ptr == NULL)
- {
- fprintf(stderr, "%s(%s): could not allocate png info\n", d->file,
- d->test);
- clean_display(d);
- exit(1);
- }
-
- png_init_io(d->png_ptr, fp);
-
-# ifdef PNG_READ_USER_CHUNKS_SUPPORTED
- /* This is only done if requested by the caller; it interferes with the
- * standard store/save mechanism.
- */
- if (set_callback)
- png_set_read_user_chunk_fn(d->png_ptr, d, read_callback);
-# else
- UNUSED(set_callback)
-# endif
-
- /* Handle each argument in turn; multiple settings are possible for the same
- * chunk and multiple calls will occur (the last one should override all
- * preceding ones).
- */
- for (i=0; i<argc; ++i)
- {
- const char *equals = strchr(argv[i], '=');
-
- if (equals != NULL)
- {
- int chunk, option;
-
- if (strcmp(equals+1, "default") == 0)
- option = PNG_HANDLE_CHUNK_AS_DEFAULT;
- else if (strcmp(equals+1, "discard") == 0)
- option = PNG_HANDLE_CHUNK_NEVER;
- else if (strcmp(equals+1, "if-safe") == 0)
- option = PNG_HANDLE_CHUNK_IF_SAFE;
- else if (strcmp(equals+1, "save") == 0)
- option = PNG_HANDLE_CHUNK_ALWAYS;
- else
- {
- fprintf(stderr, "%s(%s): %s: unrecognized chunk option\n", d->file,
- d->test, argv[i]);
- display_exit(d);
- }
-
- switch (equals - argv[i])
- {
- case 4: /* chunk name */
- chunk = find(argv[i]);
-
- if (chunk >= 0)
- {
- /* These #if tests have the effect of skipping the arguments
- * if SAVE support is unavailable - we can't do a useful test
- * in this case, so we just check the arguments! This could
- * be improved in the future by using the read callback.
- */
-# if PNG_LIBPNG_VER >= 10700 &&\
- !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)
- if (option < PNG_HANDLE_CHUNK_IF_SAFE)
-# endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */
- {
- png_byte name[5];
-
- memcpy(name, chunk_info[chunk].name, 5);
- png_set_keep_unknown_chunks(d->png_ptr, option, name, 1);
- chunk_info[chunk].keep = option;
- }
- continue;
- }
-
- break;
-
- case 7: /* default */
- if (memcmp(argv[i], "default", 7) == 0)
- {
-# if PNG_LIBPNG_VER >= 10700 &&\
- !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)
- if (option < PNG_HANDLE_CHUNK_IF_SAFE)
-# endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */
- png_set_keep_unknown_chunks(d->png_ptr, option, NULL, 0);
-
- d->keep = option;
- continue;
- }
-
- break;
-
- case 3: /* all */
- if (memcmp(argv[i], "all", 3) == 0)
- {
-# if PNG_LIBPNG_VER >= 10700 &&\
- !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)
- if (option < PNG_HANDLE_CHUNK_IF_SAFE)
-# endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */
- png_set_keep_unknown_chunks(d->png_ptr, option, NULL, -1);
-
- d->keep = option;
-
- for (chunk = 0; chunk < NINFO; ++chunk)
- if (chunk_info[chunk].all)
- chunk_info[chunk].keep = option;
- continue;
- }
-
- break;
-
- default: /* some misplaced = */
-
- break;
- }
- }
-
- fprintf(stderr, "%s(%s): %s: unrecognized chunk argument\n", d->file,
- d->test, argv[i]);
- display_exit(d);
- }
-
- png_read_info(d->png_ptr, d->info_ptr);
-
- switch (png_get_interlace_type(d->png_ptr, d->info_ptr))
- {
- case PNG_INTERLACE_NONE:
- npasses = 1;
- break;
-
- case PNG_INTERLACE_ADAM7:
- npasses = PNG_INTERLACE_ADAM7_PASSES;
- break;
-
- default:
- /* Hard error because it is not test specific */
- fprintf(stderr, "%s(%s): invalid interlace type\n", d->file, d->test);
- clean_display(d);
- exit(1);
- }
-
- /* Skip the image data, if IDAT is not being handled then don't do this
- * because it will cause a CRC error.
- */
- if (chunk_info[0/*IDAT*/].keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
- {
- png_start_read_image(d->png_ptr);
- height = png_get_image_height(d->png_ptr, d->info_ptr);
-
- if (npasses > 1)
- {
- png_uint_32 width = png_get_image_width(d->png_ptr, d->info_ptr);
-
- for (ipass=0; ipass<npasses; ++ipass)
- {
- png_uint_32 wPass = PNG_PASS_COLS(width, ipass);
-
- if (wPass > 0)
- {
- png_uint_32 y;
-
- for (y=0; y<height; ++y) if (PNG_ROW_IN_INTERLACE_PASS(y, ipass))
- png_read_row(d->png_ptr, NULL, NULL);
- }
- }
- } /* interlaced */
-
- else /* not interlaced */
- {
- png_uint_32 y;
-
- for (y=0; y<height; ++y)
- png_read_row(d->png_ptr, NULL, NULL);
- }
- }
-
- png_read_end(d->png_ptr, d->end_ptr);
-
- flags[0] = get_valid(d, d->info_ptr);
- flags[1] = get_unknown(d, d->info_ptr, 0/*before IDAT*/);
-
- /* Only png_read_png sets PNG_INFO_IDAT! */
- flags[chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT] |=
- PNG_INFO_IDAT;
-
- flags[2] = get_valid(d, d->end_ptr);
- flags[3] = get_unknown(d, d->end_ptr, 1/*after IDAT*/);
-
- clean_display(d);
-
- return d->keep;
-}
-
-static void
-check_error(display *d, png_uint_32 flags, const char *message)
-{
- while (flags)
- {
- png_uint_32 flag = flags & -(png_int_32)flags;
- int i = find_by_flag(flag);
-
- fprintf(stderr, "%s(%s): chunk %s: %s\n", d->file, d->test,
- chunk_info[i].name, message);
- ++(d->error_count);
-
- flags &= ~flag;
- }
-}
-
-static void
-check_handling(display *d, int def, png_uint_32 chunks, png_uint_32 known,
- png_uint_32 unknown, const char *position, int set_callback)
-{
- while (chunks)
- {
- png_uint_32 flag = chunks & -(png_int_32)chunks;
- int i = find_by_flag(flag);
- int keep = chunk_info[i].keep;
- const char *type;
- const char *errorx = NULL;
-
- if (chunk_info[i].unknown)
- {
- if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
- {
- type = "UNKNOWN (default)";
- keep = def;
- }
-
- else
- type = "UNKNOWN (specified)";
-
- if (flag & known)
- errorx = "chunk processed";
-
- else switch (keep)
- {
- case PNG_HANDLE_CHUNK_AS_DEFAULT:
- if (flag & unknown)
- errorx = "DEFAULT: unknown chunk saved";
- break;
-
- case PNG_HANDLE_CHUNK_NEVER:
- if (flag & unknown)
- errorx = "DISCARD: unknown chunk saved";
- break;
-
- case PNG_HANDLE_CHUNK_IF_SAFE:
- if (ancillary(chunk_info[i].name))
- {
- if (!(flag & unknown))
- errorx = "IF-SAFE: unknown ancillary chunk lost";
- }
-
- else if (flag & unknown)
- errorx = "IF-SAFE: unknown critical chunk saved";
- break;
-
- case PNG_HANDLE_CHUNK_ALWAYS:
- if (!(flag & unknown))
- errorx = "SAVE: unknown chunk lost";
- break;
-
- default:
- errorx = "internal error: bad keep";
- break;
- }
- } /* unknown chunk */
-
- else /* known chunk */
- {
- type = "KNOWN";
-
- if (flag & known)
- {
- /* chunk was processed, it won't have been saved because that is
- * caught below when checking for inconsistent processing.
- */
- if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
- errorx = "!DEFAULT: known chunk processed";
- }
-
- else /* not processed */ switch (keep)
- {
- case PNG_HANDLE_CHUNK_AS_DEFAULT:
- errorx = "DEFAULT: known chunk not processed";
- break;
-
- case PNG_HANDLE_CHUNK_NEVER:
- if (flag & unknown)
- errorx = "DISCARD: known chunk saved";
- break;
-
- case PNG_HANDLE_CHUNK_IF_SAFE:
- if (ancillary(chunk_info[i].name))
- {
- if (!(flag & unknown))
- errorx = "IF-SAFE: known ancillary chunk lost";
- }
-
- else if (flag & unknown)
- errorx = "IF-SAFE: known critical chunk saved";
- break;
-
- case PNG_HANDLE_CHUNK_ALWAYS:
- if (!(flag & unknown))
- errorx = "SAVE: known chunk lost";
- break;
-
- default:
- errorx = "internal error: bad keep (2)";
- break;
- }
- }
-
- if (errorx != NULL)
- {
- ++(d->error_count);
- fprintf(stderr, "%s(%s%s): %s %s %s: %s\n", d->file, d->test,
- set_callback ? ",callback" : "",
- type, chunk_info[i].name, position, errorx);
- }
-
- chunks &= ~flag;
- }
-}
-
-static void
-perform_one_test(FILE *fp, int argc, const char **argv,
- png_uint_32 *default_flags, display *d, int set_callback)
-{
- int def;
- png_uint_32 flags[2][4];
-
- rewind(fp);
- clear_keep();
- memcpy(flags[0], default_flags, sizeof flags[0]);
-
- def = check(fp, argc, argv, flags[1], d, set_callback);
-
- /* If IDAT is being handled as unknown the image read is skipped and all the
- * IDATs after the first end up in the end info struct, so in this case add
- * IDAT to the list of unknowns. (Do this after 'check' above sets the
- * chunk_info 'keep' fields.)
- *
- * Note that the flag setting has to be in the 'known' field to avoid
- * triggering the consistency check below and the flag must only be set if
- * there are multiple IDATs, so if the check above did find an unknown IDAT
- * after IDAT.
- */
- if (chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT &&
- (flags[1][3] & PNG_INFO_IDAT) != 0)
- flags[0][2] |= PNG_INFO_IDAT;
-
- /* Chunks should either be known or unknown, never both and this should apply
- * whether the chunk is before or after the IDAT (actually, the app can
- * probably change this by swapping the handling after the image, but this
- * test does not do that.)
- */
- check_error(d, (flags[0][0]|flags[0][2]) & (flags[0][1]|flags[0][3]),
- "chunk handled inconsistently in count tests");
- check_error(d, (flags[1][0]|flags[1][2]) & (flags[1][1]|flags[1][3]),
- "chunk handled inconsistently in option tests");
-
- /* Now find out what happened to each chunk before and after the IDAT and
- * determine if the behavior was correct. First some basic sanity checks,
- * any known chunk should be known in the original count, any unknown chunk
- * should be either known or unknown in the original.
- */
- {
- png_uint_32 test;
-
- test = flags[1][0] & ~flags[0][0];
- check_error(d, test, "new known chunk before IDAT");
- test = flags[1][1] & ~(flags[0][0] | flags[0][1]);
- check_error(d, test, "new unknown chunk before IDAT");
- test = flags[1][2] & ~flags[0][2];
- check_error(d, test, "new known chunk after IDAT");
- test = flags[1][3] & ~(flags[0][2] | flags[0][3]);
- check_error(d, test, "new unknown chunk after IDAT");
- }
-
- /* Now each chunk in the original list should have been handled according to
- * the options set for that chunk, regardless of whether libpng knows about
- * it or not.
- */
- check_handling(d, def, flags[0][0] | flags[0][1], flags[1][0], flags[1][1],
- "before IDAT", set_callback);
- check_handling(d, def, flags[0][2] | flags[0][3], flags[1][2], flags[1][3],
- "after IDAT", set_callback);
-}
-
-static void
-perform_one_test_safe(FILE *fp, int argc, const char **argv,
- png_uint_32 *default_flags, display *d, const char *test)
-{
- if (setjmp(d->error_return) == 0)
- {
- d->test = test; /* allow use of d->error_return */
-# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
- perform_one_test(fp, argc, argv, default_flags, d, 0);
-# endif
-# ifdef PNG_READ_USER_CHUNKS_SUPPORTED
- perform_one_test(fp, argc, argv, default_flags, d, 1);
-# endif
- d->test = init; /* prevent use of d->error_return */
- }
-}
-
-static const char *standard_tests[] =
-{
- "discard", "default=discard", 0,
- "save", "default=save", 0,
- "if-safe", "default=if-safe", 0,
- "vpAg", "vpAg=if-safe", 0,
- "sTER", "sTER=if-safe", 0,
- "IDAT", "default=discard", "IDAT=save", 0,
- "sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save",
- "sBIT=save", "sRGB=save", "eXIf=save", 0,
- 0/*end*/
-};
-
-static PNG_NORETURN void
-usage(const char *program, const char *reason)
-{
- fprintf(stderr, "pngunknown: %s: usage:\n %s [--strict] "
- "--default|{(CHNK|default|all)=(default|discard|if-safe|save)} "
- "testfile.png\n", reason, program);
- exit(99);
-}
-
-int
-main(int argc, const char **argv)
-{
- FILE *fp;
- png_uint_32 default_flags[4/*valid,unknown{before,after}*/];
- int strict = 0, default_tests = 0;
- const char *count_argv = "default=save";
- const char *touch_file = NULL;
- display d;
-
- init_display(&d, argv[0]);
-
- while (++argv, --argc > 0)
- {
- if (strcmp(*argv, "--strict") == 0)
- strict = 1;
-
- else if (strcmp(*argv, "--default") == 0)
- default_tests = 1;
-
- else if (strcmp(*argv, "--touch") == 0)
- {
- if (argc > 1)
- touch_file = *++argv, --argc;
-
- else
- usage(d.program, "--touch: missing file name");
- }
-
- else
- break;
- }
-
- /* A file name is required, but there should be no other arguments if
- * --default was specified.
- */
- if (argc <= 0)
- usage(d.program, "missing test file");
-
- /* GCC BUG: if (default_tests && argc != 1) triggers some weird GCC argc
- * optimization which causes warnings with -Wstrict-overflow!
- */
- else if (default_tests) if (argc != 1)
- usage(d.program, "extra arguments");
-
- /* The name of the test file is the last argument; remove it. */
- d.file = argv[--argc];
-
- fp = fopen(d.file, "rb");
- if (fp == NULL)
- {
- perror(d.file);
- exit(99);
- }
-
- /* First find all the chunks, known and unknown, in the test file, a failure
- * here aborts the whole test.
- *
- * If 'save' is supported then the normal saving method should happen,
- * otherwise if 'read' is supported then the read callback will do the
- * same thing. If both are supported the 'read' callback won't be
- * instantiated by default. If 'save' is *not* supported then a user
- * callback is required even though we can call png_get_unknown_chunks.
- */
- if (check(fp, 1, &count_argv, default_flags, &d,
-# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
- 0
-# else
- 1
-# endif
- ) != PNG_HANDLE_CHUNK_ALWAYS)
- {
- fprintf(stderr, "%s: %s: internal error\n", d.program, d.file);
- exit(99);
- }
-
- /* Now find what the various supplied options cause to change: */
- if (!default_tests)
- {
- d.test = cmd; /* acts as a flag to say exit, do not longjmp */
-# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
- perform_one_test(fp, argc, argv, default_flags, &d, 0);
-# endif
-# ifdef PNG_READ_USER_CHUNKS_SUPPORTED
- perform_one_test(fp, argc, argv, default_flags, &d, 1);
-# endif
- d.test = init;
- }
-
- else
- {
- const char **test = standard_tests;
-
- /* Set the exit_test pointer here so we can continue after a libpng error.
- * NOTE: this leaks memory because the png_struct data from the failing
- * test is never freed.
- */
- while (*test)
- {
- const char *this_test = *test++;
- const char **next = test;
- int count = display_rc(&d, strict), new_count;
- const char *result;
- int arg_count = 0;
-
- while (*next) ++next, ++arg_count;
-
- perform_one_test_safe(fp, arg_count, test, default_flags, &d,
- this_test);
-
- new_count = display_rc(&d, strict);
-
- if (new_count == count)
- result = "PASS";
-
- else
- result = "FAIL";
-
- printf("%s: %s %s\n", result, d.program, this_test);
-
- test = next+1;
- }
- }
-
- fclose(fp);
-
- if (display_rc(&d, strict) == 0)
- {
- /* Success, touch the success file if appropriate */
- if (touch_file != NULL)
- {
- FILE *fsuccess = fopen(touch_file, "wt");
-
- if (fsuccess != NULL)
- {
- int err = 0;
- fprintf(fsuccess, "PNG unknown tests succeeded\n");
- fflush(fsuccess);
- err = ferror(fsuccess);
-
- if (fclose(fsuccess) || err)
- {
- fprintf(stderr, "%s: write failed\n", touch_file);
- exit(99);
- }
- }
-
- else
- {
- fprintf(stderr, "%s: open failed\n", touch_file);
- exit(99);
- }
- }
-
- return 0;
- }
-
- return 1;
-}
-
-#else /* !(READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS) */
-int
-main(void)
-{
- fprintf(stderr,
- " test ignored: no support to find out about unknown chunks\n");
- /* So the test is skipped: */
- return SKIP;
-}
-#endif /* READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS */
-
-#else /* !(SET_UNKNOWN_CHUNKS && READ) */
-int
-main(void)
-{
- fprintf(stderr,
- " test ignored: no support to modify unknown chunk handling\n");
- /* So the test is skipped: */
- return SKIP;
-}
-#endif /* SET_UNKNOWN_CHUNKS && READ*/
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngvalid.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/pngvalid.c
deleted file mode 100644
index d800110c7a4..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/pngvalid.c
+++ /dev/null
@@ -1,12230 +0,0 @@
-
-/* pngvalid.c - validate libpng by constructing then reading png files.
- *
- * Last changed in libpng 1.6.31 [July 27, 2017]
- * Copyright (c) 2014-2017 John Cunningham Bowler
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * NOTES:
- * This is a C program that is intended to be linked against libpng. It
- * generates bitmaps internally, stores them as PNG files (using the
- * sequential write code) then reads them back (using the sequential
- * read code) and validates that the result has the correct data.
- *
- * The program can be modified and extended to test the correctness of
- * transformations performed by libpng.
- */
-
-#define _POSIX_SOURCE 1
-#define _ISOC99_SOURCE 1 /* For floating point */
-#define _GNU_SOURCE 1 /* For the floating point exception extension */
-#define _BSD_SOURCE 1 /* For the floating point exception extension */
-
-#include <signal.h>
-#include <stdio.h>
-
-#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
-# include <config.h>
-#endif
-
-#ifdef HAVE_FEENABLEEXCEPT /* from config.h, if included */
-# include <fenv.h>
-#endif
-
-#ifndef FE_DIVBYZERO
-# define FE_DIVBYZERO 0
-#endif
-#ifndef FE_INVALID
-# define FE_INVALID 0
-#endif
-#ifndef FE_OVERFLOW
-# define FE_OVERFLOW 0
-#endif
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-#ifdef PNG_ZLIB_HEADER
-# include PNG_ZLIB_HEADER
-#else
-# include <zlib.h> /* For crc32 */
-#endif
-
-/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
- * a skipped test, in earlier versions we need to succeed on a skipped test, so:
- */
-#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
-# define SKIP 77
-#else
-# define SKIP 0
-#endif
-
-/* pngvalid requires write support and one of the fixed or floating point APIs.
- */
-#if defined(PNG_WRITE_SUPPORTED) &&\
- (defined(PNG_FIXED_POINT_SUPPORTED) || defined(PNG_FLOATING_POINT_SUPPORTED))
-
-#if PNG_LIBPNG_VER < 10500
-/* This deliberately lacks the const. */
-typedef png_byte *png_const_bytep;
-
-/* This is copied from 1.5.1 png.h: */
-#define PNG_INTERLACE_ADAM7_PASSES 7
-#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
-#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
-#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
-#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
-#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
- -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
-#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
- -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
-#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
- (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
-#define PNG_COL_FROM_PASS_COL(xIn, pass) \
- (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
-#define PNG_PASS_MASK(pass,off) ( \
- ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
- ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
-#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
- ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
-#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
- ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
-
-/* These are needed too for the default build: */
-#define PNG_WRITE_16BIT_SUPPORTED
-#define PNG_READ_16BIT_SUPPORTED
-
-/* This comes from pnglibconf.h after 1.5: */
-#define PNG_FP_1 100000
-#define PNG_GAMMA_THRESHOLD_FIXED\
- ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
-#endif
-
-#if PNG_LIBPNG_VER < 10600
- /* 1.6.0 constifies many APIs, the following exists to allow pngvalid to be
- * compiled against earlier versions.
- */
-# define png_const_structp png_structp
-#endif
-
-#ifndef RELEASE_BUILD
- /* RELEASE_BUILD is true for releases and release candidates: */
-# define RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
-#endif
-#if RELEASE_BUILD
-# define debugonly(something)
-#else /* !RELEASE_BUILD */
-# define debugonly(something) something
-#endif /* !RELEASE_BUILD */
-
-#include <float.h> /* For floating point constants */
-#include <stdlib.h> /* For malloc */
-#include <string.h> /* For memcpy, memset */
-#include <math.h> /* For floor */
-
-/* Convenience macros. */
-#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
-#define CHUNK_IHDR CHUNK(73,72,68,82)
-#define CHUNK_PLTE CHUNK(80,76,84,69)
-#define CHUNK_IDAT CHUNK(73,68,65,84)
-#define CHUNK_IEND CHUNK(73,69,78,68)
-#define CHUNK_cHRM CHUNK(99,72,82,77)
-#define CHUNK_gAMA CHUNK(103,65,77,65)
-#define CHUNK_sBIT CHUNK(115,66,73,84)
-#define CHUNK_sRGB CHUNK(115,82,71,66)
-
-/* Unused formal parameter errors are removed using the following macro which is
- * expected to have no bad effects on performance.
- */
-#ifndef UNUSED
-# if defined(__GNUC__) || defined(_MSC_VER)
-# define UNUSED(param) (void)param;
-# else
-# define UNUSED(param)
-# endif
-#endif
-
-/***************************** EXCEPTION HANDLING *****************************/
-#ifdef PNG_FREESTANDING_TESTS
-# include <cexcept.h>
-#else
-# include "../visupng/cexcept.h"
-#endif
-
-#ifdef __cplusplus
-# define this not_the_cpp_this
-# define new not_the_cpp_new
-# define voidcast(type, value) static_cast<type>(value)
-#else
-# define voidcast(type, value) (value)
-#endif /* __cplusplus */
-
-struct png_store;
-define_exception_type(struct png_store*);
-
-/* The following are macros to reduce typing everywhere where the well known
- * name 'the_exception_context' must be defined.
- */
-#define anon_context(ps) struct exception_context *the_exception_context = \
- &(ps)->exception_context
-#define context(ps,fault) anon_context(ps); png_store *fault
-
-/* This macro returns the number of elements in an array as an (unsigned int),
- * it is necessary to avoid the inability of certain versions of GCC to use
- * the value of a compile-time constant when performing range checks. It must
- * be passed an array name.
- */
-#define ARRAY_SIZE(a) ((unsigned int)((sizeof (a))/(sizeof (a)[0])))
-
-/* GCC BUG 66447 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66447) requires
- * some broken GCC versions to be fixed up to avoid invalid whining about auto
- * variables that are *not* changed within the scope of a setjmp being changed.
- *
- * Feel free to extend the list of broken versions.
- */
-#define is_gnu(major,minor)\
- (defined __GNUC__) && __GNUC__ == (major) && __GNUC_MINOR__ == (minor)
-#define is_gnu_patch(major,minor,patch)\
- is_gnu(major,minor) && __GNUC_PATCHLEVEL__ == 0
-/* For the moment just do it always; all versions of GCC seem to be broken: */
-#ifdef __GNUC__
- const void * volatile make_volatile_for_gnu;
-# define gnu_volatile(x) make_volatile_for_gnu = &x;
-#else /* !GNUC broken versions */
-# define gnu_volatile(x)
-#endif /* !GNUC broken versions */
-
-/******************************* UTILITIES ************************************/
-/* Error handling is particularly problematic in production code - error
- * handlers often themselves have bugs which lead to programs that detect
- * minor errors crashing. The following functions deal with one very
- * common class of errors in error handlers - attempting to format error or
- * warning messages into buffers that are too small.
- */
-static size_t safecat(char *buffer, size_t bufsize, size_t pos,
- const char *cat)
-{
- while (pos < bufsize && cat != NULL && *cat != 0)
- buffer[pos++] = *cat++;
-
- if (pos >= bufsize)
- pos = bufsize-1;
-
- buffer[pos] = 0;
- return pos;
-}
-
-static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n)
-{
- char number[64];
- sprintf(number, "%d", n);
- return safecat(buffer, bufsize, pos, number);
-}
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d,
- int precision)
-{
- char number[64];
- sprintf(number, "%.*f", precision, d);
- return safecat(buffer, bufsize, pos, number);
-}
-#endif
-
-static const char invalid[] = "invalid";
-static const char sep[] = ": ";
-
-static const char *colour_types[8] =
-{
- "grayscale", invalid, "truecolour", "indexed-colour",
- "grayscale with alpha", invalid, "truecolour with alpha", invalid
-};
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-/* Convert a double precision value to fixed point. */
-static png_fixed_point
-fix(double d)
-{
- d = floor(d * PNG_FP_1 + .5);
- return (png_fixed_point)d;
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/* Generate random bytes. This uses a boring repeatable algorithm and it
- * is implemented here so that it gives the same set of numbers on every
- * architecture. It's a linear congruential generator (Knuth or Sedgewick
- * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
- * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise
- * Generation.)
- */
-static void
-make_random_bytes(png_uint_32* seed, void* pv, size_t size)
-{
- png_uint_32 u0 = seed[0], u1 = seed[1];
- png_bytep bytes = voidcast(png_bytep, pv);
-
- /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
- * bit-20. The top 1 bit is in u1, the bottom 32 are in u0.
- */
- size_t i;
- for (i=0; i<size; ++i)
- {
- /* First generate 8 new bits then shift them in at the end. */
- png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
- u1 <<= 8;
- u1 |= u0 >> 24;
- u0 <<= 8;
- u0 |= u;
- *bytes++ = (png_byte)u;
- }
-
- seed[0] = u0;
- seed[1] = u1;
-}
-
-static void
-make_four_random_bytes(png_uint_32* seed, png_bytep bytes)
-{
- make_random_bytes(seed, bytes, 4);
-}
-
-#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\
- defined PNG_WRITE_FILTER_SUPPORTED
-static void
-randomize(void *pv, size_t size)
-{
- static png_uint_32 random_seed[2] = {0x56789abc, 0xd};
- make_random_bytes(random_seed, pv, size);
-}
-
-#define R8(this) randomize(&(this), sizeof (this))
-
-#ifdef PNG_READ_SUPPORTED
-static png_byte
-random_byte(void)
-{
- unsigned char b1[1];
- randomize(b1, sizeof b1);
- return b1[0];
-}
-#endif /* READ */
-
-static png_uint_16
-random_u16(void)
-{
- unsigned char b2[2];
- randomize(b2, sizeof b2);
- return png_get_uint_16(b2);
-}
-
-#if defined PNG_READ_RGB_TO_GRAY_SUPPORTED ||\
- defined PNG_READ_FILLER_SUPPORTED
-static png_uint_32
-random_u32(void)
-{
- unsigned char b4[4];
- randomize(b4, sizeof b4);
- return png_get_uint_32(b4);
-}
-#endif /* READ_FILLER || READ_RGB_TO_GRAY */
-
-#endif /* READ || WRITE_tRNS || WRITE_FILTER */
-
-#if defined PNG_READ_TRANSFORMS_SUPPORTED ||\
- defined PNG_WRITE_FILTER_SUPPORTED
-static unsigned int
-random_mod(unsigned int max)
-{
- return random_u16() % max; /* 0 .. max-1 */
-}
-#endif /* READ_TRANSFORMS || WRITE_FILTER */
-
-#if (defined PNG_READ_RGB_TO_GRAY_SUPPORTED) ||\
- (defined PNG_READ_FILLER_SUPPORTED)
-static int
-random_choice(void)
-{
- return random_byte() & 1;
-}
-#endif /* READ_RGB_TO_GRAY || READ_FILLER */
-
-/* A numeric ID based on PNG file characteristics. The 'do_interlace' field
- * simply records whether pngvalid did the interlace itself or whether it
- * was done by libpng. Width and height must be less than 256. 'palette' is an
- * index of the palette to use for formats with a palette otherwise a boolean
- * indicating if a tRNS chunk was generated.
- */
-#define FILEID(col, depth, palette, interlace, width, height, do_interlace) \
- ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \
- (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24)))
-
-#define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))
-#define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))
-#define PALETTE_FROM_ID(id) (((id) >> 8) & 0x1f)
-#define INTERLACE_FROM_ID(id) ((png_byte)(((id) >> 13) & 0x3))
-#define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))
-#define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)
-#define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)
-
-/* Utility to construct a standard name for a standard image. */
-static size_t
-standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
- int bit_depth, unsigned int npalette, int interlace_type,
- png_uint_32 w, png_uint_32 h, int do_interlace)
-{
- pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
- if (colour_type == 3) /* must have a palette */
- {
- pos = safecat(buffer, bufsize, pos, "[");
- pos = safecatn(buffer, bufsize, pos, npalette);
- pos = safecat(buffer, bufsize, pos, "]");
- }
-
- else if (npalette != 0)
- pos = safecat(buffer, bufsize, pos, "+tRNS");
-
- pos = safecat(buffer, bufsize, pos, " ");
- pos = safecatn(buffer, bufsize, pos, bit_depth);
- pos = safecat(buffer, bufsize, pos, " bit");
-
- if (interlace_type != PNG_INTERLACE_NONE)
- {
- pos = safecat(buffer, bufsize, pos, " interlaced");
- if (do_interlace)
- pos = safecat(buffer, bufsize, pos, "(pngvalid)");
- else
- pos = safecat(buffer, bufsize, pos, "(libpng)");
- }
-
- if (w > 0 || h > 0)
- {
- pos = safecat(buffer, bufsize, pos, " ");
- pos = safecatn(buffer, bufsize, pos, w);
- pos = safecat(buffer, bufsize, pos, "x");
- pos = safecatn(buffer, bufsize, pos, h);
- }
-
- return pos;
-}
-
-static size_t
-standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
-{
- return standard_name(buffer, bufsize, pos, COL_FROM_ID(id),
- DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id),
- WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id));
-}
-
-/* Convenience API and defines to list valid formats. Note that 16 bit read and
- * write support is required to do 16 bit read tests (we must be able to make a
- * 16 bit image to test!)
- */
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-# define WRITE_BDHI 4
-# ifdef PNG_READ_16BIT_SUPPORTED
-# define READ_BDHI 4
-# define DO_16BIT
-# endif
-#else
-# define WRITE_BDHI 3
-#endif
-#ifndef DO_16BIT
-# define READ_BDHI 3
-#endif
-
-/* The following defines the number of different palettes to generate for
- * each log bit depth of a colour type 3 standard image.
- */
-#define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1U : 16U)
-
-static int
-next_format(png_bytep colour_type, png_bytep bit_depth,
- unsigned int* palette_number, int low_depth_gray, int tRNS)
-{
- if (*bit_depth == 0)
- {
- *colour_type = 0;
- if (low_depth_gray)
- *bit_depth = 1;
- else
- *bit_depth = 8;
- *palette_number = 0;
- return 1;
- }
-
- if (*colour_type < 4/*no alpha channel*/)
- {
- /* Add multiple palettes for colour type 3, one image with tRNS
- * and one without for other non-alpha formats:
- */
- unsigned int pn = ++*palette_number;
- png_byte ct = *colour_type;
-
- if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) ||
- (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth)))
- return 1;
-
- /* No: next bit depth */
- *palette_number = 0;
- }
-
- *bit_depth = (png_byte)(*bit_depth << 1);
-
- /* Palette images are restricted to 8 bit depth */
- if (*bit_depth <= 8
-#ifdef DO_16BIT
- || (*colour_type != 3 && *bit_depth <= 16)
-#endif
- )
- return 1;
-
- /* Move to the next color type, or return 0 at the end. */
- switch (*colour_type)
- {
- case 0:
- *colour_type = 2;
- *bit_depth = 8;
- return 1;
-
- case 2:
- *colour_type = 3;
- *bit_depth = 1;
- return 1;
-
- case 3:
- *colour_type = 4;
- *bit_depth = 8;
- return 1;
-
- case 4:
- *colour_type = 6;
- *bit_depth = 8;
- return 1;
-
- default:
- return 0;
- }
-}
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-static unsigned int
-sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,
- png_uint_32 x, unsigned int sample_index, int swap16, int littleendian)
-{
- png_uint_32 bit_index, result;
-
- /* Find a sample index for the desired sample: */
- x *= bit_depth;
- bit_index = x;
-
- if ((colour_type & 1) == 0) /* !palette */
- {
- if (colour_type & 2)
- bit_index *= 3;
-
- if (colour_type & 4)
- bit_index += x; /* Alpha channel */
-
- /* Multiple channels; select one: */
- if (colour_type & (2+4))
- bit_index += sample_index * bit_depth;
- }
-
- /* Return the sample from the row as an integer. */
- row += bit_index >> 3;
- result = *row;
-
- if (bit_depth == 8)
- return result;
-
- else if (bit_depth > 8)
- {
- if (swap16)
- return (*++row << 8) + result;
- else
- return (result << 8) + *++row;
- }
-
- /* Less than 8 bits per sample. By default PNG has the big end of
- * the egg on the left of the screen, but if littleendian is set
- * then the big end is on the right.
- */
- bit_index &= 7;
-
- if (!littleendian)
- bit_index = 8-bit_index-bit_depth;
-
- return (result >> bit_index) & ((1U<<bit_depth)-1);
-}
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-/* Copy a single pixel, of a given size, from one buffer to another -
- * while this is basically bit addressed there is an implicit assumption
- * that pixels 8 or more bits in size are byte aligned and that pixels
- * do not otherwise cross byte boundaries. (This is, so far as I know,
- * universally true in bitmap computer graphics. [JCB 20101212])
- *
- * NOTE: The to and from buffers may be the same.
- */
-static void
-pixel_copy(png_bytep toBuffer, png_uint_32 toIndex,
- png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize,
- int littleendian)
-{
- /* Assume we can multiply by 'size' without overflow because we are
- * just working in a single buffer.
- */
- toIndex *= pixelSize;
- fromIndex *= pixelSize;
- if (pixelSize < 8) /* Sub-byte */
- {
- /* Mask to select the location of the copied pixel: */
- unsigned int destMask = ((1U<<pixelSize)-1) <<
- (littleendian ? toIndex&7 : 8-pixelSize-(toIndex&7));
- /* The following read the entire pixels and clears the extra: */
- unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask;
- unsigned int sourceByte = fromBuffer[fromIndex >> 3];
-
- /* Don't rely on << or >> supporting '0' here, just in case: */
- fromIndex &= 7;
- if (littleendian)
- {
- if (fromIndex > 0) sourceByte >>= fromIndex;
- if ((toIndex & 7) > 0) sourceByte <<= toIndex & 7;
- }
-
- else
- {
- if (fromIndex > 0) sourceByte <<= fromIndex;
- if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7;
- }
-
- toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask));
- }
- else /* One or more bytes */
- memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3);
-}
-
-#ifdef PNG_READ_SUPPORTED
-/* Copy a complete row of pixels, taking into account potential partial
- * bytes at the end.
- */
-static void
-row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth,
- int littleendian)
-{
- memcpy(toBuffer, fromBuffer, bitWidth >> 3);
-
- if ((bitWidth & 7) != 0)
- {
- unsigned int mask;
-
- toBuffer += bitWidth >> 3;
- fromBuffer += bitWidth >> 3;
- if (littleendian)
- mask = 0xff << (bitWidth & 7);
- else
- mask = 0xff >> (bitWidth & 7);
- *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask));
- }
-}
-
-/* Compare pixels - they are assumed to start at the first byte in the
- * given buffers.
- */
-static int
-pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)
-{
-#if PNG_LIBPNG_VER < 10506
- if (memcmp(pa, pb, bit_width>>3) == 0)
- {
- png_uint_32 p;
-
- if ((bit_width & 7) == 0) return 0;
-
- /* Ok, any differences? */
- p = pa[bit_width >> 3];
- p ^= pb[bit_width >> 3];
-
- if (p == 0) return 0;
-
- /* There are, but they may not be significant, remove the bits
- * after the end (the low order bits in PNG.)
- */
- bit_width &= 7;
- p >>= 8-bit_width;
-
- if (p == 0) return 0;
- }
-#else
- /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing
- * bits too:
- */
- if (memcmp(pa, pb, (bit_width+7)>>3) == 0)
- return 0;
-#endif
-
- /* Return the index of the changed byte. */
- {
- png_uint_32 where = 0;
-
- while (pa[where] == pb[where]) ++where;
- return 1+where;
- }
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/*************************** BASIC PNG FILE WRITING ***************************/
-/* A png_store takes data from the sequential writer or provides data
- * to the sequential reader. It can also store the result of a PNG
- * write for later retrieval.
- */
-#define STORE_BUFFER_SIZE 500 /* arbitrary */
-typedef struct png_store_buffer
-{
- struct png_store_buffer* prev; /* NOTE: stored in reverse order */
- png_byte buffer[STORE_BUFFER_SIZE];
-} png_store_buffer;
-
-#define FILE_NAME_SIZE 64
-
-typedef struct store_palette_entry /* record of a single palette entry */
-{
- png_byte red;
- png_byte green;
- png_byte blue;
- png_byte alpha;
-} store_palette_entry, store_palette[256];
-
-typedef struct png_store_file
-{
- struct png_store_file* next; /* as many as you like... */
- char name[FILE_NAME_SIZE];
- unsigned int IDAT_bits; /* Number of bits in IDAT size */
- png_uint_32 IDAT_size; /* Total size of IDAT data */
- png_uint_32 id; /* must be correct (see FILEID) */
- size_t datacount; /* In this (the last) buffer */
- png_store_buffer data; /* Last buffer in file */
- int npalette; /* Number of entries in palette */
- store_palette_entry* palette; /* May be NULL */
-} png_store_file;
-
-/* The following is a pool of memory allocated by a single libpng read or write
- * operation.
- */
-typedef struct store_pool
-{
- struct png_store *store; /* Back pointer */
- struct store_memory *list; /* List of allocated memory */
- png_byte mark[4]; /* Before and after data */
-
- /* Statistics for this run. */
- png_alloc_size_t max; /* Maximum single allocation */
- png_alloc_size_t current; /* Current allocation */
- png_alloc_size_t limit; /* Highest current allocation */
- png_alloc_size_t total; /* Total allocation */
-
- /* Overall statistics (retained across successive runs). */
- png_alloc_size_t max_max;
- png_alloc_size_t max_limit;
- png_alloc_size_t max_total;
-} store_pool;
-
-typedef struct png_store
-{
- /* For cexcept.h exception handling - simply store one of these;
- * the context is a self pointer but it may point to a different
- * png_store (in fact it never does in this program.)
- */
- struct exception_context
- exception_context;
-
- unsigned int verbose :1;
- unsigned int treat_warnings_as_errors :1;
- unsigned int expect_error :1;
- unsigned int expect_warning :1;
- unsigned int saw_warning :1;
- unsigned int speed :1;
- unsigned int progressive :1; /* use progressive read */
- unsigned int validated :1; /* used as a temporary flag */
- int nerrors;
- int nwarnings;
- int noptions; /* number of options below: */
- struct {
- unsigned char option; /* option number, 0..30 */
- unsigned char setting; /* setting (unset,invalid,on,off) */
- } options[16];
- char test[128]; /* Name of test */
- char error[256];
-
- /* Share fields */
- png_uint_32 chunklen; /* Length of chunk+overhead (chunkpos >= 8) */
- png_uint_32 chunktype;/* Type of chunk (valid if chunkpos >= 4) */
- png_uint_32 chunkpos; /* Position in chunk */
- png_uint_32 IDAT_size;/* Accumulated IDAT size in .new */
- unsigned int IDAT_bits;/* Cache of the file store value */
-
- /* Read fields */
- png_structp pread; /* Used to read a saved file */
- png_infop piread;
- png_store_file* current; /* Set when reading */
- png_store_buffer* next; /* Set when reading */
- size_t readpos; /* Position in *next */
- png_byte* image; /* Buffer for reading interlaced images */
- size_t cb_image; /* Size of this buffer */
- size_t cb_row; /* Row size of the image(s) */
- uLong IDAT_crc;
- png_uint_32 IDAT_len; /* Used when re-chunking IDAT chunks */
- png_uint_32 IDAT_pos; /* Used when re-chunking IDAT chunks */
- png_uint_32 image_h; /* Number of rows in a single image */
- store_pool read_memory_pool;
-
- /* Write fields */
- png_store_file* saved;
- png_structp pwrite; /* Used when writing a new file */
- png_infop piwrite;
- size_t writepos; /* Position in .new */
- char wname[FILE_NAME_SIZE];
- png_store_buffer new; /* The end of the new PNG file being written. */
- store_pool write_memory_pool;
- store_palette_entry* palette;
- int npalette;
-} png_store;
-
-/* Initialization and cleanup */
-static void
-store_pool_mark(png_bytep mark)
-{
- static png_uint_32 store_seed[2] = { 0x12345678, 1};
-
- make_four_random_bytes(store_seed, mark);
-}
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-/* Use this for random 32 bit values; this function makes sure the result is
- * non-zero.
- */
-static png_uint_32
-random_32(void)
-{
-
- for (;;)
- {
- png_byte mark[4];
- png_uint_32 result;
-
- store_pool_mark(mark);
- result = png_get_uint_32(mark);
-
- if (result != 0)
- return result;
- }
-}
-#endif /* PNG_READ_SUPPORTED */
-
-static void
-store_pool_init(png_store *ps, store_pool *pool)
-{
- memset(pool, 0, sizeof *pool);
-
- pool->store = ps;
- pool->list = NULL;
- pool->max = pool->current = pool->limit = pool->total = 0;
- pool->max_max = pool->max_limit = pool->max_total = 0;
- store_pool_mark(pool->mark);
-}
-
-static void
-store_init(png_store* ps)
-{
- memset(ps, 0, sizeof *ps);
- init_exception_context(&ps->exception_context);
- store_pool_init(ps, &ps->read_memory_pool);
- store_pool_init(ps, &ps->write_memory_pool);
- ps->verbose = 0;
- ps->treat_warnings_as_errors = 0;
- ps->expect_error = 0;
- ps->expect_warning = 0;
- ps->saw_warning = 0;
- ps->speed = 0;
- ps->progressive = 0;
- ps->validated = 0;
- ps->nerrors = ps->nwarnings = 0;
- ps->pread = NULL;
- ps->piread = NULL;
- ps->saved = ps->current = NULL;
- ps->next = NULL;
- ps->readpos = 0;
- ps->image = NULL;
- ps->cb_image = 0;
- ps->cb_row = 0;
- ps->image_h = 0;
- ps->pwrite = NULL;
- ps->piwrite = NULL;
- ps->writepos = 0;
- ps->chunkpos = 8;
- ps->chunktype = 0;
- ps->chunklen = 16;
- ps->IDAT_size = 0;
- ps->IDAT_bits = 0;
- ps->new.prev = NULL;
- ps->palette = NULL;
- ps->npalette = 0;
- ps->noptions = 0;
-}
-
-static void
-store_freebuffer(png_store_buffer* psb)
-{
- if (psb->prev)
- {
- store_freebuffer(psb->prev);
- free(psb->prev);
- psb->prev = NULL;
- }
-}
-
-static void
-store_freenew(png_store *ps)
-{
- store_freebuffer(&ps->new);
- ps->writepos = 0;
- ps->chunkpos = 8;
- ps->chunktype = 0;
- ps->chunklen = 16;
- ps->IDAT_size = 0;
- ps->IDAT_bits = 0;
- if (ps->palette != NULL)
- {
- free(ps->palette);
- ps->palette = NULL;
- ps->npalette = 0;
- }
-}
-
-static void
-store_storenew(png_store *ps)
-{
- png_store_buffer *pb;
-
- pb = voidcast(png_store_buffer*, malloc(sizeof *pb));
-
- if (pb == NULL)
- png_error(ps->pwrite, "store new: OOM");
-
- *pb = ps->new;
- ps->new.prev = pb;
- ps->writepos = 0;
-}
-
-static void
-store_freefile(png_store_file **ppf)
-{
- if (*ppf != NULL)
- {
- store_freefile(&(*ppf)->next);
-
- store_freebuffer(&(*ppf)->data);
- (*ppf)->datacount = 0;
- if ((*ppf)->palette != NULL)
- {
- free((*ppf)->palette);
- (*ppf)->palette = NULL;
- (*ppf)->npalette = 0;
- }
- free(*ppf);
- *ppf = NULL;
- }
-}
-
-static unsigned int
-bits_of(png_uint_32 num)
-{
- /* Return the number of bits in 'num' */
- unsigned int b = 0;
-
- if (num & 0xffff0000U) b += 16U, num >>= 16;
- if (num & 0xff00U) b += 8U, num >>= 8;
- if (num & 0xf0U) b += 4U, num >>= 4;
- if (num & 0xcU) b += 2U, num >>= 2;
- if (num & 0x2U) ++b, num >>= 1;
- if (num) ++b;
-
- return b; /* 0..32 */
-}
-
-/* Main interface to file storage, after writing a new PNG file (see the API
- * below) call store_storefile to store the result with the given name and id.
- */
-static void
-store_storefile(png_store *ps, png_uint_32 id)
-{
- png_store_file *pf;
-
- if (ps->chunkpos != 0U || ps->chunktype != 0U || ps->chunklen != 0U ||
- ps->IDAT_size == 0)
- png_error(ps->pwrite, "storefile: incomplete write");
-
- pf = voidcast(png_store_file*, malloc(sizeof *pf));
- if (pf == NULL)
- png_error(ps->pwrite, "storefile: OOM");
- safecat(pf->name, sizeof pf->name, 0, ps->wname);
- pf->id = id;
- pf->data = ps->new;
- pf->datacount = ps->writepos;
- pf->IDAT_size = ps->IDAT_size;
- pf->IDAT_bits = bits_of(ps->IDAT_size);
- /* Because the IDAT always has zlib header stuff this must be true: */
- if (pf->IDAT_bits == 0U)
- png_error(ps->pwrite, "storefile: 0 sized IDAT");
- ps->new.prev = NULL;
- ps->writepos = 0;
- ps->chunkpos = 8;
- ps->chunktype = 0;
- ps->chunklen = 16;
- ps->IDAT_size = 0;
- pf->palette = ps->palette;
- pf->npalette = ps->npalette;
- ps->palette = 0;
- ps->npalette = 0;
-
- /* And save it. */
- pf->next = ps->saved;
- ps->saved = pf;
-}
-
-/* Generate an error message (in the given buffer) */
-static size_t
-store_message(png_store *ps, png_const_structp pp, char *buffer, size_t bufsize,
- size_t pos, const char *msg)
-{
- if (pp != NULL && pp == ps->pread)
- {
- /* Reading a file */
- pos = safecat(buffer, bufsize, pos, "read: ");
-
- if (ps->current != NULL)
- {
- pos = safecat(buffer, bufsize, pos, ps->current->name);
- pos = safecat(buffer, bufsize, pos, sep);
- }
- }
-
- else if (pp != NULL && pp == ps->pwrite)
- {
- /* Writing a file */
- pos = safecat(buffer, bufsize, pos, "write: ");
- pos = safecat(buffer, bufsize, pos, ps->wname);
- pos = safecat(buffer, bufsize, pos, sep);
- }
-
- else
- {
- /* Neither reading nor writing (or a memory error in struct delete) */
- pos = safecat(buffer, bufsize, pos, "pngvalid: ");
- }
-
- if (ps->test[0] != 0)
- {
- pos = safecat(buffer, bufsize, pos, ps->test);
- pos = safecat(buffer, bufsize, pos, sep);
- }
- pos = safecat(buffer, bufsize, pos, msg);
- return pos;
-}
-
-/* Verbose output to the error stream: */
-static void
-store_verbose(png_store *ps, png_const_structp pp, png_const_charp prefix,
- png_const_charp message)
-{
- char buffer[512];
-
- if (prefix)
- fputs(prefix, stderr);
-
- (void)store_message(ps, pp, buffer, sizeof buffer, 0, message);
- fputs(buffer, stderr);
- fputc('\n', stderr);
-}
-
-/* Log an error or warning - the relevant count is always incremented. */
-static void
-store_log(png_store* ps, png_const_structp pp, png_const_charp message,
- int is_error)
-{
- /* The warning is copied to the error buffer if there are no errors and it is
- * the first warning. The error is copied to the error buffer if it is the
- * first error (overwriting any prior warnings).
- */
- if (is_error ? (ps->nerrors)++ == 0 :
- (ps->nwarnings)++ == 0 && ps->nerrors == 0)
- store_message(ps, pp, ps->error, sizeof ps->error, 0, message);
-
- if (ps->verbose)
- store_verbose(ps, pp, is_error ? "error: " : "warning: ", message);
-}
-
-#ifdef PNG_READ_SUPPORTED
-/* Internal error function, called with a png_store but no libpng stuff. */
-static void
-internal_error(png_store *ps, png_const_charp message)
-{
- store_log(ps, NULL, message, 1 /* error */);
-
- /* And finally throw an exception. */
- {
- struct exception_context *the_exception_context = &ps->exception_context;
- Throw ps;
- }
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/* Functions to use as PNG callbacks. */
-static void PNGCBAPI
-store_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */
-{
- png_const_structp pp = ppIn;
- png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
-
- if (!ps->expect_error)
- store_log(ps, pp, message, 1 /* error */);
-
- /* And finally throw an exception. */
- {
- struct exception_context *the_exception_context = &ps->exception_context;
- Throw ps;
- }
-}
-
-static void PNGCBAPI
-store_warning(png_structp ppIn, png_const_charp message)
-{
- png_const_structp pp = ppIn;
- png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
-
- if (!ps->expect_warning)
- store_log(ps, pp, message, 0 /* warning */);
- else
- ps->saw_warning = 1;
-}
-
-/* These somewhat odd functions are used when reading an image to ensure that
- * the buffer is big enough, the png_structp is for errors.
- */
-/* Return a single row from the correct image. */
-static png_bytep
-store_image_row(const png_store* ps, png_const_structp pp, int nImage,
- png_uint_32 y)
-{
- size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2;
-
- if (ps->image == NULL)
- png_error(pp, "no allocated image");
-
- if (coffset + ps->cb_row + 3 > ps->cb_image)
- png_error(pp, "image too small");
-
- return ps->image + coffset;
-}
-
-static void
-store_image_free(png_store *ps, png_const_structp pp)
-{
- if (ps->image != NULL)
- {
- png_bytep image = ps->image;
-
- if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
- {
- if (pp != NULL)
- png_error(pp, "png_store image overwrite (1)");
- else
- store_log(ps, NULL, "png_store image overwrite (2)", 1);
- }
-
- ps->image = NULL;
- ps->cb_image = 0;
- --image;
- free(image);
- }
-}
-
-static void
-store_ensure_image(png_store *ps, png_const_structp pp, int nImages,
- size_t cbRow, png_uint_32 cRows)
-{
- size_t cb = nImages * cRows * (cbRow + 5);
-
- if (ps->cb_image < cb)
- {
- png_bytep image;
-
- store_image_free(ps, pp);
-
- /* The buffer is deliberately mis-aligned. */
- image = voidcast(png_bytep, malloc(cb+2));
- if (image == NULL)
- {
- /* Called from the startup - ignore the error for the moment. */
- if (pp == NULL)
- return;
-
- png_error(pp, "OOM allocating image buffer");
- }
-
- /* These magic tags are used to detect overwrites above. */
- ++image;
- image[-1] = 0xed;
- image[cb] = 0xfe;
-
- ps->image = image;
- ps->cb_image = cb;
- }
-
- /* We have an adequate sized image; lay out the rows. There are 2 bytes at
- * the start and three at the end of each (this ensures that the row
- * alignment starts out odd - 2+1 and changes for larger images on each row.)
- */
- ps->cb_row = cbRow;
- ps->image_h = cRows;
-
- /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178).
- * This deliberately doesn't match the bits in the size test image which are
- * outside the image; these are set to 0xff (all 1). To make the row
- * comparison work in the 'size' test case the size rows are pre-initialized
- * to the same value prior to calling 'standard_row'.
- */
- memset(ps->image, 178, cb);
-
- /* Then put in the marks. */
- while (--nImages >= 0)
- {
- png_uint_32 y;
-
- for (y=0; y<cRows; ++y)
- {
- png_bytep row = store_image_row(ps, pp, nImages, y);
-
- /* The markers: */
- row[-2] = 190;
- row[-1] = 239;
- row[cbRow] = 222;
- row[cbRow+1] = 173;
- row[cbRow+2] = 17;
- }
- }
-}
-
-#ifdef PNG_READ_SUPPORTED
-static void
-store_image_check(const png_store* ps, png_const_structp pp, int iImage)
-{
- png_const_bytep image = ps->image;
-
- if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
- png_error(pp, "image overwrite");
- else
- {
- size_t cbRow = ps->cb_row;
- png_uint_32 rows = ps->image_h;
-
- image += iImage * (cbRow+5) * ps->image_h;
-
- image += 2; /* skip image first row markers */
-
- for (; rows > 0; --rows)
- {
- if (image[-2] != 190 || image[-1] != 239)
- png_error(pp, "row start overwritten");
-
- if (image[cbRow] != 222 || image[cbRow+1] != 173 ||
- image[cbRow+2] != 17)
- png_error(pp, "row end overwritten");
-
- image += cbRow+5;
- }
- }
-}
-#endif /* PNG_READ_SUPPORTED */
-
-static int
-valid_chunktype(png_uint_32 chunktype)
-{
- /* Each byte in the chunk type must be in one of the ranges 65..90, 97..122
- * (both inclusive), so:
- */
- unsigned int i;
-
- for (i=0; i<4; ++i)
- {
- unsigned int c = chunktype & 0xffU;
-
- if (!((c >= 65U && c <= 90U) || (c >= 97U && c <= 122U)))
- return 0;
-
- chunktype >>= 8;
- }
-
- return 1; /* It's valid */
-}
-
-static void PNGCBAPI
-store_write(png_structp ppIn, png_bytep pb, size_t st)
-{
- png_const_structp pp = ppIn;
- png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
- size_t writepos = ps->writepos;
- png_uint_32 chunkpos = ps->chunkpos;
- png_uint_32 chunktype = ps->chunktype;
- png_uint_32 chunklen = ps->chunklen;
-
- if (ps->pwrite != pp)
- png_error(pp, "store state damaged");
-
- /* Technically this is legal, but in practice libpng never writes more than
- * the maximum chunk size at once so if it happens something weird has
- * changed inside libpng (probably).
- */
- if (st > 0x7fffffffU)
- png_error(pp, "unexpected write size");
-
- /* Now process the bytes to be written. Do this in units of the space in the
- * output (write) buffer or, at the start 4 bytes for the chunk type and
- * length limited in any case by the amount of data.
- */
- while (st > 0)
- {
- if (writepos >= STORE_BUFFER_SIZE)
- store_storenew(ps), writepos = 0;
-
- if (chunkpos < 4)
- {
- png_byte b = *pb++;
- --st;
- chunklen = (chunklen << 8) + b;
- ps->new.buffer[writepos++] = b;
- ++chunkpos;
- }
-
- else if (chunkpos < 8)
- {
- png_byte b = *pb++;
- --st;
- chunktype = (chunktype << 8) + b;
- ps->new.buffer[writepos++] = b;
-
- if (++chunkpos == 8)
- {
- chunklen &= 0xffffffffU;
- if (chunklen > 0x7fffffffU)
- png_error(pp, "chunk length too great");
-
- chunktype &= 0xffffffffU;
- if (chunktype == CHUNK_IDAT)
- {
- if (chunklen > ~ps->IDAT_size)
- png_error(pp, "pngvalid internal image too large");
-
- ps->IDAT_size += chunklen;
- }
-
- else if (!valid_chunktype(chunktype))
- png_error(pp, "invalid chunk type");
-
- chunklen += 12; /* for header and CRC */
- }
- }
-
- else /* chunkpos >= 8 */
- {
- size_t cb = st;
-
- if (cb > STORE_BUFFER_SIZE - writepos)
- cb = STORE_BUFFER_SIZE - writepos;
-
- if (cb > chunklen - chunkpos/* bytes left in chunk*/)
- cb = (size_t)/*SAFE*/(chunklen - chunkpos);
-
- memcpy(ps->new.buffer + writepos, pb, cb);
- chunkpos += (png_uint_32)/*SAFE*/cb;
- pb += cb;
- writepos += cb;
- st -= cb;
-
- if (chunkpos >= chunklen) /* must be equal */
- chunkpos = chunktype = chunklen = 0;
- }
- } /* while (st > 0) */
-
- ps->writepos = writepos;
- ps->chunkpos = chunkpos;
- ps->chunktype = chunktype;
- ps->chunklen = chunklen;
-}
-
-static void PNGCBAPI
-store_flush(png_structp ppIn)
-{
- UNUSED(ppIn) /*DOES NOTHING*/
-}
-
-#ifdef PNG_READ_SUPPORTED
-static size_t
-store_read_buffer_size(png_store *ps)
-{
- /* Return the bytes available for read in the current buffer. */
- if (ps->next != &ps->current->data)
- return STORE_BUFFER_SIZE;
-
- return ps->current->datacount;
-}
-
-/* Return total bytes available for read. */
-static size_t
-store_read_buffer_avail(png_store *ps)
-{
- if (ps->current != NULL && ps->next != NULL)
- {
- png_store_buffer *next = &ps->current->data;
- size_t cbAvail = ps->current->datacount;
-
- while (next != ps->next && next != NULL)
- {
- next = next->prev;
- cbAvail += STORE_BUFFER_SIZE;
- }
-
- if (next != ps->next)
- png_error(ps->pread, "buffer read error");
-
- if (cbAvail > ps->readpos)
- return cbAvail - ps->readpos;
- }
-
- return 0;
-}
-
-static int
-store_read_buffer_next(png_store *ps)
-{
- png_store_buffer *pbOld = ps->next;
- png_store_buffer *pbNew = &ps->current->data;
- if (pbOld != pbNew)
- {
- while (pbNew != NULL && pbNew->prev != pbOld)
- pbNew = pbNew->prev;
-
- if (pbNew != NULL)
- {
- ps->next = pbNew;
- ps->readpos = 0;
- return 1;
- }
-
- png_error(ps->pread, "buffer lost");
- }
-
- return 0; /* EOF or error */
-}
-
-/* Need separate implementation and callback to allow use of the same code
- * during progressive read, where the io_ptr is set internally by libpng.
- */
-static void
-store_read_imp(png_store *ps, png_bytep pb, size_t st)
-{
- if (ps->current == NULL || ps->next == NULL)
- png_error(ps->pread, "store state damaged");
-
- while (st > 0)
- {
- size_t cbAvail = store_read_buffer_size(ps) - ps->readpos;
-
- if (cbAvail > 0)
- {
- if (cbAvail > st) cbAvail = st;
- memcpy(pb, ps->next->buffer + ps->readpos, cbAvail);
- st -= cbAvail;
- pb += cbAvail;
- ps->readpos += cbAvail;
- }
-
- else if (!store_read_buffer_next(ps))
- png_error(ps->pread, "read beyond end of file");
- }
-}
-
-static size_t
-store_read_chunk(png_store *ps, png_bytep pb, size_t max, size_t min)
-{
- png_uint_32 chunklen = ps->chunklen;
- png_uint_32 chunktype = ps->chunktype;
- png_uint_32 chunkpos = ps->chunkpos;
- size_t st = max;
-
- if (st > 0) do
- {
- if (chunkpos >= chunklen) /* end of last chunk */
- {
- png_byte buffer[8];
-
- /* Read the header of the next chunk: */
- store_read_imp(ps, buffer, 8U);
- chunklen = png_get_uint_32(buffer) + 12U;
- chunktype = png_get_uint_32(buffer+4U);
- chunkpos = 0U; /* Position read so far */
- }
-
- if (chunktype == CHUNK_IDAT)
- {
- png_uint_32 IDAT_pos = ps->IDAT_pos;
- png_uint_32 IDAT_len = ps->IDAT_len;
- png_uint_32 IDAT_size = ps->IDAT_size;
-
- /* The IDAT headers are constructed here; skip the input header. */
- if (chunkpos < 8U)
- chunkpos = 8U;
-
- if (IDAT_pos == IDAT_len)
- {
- png_byte random = random_byte();
-
- /* Make a new IDAT chunk, if IDAT_len is 0 this is the first IDAT,
- * if IDAT_size is 0 this is the end. At present this is set up
- * using a random number so that there is a 25% chance before
- * the start of the first IDAT chunk being 0 length.
- */
- if (IDAT_len == 0U) /* First IDAT */
- {
- switch (random & 3U)
- {
- case 0U: IDAT_len = 12U; break; /* 0 bytes */
- case 1U: IDAT_len = 13U; break; /* 1 byte */
- default: IDAT_len = random_u32();
- IDAT_len %= IDAT_size;
- IDAT_len += 13U; /* 1..IDAT_size bytes */
- break;
- }
- }
-
- else if (IDAT_size == 0U) /* all IDAT data read */
- {
- /* The last (IDAT) chunk should be positioned at the CRC now: */
- if (chunkpos != chunklen-4U)
- png_error(ps->pread, "internal: IDAT size mismatch");
-
- /* The only option here is to add a zero length IDAT, this
- * happens 25% of the time. Because of the check above
- * chunklen-4U-chunkpos must be zero, we just need to skip the
- * CRC now.
- */
- if ((random & 3U) == 0U)
- IDAT_len = 12U; /* Output another 0 length IDAT */
-
- else
- {
- /* End of IDATs, skip the CRC to make the code above load the
- * next chunk header next time round.
- */
- png_byte buffer[4];
-
- store_read_imp(ps, buffer, 4U);
- chunkpos += 4U;
- ps->IDAT_pos = IDAT_pos;
- ps->IDAT_len = IDAT_len;
- ps->IDAT_size = 0U;
- continue; /* Read the next chunk */
- }
- }
-
- else
- {
- /* Middle of IDATs, use 'random' to determine the number of bits
- * to use in the IDAT length.
- */
- IDAT_len = random_u32();
- IDAT_len &= (1U << (1U + random % ps->IDAT_bits)) - 1U;
- if (IDAT_len > IDAT_size)
- IDAT_len = IDAT_size;
- IDAT_len += 12U; /* zero bytes may occur */
- }
-
- IDAT_pos = 0U;
- ps->IDAT_crc = 0x35af061e; /* Ie: crc32(0UL, "IDAT", 4) */
- } /* IDAT_pos == IDAT_len */
-
- if (IDAT_pos < 8U) /* Return the header */ do
- {
- png_uint_32 b;
- unsigned int shift;
-
- if (IDAT_pos < 4U)
- b = IDAT_len - 12U;
-
- else
- b = CHUNK_IDAT;
-
- shift = 3U & IDAT_pos;
- ++IDAT_pos;
-
- if (shift < 3U)
- b >>= 8U*(3U-shift);
-
- *pb++ = 0xffU & b;
- }
- while (--st > 0 && IDAT_pos < 8);
-
- else if (IDAT_pos < IDAT_len - 4U) /* I.e not the CRC */
- {
- if (chunkpos < chunklen-4U)
- {
- uInt avail = (uInt)-1;
-
- if (avail > (IDAT_len-4U) - IDAT_pos)
- avail = (uInt)/*SAFE*/((IDAT_len-4U) - IDAT_pos);
-
- if (avail > st)
- avail = (uInt)/*SAFE*/st;
-
- if (avail > (chunklen-4U) - chunkpos)
- avail = (uInt)/*SAFE*/((chunklen-4U) - chunkpos);
-
- store_read_imp(ps, pb, avail);
- ps->IDAT_crc = crc32(ps->IDAT_crc, pb, avail);
- pb += (size_t)/*SAFE*/avail;
- st -= (size_t)/*SAFE*/avail;
- chunkpos += (png_uint_32)/*SAFE*/avail;
- IDAT_size -= (png_uint_32)/*SAFE*/avail;
- IDAT_pos += (png_uint_32)/*SAFE*/avail;
- }
-
- else /* skip the input CRC */
- {
- png_byte buffer[4];
-
- store_read_imp(ps, buffer, 4U);
- chunkpos += 4U;
- }
- }
-
- else /* IDAT crc */ do
- {
- uLong b = ps->IDAT_crc;
- unsigned int shift = (IDAT_len - IDAT_pos); /* 4..1 */
- ++IDAT_pos;
-
- if (shift > 1U)
- b >>= 8U*(shift-1U);
-
- *pb++ = 0xffU & b;
- }
- while (--st > 0 && IDAT_pos < IDAT_len);
-
- ps->IDAT_pos = IDAT_pos;
- ps->IDAT_len = IDAT_len;
- ps->IDAT_size = IDAT_size;
- }
-
- else /* !IDAT */
- {
- /* If there is still some pending IDAT data after the IDAT chunks have
- * been processed there is a problem:
- */
- if (ps->IDAT_len > 0 && ps->IDAT_size > 0)
- png_error(ps->pread, "internal: missing IDAT data");
-
- if (chunktype == CHUNK_IEND && ps->IDAT_len == 0U)
- png_error(ps->pread, "internal: missing IDAT");
-
- if (chunkpos < 8U) /* Return the header */ do
- {
- png_uint_32 b;
- unsigned int shift;
-
- if (chunkpos < 4U)
- b = chunklen - 12U;
-
- else
- b = chunktype;
-
- shift = 3U & chunkpos;
- ++chunkpos;
-
- if (shift < 3U)
- b >>= 8U*(3U-shift);
-
- *pb++ = 0xffU & b;
- }
- while (--st > 0 && chunkpos < 8);
-
- else /* Return chunk bytes, including the CRC */
- {
- size_t avail = st;
-
- if (avail > chunklen - chunkpos)
- avail = (size_t)/*SAFE*/(chunklen - chunkpos);
-
- store_read_imp(ps, pb, avail);
- pb += avail;
- st -= avail;
- chunkpos += (png_uint_32)/*SAFE*/avail;
-
- /* Check for end of chunk and end-of-file; don't try to read a new
- * chunk header at this point unless instructed to do so by 'min'.
- */
- if (chunkpos >= chunklen && max-st >= min &&
- store_read_buffer_avail(ps) == 0)
- break;
- }
- } /* !IDAT */
- }
- while (st > 0);
-
- ps->chunklen = chunklen;
- ps->chunktype = chunktype;
- ps->chunkpos = chunkpos;
-
- return st; /* space left */
-}
-
-static void PNGCBAPI
-store_read(png_structp ppIn, png_bytep pb, size_t st)
-{
- png_const_structp pp = ppIn;
- png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
-
- if (ps == NULL || ps->pread != pp)
- png_error(pp, "bad store read call");
-
- store_read_chunk(ps, pb, st, st);
-}
-
-static void
-store_progressive_read(png_store *ps, png_structp pp, png_infop pi)
-{
- if (ps->pread != pp || ps->current == NULL || ps->next == NULL)
- png_error(pp, "store state damaged (progressive)");
-
- /* This is another Horowitz and Hill random noise generator. In this case
- * the aim is to stress the progressive reader with truly horrible variable
- * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers
- * is generated. We could probably just count from 1 to 32767 and get as
- * good a result.
- */
- while (store_read_buffer_avail(ps) > 0)
- {
- static png_uint_32 noise = 2;
- size_t cb;
- png_byte buffer[512];
-
- /* Generate 15 more bits of stuff: */
- noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);
- cb = noise & 0x1ff;
- cb -= store_read_chunk(ps, buffer, cb, 1);
- png_process_data(pp, pi, buffer, cb);
- }
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/* The caller must fill this in: */
-static store_palette_entry *
-store_write_palette(png_store *ps, int npalette)
-{
- if (ps->pwrite == NULL)
- store_log(ps, NULL, "attempt to write palette without write stream", 1);
-
- if (ps->palette != NULL)
- png_error(ps->pwrite, "multiple store_write_palette calls");
-
- /* This function can only return NULL if called with '0'! */
- if (npalette > 0)
- {
- ps->palette = voidcast(store_palette_entry*, malloc(npalette *
- sizeof *ps->palette));
-
- if (ps->palette == NULL)
- png_error(ps->pwrite, "store new palette: OOM");
-
- ps->npalette = npalette;
- }
-
- return ps->palette;
-}
-
-#ifdef PNG_READ_SUPPORTED
-static store_palette_entry *
-store_current_palette(png_store *ps, int *npalette)
-{
- /* This is an internal error (the call has been made outside a read
- * operation.)
- */
- if (ps->current == NULL)
- {
- store_log(ps, ps->pread, "no current stream for palette", 1);
- return NULL;
- }
-
- /* The result may be null if there is no palette. */
- *npalette = ps->current->npalette;
- return ps->current->palette;
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/***************************** MEMORY MANAGEMENT*** ***************************/
-#ifdef PNG_USER_MEM_SUPPORTED
-/* A store_memory is simply the header for an allocated block of memory. The
- * pointer returned to libpng is just after the end of the header block, the
- * allocated memory is followed by a second copy of the 'mark'.
- */
-typedef struct store_memory
-{
- store_pool *pool; /* Originating pool */
- struct store_memory *next; /* Singly linked list */
- png_alloc_size_t size; /* Size of memory allocated */
- png_byte mark[4]; /* ID marker */
-} store_memory;
-
-/* Handle a fatal error in memory allocation. This calls png_error if the
- * libpng struct is non-NULL, else it outputs a message and returns. This means
- * that a memory problem while libpng is running will abort (png_error) the
- * handling of particular file while one in cleanup (after the destroy of the
- * struct has returned) will simply keep going and free (or attempt to free)
- * all the memory.
- */
-static void
-store_pool_error(png_store *ps, png_const_structp pp, const char *msg)
-{
- if (pp != NULL)
- png_error(pp, msg);
-
- /* Else we have to do it ourselves. png_error eventually calls store_log,
- * above. store_log accepts a NULL png_structp - it just changes what gets
- * output by store_message.
- */
- store_log(ps, pp, msg, 1 /* error */);
-}
-
-static void
-store_memory_free(png_const_structp pp, store_pool *pool, store_memory *memory)
-{
- /* Note that pp may be NULL (see store_pool_delete below), the caller has
- * found 'memory' in pool->list *and* unlinked this entry, so this is a valid
- * pointer (for sure), but the contents may have been trashed.
- */
- if (memory->pool != pool)
- store_pool_error(pool->store, pp, "memory corrupted (pool)");
-
- else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0)
- store_pool_error(pool->store, pp, "memory corrupted (start)");
-
- /* It should be safe to read the size field now. */
- else
- {
- png_alloc_size_t cb = memory->size;
-
- if (cb > pool->max)
- store_pool_error(pool->store, pp, "memory corrupted (size)");
-
- else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark)
- != 0)
- store_pool_error(pool->store, pp, "memory corrupted (end)");
-
- /* Finally give the library a chance to find problems too: */
- else
- {
- pool->current -= cb;
- free(memory);
- }
- }
-}
-
-static void
-store_pool_delete(png_store *ps, store_pool *pool)
-{
- if (pool->list != NULL)
- {
- fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test,
- pool == &ps->read_memory_pool ? "read" : "write",
- pool == &ps->read_memory_pool ? (ps->current != NULL ?
- ps->current->name : "unknown file") : ps->wname);
- ++ps->nerrors;
-
- do
- {
- store_memory *next = pool->list;
- pool->list = next->next;
- next->next = NULL;
-
- fprintf(stderr, "\t%lu bytes @ %p\n",
- (unsigned long)next->size, (const void*)(next+1));
- /* The NULL means this will always return, even if the memory is
- * corrupted.
- */
- store_memory_free(NULL, pool, next);
- }
- while (pool->list != NULL);
- }
-
- /* And reset the other fields too for the next time. */
- if (pool->max > pool->max_max) pool->max_max = pool->max;
- pool->max = 0;
- if (pool->current != 0) /* unexpected internal error */
- fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n",
- ps->test, pool == &ps->read_memory_pool ? "read" : "write",
- pool == &ps->read_memory_pool ? (ps->current != NULL ?
- ps->current->name : "unknown file") : ps->wname);
- pool->current = 0;
-
- if (pool->limit > pool->max_limit)
- pool->max_limit = pool->limit;
-
- pool->limit = 0;
-
- if (pool->total > pool->max_total)
- pool->max_total = pool->total;
-
- pool->total = 0;
-
- /* Get a new mark too. */
- store_pool_mark(pool->mark);
-}
-
-/* The memory callbacks: */
-static png_voidp PNGCBAPI
-store_malloc(png_structp ppIn, png_alloc_size_t cb)
-{
- png_const_structp pp = ppIn;
- store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
- store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) +
- (sizeof pool->mark)));
-
- if (new != NULL)
- {
- if (cb > pool->max)
- pool->max = cb;
-
- pool->current += cb;
-
- if (pool->current > pool->limit)
- pool->limit = pool->current;
-
- pool->total += cb;
-
- new->size = cb;
- memcpy(new->mark, pool->mark, sizeof new->mark);
- memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark);
- new->pool = pool;
- new->next = pool->list;
- pool->list = new;
- ++new;
- }
-
- else
- {
- /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed
- * other than to retrieve the allocation pointer! libpng calls the
- * store_malloc callback in two basic cases:
- *
- * 1) From png_malloc; png_malloc will do a png_error itself if NULL is
- * returned.
- * 2) From png_struct or png_info structure creation; png_malloc is
- * to return so cleanup can be performed.
- *
- * To handle this store_malloc can log a message, but can't do anything
- * else.
- */
- store_log(pool->store, pp, "out of memory", 1 /* is_error */);
- }
-
- return new;
-}
-
-static void PNGCBAPI
-store_free(png_structp ppIn, png_voidp memory)
-{
- png_const_structp pp = ppIn;
- store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
- store_memory *this = voidcast(store_memory*, memory), **test;
-
- /* Because libpng calls store_free with a dummy png_struct when deleting
- * png_struct or png_info via png_destroy_struct_2 it is necessary to check
- * the passed in png_structp to ensure it is valid, and not pass it to
- * png_error if it is not.
- */
- if (pp != pool->store->pread && pp != pool->store->pwrite)
- pp = NULL;
-
- /* First check that this 'memory' really is valid memory - it must be in the
- * pool list. If it is, use the shared memory_free function to free it.
- */
- --this;
- for (test = &pool->list; *test != this; test = &(*test)->next)
- {
- if (*test == NULL)
- {
- store_pool_error(pool->store, pp, "bad pointer to free");
- return;
- }
- }
-
- /* Unlink this entry, *test == this. */
- *test = this->next;
- this->next = NULL;
- store_memory_free(pp, pool, this);
-}
-#endif /* PNG_USER_MEM_SUPPORTED */
-
-/* Setup functions. */
-/* Cleanup when aborting a write or after storing the new file. */
-static void
-store_write_reset(png_store *ps)
-{
- if (ps->pwrite != NULL)
- {
- anon_context(ps);
-
- Try
- png_destroy_write_struct(&ps->pwrite, &ps->piwrite);
-
- Catch_anonymous
- {
- /* memory corruption: continue. */
- }
-
- ps->pwrite = NULL;
- ps->piwrite = NULL;
- }
-
- /* And make sure that all the memory has been freed - this will output
- * spurious errors in the case of memory corruption above, but this is safe.
- */
-# ifdef PNG_USER_MEM_SUPPORTED
- store_pool_delete(ps, &ps->write_memory_pool);
-# endif
-
- store_freenew(ps);
-}
-
-/* The following is the main write function, it returns a png_struct and,
- * optionally, a png_info suitable for writiing a new PNG file. Use
- * store_storefile above to record this file after it has been written. The
- * returned libpng structures as destroyed by store_write_reset above.
- */
-static png_structp
-set_store_for_write(png_store *ps, png_infopp ppi, const char *name)
-{
- anon_context(ps);
-
- Try
- {
- if (ps->pwrite != NULL)
- png_error(ps->pwrite, "write store already in use");
-
- store_write_reset(ps);
- safecat(ps->wname, sizeof ps->wname, 0, name);
-
- /* Don't do the slow memory checks if doing a speed test, also if user
- * memory is not supported we can't do it anyway.
- */
-# ifdef PNG_USER_MEM_SUPPORTED
- if (!ps->speed)
- ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
- ps, store_error, store_warning, &ps->write_memory_pool,
- store_malloc, store_free);
-
- else
-# endif
- ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- ps, store_error, store_warning);
-
- png_set_write_fn(ps->pwrite, ps, store_write, store_flush);
-
-# ifdef PNG_SET_OPTION_SUPPORTED
- {
- int opt;
- for (opt=0; opt<ps->noptions; ++opt)
- if (png_set_option(ps->pwrite, ps->options[opt].option,
- ps->options[opt].setting) == PNG_OPTION_INVALID)
- png_error(ps->pwrite, "png option invalid");
- }
-# endif
-
- if (ppi != NULL)
- *ppi = ps->piwrite = png_create_info_struct(ps->pwrite);
- }
-
- Catch_anonymous
- return NULL;
-
- return ps->pwrite;
-}
-
-/* Cleanup when finished reading (either due to error or in the success case).
- * This routine exists even when there is no read support to make the code
- * tidier (avoid a mass of ifdefs) and so easier to maintain.
- */
-static void
-store_read_reset(png_store *ps)
-{
-# ifdef PNG_READ_SUPPORTED
- if (ps->pread != NULL)
- {
- anon_context(ps);
-
- Try
- png_destroy_read_struct(&ps->pread, &ps->piread, NULL);
-
- Catch_anonymous
- {
- /* error already output: continue */
- }
-
- ps->pread = NULL;
- ps->piread = NULL;
- }
-# endif
-
-# ifdef PNG_USER_MEM_SUPPORTED
- /* Always do this to be safe. */
- store_pool_delete(ps, &ps->read_memory_pool);
-# endif
-
- ps->current = NULL;
- ps->next = NULL;
- ps->readpos = 0;
- ps->validated = 0;
-
- ps->chunkpos = 8;
- ps->chunktype = 0;
- ps->chunklen = 16;
- ps->IDAT_size = 0;
-}
-
-#ifdef PNG_READ_SUPPORTED
-static void
-store_read_set(png_store *ps, png_uint_32 id)
-{
- png_store_file *pf = ps->saved;
-
- while (pf != NULL)
- {
- if (pf->id == id)
- {
- ps->current = pf;
- ps->next = NULL;
- ps->IDAT_size = pf->IDAT_size;
- ps->IDAT_bits = pf->IDAT_bits; /* just a cache */
- ps->IDAT_len = 0;
- ps->IDAT_pos = 0;
- ps->IDAT_crc = 0UL;
- store_read_buffer_next(ps);
- return;
- }
-
- pf = pf->next;
- }
-
- {
- size_t pos;
- char msg[FILE_NAME_SIZE+64];
-
- pos = standard_name_from_id(msg, sizeof msg, 0, id);
- pos = safecat(msg, sizeof msg, pos, ": file not found");
- png_error(ps->pread, msg);
- }
-}
-
-/* The main interface for reading a saved file - pass the id number of the file
- * to retrieve. Ids must be unique or the earlier file will be hidden. The API
- * returns a png_struct and, optionally, a png_info. Both of these will be
- * destroyed by store_read_reset above.
- */
-static png_structp
-set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id,
- const char *name)
-{
- /* Set the name for png_error */
- safecat(ps->test, sizeof ps->test, 0, name);
-
- if (ps->pread != NULL)
- png_error(ps->pread, "read store already in use");
-
- store_read_reset(ps);
-
- /* Both the create APIs can return NULL if used in their default mode
- * (because there is no other way of handling an error because the jmp_buf
- * by default is stored in png_struct and that has not been allocated!)
- * However, given that store_error works correctly in these circumstances
- * we don't ever expect NULL in this program.
- */
-# ifdef PNG_USER_MEM_SUPPORTED
- if (!ps->speed)
- ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps,
- store_error, store_warning, &ps->read_memory_pool, store_malloc,
- store_free);
-
- else
-# endif
- ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, store_error,
- store_warning);
-
- if (ps->pread == NULL)
- {
- struct exception_context *the_exception_context = &ps->exception_context;
-
- store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)",
- 1 /*error*/);
-
- Throw ps;
- }
-
-# ifdef PNG_SET_OPTION_SUPPORTED
- {
- int opt;
- for (opt=0; opt<ps->noptions; ++opt)
- if (png_set_option(ps->pread, ps->options[opt].option,
- ps->options[opt].setting) == PNG_OPTION_INVALID)
- png_error(ps->pread, "png option invalid");
- }
-# endif
-
- store_read_set(ps, id);
-
- if (ppi != NULL)
- *ppi = ps->piread = png_create_info_struct(ps->pread);
-
- return ps->pread;
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/* The overall cleanup of a store simply calls the above then removes all the
- * saved files. This does not delete the store itself.
- */
-static void
-store_delete(png_store *ps)
-{
- store_write_reset(ps);
- store_read_reset(ps);
- store_freefile(&ps->saved);
- store_image_free(ps, NULL);
-}
-
-/*********************** PNG FILE MODIFICATION ON READ ************************/
-/* Files may be modified on read. The following structure contains a complete
- * png_store together with extra members to handle modification and a special
- * read callback for libpng. To use this the 'modifications' field must be set
- * to a list of png_modification structures that actually perform the
- * modification, otherwise a png_modifier is functionally equivalent to a
- * png_store. There is a special read function, set_modifier_for_read, which
- * replaces set_store_for_read.
- */
-typedef enum modifier_state
-{
- modifier_start, /* Initial value */
- modifier_signature, /* Have a signature */
- modifier_IHDR /* Have an IHDR */
-} modifier_state;
-
-typedef struct CIE_color
-{
- /* A single CIE tristimulus value, representing the unique response of a
- * standard observer to a variety of light spectra. The observer recognizes
- * all spectra that produce this response as the same color, therefore this
- * is effectively a description of a color.
- */
- double X, Y, Z;
-} CIE_color;
-
-typedef struct color_encoding
-{
- /* A description of an (R,G,B) encoding of color (as defined above); this
- * includes the actual colors of the (R,G,B) triples (1,0,0), (0,1,0) and
- * (0,0,1) plus an encoding value that is used to encode the linear
- * components R, G and B to give the actual values R^gamma, G^gamma and
- * B^gamma that are stored.
- */
- double gamma; /* Encoding (file) gamma of space */
- CIE_color red, green, blue; /* End points */
-} color_encoding;
-
-#ifdef PNG_READ_SUPPORTED
-#if defined PNG_READ_TRANSFORMS_SUPPORTED && defined PNG_READ_cHRM_SUPPORTED
-static double
-chromaticity_x(CIE_color c)
-{
- return c.X / (c.X + c.Y + c.Z);
-}
-
-static double
-chromaticity_y(CIE_color c)
-{
- return c.Y / (c.X + c.Y + c.Z);
-}
-
-static CIE_color
-white_point(const color_encoding *encoding)
-{
- CIE_color white;
-
- white.X = encoding->red.X + encoding->green.X + encoding->blue.X;
- white.Y = encoding->red.Y + encoding->green.Y + encoding->blue.Y;
- white.Z = encoding->red.Z + encoding->green.Z + encoding->blue.Z;
-
- return white;
-}
-#endif /* READ_TRANSFORMS && READ_cHRM */
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-static void
-normalize_color_encoding(color_encoding *encoding)
-{
- const double whiteY = encoding->red.Y + encoding->green.Y +
- encoding->blue.Y;
-
- if (whiteY != 1)
- {
- encoding->red.X /= whiteY;
- encoding->red.Y /= whiteY;
- encoding->red.Z /= whiteY;
- encoding->green.X /= whiteY;
- encoding->green.Y /= whiteY;
- encoding->green.Z /= whiteY;
- encoding->blue.X /= whiteY;
- encoding->blue.Y /= whiteY;
- encoding->blue.Z /= whiteY;
- }
-}
-#endif
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-static size_t
-safecat_color_encoding(char *buffer, size_t bufsize, size_t pos,
- const color_encoding *e, double encoding_gamma)
-{
- if (e != 0)
- {
- if (encoding_gamma != 0)
- pos = safecat(buffer, bufsize, pos, "(");
- pos = safecat(buffer, bufsize, pos, "R(");
- pos = safecatd(buffer, bufsize, pos, e->red.X, 4);
- pos = safecat(buffer, bufsize, pos, ",");
- pos = safecatd(buffer, bufsize, pos, e->red.Y, 4);
- pos = safecat(buffer, bufsize, pos, ",");
- pos = safecatd(buffer, bufsize, pos, e->red.Z, 4);
- pos = safecat(buffer, bufsize, pos, "),G(");
- pos = safecatd(buffer, bufsize, pos, e->green.X, 4);
- pos = safecat(buffer, bufsize, pos, ",");
- pos = safecatd(buffer, bufsize, pos, e->green.Y, 4);
- pos = safecat(buffer, bufsize, pos, ",");
- pos = safecatd(buffer, bufsize, pos, e->green.Z, 4);
- pos = safecat(buffer, bufsize, pos, "),B(");
- pos = safecatd(buffer, bufsize, pos, e->blue.X, 4);
- pos = safecat(buffer, bufsize, pos, ",");
- pos = safecatd(buffer, bufsize, pos, e->blue.Y, 4);
- pos = safecat(buffer, bufsize, pos, ",");
- pos = safecatd(buffer, bufsize, pos, e->blue.Z, 4);
- pos = safecat(buffer, bufsize, pos, ")");
- if (encoding_gamma != 0)
- pos = safecat(buffer, bufsize, pos, ")");
- }
-
- if (encoding_gamma != 0)
- {
- pos = safecat(buffer, bufsize, pos, "^");
- pos = safecatd(buffer, bufsize, pos, encoding_gamma, 5);
- }
-
- return pos;
-}
-#endif /* READ_TRANSFORMS */
-#endif /* PNG_READ_SUPPORTED */
-
-typedef struct png_modifier
-{
- png_store this; /* I am a png_store */
- struct png_modification *modifications; /* Changes to make */
-
- modifier_state state; /* My state */
-
- /* Information from IHDR: */
- png_byte bit_depth; /* From IHDR */
- png_byte colour_type; /* From IHDR */
-
- /* While handling PLTE, IDAT and IEND these chunks may be pended to allow
- * other chunks to be inserted.
- */
- png_uint_32 pending_len;
- png_uint_32 pending_chunk;
-
- /* Test values */
- double *gammas;
- unsigned int ngammas;
- unsigned int ngamma_tests; /* Number of gamma tests to run*/
- double current_gamma; /* 0 if not set */
- const color_encoding *encodings;
- unsigned int nencodings;
- const color_encoding *current_encoding; /* If an encoding has been set */
- unsigned int encoding_counter; /* For iteration */
- int encoding_ignored; /* Something overwrote it */
-
- /* Control variables used to iterate through possible encodings, the
- * following must be set to 0 and tested by the function that uses the
- * png_modifier because the modifier only sets it to 1 (true.)
- */
- unsigned int repeat :1; /* Repeat this transform test. */
- unsigned int test_uses_encoding :1;
-
- /* Lowest sbit to test (pre-1.7 libpng fails for sbit < 8) */
- png_byte sbitlow;
-
- /* Error control - these are the limits on errors accepted by the gamma tests
- * below.
- */
- double maxout8; /* Maximum output value error */
- double maxabs8; /* Absolute sample error 0..1 */
- double maxcalc8; /* Absolute sample error 0..1 */
- double maxpc8; /* Percentage sample error 0..100% */
- double maxout16; /* Maximum output value error */
- double maxabs16; /* Absolute sample error 0..1 */
- double maxcalc16;/* Absolute sample error 0..1 */
- double maxcalcG; /* Absolute sample error 0..1 */
- double maxpc16; /* Percentage sample error 0..100% */
-
- /* This is set by transforms that need to allow a higher limit, it is an
- * internal check on pngvalid to ensure that the calculated error limits are
- * not ridiculous; without this it is too easy to make a mistake in pngvalid
- * that allows any value through.
- *
- * NOTE: this is not checked in release builds.
- */
- double limit; /* limit on error values, normally 4E-3 */
-
- /* Log limits - values above this are logged, but not necessarily
- * warned.
- */
- double log8; /* Absolute error in 8 bits to log */
- double log16; /* Absolute error in 16 bits to log */
-
- /* Logged 8 and 16 bit errors ('output' values): */
- double error_gray_2;
- double error_gray_4;
- double error_gray_8;
- double error_gray_16;
- double error_color_8;
- double error_color_16;
- double error_indexed;
-
- /* Flags: */
- /* Whether to call png_read_update_info, not png_read_start_image, and how
- * many times to call it.
- */
- int use_update_info;
-
- /* Whether or not to interlace. */
- int interlace_type :9; /* int, but must store '1' */
-
- /* Run the standard tests? */
- unsigned int test_standard :1;
-
- /* Run the odd-sized image and interlace read/write tests? */
- unsigned int test_size :1;
-
- /* Run tests on reading with a combination of transforms, */
- unsigned int test_transform :1;
- unsigned int test_tRNS :1; /* Includes tRNS images */
-
- /* When to use the use_input_precision option, this controls the gamma
- * validation code checks. If set any value that is within the transformed
- * range input-.5 to input+.5 will be accepted, otherwise the value must be
- * within the normal limits. It should not be necessary to set this; the
- * result should always be exact within the permitted error limits.
- */
- unsigned int use_input_precision :1;
- unsigned int use_input_precision_sbit :1;
- unsigned int use_input_precision_16to8 :1;
-
- /* If set assume that the calculation bit depth is set by the input
- * precision, not the output precision.
- */
- unsigned int calculations_use_input_precision :1;
-
- /* If set assume that the calculations are done in 16 bits even if the sample
- * depth is 8 bits.
- */
- unsigned int assume_16_bit_calculations :1;
-
- /* Which gamma tests to run: */
- unsigned int test_gamma_threshold :1;
- unsigned int test_gamma_transform :1; /* main tests */
- unsigned int test_gamma_sbit :1;
- unsigned int test_gamma_scale16 :1;
- unsigned int test_gamma_background :1;
- unsigned int test_gamma_alpha_mode :1;
- unsigned int test_gamma_expand16 :1;
- unsigned int test_exhaustive :1;
-
- /* Whether or not to run the low-bit-depth grayscale tests. This fails on
- * gamma images in some cases because of gross inaccuracies in the grayscale
- * gamma handling for low bit depth.
- */
- unsigned int test_lbg :1;
- unsigned int test_lbg_gamma_threshold :1;
- unsigned int test_lbg_gamma_transform :1;
- unsigned int test_lbg_gamma_sbit :1;
- unsigned int test_lbg_gamma_composition :1;
-
- unsigned int log :1; /* Log max error */
-
- /* Buffer information, the buffer size limits the size of the chunks that can
- * be modified - they must fit (including header and CRC) into the buffer!
- */
- size_t flush; /* Count of bytes to flush */
- size_t buffer_count; /* Bytes in buffer */
- size_t buffer_position; /* Position in buffer */
- png_byte buffer[1024];
-} png_modifier;
-
-/* This returns true if the test should be stopped now because it has already
- * failed and it is running silently.
- */
-static int fail(png_modifier *pm)
-{
- return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 ||
- (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0));
-}
-
-static void
-modifier_init(png_modifier *pm)
-{
- memset(pm, 0, sizeof *pm);
- store_init(&pm->this);
- pm->modifications = NULL;
- pm->state = modifier_start;
- pm->sbitlow = 1U;
- pm->ngammas = 0;
- pm->ngamma_tests = 0;
- pm->gammas = 0;
- pm->current_gamma = 0;
- pm->encodings = 0;
- pm->nencodings = 0;
- pm->current_encoding = 0;
- pm->encoding_counter = 0;
- pm->encoding_ignored = 0;
- pm->repeat = 0;
- pm->test_uses_encoding = 0;
- pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0;
- pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0;
- pm->maxcalcG = 0;
- pm->limit = 4E-3;
- pm->log8 = pm->log16 = 0; /* Means 'off' */
- pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
- pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
- pm->error_indexed = 0;
- pm->use_update_info = 0;
- pm->interlace_type = PNG_INTERLACE_NONE;
- pm->test_standard = 0;
- pm->test_size = 0;
- pm->test_transform = 0;
-# ifdef PNG_WRITE_tRNS_SUPPORTED
- pm->test_tRNS = 1;
-# else
- pm->test_tRNS = 0;
-# endif
- pm->use_input_precision = 0;
- pm->use_input_precision_sbit = 0;
- pm->use_input_precision_16to8 = 0;
- pm->calculations_use_input_precision = 0;
- pm->assume_16_bit_calculations = 0;
- pm->test_gamma_threshold = 0;
- pm->test_gamma_transform = 0;
- pm->test_gamma_sbit = 0;
- pm->test_gamma_scale16 = 0;
- pm->test_gamma_background = 0;
- pm->test_gamma_alpha_mode = 0;
- pm->test_gamma_expand16 = 0;
- pm->test_lbg = 1;
- pm->test_lbg_gamma_threshold = 1;
- pm->test_lbg_gamma_transform = 1;
- pm->test_lbg_gamma_sbit = 1;
- pm->test_lbg_gamma_composition = 1;
- pm->test_exhaustive = 0;
- pm->log = 0;
-
- /* Rely on the memset for all the other fields - there are no pointers */
-}
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-
-/* This controls use of checks that explicitly know how libpng digitizes the
- * samples in calculations; setting this circumvents simple error limit checking
- * in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5
- * algorithm.
- */
-#define DIGITIZE PNG_LIBPNG_VER < 10700
-
-/* If pm->calculations_use_input_precision is set then operations will happen
- * with the precision of the input, not the precision of the output depth.
- *
- * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16
- * bit precision. This only affects those of the following limits that pertain
- * to a calculation - not a digitization operation - unless the following API is
- * called directly.
- */
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-#if DIGITIZE
-static double digitize(double value, int depth, int do_round)
-{
- /* 'value' is in the range 0 to 1, the result is the same value rounded to a
- * multiple of the digitization factor - 8 or 16 bits depending on both the
- * sample depth and the 'assume' setting. Digitization is normally by
- * rounding and 'do_round' should be 1, if it is 0 the digitized value will
- * be truncated.
- */
- unsigned int digitization_factor = (1U << depth) - 1;
-
- /* Limiting the range is done as a convenience to the caller - it's easier to
- * do it once here than every time at the call site.
- */
- if (value <= 0)
- value = 0;
-
- else if (value >= 1)
- value = 1;
-
- value *= digitization_factor;
- if (do_round) value += .5;
- return floor(value)/digitization_factor;
-}
-#endif
-#endif /* RGB_TO_GRAY */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-static double abserr(const png_modifier *pm, int in_depth, int out_depth)
-{
- /* Absolute error permitted in linear values - affected by the bit depth of
- * the calculations.
- */
- if (pm->assume_16_bit_calculations ||
- (pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
- return pm->maxabs16;
- else
- return pm->maxabs8;
-}
-
-static double calcerr(const png_modifier *pm, int in_depth, int out_depth)
-{
- /* Error in the linear composition arithmetic - only relevant when
- * composition actually happens (0 < alpha < 1).
- */
- if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
- return pm->maxcalc16;
- else if (pm->assume_16_bit_calculations)
- return pm->maxcalcG;
- else
- return pm->maxcalc8;
-}
-
-static double pcerr(const png_modifier *pm, int in_depth, int out_depth)
-{
- /* Percentage error permitted in the linear values. Note that the specified
- * value is a percentage but this routine returns a simple number.
- */
- if (pm->assume_16_bit_calculations ||
- (pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
- return pm->maxpc16 * .01;
- else
- return pm->maxpc8 * .01;
-}
-
-/* Output error - the error in the encoded value. This is determined by the
- * digitization of the output so can be +/-0.5 in the actual output value. In
- * the expand_16 case with the current code in libpng the expand happens after
- * all the calculations are done in 8 bit arithmetic, so even though the output
- * depth is 16 the output error is determined by the 8 bit calculation.
- *
- * This limit is not determined by the bit depth of internal calculations.
- *
- * The specified parameter does *not* include the base .5 digitization error but
- * it is added here.
- */
-static double outerr(const png_modifier *pm, int in_depth, int out_depth)
-{
- /* There is a serious error in the 2 and 4 bit grayscale transform because
- * the gamma table value (8 bits) is simply shifted, not rounded, so the
- * error in 4 bit grayscale gamma is up to the value below. This is a hack
- * to allow pngvalid to succeed:
- *
- * TODO: fix this in libpng
- */
- if (out_depth == 2)
- return .73182-.5;
-
- if (out_depth == 4)
- return .90644-.5;
-
- if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
- return pm->maxout16;
-
- /* This is the case where the value was calculated at 8-bit precision then
- * scaled to 16 bits.
- */
- else if (out_depth == 16)
- return pm->maxout8 * 257;
-
- else
- return pm->maxout8;
-}
-
-/* This does the same thing as the above however it returns the value to log,
- * rather than raising a warning. This is useful for debugging to track down
- * exactly what set of parameters cause high error values.
- */
-static double outlog(const png_modifier *pm, int in_depth, int out_depth)
-{
- /* The command line parameters are either 8 bit (0..255) or 16 bit (0..65535)
- * and so must be adjusted for low bit depth grayscale:
- */
- if (out_depth <= 8)
- {
- if (pm->log8 == 0) /* switched off */
- return 256;
-
- if (out_depth < 8)
- return pm->log8 / 255 * ((1<<out_depth)-1);
-
- return pm->log8;
- }
-
- if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
- {
- if (pm->log16 == 0)
- return 65536;
-
- return pm->log16;
- }
-
- /* This is the case where the value was calculated at 8-bit precision then
- * scaled to 16 bits.
- */
- if (pm->log8 == 0)
- return 65536;
-
- return pm->log8 * 257;
-}
-
-/* This complements the above by providing the appropriate quantization for the
- * final value. Normally this would just be quantization to an integral value,
- * but in the 8 bit calculation case it's actually quantization to a multiple of
- * 257!
- */
-static int output_quantization_factor(const png_modifier *pm, int in_depth,
- int out_depth)
-{
- if (out_depth == 16 && in_depth != 16 &&
- pm->calculations_use_input_precision)
- return 257;
- else
- return 1;
-}
-#endif /* PNG_READ_GAMMA_SUPPORTED */
-
-/* One modification structure must be provided for each chunk to be modified (in
- * fact more than one can be provided if multiple separate changes are desired
- * for a single chunk.) Modifications include adding a new chunk when a
- * suitable chunk does not exist.
- *
- * The caller of modify_fn will reset the CRC of the chunk and record 'modified'
- * or 'added' as appropriate if the modify_fn returns 1 (true). If the
- * modify_fn is NULL the chunk is simply removed.
- */
-typedef struct png_modification
-{
- struct png_modification *next;
- png_uint_32 chunk;
-
- /* If the following is NULL all matching chunks will be removed: */
- int (*modify_fn)(struct png_modifier *pm,
- struct png_modification *me, int add);
-
- /* If the following is set to PLTE, IDAT or IEND and the chunk has not been
- * found and modified (and there is a modify_fn) the modify_fn will be called
- * to add the chunk before the relevant chunk.
- */
- png_uint_32 add;
- unsigned int modified :1; /* Chunk was modified */
- unsigned int added :1; /* Chunk was added */
- unsigned int removed :1; /* Chunk was removed */
-} png_modification;
-
-static void
-modification_reset(png_modification *pmm)
-{
- if (pmm != NULL)
- {
- pmm->modified = 0;
- pmm->added = 0;
- pmm->removed = 0;
- modification_reset(pmm->next);
- }
-}
-
-static void
-modification_init(png_modification *pmm)
-{
- memset(pmm, 0, sizeof *pmm);
- pmm->next = NULL;
- pmm->chunk = 0;
- pmm->modify_fn = NULL;
- pmm->add = 0;
- modification_reset(pmm);
-}
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-static void
-modifier_current_encoding(const png_modifier *pm, color_encoding *ce)
-{
- if (pm->current_encoding != 0)
- *ce = *pm->current_encoding;
-
- else
- memset(ce, 0, sizeof *ce);
-
- ce->gamma = pm->current_gamma;
-}
-#endif
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-static size_t
-safecat_current_encoding(char *buffer, size_t bufsize, size_t pos,
- const png_modifier *pm)
-{
- pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding,
- pm->current_gamma);
-
- if (pm->encoding_ignored)
- pos = safecat(buffer, bufsize, pos, "[overridden]");
-
- return pos;
-}
-#endif
-
-/* Iterate through the usefully testable color encodings. An encoding is one
- * of:
- *
- * 1) Nothing (no color space, no gamma).
- * 2) Just a gamma value from the gamma array (including 1.0)
- * 3) A color space from the encodings array with the corresponding gamma.
- * 4) The same, but with gamma 1.0 (only really useful with 16 bit calculations)
- *
- * The iterator selects these in turn, the randomizer selects one at random,
- * which is used depends on the setting of the 'test_exhaustive' flag. Notice
- * that this function changes the colour space encoding so it must only be
- * called on completion of the previous test. This is what 'modifier_reset'
- * does, below.
- *
- * After the function has been called the 'repeat' flag will still be set; the
- * caller of modifier_reset must reset it at the start of each run of the test!
- */
-static unsigned int
-modifier_total_encodings(const png_modifier *pm)
-{
- return 1 + /* (1) nothing */
- pm->ngammas + /* (2) gamma values to test */
- pm->nencodings + /* (3) total number of encodings */
- /* The following test only works after the first time through the
- * png_modifier code because 'bit_depth' is set when the IHDR is read.
- * modifier_reset, below, preserves the setting until after it has called
- * the iterate function (also below.)
- *
- * For this reason do not rely on this function outside a call to
- * modifier_reset.
- */
- ((pm->bit_depth == 16 || pm->assume_16_bit_calculations) ?
- pm->nencodings : 0); /* (4) encodings with gamma == 1.0 */
-}
-
-static void
-modifier_encoding_iterate(png_modifier *pm)
-{
- if (!pm->repeat && /* Else something needs the current encoding again. */
- pm->test_uses_encoding) /* Some transform is encoding dependent */
- {
- if (pm->test_exhaustive)
- {
- if (++pm->encoding_counter >= modifier_total_encodings(pm))
- pm->encoding_counter = 0; /* This will stop the repeat */
- }
-
- else
- {
- /* Not exhaustive - choose an encoding at random; generate a number in
- * the range 1..(max-1), so the result is always non-zero:
- */
- if (pm->encoding_counter == 0)
- pm->encoding_counter = random_mod(modifier_total_encodings(pm)-1)+1;
- else
- pm->encoding_counter = 0;
- }
-
- if (pm->encoding_counter > 0)
- pm->repeat = 1;
- }
-
- else if (!pm->repeat)
- pm->encoding_counter = 0;
-}
-
-static void
-modifier_reset(png_modifier *pm)
-{
- store_read_reset(&pm->this);
- pm->limit = 4E-3;
- pm->pending_len = pm->pending_chunk = 0;
- pm->flush = pm->buffer_count = pm->buffer_position = 0;
- pm->modifications = NULL;
- pm->state = modifier_start;
- modifier_encoding_iterate(pm);
- /* The following must be set in the next run. In particular
- * test_uses_encodings must be set in the _ini function of each transform
- * that looks at the encodings. (Not the 'add' function!)
- */
- pm->test_uses_encoding = 0;
- pm->current_gamma = 0;
- pm->current_encoding = 0;
- pm->encoding_ignored = 0;
- /* These only become value after IHDR is read: */
- pm->bit_depth = pm->colour_type = 0;
-}
-
-/* The following must be called before anything else to get the encoding set up
- * on the modifier. In particular it must be called before the transform init
- * functions are called.
- */
-static void
-modifier_set_encoding(png_modifier *pm)
-{
- /* Set the encoding to the one specified by the current encoding counter,
- * first clear out all the settings - this corresponds to an encoding_counter
- * of 0.
- */
- pm->current_gamma = 0;
- pm->current_encoding = 0;
- pm->encoding_ignored = 0; /* not ignored yet - happens in _ini functions. */
-
- /* Now, if required, set the gamma and encoding fields. */
- if (pm->encoding_counter > 0)
- {
- /* The gammas[] array is an array of screen gammas, not encoding gammas,
- * so we need the inverse:
- */
- if (pm->encoding_counter <= pm->ngammas)
- pm->current_gamma = 1/pm->gammas[pm->encoding_counter-1];
-
- else
- {
- unsigned int i = pm->encoding_counter - pm->ngammas;
-
- if (i >= pm->nencodings)
- {
- i %= pm->nencodings;
- pm->current_gamma = 1; /* Linear, only in the 16 bit case */
- }
-
- else
- pm->current_gamma = pm->encodings[i].gamma;
-
- pm->current_encoding = pm->encodings + i;
- }
- }
-}
-
-/* Enquiry functions to find out what is set. Notice that there is an implicit
- * assumption below that the first encoding in the list is the one for sRGB.
- */
-static int
-modifier_color_encoding_is_sRGB(const png_modifier *pm)
-{
- return pm->current_encoding != 0 && pm->current_encoding == pm->encodings &&
- pm->current_encoding->gamma == pm->current_gamma;
-}
-
-static int
-modifier_color_encoding_is_set(const png_modifier *pm)
-{
- return pm->current_gamma != 0;
-}
-
-/* The guts of modification are performed during a read. */
-static void
-modifier_crc(png_bytep buffer)
-{
- /* Recalculate the chunk CRC - a complete chunk must be in
- * the buffer, at the start.
- */
- uInt datalen = png_get_uint_32(buffer);
- uLong crc = crc32(0, buffer+4, datalen+4);
- /* The cast to png_uint_32 is safe because a crc32 is always a 32 bit value.
- */
- png_save_uint_32(buffer+datalen+8, (png_uint_32)crc);
-}
-
-static void
-modifier_setbuffer(png_modifier *pm)
-{
- modifier_crc(pm->buffer);
- pm->buffer_count = png_get_uint_32(pm->buffer)+12;
- pm->buffer_position = 0;
-}
-
-/* Separate the callback into the actual implementation (which is passed the
- * png_modifier explicitly) and the callback, which gets the modifier from the
- * png_struct.
- */
-static void
-modifier_read_imp(png_modifier *pm, png_bytep pb, size_t st)
-{
- while (st > 0)
- {
- size_t cb;
- png_uint_32 len, chunk;
- png_modification *mod;
-
- if (pm->buffer_position >= pm->buffer_count) switch (pm->state)
- {
- static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
- case modifier_start:
- store_read_chunk(&pm->this, pm->buffer, 8, 8); /* signature. */
- pm->buffer_count = 8;
- pm->buffer_position = 0;
-
- if (memcmp(pm->buffer, sign, 8) != 0)
- png_error(pm->this.pread, "invalid PNG file signature");
- pm->state = modifier_signature;
- break;
-
- case modifier_signature:
- store_read_chunk(&pm->this, pm->buffer, 13+12, 13+12); /* IHDR */
- pm->buffer_count = 13+12;
- pm->buffer_position = 0;
-
- if (png_get_uint_32(pm->buffer) != 13 ||
- png_get_uint_32(pm->buffer+4) != CHUNK_IHDR)
- png_error(pm->this.pread, "invalid IHDR");
-
- /* Check the list of modifiers for modifications to the IHDR. */
- mod = pm->modifications;
- while (mod != NULL)
- {
- if (mod->chunk == CHUNK_IHDR && mod->modify_fn &&
- (*mod->modify_fn)(pm, mod, 0))
- {
- mod->modified = 1;
- modifier_setbuffer(pm);
- }
-
- /* Ignore removal or add if IHDR! */
- mod = mod->next;
- }
-
- /* Cache information from the IHDR (the modified one.) */
- pm->bit_depth = pm->buffer[8+8];
- pm->colour_type = pm->buffer[8+8+1];
-
- pm->state = modifier_IHDR;
- pm->flush = 0;
- break;
-
- case modifier_IHDR:
- default:
- /* Read a new chunk and process it until we see PLTE, IDAT or
- * IEND. 'flush' indicates that there is still some data to
- * output from the preceding chunk.
- */
- if ((cb = pm->flush) > 0)
- {
- if (cb > st) cb = st;
- pm->flush -= cb;
- store_read_chunk(&pm->this, pb, cb, cb);
- pb += cb;
- st -= cb;
- if (st == 0) return;
- }
-
- /* No more bytes to flush, read a header, or handle a pending
- * chunk.
- */
- if (pm->pending_chunk != 0)
- {
- png_save_uint_32(pm->buffer, pm->pending_len);
- png_save_uint_32(pm->buffer+4, pm->pending_chunk);
- pm->pending_len = 0;
- pm->pending_chunk = 0;
- }
- else
- store_read_chunk(&pm->this, pm->buffer, 8, 8);
-
- pm->buffer_count = 8;
- pm->buffer_position = 0;
-
- /* Check for something to modify or a terminator chunk. */
- len = png_get_uint_32(pm->buffer);
- chunk = png_get_uint_32(pm->buffer+4);
-
- /* Terminators first, they may have to be delayed for added
- * chunks
- */
- if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT ||
- chunk == CHUNK_IEND)
- {
- mod = pm->modifications;
-
- while (mod != NULL)
- {
- if ((mod->add == chunk ||
- (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) &&
- mod->modify_fn != NULL && !mod->modified && !mod->added)
- {
- /* Regardless of what the modify function does do not run
- * this again.
- */
- mod->added = 1;
-
- if ((*mod->modify_fn)(pm, mod, 1 /*add*/))
- {
- /* Reset the CRC on a new chunk */
- if (pm->buffer_count > 0)
- modifier_setbuffer(pm);
-
- else
- {
- pm->buffer_position = 0;
- mod->removed = 1;
- }
-
- /* The buffer has been filled with something (we assume)
- * so output this. Pend the current chunk.
- */
- pm->pending_len = len;
- pm->pending_chunk = chunk;
- break; /* out of while */
- }
- }
-
- mod = mod->next;
- }
-
- /* Don't do any further processing if the buffer was modified -
- * otherwise the code will end up modifying a chunk that was
- * just added.
- */
- if (mod != NULL)
- break; /* out of switch */
- }
-
- /* If we get to here then this chunk may need to be modified. To
- * do this it must be less than 1024 bytes in total size, otherwise
- * it just gets flushed.
- */
- if (len+12 <= sizeof pm->buffer)
- {
- size_t s = len+12-pm->buffer_count;
- store_read_chunk(&pm->this, pm->buffer+pm->buffer_count, s, s);
- pm->buffer_count = len+12;
-
- /* Check for a modification, else leave it be. */
- mod = pm->modifications;
- while (mod != NULL)
- {
- if (mod->chunk == chunk)
- {
- if (mod->modify_fn == NULL)
- {
- /* Remove this chunk */
- pm->buffer_count = pm->buffer_position = 0;
- mod->removed = 1;
- break; /* Terminate the while loop */
- }
-
- else if ((*mod->modify_fn)(pm, mod, 0))
- {
- mod->modified = 1;
- /* The chunk may have been removed: */
- if (pm->buffer_count == 0)
- {
- pm->buffer_position = 0;
- break;
- }
- modifier_setbuffer(pm);
- }
- }
-
- mod = mod->next;
- }
- }
-
- else
- pm->flush = len+12 - pm->buffer_count; /* data + crc */
-
- /* Take the data from the buffer (if there is any). */
- break;
- }
-
- /* Here to read from the modifier buffer (not directly from
- * the store, as in the flush case above.)
- */
- cb = pm->buffer_count - pm->buffer_position;
-
- if (cb > st)
- cb = st;
-
- memcpy(pb, pm->buffer + pm->buffer_position, cb);
- st -= cb;
- pb += cb;
- pm->buffer_position += cb;
- }
-}
-
-/* The callback: */
-static void PNGCBAPI
-modifier_read(png_structp ppIn, png_bytep pb, size_t st)
-{
- png_const_structp pp = ppIn;
- png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp));
-
- if (pm == NULL || pm->this.pread != pp)
- png_error(pp, "bad modifier_read call");
-
- modifier_read_imp(pm, pb, st);
-}
-
-/* Like store_progressive_read but the data is getting changed as we go so we
- * need a local buffer.
- */
-static void
-modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi)
-{
- if (pm->this.pread != pp || pm->this.current == NULL ||
- pm->this.next == NULL)
- png_error(pp, "store state damaged (progressive)");
-
- /* This is another Horowitz and Hill random noise generator. In this case
- * the aim is to stress the progressive reader with truly horrible variable
- * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers
- * is generated. We could probably just count from 1 to 32767 and get as
- * good a result.
- */
- for (;;)
- {
- static png_uint_32 noise = 1;
- size_t cb, cbAvail;
- png_byte buffer[512];
-
- /* Generate 15 more bits of stuff: */
- noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);
- cb = noise & 0x1ff;
-
- /* Check that this number of bytes are available (in the current buffer.)
- * (This doesn't quite work - the modifier might delete a chunk; unlikely
- * but possible, it doesn't happen at present because the modifier only
- * adds chunks to standard images.)
- */
- cbAvail = store_read_buffer_avail(&pm->this);
- if (pm->buffer_count > pm->buffer_position)
- cbAvail += pm->buffer_count - pm->buffer_position;
-
- if (cb > cbAvail)
- {
- /* Check for EOF: */
- if (cbAvail == 0)
- break;
-
- cb = cbAvail;
- }
-
- modifier_read_imp(pm, buffer, cb);
- png_process_data(pp, pi, buffer, cb);
- }
-
- /* Check the invariants at the end (if this fails it's a problem in this
- * file!)
- */
- if (pm->buffer_count > pm->buffer_position ||
- pm->this.next != &pm->this.current->data ||
- pm->this.readpos < pm->this.current->datacount)
- png_error(pp, "progressive read implementation error");
-}
-
-/* Set up a modifier. */
-static png_structp
-set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id,
- const char *name)
-{
- /* Do this first so that the modifier fields are cleared even if an error
- * happens allocating the png_struct. No allocation is done here so no
- * cleanup is required.
- */
- pm->state = modifier_start;
- pm->bit_depth = 0;
- pm->colour_type = 255;
-
- pm->pending_len = 0;
- pm->pending_chunk = 0;
- pm->flush = 0;
- pm->buffer_count = 0;
- pm->buffer_position = 0;
-
- return set_store_for_read(&pm->this, ppi, id, name);
-}
-
-
-/******************************** MODIFICATIONS *******************************/
-/* Standard modifications to add chunks. These do not require the _SUPPORTED
- * macros because the chunks can be there regardless of whether this specific
- * libpng supports them.
- */
-typedef struct gama_modification
-{
- png_modification this;
- png_fixed_point gamma;
-} gama_modification;
-
-static int
-gama_modify(png_modifier *pm, png_modification *me, int add)
-{
- UNUSED(add)
- /* This simply dumps the given gamma value into the buffer. */
- png_save_uint_32(pm->buffer, 4);
- png_save_uint_32(pm->buffer+4, CHUNK_gAMA);
- png_save_uint_32(pm->buffer+8, ((gama_modification*)me)->gamma);
- return 1;
-}
-
-static void
-gama_modification_init(gama_modification *me, png_modifier *pm, double gammad)
-{
- double g;
-
- modification_init(&me->this);
- me->this.chunk = CHUNK_gAMA;
- me->this.modify_fn = gama_modify;
- me->this.add = CHUNK_PLTE;
- g = fix(gammad);
- me->gamma = (png_fixed_point)g;
- me->this.next = pm->modifications;
- pm->modifications = &me->this;
-}
-
-typedef struct chrm_modification
-{
- png_modification this;
- const color_encoding *encoding;
- png_fixed_point wx, wy, rx, ry, gx, gy, bx, by;
-} chrm_modification;
-
-static int
-chrm_modify(png_modifier *pm, png_modification *me, int add)
-{
- UNUSED(add)
- /* As with gAMA this just adds the required cHRM chunk to the buffer. */
- png_save_uint_32(pm->buffer , 32);
- png_save_uint_32(pm->buffer+ 4, CHUNK_cHRM);
- png_save_uint_32(pm->buffer+ 8, ((chrm_modification*)me)->wx);
- png_save_uint_32(pm->buffer+12, ((chrm_modification*)me)->wy);
- png_save_uint_32(pm->buffer+16, ((chrm_modification*)me)->rx);
- png_save_uint_32(pm->buffer+20, ((chrm_modification*)me)->ry);
- png_save_uint_32(pm->buffer+24, ((chrm_modification*)me)->gx);
- png_save_uint_32(pm->buffer+28, ((chrm_modification*)me)->gy);
- png_save_uint_32(pm->buffer+32, ((chrm_modification*)me)->bx);
- png_save_uint_32(pm->buffer+36, ((chrm_modification*)me)->by);
- return 1;
-}
-
-static void
-chrm_modification_init(chrm_modification *me, png_modifier *pm,
- const color_encoding *encoding)
-{
- CIE_color white = white_point(encoding);
-
- /* Original end points: */
- me->encoding = encoding;
-
- /* Chromaticities (in fixed point): */
- me->wx = fix(chromaticity_x(white));
- me->wy = fix(chromaticity_y(white));
-
- me->rx = fix(chromaticity_x(encoding->red));
- me->ry = fix(chromaticity_y(encoding->red));
- me->gx = fix(chromaticity_x(encoding->green));
- me->gy = fix(chromaticity_y(encoding->green));
- me->bx = fix(chromaticity_x(encoding->blue));
- me->by = fix(chromaticity_y(encoding->blue));
-
- modification_init(&me->this);
- me->this.chunk = CHUNK_cHRM;
- me->this.modify_fn = chrm_modify;
- me->this.add = CHUNK_PLTE;
- me->this.next = pm->modifications;
- pm->modifications = &me->this;
-}
-
-typedef struct srgb_modification
-{
- png_modification this;
- png_byte intent;
-} srgb_modification;
-
-static int
-srgb_modify(png_modifier *pm, png_modification *me, int add)
-{
- UNUSED(add)
- /* As above, ignore add and just make a new chunk */
- png_save_uint_32(pm->buffer, 1);
- png_save_uint_32(pm->buffer+4, CHUNK_sRGB);
- pm->buffer[8] = ((srgb_modification*)me)->intent;
- return 1;
-}
-
-static void
-srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent)
-{
- modification_init(&me->this);
- me->this.chunk = CHUNK_sBIT;
-
- if (intent <= 3) /* if valid, else *delete* sRGB chunks */
- {
- me->this.modify_fn = srgb_modify;
- me->this.add = CHUNK_PLTE;
- me->intent = intent;
- }
-
- else
- {
- me->this.modify_fn = 0;
- me->this.add = 0;
- me->intent = 0;
- }
-
- me->this.next = pm->modifications;
- pm->modifications = &me->this;
-}
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-typedef struct sbit_modification
-{
- png_modification this;
- png_byte sbit;
-} sbit_modification;
-
-static int
-sbit_modify(png_modifier *pm, png_modification *me, int add)
-{
- png_byte sbit = ((sbit_modification*)me)->sbit;
- if (pm->bit_depth > sbit)
- {
- int cb = 0;
- switch (pm->colour_type)
- {
- case 0:
- cb = 1;
- break;
-
- case 2:
- case 3:
- cb = 3;
- break;
-
- case 4:
- cb = 2;
- break;
-
- case 6:
- cb = 4;
- break;
-
- default:
- png_error(pm->this.pread,
- "unexpected colour type in sBIT modification");
- }
-
- png_save_uint_32(pm->buffer, cb);
- png_save_uint_32(pm->buffer+4, CHUNK_sBIT);
-
- while (cb > 0)
- (pm->buffer+8)[--cb] = sbit;
-
- return 1;
- }
- else if (!add)
- {
- /* Remove the sBIT chunk */
- pm->buffer_count = pm->buffer_position = 0;
- return 1;
- }
- else
- return 0; /* do nothing */
-}
-
-static void
-sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit)
-{
- modification_init(&me->this);
- me->this.chunk = CHUNK_sBIT;
- me->this.modify_fn = sbit_modify;
- me->this.add = CHUNK_PLTE;
- me->sbit = sbit;
- me->this.next = pm->modifications;
- pm->modifications = &me->this;
-}
-#endif /* PNG_READ_GAMMA_SUPPORTED */
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-/***************************** STANDARD PNG FILES *****************************/
-/* Standard files - write and save standard files. */
-/* There are two basic forms of standard images. Those which attempt to have
- * all the possible pixel values (not possible for 16bpp images, but a range of
- * values are produced) and those which have a range of image sizes. The former
- * are used for testing transforms, in particular gamma correction and bit
- * reduction and increase. The latter are reserved for testing the behavior of
- * libpng with respect to 'odd' image sizes - particularly small images where
- * rows become 1 byte and interlace passes disappear.
- *
- * The first, most useful, set are the 'transform' images, the second set of
- * small images are the 'size' images.
- *
- * The transform files are constructed with rows which fit into a 1024 byte row
- * buffer. This makes allocation easier below. Further regardless of the file
- * format every row has 128 pixels (giving 1024 bytes for 64bpp formats).
- *
- * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed
- * and with an ID derived from the colour type, bit depth and interlace type
- * as above (FILEID). The width (128) and height (variable) are not stored in
- * the FILEID - instead the fields are set to 0, indicating a transform file.
- *
- * The size files ar constructed with rows a maximum of 128 bytes wide, allowing
- * a maximum width of 16 pixels (for the 64bpp case.) They also have a maximum
- * height of 16 rows. The width and height are stored in the FILEID and, being
- * non-zero, indicate a size file.
- *
- * Because the PNG filter code is typically the largest CPU consumer within
- * libpng itself there is a tendency to attempt to optimize it. This results in
- * special case code which needs to be validated. To cause this to happen the
- * 'size' images are made to use each possible filter, in so far as this is
- * possible for smaller images.
- *
- * For palette image (colour type 3) multiple transform images are stored with
- * the same bit depth to allow testing of more colour combinations -
- * particularly important for testing the gamma code because libpng uses a
- * different code path for palette images. For size images a single palette is
- * used.
- */
-
-/* Make a 'standard' palette. Because there are only 256 entries in a palette
- * (maximum) this actually makes a random palette in the hope that enough tests
- * will catch enough errors. (Note that the same palette isn't produced every
- * time for the same test - it depends on what previous tests have been run -
- * but a given set of arguments to pngvalid will always produce the same palette
- * at the same test! This is why pseudo-random number generators are useful for
- * testing.)
- *
- * The store must be open for write when this is called, otherwise an internal
- * error will occur. This routine contains its own magic number seed, so the
- * palettes generated don't change if there are intervening errors (changing the
- * calls to the store_mark seed.)
- */
-static store_palette_entry *
-make_standard_palette(png_store* ps, int npalette, int do_tRNS)
-{
- static png_uint_32 palette_seed[2] = { 0x87654321, 9 };
-
- int i = 0;
- png_byte values[256][4];
-
- /* Always put in black and white plus the six primary and secondary colors.
- */
- for (; i<8; ++i)
- {
- values[i][1] = (png_byte)((i&1) ? 255U : 0U);
- values[i][2] = (png_byte)((i&2) ? 255U : 0U);
- values[i][3] = (png_byte)((i&4) ? 255U : 0U);
- }
-
- /* Then add 62 grays (one quarter of the remaining 256 slots). */
- {
- int j = 0;
- png_byte random_bytes[4];
- png_byte need[256];
-
- need[0] = 0; /*got black*/
- memset(need+1, 1, (sizeof need)-2); /*need these*/
- need[255] = 0; /*but not white*/
-
- while (i<70)
- {
- png_byte b;
-
- if (j==0)
- {
- make_four_random_bytes(palette_seed, random_bytes);
- j = 4;
- }
-
- b = random_bytes[--j];
- if (need[b])
- {
- values[i][1] = b;
- values[i][2] = b;
- values[i++][3] = b;
- }
- }
- }
-
- /* Finally add 192 colors at random - don't worry about matches to things we
- * already have, chance is less than 1/65536. Don't worry about grays,
- * chance is the same, so we get a duplicate or extra gray less than 1 time
- * in 170.
- */
- for (; i<256; ++i)
- make_four_random_bytes(palette_seed, values[i]);
-
- /* Fill in the alpha values in the first byte. Just use all possible values
- * (0..255) in an apparently random order:
- */
- {
- store_palette_entry *palette;
- png_byte selector[4];
-
- make_four_random_bytes(palette_seed, selector);
-
- if (do_tRNS)
- for (i=0; i<256; ++i)
- values[i][0] = (png_byte)(i ^ selector[0]);
-
- else
- for (i=0; i<256; ++i)
- values[i][0] = 255; /* no transparency/tRNS chunk */
-
- /* 'values' contains 256 ARGB values, but we only need 'npalette'.
- * 'npalette' will always be a power of 2: 2, 4, 16 or 256. In the low
- * bit depth cases select colors at random, else it is difficult to have
- * a set of low bit depth palette test with any chance of a reasonable
- * range of colors. Do this by randomly permuting values into the low
- * 'npalette' entries using an XOR mask generated here. This also
- * permutes the npalette == 256 case in a potentially useful way (there is
- * no relationship between palette index and the color value therein!)
- */
- palette = store_write_palette(ps, npalette);
-
- for (i=0; i<npalette; ++i)
- {
- palette[i].alpha = values[i ^ selector[1]][0];
- palette[i].red = values[i ^ selector[1]][1];
- palette[i].green = values[i ^ selector[1]][2];
- palette[i].blue = values[i ^ selector[1]][3];
- }
-
- return palette;
- }
-}
-
-/* Initialize a standard palette on a write stream. The 'do_tRNS' argument
- * indicates whether or not to also set the tRNS chunk.
- */
-/* TODO: the png_structp here can probably be 'const' in the future */
-static void
-init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette,
- int do_tRNS)
-{
- store_palette_entry *ppal = make_standard_palette(ps, npalette, do_tRNS);
-
- {
- int i;
- png_color palette[256];
-
- /* Set all entries to detect overread errors. */
- for (i=0; i<npalette; ++i)
- {
- palette[i].red = ppal[i].red;
- palette[i].green = ppal[i].green;
- palette[i].blue = ppal[i].blue;
- }
-
- /* Just in case fill in the rest with detectable values: */
- for (; i<256; ++i)
- palette[i].red = palette[i].green = palette[i].blue = 42;
-
- png_set_PLTE(pp, pi, palette, npalette);
- }
-
- if (do_tRNS)
- {
- int i, j;
- png_byte tRNS[256];
-
- /* Set all the entries, but skip trailing opaque entries */
- for (i=j=0; i<npalette; ++i)
- if ((tRNS[i] = ppal[i].alpha) < 255)
- j = i+1;
-
- /* Fill in the remainder with a detectable value: */
- for (; i<256; ++i)
- tRNS[i] = 24;
-
-#ifdef PNG_WRITE_tRNS_SUPPORTED
- if (j > 0)
- png_set_tRNS(pp, pi, tRNS, j, 0/*color*/);
-#endif
- }
-}
-
-#ifdef PNG_WRITE_tRNS_SUPPORTED
-static void
-set_random_tRNS(png_structp pp, png_infop pi, png_byte colour_type,
- int bit_depth)
-{
- /* To make this useful the tRNS color needs to match at least one pixel.
- * Random values are fine for gray, including the 16-bit case where we know
- * that the test image contains all the gray values. For RGB we need more
- * method as only 65536 different RGB values are generated.
- */
- png_color_16 tRNS;
- png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);
-
- R8(tRNS); /* makes unset fields random */
-
- if (colour_type & 2/*RGB*/)
- {
- if (bit_depth == 8)
- {
- tRNS.red = random_u16();
- tRNS.green = random_u16();
- tRNS.blue = tRNS.red ^ tRNS.green;
- tRNS.red &= mask;
- tRNS.green &= mask;
- tRNS.blue &= mask;
- }
-
- else /* bit_depth == 16 */
- {
- tRNS.red = random_u16();
- tRNS.green = (png_uint_16)(tRNS.red * 257);
- tRNS.blue = (png_uint_16)(tRNS.green * 17);
- }
- }
-
- else
- {
- tRNS.gray = random_u16();
- tRNS.gray &= mask;
- }
-
- png_set_tRNS(pp, pi, NULL, 0, &tRNS);
-}
-#endif
-
-/* The number of passes is related to the interlace type. There was no libpng
- * API to determine this prior to 1.5, so we need an inquiry function:
- */
-static int
-npasses_from_interlace_type(png_const_structp pp, int interlace_type)
-{
- switch (interlace_type)
- {
- default:
- png_error(pp, "invalid interlace type");
-
- case PNG_INTERLACE_NONE:
- return 1;
-
- case PNG_INTERLACE_ADAM7:
- return PNG_INTERLACE_ADAM7_PASSES;
- }
-}
-
-static unsigned int
-bit_size(png_const_structp pp, png_byte colour_type, png_byte bit_depth)
-{
- switch (colour_type)
- {
- default: png_error(pp, "invalid color type");
-
- case 0: return bit_depth;
-
- case 2: return 3*bit_depth;
-
- case 3: return bit_depth;
-
- case 4: return 2*bit_depth;
-
- case 6: return 4*bit_depth;
- }
-}
-
-#define TRANSFORM_WIDTH 128U
-#define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U)
-#define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */
-#define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */
-#define SIZE_HEIGHTMAX 16 /* Maximum range of size images */
-
-static size_t
-transform_rowsize(png_const_structp pp, png_byte colour_type,
- png_byte bit_depth)
-{
- return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8;
-}
-
-/* transform_width(pp, colour_type, bit_depth) current returns the same number
- * every time, so just use a macro:
- */
-#define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH
-
-static png_uint_32
-transform_height(png_const_structp pp, png_byte colour_type, png_byte bit_depth)
-{
- switch (bit_size(pp, colour_type, bit_depth))
- {
- case 1:
- case 2:
- case 4:
- return 1; /* Total of 128 pixels */
-
- case 8:
- return 2; /* Total of 256 pixels/bytes */
-
- case 16:
- return 512; /* Total of 65536 pixels */
-
- case 24:
- case 32:
- return 512; /* 65536 pixels */
-
- case 48:
- case 64:
- return 2048;/* 4 x 65536 pixels. */
-# define TRANSFORM_HEIGHTMAX 2048
-
- default:
- return 0; /* Error, will be caught later */
- }
-}
-
-#ifdef PNG_READ_SUPPORTED
-/* The following can only be defined here, now we have the definitions
- * of the transform image sizes.
- */
-static png_uint_32
-standard_width(png_const_structp pp, png_uint_32 id)
-{
- png_uint_32 width = WIDTH_FROM_ID(id);
- UNUSED(pp)
-
- if (width == 0)
- width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
-
- return width;
-}
-
-static png_uint_32
-standard_height(png_const_structp pp, png_uint_32 id)
-{
- png_uint_32 height = HEIGHT_FROM_ID(id);
-
- if (height == 0)
- height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
-
- return height;
-}
-
-static png_uint_32
-standard_rowsize(png_const_structp pp, png_uint_32 id)
-{
- png_uint_32 width = standard_width(pp, id);
-
- /* This won't overflow: */
- width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
- return (width + 7) / 8;
-}
-#endif /* PNG_READ_SUPPORTED */
-
-static void
-transform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX],
- png_byte colour_type, png_byte bit_depth, png_uint_32 y)
-{
- png_uint_32 v = y << 7;
- png_uint_32 i = 0;
-
- switch (bit_size(pp, colour_type, bit_depth))
- {
- case 1:
- while (i<128/8) buffer[i] = (png_byte)(v & 0xff), v += 17, ++i;
- return;
-
- case 2:
- while (i<128/4) buffer[i] = (png_byte)(v & 0xff), v += 33, ++i;
- return;
-
- case 4:
- while (i<128/2) buffer[i] = (png_byte)(v & 0xff), v += 65, ++i;
- return;
-
- case 8:
- /* 256 bytes total, 128 bytes in each row set as follows: */
- while (i<128) buffer[i] = (png_byte)(v & 0xff), ++v, ++i;
- return;
-
- case 16:
- /* Generate all 65536 pixel values in order, which includes the 8 bit
- * GA case as well as the 16 bit G case.
- */
- while (i<128)
- {
- buffer[2*i] = (png_byte)((v>>8) & 0xff);
- buffer[2*i+1] = (png_byte)(v & 0xff);
- ++v;
- ++i;
- }
-
- return;
-
- case 24:
- /* 65535 pixels, but rotate the values. */
- while (i<128)
- {
- /* Three bytes per pixel, r, g, b, make b by r^g */
- buffer[3*i+0] = (png_byte)((v >> 8) & 0xff);
- buffer[3*i+1] = (png_byte)(v & 0xff);
- buffer[3*i+2] = (png_byte)(((v >> 8) ^ v) & 0xff);
- ++v;
- ++i;
- }
-
- return;
-
- case 32:
- /* 65535 pixels, r, g, b, a; just replicate */
- while (i<128)
- {
- buffer[4*i+0] = (png_byte)((v >> 8) & 0xff);
- buffer[4*i+1] = (png_byte)(v & 0xff);
- buffer[4*i+2] = (png_byte)((v >> 8) & 0xff);
- buffer[4*i+3] = (png_byte)(v & 0xff);
- ++v;
- ++i;
- }
-
- return;
-
- case 48:
- /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at
- * each pixel, g increase by 257 (0x101) and 'b' by 0x1111:
- */
- while (i<128)
- {
- png_uint_32 t = v++;
- buffer[6*i+0] = (png_byte)((t >> 8) & 0xff);
- buffer[6*i+1] = (png_byte)(t & 0xff);
- t *= 257;
- buffer[6*i+2] = (png_byte)((t >> 8) & 0xff);
- buffer[6*i+3] = (png_byte)(t & 0xff);
- t *= 17;
- buffer[6*i+4] = (png_byte)((t >> 8) & 0xff);
- buffer[6*i+5] = (png_byte)(t & 0xff);
- ++i;
- }
-
- return;
-
- case 64:
- /* As above in the 32 bit case. */
- while (i<128)
- {
- png_uint_32 t = v++;
- buffer[8*i+0] = (png_byte)((t >> 8) & 0xff);
- buffer[8*i+1] = (png_byte)(t & 0xff);
- buffer[8*i+4] = (png_byte)((t >> 8) & 0xff);
- buffer[8*i+5] = (png_byte)(t & 0xff);
- t *= 257;
- buffer[8*i+2] = (png_byte)((t >> 8) & 0xff);
- buffer[8*i+3] = (png_byte)(t & 0xff);
- buffer[8*i+6] = (png_byte)((t >> 8) & 0xff);
- buffer[8*i+7] = (png_byte)(t & 0xff);
- ++i;
- }
- return;
-
- default:
- break;
- }
-
- png_error(pp, "internal error");
-}
-
-/* This is just to do the right cast - could be changed to a function to check
- * 'bd' but there isn't much point.
- */
-#define DEPTH(bd) ((png_byte)(1U << (bd)))
-
-/* This is just a helper for compiling on minimal systems with no write
- * interlacing support. If there is no write interlacing we can't generate test
- * cases with interlace:
- */
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-# define INTERLACE_LAST PNG_INTERLACE_LAST
-# define check_interlace_type(type) ((void)(type))
-# define set_write_interlace_handling(pp,type) png_set_interlace_handling(pp)
-# define do_own_interlace 0
-#elif PNG_LIBPNG_VER < 10700
-# define set_write_interlace_handling(pp,type) (1)
-static void
-check_interlace_type(int const interlace_type)
-{
- /* Prior to 1.7.0 libpng does not support the write of an interlaced image
- * unless PNG_WRITE_INTERLACING_SUPPORTED, even with do_interlace so the
- * code here does the pixel interlace itself, so:
- */
- if (interlace_type != PNG_INTERLACE_NONE)
- {
- /* This is an internal error - --interlace tests should be skipped, not
- * attempted.
- */
- fprintf(stderr, "pngvalid: no interlace support\n");
- exit(99);
- }
-}
-# define INTERLACE_LAST (PNG_INTERLACE_NONE+1)
-# define do_own_interlace 0
-#else /* libpng 1.7+ */
-# define set_write_interlace_handling(pp,type)\
- npasses_from_interlace_type(pp,type)
-# define check_interlace_type(type) ((void)(type))
-# define INTERLACE_LAST PNG_INTERLACE_LAST
-# define do_own_interlace 1
-#endif /* WRITE_INTERLACING tests */
-
-#if PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED
-# define CAN_WRITE_INTERLACE 1
-#else
-# define CAN_WRITE_INTERLACE 0
-#endif
-
-/* Do the same thing for read interlacing; this controls whether read tests do
- * their own de-interlace or use libpng.
- */
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-# define do_read_interlace 0
-#else /* no libpng read interlace support */
-# define do_read_interlace 1
-#endif
-/* The following two routines use the PNG interlace support macros from
- * png.h to interlace or deinterlace rows.
- */
-static void
-interlace_row(png_bytep buffer, png_const_bytep imageRow,
- unsigned int pixel_size, png_uint_32 w, int pass, int littleendian)
-{
- png_uint_32 xin, xout, xstep;
-
- /* Note that this can, trivially, be optimized to a memcpy on pass 7, the
- * code is presented this way to make it easier to understand. In practice
- * consult the code in the libpng source to see other ways of doing this.
- *
- * It is OK for buffer and imageRow to be identical, because 'xin' moves
- * faster than 'xout' and we copy up.
- */
- xin = PNG_PASS_START_COL(pass);
- xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
-
- for (xout=0; xin<w; xin+=xstep)
- {
- pixel_copy(buffer, xout, imageRow, xin, pixel_size, littleendian);
- ++xout;
- }
-}
-
-#ifdef PNG_READ_SUPPORTED
-static void
-deinterlace_row(png_bytep buffer, png_const_bytep row,
- unsigned int pixel_size, png_uint_32 w, int pass, int littleendian)
-{
- /* The inverse of the above, 'row' is part of row 'y' of the output image,
- * in 'buffer'. The image is 'w' wide and this is pass 'pass', distribute
- * the pixels of row into buffer and return the number written (to allow
- * this to be checked).
- */
- png_uint_32 xin, xout, xstep;
-
- xout = PNG_PASS_START_COL(pass);
- xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
-
- for (xin=0; xout<w; xout+=xstep)
- {
- pixel_copy(buffer, xout, row, xin, pixel_size, littleendian);
- ++xin;
- }
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/* Make a standardized image given an image colour type, bit depth and
- * interlace type. The standard images have a very restricted range of
- * rows and heights and are used for testing transforms rather than image
- * layout details. See make_size_images below for a way to make images
- * that test odd sizes along with the libpng interlace handling.
- */
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-static void
-choose_random_filter(png_structp pp, int start)
-{
- /* Choose filters randomly except that on the very first row ensure that
- * there is at least one previous row filter.
- */
- int filters = PNG_ALL_FILTERS & random_mod(256U);
-
- /* There may be no filters; skip the setting. */
- if (filters != 0)
- {
- if (start && filters < PNG_FILTER_UP)
- filters |= PNG_FILTER_UP;
-
- png_set_filter(pp, 0/*method*/, filters);
- }
-}
-#else /* !WRITE_FILTER */
-# define choose_random_filter(pp, start) ((void)0)
-#endif /* !WRITE_FILTER */
-
-static void
-make_transform_image(png_store* const ps, png_byte const colour_type,
- png_byte const bit_depth, unsigned int palette_number,
- int interlace_type, png_const_charp name)
-{
- context(ps, fault);
-
- check_interlace_type(interlace_type);
-
- Try
- {
- png_infop pi;
- png_structp pp = set_store_for_write(ps, &pi, name);
- png_uint_32 h, w;
-
- /* In the event of a problem return control to the Catch statement below
- * to do the clean up - it is not possible to 'return' directly from a Try
- * block.
- */
- if (pp == NULL)
- Throw ps;
-
- w = transform_width(pp, colour_type, bit_depth);
- h = transform_height(pp, colour_type, bit_depth);
-
- png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
-#ifdef PNG_TEXT_SUPPORTED
-# if defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED)
-# define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_zTXt
-# else
-# define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_NONE
-# endif
- {
- static char key[] = "image name"; /* must be writeable */
- size_t pos;
- png_text text;
- char copy[FILE_NAME_SIZE];
-
- /* Use a compressed text string to test the correct interaction of text
- * compression and IDAT compression.
- */
- text.compression = TEXT_COMPRESSION;
- text.key = key;
- /* Yuck: the text must be writable! */
- pos = safecat(copy, sizeof copy, 0, ps->wname);
- text.text = copy;
- text.text_length = pos;
- text.itxt_length = 0;
- text.lang = 0;
- text.lang_key = 0;
-
- png_set_text(pp, pi, &text, 1);
- }
-#endif
-
- if (colour_type == 3) /* palette */
- init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/);
-
-# ifdef PNG_WRITE_tRNS_SUPPORTED
- else if (palette_number)
- set_random_tRNS(pp, pi, colour_type, bit_depth);
-# endif
-
- png_write_info(pp, pi);
-
- if (png_get_rowbytes(pp, pi) !=
- transform_rowsize(pp, colour_type, bit_depth))
- png_error(pp, "transform row size incorrect");
-
- else
- {
- /* Somewhat confusingly this must be called *after* png_write_info
- * because if it is called before, the information in *pp has not been
- * updated to reflect the interlaced image.
- */
- int npasses = set_write_interlace_handling(pp, interlace_type);
- int pass;
-
- if (npasses != npasses_from_interlace_type(pp, interlace_type))
- png_error(pp, "write: png_set_interlace_handling failed");
-
- for (pass=0; pass<npasses; ++pass)
- {
- png_uint_32 y;
-
- /* do_own_interlace is a pre-defined boolean (a #define) which is
- * set if we have to work out the interlaced rows here.
- */
- for (y=0; y<h; ++y)
- {
- png_byte buffer[TRANSFORM_ROWMAX];
-
- transform_row(pp, buffer, colour_type, bit_depth, y);
-
-# if do_own_interlace
- /* If do_own_interlace *and* the image is interlaced we need a
- * reduced interlace row; this may be reduced to empty.
- */
- if (interlace_type == PNG_INTERLACE_ADAM7)
- {
- /* The row must not be written if it doesn't exist, notice
- * that there are two conditions here, either the row isn't
- * ever in the pass or the row would be but isn't wide
- * enough to contribute any pixels. In fact the wPass test
- * can be used to skip the whole y loop in this case.
- */
- if (PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
- PNG_PASS_COLS(w, pass) > 0)
- interlace_row(buffer, buffer,
- bit_size(pp, colour_type, bit_depth), w, pass,
- 0/*data always bigendian*/);
- else
- continue;
- }
-# endif /* do_own_interlace */
-
- choose_random_filter(pp, pass == 0 && y == 0);
- png_write_row(pp, buffer);
- }
- }
- }
-
-#ifdef PNG_TEXT_SUPPORTED
- {
- static char key[] = "end marker";
- static char comment[] = "end";
- png_text text;
-
- /* Use a compressed text string to test the correct interaction of text
- * compression and IDAT compression.
- */
- text.compression = TEXT_COMPRESSION;
- text.key = key;
- text.text = comment;
- text.text_length = (sizeof comment)-1;
- text.itxt_length = 0;
- text.lang = 0;
- text.lang_key = 0;
-
- png_set_text(pp, pi, &text, 1);
- }
-#endif
-
- png_write_end(pp, pi);
-
- /* And store this under the appropriate id, then clean up. */
- store_storefile(ps, FILEID(colour_type, bit_depth, palette_number,
- interlace_type, 0, 0, 0));
-
- store_write_reset(ps);
- }
-
- Catch(fault)
- {
- /* Use the png_store returned by the exception. This may help the compiler
- * because 'ps' is not used in this branch of the setjmp. Note that fault
- * and ps will always be the same value.
- */
- store_write_reset(fault);
- }
-}
-
-static void
-make_transform_images(png_modifier *pm)
-{
- png_byte colour_type = 0;
- png_byte bit_depth = 0;
- unsigned int palette_number = 0;
-
- /* This is in case of errors. */
- safecat(pm->this.test, sizeof pm->this.test, 0, "make standard images");
-
- /* Use next_format to enumerate all the combinations we test, including
- * generating multiple low bit depth palette images. Non-A images (palette
- * and direct) are created with and without tRNS chunks.
- */
- while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1))
- {
- int interlace_type;
-
- for (interlace_type = PNG_INTERLACE_NONE;
- interlace_type < INTERLACE_LAST; ++interlace_type)
- {
- char name[FILE_NAME_SIZE];
-
- standard_name(name, sizeof name, 0, colour_type, bit_depth,
- palette_number, interlace_type, 0, 0, do_own_interlace);
- make_transform_image(&pm->this, colour_type, bit_depth, palette_number,
- interlace_type, name);
- }
- }
-}
-
-/* Build a single row for the 'size' test images; this fills in only the
- * first bit_width bits of the sample row.
- */
-static void
-size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y)
-{
- /* height is in the range 1 to 16, so: */
- y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4);
- /* the following ensures bits are set in small images: */
- y ^= 0xA5;
-
- while (bit_width >= 8)
- *buffer++ = (png_byte)y++, bit_width -= 8;
-
- /* There may be up to 7 remaining bits, these go in the most significant
- * bits of the byte.
- */
- if (bit_width > 0)
- {
- png_uint_32 mask = (1U<<(8-bit_width))-1;
- *buffer = (png_byte)((*buffer & mask) | (y & ~mask));
- }
-}
-
-static void
-make_size_image(png_store* const ps, png_byte const colour_type,
- png_byte const bit_depth, int const interlace_type,
- png_uint_32 const w, png_uint_32 const h,
- int const do_interlace)
-{
- context(ps, fault);
-
- check_interlace_type(interlace_type);
-
- Try
- {
- png_infop pi;
- png_structp pp;
- unsigned int pixel_size;
-
- /* Make a name and get an appropriate id for the store: */
- char name[FILE_NAME_SIZE];
- png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/,
- interlace_type, w, h, do_interlace);
-
- standard_name_from_id(name, sizeof name, 0, id);
- pp = set_store_for_write(ps, &pi, name);
-
- /* In the event of a problem return control to the Catch statement below
- * to do the clean up - it is not possible to 'return' directly from a Try
- * block.
- */
- if (pp == NULL)
- Throw ps;
-
- png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
-#ifdef PNG_TEXT_SUPPORTED
- {
- static char key[] = "image name"; /* must be writeable */
- size_t pos;
- png_text text;
- char copy[FILE_NAME_SIZE];
-
- /* Use a compressed text string to test the correct interaction of text
- * compression and IDAT compression.
- */
- text.compression = TEXT_COMPRESSION;
- text.key = key;
- /* Yuck: the text must be writable! */
- pos = safecat(copy, sizeof copy, 0, ps->wname);
- text.text = copy;
- text.text_length = pos;
- text.itxt_length = 0;
- text.lang = 0;
- text.lang_key = 0;
-
- png_set_text(pp, pi, &text, 1);
- }
-#endif
-
- if (colour_type == 3) /* palette */
- init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);
-
- png_write_info(pp, pi);
-
- /* Calculate the bit size, divide by 8 to get the byte size - this won't
- * overflow because we know the w values are all small enough even for
- * a system where 'unsigned int' is only 16 bits.
- */
- pixel_size = bit_size(pp, colour_type, bit_depth);
- if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8)
- png_error(pp, "size row size incorrect");
-
- else
- {
- int npasses = npasses_from_interlace_type(pp, interlace_type);
- png_uint_32 y;
- int pass;
- png_byte image[16][SIZE_ROWMAX];
-
- /* To help consistent error detection make the parts of this buffer
- * that aren't set below all '1':
- */
- memset(image, 0xff, sizeof image);
-
- if (!do_interlace &&
- npasses != set_write_interlace_handling(pp, interlace_type))
- png_error(pp, "write: png_set_interlace_handling failed");
-
- /* Prepare the whole image first to avoid making it 7 times: */
- for (y=0; y<h; ++y)
- size_row(image[y], w * pixel_size, y);
-
- for (pass=0; pass<npasses; ++pass)
- {
- /* The following two are for checking the macros: */
- png_uint_32 wPass = PNG_PASS_COLS(w, pass);
-
- /* If do_interlace is set we don't call png_write_row for every
- * row because some of them are empty. In fact, for a 1x1 image,
- * most of them are empty!
- */
- for (y=0; y<h; ++y)
- {
- png_const_bytep row = image[y];
- png_byte tempRow[SIZE_ROWMAX];
-
- /* If do_interlace *and* the image is interlaced we
- * need a reduced interlace row; this may be reduced
- * to empty.
- */
- if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7)
- {
- /* The row must not be written if it doesn't exist, notice
- * that there are two conditions here, either the row isn't
- * ever in the pass or the row would be but isn't wide
- * enough to contribute any pixels. In fact the wPass test
- * can be used to skip the whole y loop in this case.
- */
- if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0)
- {
- /* Set to all 1's for error detection (libpng tends to
- * set unset things to 0).
- */
- memset(tempRow, 0xff, sizeof tempRow);
- interlace_row(tempRow, row, pixel_size, w, pass,
- 0/*data always bigendian*/);
- row = tempRow;
- }
- else
- continue;
- }
-
-# ifdef PNG_WRITE_FILTER_SUPPORTED
- /* Only get to here if the row has some pixels in it, set the
- * filters to 'all' for the very first row and thereafter to a
- * single filter. It isn't well documented, but png_set_filter
- * does accept a filter number (per the spec) as well as a bit
- * mask.
- *
- * The code now uses filters at random, except that on the first
- * row of an image it ensures that a previous row filter is in
- * the set so that libpng allocates the row buffer.
- */
- {
- int filters = 8 << random_mod(PNG_FILTER_VALUE_LAST);
-
- if (pass == 0 && y == 0 &&
- (filters < PNG_FILTER_UP || w == 1U))
- filters |= PNG_FILTER_UP;
-
- png_set_filter(pp, 0/*method*/, filters);
- }
-# endif
-
- png_write_row(pp, row);
- }
- }
- }
-
-#ifdef PNG_TEXT_SUPPORTED
- {
- static char key[] = "end marker";
- static char comment[] = "end";
- png_text text;
-
- /* Use a compressed text string to test the correct interaction of text
- * compression and IDAT compression.
- */
- text.compression = TEXT_COMPRESSION;
- text.key = key;
- text.text = comment;
- text.text_length = (sizeof comment)-1;
- text.itxt_length = 0;
- text.lang = 0;
- text.lang_key = 0;
-
- png_set_text(pp, pi, &text, 1);
- }
-#endif
-
- png_write_end(pp, pi);
-
- /* And store this under the appropriate id, then clean up. */
- store_storefile(ps, id);
-
- store_write_reset(ps);
- }
-
- Catch(fault)
- {
- /* Use the png_store returned by the exception. This may help the compiler
- * because 'ps' is not used in this branch of the setjmp. Note that fault
- * and ps will always be the same value.
- */
- store_write_reset(fault);
- }
-}
-
-static void
-make_size(png_store* const ps, png_byte const colour_type, int bdlo,
- int const bdhi)
-{
- for (; bdlo <= bdhi; ++bdlo)
- {
- png_uint_32 width;
-
- for (width = 1; width <= 16; ++width)
- {
- png_uint_32 height;
-
- for (height = 1; height <= 16; ++height)
- {
- /* The four combinations of DIY interlace and interlace or not -
- * no interlace + DIY should be identical to no interlace with
- * libpng doing it.
- */
- make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
- width, height, 0);
- make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
- width, height, 1);
-# ifdef PNG_WRITE_INTERLACING_SUPPORTED
- make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
- width, height, 0);
-# endif
-# if CAN_WRITE_INTERLACE
- /* 1.7.0 removes the hack that prevented app write of an interlaced
- * image if WRITE_INTERLACE was not supported
- */
- make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
- width, height, 1);
-# endif
- }
- }
- }
-}
-
-static void
-make_size_images(png_store *ps)
-{
- /* This is in case of errors. */
- safecat(ps->test, sizeof ps->test, 0, "make size images");
-
- /* Arguments are colour_type, low bit depth, high bit depth
- */
- make_size(ps, 0, 0, WRITE_BDHI);
- make_size(ps, 2, 3, WRITE_BDHI);
- make_size(ps, 3, 0, 3 /*palette: max 8 bits*/);
- make_size(ps, 4, 3, WRITE_BDHI);
- make_size(ps, 6, 3, WRITE_BDHI);
-}
-
-#ifdef PNG_READ_SUPPORTED
-/* Return a row based on image id and 'y' for checking: */
-static void
-standard_row(png_const_structp pp, png_byte std[STANDARD_ROWMAX],
- png_uint_32 id, png_uint_32 y)
-{
- if (WIDTH_FROM_ID(id) == 0)
- transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y);
- else
- size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id),
- DEPTH_FROM_ID(id)), y);
-}
-#endif /* PNG_READ_SUPPORTED */
-
-/* Tests - individual test cases */
-/* Like 'make_standard' but errors are deliberately introduced into the calls
- * to ensure that they get detected - it should not be possible to write an
- * invalid image with libpng!
- */
-/* TODO: the 'set' functions can probably all be made to take a
- * png_const_structp rather than a modifiable one.
- */
-#ifdef PNG_WARNINGS_SUPPORTED
-static void
-sBIT0_error_fn(png_structp pp, png_infop pi)
-{
- /* 0 is invalid... */
- png_color_8 bad;
- bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0;
- png_set_sBIT(pp, pi, &bad);
-}
-
-static void
-sBIT_error_fn(png_structp pp, png_infop pi)
-{
- png_byte bit_depth;
- png_color_8 bad;
-
- if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE)
- bit_depth = 8;
-
- else
- bit_depth = png_get_bit_depth(pp, pi);
-
- /* Now we know the bit depth we can easily generate an invalid sBIT entry */
- bad.red = bad.green = bad.blue = bad.gray = bad.alpha =
- (png_byte)(bit_depth+1);
- png_set_sBIT(pp, pi, &bad);
-}
-
-static const struct
-{
- void (*fn)(png_structp, png_infop);
- const char *msg;
- unsigned int warning :1; /* the error is a warning... */
-} error_test[] =
- {
- /* no warnings makes these errors undetectable prior to 1.7.0 */
- { sBIT0_error_fn, "sBIT(0): failed to detect error",
- PNG_LIBPNG_VER < 10700 },
-
- { sBIT_error_fn, "sBIT(too big): failed to detect error",
- PNG_LIBPNG_VER < 10700 },
- };
-
-static void
-make_error(png_store* const ps, png_byte const colour_type,
- png_byte bit_depth, int interlace_type, int test, png_const_charp name)
-{
- context(ps, fault);
-
- check_interlace_type(interlace_type);
-
- Try
- {
- png_infop pi;
- png_structp pp = set_store_for_write(ps, &pi, name);
- png_uint_32 w, h;
- gnu_volatile(pp)
-
- if (pp == NULL)
- Throw ps;
-
- w = transform_width(pp, colour_type, bit_depth);
- gnu_volatile(w)
- h = transform_height(pp, colour_type, bit_depth);
- gnu_volatile(h)
- png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
- if (colour_type == 3) /* palette */
- init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);
-
- /* Time for a few errors; these are in various optional chunks, the
- * standard tests test the standard chunks pretty well.
- */
-# define exception__prev exception_prev_1
-# define exception__env exception_env_1
- Try
- {
- gnu_volatile(exception__prev)
-
- /* Expect this to throw: */
- ps->expect_error = !error_test[test].warning;
- ps->expect_warning = error_test[test].warning;
- ps->saw_warning = 0;
- error_test[test].fn(pp, pi);
-
- /* Normally the error is only detected here: */
- png_write_info(pp, pi);
-
- /* And handle the case where it was only a warning: */
- if (ps->expect_warning && ps->saw_warning)
- Throw ps;
-
- /* If we get here there is a problem, we have success - no error or
- * no warning - when we shouldn't have success. Log an error.
- */
- store_log(ps, pp, error_test[test].msg, 1 /*error*/);
- }
-
- Catch (fault)
- { /* expected exit */
- }
-#undef exception__prev
-#undef exception__env
-
- /* And clear these flags */
- ps->expect_warning = 0;
-
- if (ps->expect_error)
- ps->expect_error = 0;
-
- else
- {
- /* Now write the whole image, just to make sure that the detected, or
- * undetected, error has not created problems inside libpng. This
- * doesn't work if there was a png_error in png_write_info because that
- * can abort before PLTE was written.
- */
- if (png_get_rowbytes(pp, pi) !=
- transform_rowsize(pp, colour_type, bit_depth))
- png_error(pp, "row size incorrect");
-
- else
- {
- int npasses = set_write_interlace_handling(pp, interlace_type);
- int pass;
-
- if (npasses != npasses_from_interlace_type(pp, interlace_type))
- png_error(pp, "write: png_set_interlace_handling failed");
-
- for (pass=0; pass<npasses; ++pass)
- {
- png_uint_32 y;
-
- for (y=0; y<h; ++y)
- {
- png_byte buffer[TRANSFORM_ROWMAX];
-
- transform_row(pp, buffer, colour_type, bit_depth, y);
-
-# if do_own_interlace
- /* If do_own_interlace *and* the image is interlaced we
- * need a reduced interlace row; this may be reduced to
- * empty.
- */
- if (interlace_type == PNG_INTERLACE_ADAM7)
- {
- /* The row must not be written if it doesn't exist,
- * notice that there are two conditions here, either the
- * row isn't ever in the pass or the row would be but
- * isn't wide enough to contribute any pixels. In fact
- * the wPass test can be used to skip the whole y loop
- * in this case.
- */
- if (PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
- PNG_PASS_COLS(w, pass) > 0)
- interlace_row(buffer, buffer,
- bit_size(pp, colour_type, bit_depth), w, pass,
- 0/*data always bigendian*/);
- else
- continue;
- }
-# endif /* do_own_interlace */
-
- png_write_row(pp, buffer);
- }
- }
- } /* image writing */
-
- png_write_end(pp, pi);
- }
-
- /* The following deletes the file that was just written. */
- store_write_reset(ps);
- }
-
- Catch(fault)
- {
- store_write_reset(fault);
- }
-}
-
-static int
-make_errors(png_modifier* const pm, png_byte const colour_type,
- int bdlo, int const bdhi)
-{
- for (; bdlo <= bdhi; ++bdlo)
- {
- int interlace_type;
-
- for (interlace_type = PNG_INTERLACE_NONE;
- interlace_type < INTERLACE_LAST; ++interlace_type)
- {
- unsigned int test;
- char name[FILE_NAME_SIZE];
-
- standard_name(name, sizeof name, 0, colour_type, 1<<bdlo, 0,
- interlace_type, 0, 0, do_own_interlace);
-
- for (test=0; test<ARRAY_SIZE(error_test); ++test)
- {
- make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type,
- test, name);
-
- if (fail(pm))
- return 0;
- }
- }
- }
-
- return 1; /* keep going */
-}
-#endif /* PNG_WARNINGS_SUPPORTED */
-
-static void
-perform_error_test(png_modifier *pm)
-{
-#ifdef PNG_WARNINGS_SUPPORTED /* else there are no cases that work! */
- /* Need to do this here because we just write in this test. */
- safecat(pm->this.test, sizeof pm->this.test, 0, "error test");
-
- if (!make_errors(pm, 0, 0, WRITE_BDHI))
- return;
-
- if (!make_errors(pm, 2, 3, WRITE_BDHI))
- return;
-
- if (!make_errors(pm, 3, 0, 3))
- return;
-
- if (!make_errors(pm, 4, 3, WRITE_BDHI))
- return;
-
- if (!make_errors(pm, 6, 3, WRITE_BDHI))
- return;
-#else
- UNUSED(pm)
-#endif
-}
-
-/* This is just to validate the internal PNG formatting code - if this fails
- * then the warning messages the library outputs will probably be garbage.
- */
-static void
-perform_formatting_test(png_store *ps)
-{
-#ifdef PNG_TIME_RFC1123_SUPPORTED
- /* The handle into the formatting code is the RFC1123 support; this test does
- * nothing if that is compiled out.
- */
- context(ps, fault);
-
- Try
- {
- png_const_charp correct = "29 Aug 2079 13:53:60 +0000";
- png_const_charp result;
-# if PNG_LIBPNG_VER >= 10600
- char timestring[29];
-# endif
- png_structp pp;
- png_time pt;
-
- pp = set_store_for_write(ps, NULL, "libpng formatting test");
-
- if (pp == NULL)
- Throw ps;
-
-
- /* Arbitrary settings: */
- pt.year = 2079;
- pt.month = 8;
- pt.day = 29;
- pt.hour = 13;
- pt.minute = 53;
- pt.second = 60; /* a leap second */
-
-# if PNG_LIBPNG_VER < 10600
- result = png_convert_to_rfc1123(pp, &pt);
-# else
- if (png_convert_to_rfc1123_buffer(timestring, &pt))
- result = timestring;
-
- else
- result = NULL;
-# endif
-
- if (result == NULL)
- png_error(pp, "png_convert_to_rfc1123 failed");
-
- if (strcmp(result, correct) != 0)
- {
- size_t pos = 0;
- char msg[128];
-
- pos = safecat(msg, sizeof msg, pos, "png_convert_to_rfc1123(");
- pos = safecat(msg, sizeof msg, pos, correct);
- pos = safecat(msg, sizeof msg, pos, ") returned: '");
- pos = safecat(msg, sizeof msg, pos, result);
- pos = safecat(msg, sizeof msg, pos, "'");
-
- png_error(pp, msg);
- }
-
- store_write_reset(ps);
- }
-
- Catch(fault)
- {
- store_write_reset(fault);
- }
-#else
- UNUSED(ps)
-#endif
-}
-
-#ifdef PNG_READ_SUPPORTED
-/* Because we want to use the same code in both the progressive reader and the
- * sequential reader it is necessary to deal with the fact that the progressive
- * reader callbacks only have one parameter (png_get_progressive_ptr()), so this
- * must contain all the test parameters and all the local variables directly
- * accessible to the sequential reader implementation.
- *
- * The technique adopted is to reinvent part of what Dijkstra termed a
- * 'display'; an array of pointers to the stack frames of enclosing functions so
- * that a nested function definition can access the local (C auto) variables of
- * the functions that contain its definition. In fact C provides the first
- * pointer (the local variables - the stack frame pointer) and the last (the
- * global variables - the BCPL global vector typically implemented as global
- * addresses), this code requires one more pointer to make the display - the
- * local variables (and function call parameters) of the function that actually
- * invokes either the progressive or sequential reader.
- *
- * Perhaps confusingly this technique is confounded with classes - the
- * 'standard_display' defined here is sub-classed as the 'gamma_display' below.
- * A gamma_display is a standard_display, taking advantage of the ANSI-C
- * requirement that the pointer to the first member of a structure must be the
- * same as the pointer to the structure. This allows us to reuse standard_
- * functions in the gamma test code; something that could not be done with
- * nested functions!
- */
-typedef struct standard_display
-{
- png_store* ps; /* Test parameters (passed to the function) */
- png_byte colour_type;
- png_byte bit_depth;
- png_byte red_sBIT; /* Input data sBIT values. */
- png_byte green_sBIT;
- png_byte blue_sBIT;
- png_byte alpha_sBIT;
- png_byte interlace_type;
- png_byte filler; /* Output has a filler */
- png_uint_32 id; /* Calculated file ID */
- png_uint_32 w; /* Width of image */
- png_uint_32 h; /* Height of image */
- int npasses; /* Number of interlaced passes */
- png_uint_32 pixel_size; /* Width of one pixel in bits */
- png_uint_32 bit_width; /* Width of output row in bits */
- size_t cbRow; /* Bytes in a row of the output image */
- int do_interlace; /* Do interlacing internally */
- int littleendian; /* App (row) data is little endian */
- int is_transparent; /* Transparency information was present. */
- int has_tRNS; /* color type GRAY or RGB with a tRNS chunk. */
- int speed; /* Doing a speed test */
- int use_update_info;/* Call update_info, not start_image */
- struct
- {
- png_uint_16 red;
- png_uint_16 green;
- png_uint_16 blue;
- } transparent; /* The transparent color, if set. */
- int npalette; /* Number of entries in the palette. */
- store_palette
- palette;
-} standard_display;
-
-static void
-standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
- int do_interlace, int use_update_info)
-{
- memset(dp, 0, sizeof *dp);
-
- dp->ps = ps;
- dp->colour_type = COL_FROM_ID(id);
- dp->bit_depth = DEPTH_FROM_ID(id);
- if (dp->bit_depth < 1 || dp->bit_depth > 16)
- internal_error(ps, "internal: bad bit depth");
- if (dp->colour_type == 3)
- dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 8;
- else
- dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT =
- dp->bit_depth;
- dp->interlace_type = INTERLACE_FROM_ID(id);
- check_interlace_type(dp->interlace_type);
- dp->id = id;
- /* All the rest are filled in after the read_info: */
- dp->w = 0;
- dp->h = 0;
- dp->npasses = 0;
- dp->pixel_size = 0;
- dp->bit_width = 0;
- dp->cbRow = 0;
- dp->do_interlace = do_interlace;
- dp->littleendian = 0;
- dp->is_transparent = 0;
- dp->speed = ps->speed;
- dp->use_update_info = use_update_info;
- dp->npalette = 0;
- /* Preset the transparent color to black: */
- memset(&dp->transparent, 0, sizeof dp->transparent);
- /* Preset the palette to full intensity/opaque throughout: */
- memset(dp->palette, 0xff, sizeof dp->palette);
-}
-
-/* Initialize the palette fields - this must be done later because the palette
- * comes from the particular png_store_file that is selected.
- */
-static void
-standard_palette_init(standard_display *dp)
-{
- store_palette_entry *palette = store_current_palette(dp->ps, &dp->npalette);
-
- /* The remaining entries remain white/opaque. */
- if (dp->npalette > 0)
- {
- int i = dp->npalette;
- memcpy(dp->palette, palette, i * sizeof *palette);
-
- /* Check for a non-opaque palette entry: */
- while (--i >= 0)
- if (palette[i].alpha < 255)
- break;
-
-# ifdef __GNUC__
- /* GCC can't handle the more obviously optimizable version. */
- if (i >= 0)
- dp->is_transparent = 1;
- else
- dp->is_transparent = 0;
-# else
- dp->is_transparent = (i >= 0);
-# endif
- }
-}
-
-/* Utility to read the palette from the PNG file and convert it into
- * store_palette format. This returns 1 if there is any transparency in the
- * palette (it does not check for a transparent colour in the non-palette case.)
- */
-static int
-read_palette(store_palette palette, int *npalette, png_const_structp pp,
- png_infop pi)
-{
- png_colorp pal;
- png_bytep trans_alpha;
- int num;
-
- pal = 0;
- *npalette = -1;
-
- if (png_get_PLTE(pp, pi, &pal, npalette) & PNG_INFO_PLTE)
- {
- int i = *npalette;
-
- if (i <= 0 || i > 256)
- png_error(pp, "validate: invalid PLTE count");
-
- while (--i >= 0)
- {
- palette[i].red = pal[i].red;
- palette[i].green = pal[i].green;
- palette[i].blue = pal[i].blue;
- }
-
- /* Mark the remainder of the entries with a flag value (other than
- * white/opaque which is the flag value stored above.)
- */
- memset(palette + *npalette, 126, (256-*npalette) * sizeof *palette);
- }
-
- else /* !png_get_PLTE */
- {
- if (*npalette != (-1))
- png_error(pp, "validate: invalid PLTE result");
- /* But there is no palette, so record this: */
- *npalette = 0;
- memset(palette, 113, sizeof (store_palette));
- }
-
- trans_alpha = 0;
- num = 2; /* force error below */
- if ((png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS) != 0 &&
- (trans_alpha != NULL || num != 1/*returns 1 for a transparent color*/) &&
- /* Oops, if a palette tRNS gets expanded png_read_update_info (at least so
- * far as 1.5.4) does not remove the trans_alpha pointer, only num_trans,
- * so in the above call we get a success, we get a pointer (who knows what
- * to) and we get num_trans == 0:
- */
- !(trans_alpha != NULL && num == 0)) /* TODO: fix this in libpng. */
- {
- int i;
-
- /* Any of these are crash-worthy - given the implementation of
- * png_get_tRNS up to 1.5 an app won't crash if it just checks the
- * result above and fails to check that the variables it passed have
- * actually been filled in! Note that if the app were to pass the
- * last, png_color_16p, variable too it couldn't rely on this.
- */
- if (trans_alpha == NULL || num <= 0 || num > 256 || num > *npalette)
- png_error(pp, "validate: unexpected png_get_tRNS (palette) result");
-
- for (i=0; i<num; ++i)
- palette[i].alpha = trans_alpha[i];
-
- for (num=*npalette; i<num; ++i)
- palette[i].alpha = 255;
-
- for (; i<256; ++i)
- palette[i].alpha = 33; /* flag value */
-
- return 1; /* transparency */
- }
-
- else
- {
- /* No palette transparency - just set the alpha channel to opaque. */
- int i;
-
- for (i=0, num=*npalette; i<num; ++i)
- palette[i].alpha = 255;
-
- for (; i<256; ++i)
- palette[i].alpha = 55; /* flag value */
-
- return 0; /* no transparency */
- }
-}
-
-/* Utility to validate the palette if it should not have changed (the
- * non-transform case).
- */
-static void
-standard_palette_validate(standard_display *dp, png_const_structp pp,
- png_infop pi)
-{
- int npalette;
- store_palette palette;
-
- if (read_palette(palette, &npalette, pp, pi) != dp->is_transparent)
- png_error(pp, "validate: palette transparency changed");
-
- if (npalette != dp->npalette)
- {
- size_t pos = 0;
- char msg[64];
-
- pos = safecat(msg, sizeof msg, pos, "validate: palette size changed: ");
- pos = safecatn(msg, sizeof msg, pos, dp->npalette);
- pos = safecat(msg, sizeof msg, pos, " -> ");
- pos = safecatn(msg, sizeof msg, pos, npalette);
- png_error(pp, msg);
- }
-
- {
- int i = npalette; /* npalette is aliased */
-
- while (--i >= 0)
- if (palette[i].red != dp->palette[i].red ||
- palette[i].green != dp->palette[i].green ||
- palette[i].blue != dp->palette[i].blue ||
- palette[i].alpha != dp->palette[i].alpha)
- png_error(pp, "validate: PLTE or tRNS chunk changed");
- }
-}
-
-/* By passing a 'standard_display' the progressive callbacks can be used
- * directly by the sequential code, the functions suffixed "_imp" are the
- * implementations, the functions without the suffix are the callbacks.
- *
- * The code for the info callback is split into two because this callback calls
- * png_read_update_info or png_start_read_image and what gets called depends on
- * whether the info needs updating (we want to test both calls in pngvalid.)
- */
-static void
-standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
-{
- if (png_get_bit_depth(pp, pi) != dp->bit_depth)
- png_error(pp, "validate: bit depth changed");
-
- if (png_get_color_type(pp, pi) != dp->colour_type)
- png_error(pp, "validate: color type changed");
-
- if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE)
- png_error(pp, "validate: filter type changed");
-
- if (png_get_interlace_type(pp, pi) != dp->interlace_type)
- png_error(pp, "validate: interlacing changed");
-
- if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE)
- png_error(pp, "validate: compression type changed");
-
- dp->w = png_get_image_width(pp, pi);
-
- if (dp->w != standard_width(pp, dp->id))
- png_error(pp, "validate: image width changed");
-
- dp->h = png_get_image_height(pp, pi);
-
- if (dp->h != standard_height(pp, dp->id))
- png_error(pp, "validate: image height changed");
-
- /* Record (but don't check at present) the input sBIT according to the colour
- * type information.
- */
- {
- png_color_8p sBIT = 0;
-
- if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT)
- {
- int sBIT_invalid = 0;
-
- if (sBIT == 0)
- png_error(pp, "validate: unexpected png_get_sBIT result");
-
- if (dp->colour_type & PNG_COLOR_MASK_COLOR)
- {
- if (sBIT->red == 0 || sBIT->red > dp->bit_depth)
- sBIT_invalid = 1;
- else
- dp->red_sBIT = sBIT->red;
-
- if (sBIT->green == 0 || sBIT->green > dp->bit_depth)
- sBIT_invalid = 1;
- else
- dp->green_sBIT = sBIT->green;
-
- if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth)
- sBIT_invalid = 1;
- else
- dp->blue_sBIT = sBIT->blue;
- }
-
- else /* !COLOR */
- {
- if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth)
- sBIT_invalid = 1;
- else
- dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray;
- }
-
- /* All 8 bits in tRNS for a palette image are significant - see the
- * spec.
- */
- if (dp->colour_type & PNG_COLOR_MASK_ALPHA)
- {
- if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth)
- sBIT_invalid = 1;
- else
- dp->alpha_sBIT = sBIT->alpha;
- }
-
- if (sBIT_invalid)
- png_error(pp, "validate: sBIT value out of range");
- }
- }
-
- /* Important: this is validating the value *before* any transforms have been
- * put in place. It doesn't matter for the standard tests, where there are
- * no transforms, but it does for other tests where rowbytes may change after
- * png_read_update_info.
- */
- if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id))
- png_error(pp, "validate: row size changed");
-
- /* Validate the colour type 3 palette (this can be present on other color
- * types.)
- */
- standard_palette_validate(dp, pp, pi);
-
- /* In any case always check for a transparent color (notice that the
- * colour type 3 case must not give a successful return on the get_tRNS call
- * with these arguments!)
- */
- {
- png_color_16p trans_color = 0;
-
- if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS)
- {
- if (trans_color == 0)
- png_error(pp, "validate: unexpected png_get_tRNS (color) result");
-
- switch (dp->colour_type)
- {
- case 0:
- dp->transparent.red = dp->transparent.green = dp->transparent.blue =
- trans_color->gray;
- dp->has_tRNS = 1;
- break;
-
- case 2:
- dp->transparent.red = trans_color->red;
- dp->transparent.green = trans_color->green;
- dp->transparent.blue = trans_color->blue;
- dp->has_tRNS = 1;
- break;
-
- case 3:
- /* Not expected because it should result in the array case
- * above.
- */
- png_error(pp, "validate: unexpected png_get_tRNS result");
- break;
-
- default:
- png_error(pp, "validate: invalid tRNS chunk with alpha image");
- }
- }
- }
-
- /* Read the number of passes - expected to match the value used when
- * creating the image (interlaced or not). This has the side effect of
- * turning on interlace handling (if do_interlace is not set.)
- */
- dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type);
- if (!dp->do_interlace)
- {
-# ifdef PNG_READ_INTERLACING_SUPPORTED
- if (dp->npasses != png_set_interlace_handling(pp))
- png_error(pp, "validate: file changed interlace type");
-# else /* !READ_INTERLACING */
- /* This should never happen: the relevant tests (!do_interlace) should
- * not be run.
- */
- if (dp->npasses > 1)
- png_error(pp, "validate: no libpng interlace support");
-# endif /* !READ_INTERLACING */
- }
-
- /* Caller calls png_read_update_info or png_start_read_image now, then calls
- * part2.
- */
-}
-
-/* This must be called *after* the png_read_update_info call to get the correct
- * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed
- * image.
- */
-static void
-standard_info_part2(standard_display *dp, png_const_structp pp,
- png_const_infop pi, int nImages)
-{
- /* Record cbRow now that it can be found. */
- {
- png_byte ct = png_get_color_type(pp, pi);
- png_byte bd = png_get_bit_depth(pp, pi);
-
- if (bd >= 8 && (ct == PNG_COLOR_TYPE_RGB || ct == PNG_COLOR_TYPE_GRAY) &&
- dp->filler)
- ct |= 4; /* handle filler as faked alpha channel */
-
- dp->pixel_size = bit_size(pp, ct, bd);
- }
- dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size;
- dp->cbRow = png_get_rowbytes(pp, pi);
-
- /* Validate the rowbytes here again. */
- if (dp->cbRow != (dp->bit_width+7)/8)
- png_error(pp, "bad png_get_rowbytes calculation");
-
- /* Then ensure there is enough space for the output image(s). */
- store_ensure_image(dp->ps, pp, nImages, dp->cbRow, dp->h);
-}
-
-static void
-standard_info_imp(standard_display *dp, png_structp pp, png_infop pi,
- int nImages)
-{
- /* Note that the validation routine has the side effect of turning on
- * interlace handling in the subsequent code.
- */
- standard_info_part1(dp, pp, pi);
-
- /* And the info callback has to call this (or png_read_update_info - see
- * below in the png_modifier code for that variant.
- */
- if (dp->use_update_info)
- {
- /* For debugging the effect of multiple calls: */
- int i = dp->use_update_info;
- while (i-- > 0)
- png_read_update_info(pp, pi);
- }
-
- else
- png_start_read_image(pp);
-
- /* Validate the height, width and rowbytes plus ensure that sufficient buffer
- * exists for decoding the image.
- */
- standard_info_part2(dp, pp, pi, nImages);
-}
-
-static void PNGCBAPI
-standard_info(png_structp pp, png_infop pi)
-{
- standard_display *dp = voidcast(standard_display*,
- png_get_progressive_ptr(pp));
-
- /* Call with nImages==1 because the progressive reader can only produce one
- * image.
- */
- standard_info_imp(dp, pp, pi, 1 /*only one image*/);
-}
-
-static void PNGCBAPI
-progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass)
-{
- png_const_structp pp = ppIn;
- const standard_display *dp = voidcast(standard_display*,
- png_get_progressive_ptr(pp));
-
- /* When handling interlacing some rows will be absent in each pass, the
- * callback still gets called, but with a NULL pointer. This is checked
- * in the 'else' clause below. We need our own 'cbRow', but we can't call
- * png_get_rowbytes because we got no info structure.
- */
- if (new_row != NULL)
- {
- png_bytep row;
-
- /* In the case where the reader doesn't do the interlace it gives
- * us the y in the sub-image:
- */
- if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7)
- {
-#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
- /* Use this opportunity to validate the png 'current' APIs: */
- if (y != png_get_current_row_number(pp))
- png_error(pp, "png_get_current_row_number is broken");
-
- if (pass != png_get_current_pass_number(pp))
- png_error(pp, "png_get_current_pass_number is broken");
-#endif /* USER_TRANSFORM_INFO */
-
- y = PNG_ROW_FROM_PASS_ROW(y, pass);
- }
-
- /* Validate this just in case. */
- if (y >= dp->h)
- png_error(pp, "invalid y to progressive row callback");
-
- row = store_image_row(dp->ps, pp, 0, y);
-
- /* Combine the new row into the old: */
-#ifdef PNG_READ_INTERLACING_SUPPORTED
- if (dp->do_interlace)
-#endif /* READ_INTERLACING */
- {
- if (dp->interlace_type == PNG_INTERLACE_ADAM7)
- deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass,
- dp->littleendian);
- else
- row_copy(row, new_row, dp->pixel_size * dp->w, dp->littleendian);
- }
-#ifdef PNG_READ_INTERLACING_SUPPORTED
- else
- png_progressive_combine_row(pp, row, new_row);
-#endif /* PNG_READ_INTERLACING_SUPPORTED */
- }
-
- else if (dp->interlace_type == PNG_INTERLACE_ADAM7 &&
- PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
- PNG_PASS_COLS(dp->w, pass) > 0)
- png_error(pp, "missing row in progressive de-interlacing");
-}
-
-static void
-sequential_row(standard_display *dp, png_structp pp, png_infop pi,
- int iImage, int iDisplay)
-{
- int npasses = dp->npasses;
- int do_interlace = dp->do_interlace &&
- dp->interlace_type == PNG_INTERLACE_ADAM7;
- png_uint_32 height = standard_height(pp, dp->id);
- png_uint_32 width = standard_width(pp, dp->id);
- const png_store* ps = dp->ps;
- int pass;
-
- for (pass=0; pass<npasses; ++pass)
- {
- png_uint_32 y;
- png_uint_32 wPass = PNG_PASS_COLS(width, pass);
-
- for (y=0; y<height; ++y)
- {
- if (do_interlace)
- {
- /* wPass may be zero or this row may not be in this pass.
- * png_read_row must not be called in either case.
- */
- if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass))
- {
- /* Read the row into a pair of temporary buffers, then do the
- * merge here into the output rows.
- */
- png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX];
-
- /* The following aids (to some extent) error detection - we can
- * see where png_read_row wrote. Use opposite values in row and
- * display to make this easier. Don't use 0xff (which is used in
- * the image write code to fill unused bits) or 0 (which is a
- * likely value to overwrite unused bits with).
- */
- memset(row, 0xc5, sizeof row);
- memset(display, 0x5c, sizeof display);
-
- png_read_row(pp, row, display);
-
- if (iImage >= 0)
- deinterlace_row(store_image_row(ps, pp, iImage, y), row,
- dp->pixel_size, dp->w, pass, dp->littleendian);
-
- if (iDisplay >= 0)
- deinterlace_row(store_image_row(ps, pp, iDisplay, y), display,
- dp->pixel_size, dp->w, pass, dp->littleendian);
- }
- }
- else
- png_read_row(pp,
- iImage >= 0 ? store_image_row(ps, pp, iImage, y) : NULL,
- iDisplay >= 0 ? store_image_row(ps, pp, iDisplay, y) : NULL);
- }
- }
-
- /* And finish the read operation (only really necessary if the caller wants
- * to find additional data in png_info from chunks after the last IDAT.)
- */
- png_read_end(pp, pi);
-}
-
-#ifdef PNG_TEXT_SUPPORTED
-static void
-standard_check_text(png_const_structp pp, png_const_textp tp,
- png_const_charp keyword, png_const_charp text)
-{
- char msg[1024];
- size_t pos = safecat(msg, sizeof msg, 0, "text: ");
- size_t ok;
-
- pos = safecat(msg, sizeof msg, pos, keyword);
- pos = safecat(msg, sizeof msg, pos, ": ");
- ok = pos;
-
- if (tp->compression != TEXT_COMPRESSION)
- {
- char buf[64];
-
- sprintf(buf, "compression [%d->%d], ", TEXT_COMPRESSION,
- tp->compression);
- pos = safecat(msg, sizeof msg, pos, buf);
- }
-
- if (tp->key == NULL || strcmp(tp->key, keyword) != 0)
- {
- pos = safecat(msg, sizeof msg, pos, "keyword \"");
- if (tp->key != NULL)
- {
- pos = safecat(msg, sizeof msg, pos, tp->key);
- pos = safecat(msg, sizeof msg, pos, "\", ");
- }
-
- else
- pos = safecat(msg, sizeof msg, pos, "null, ");
- }
-
- if (tp->text == NULL)
- pos = safecat(msg, sizeof msg, pos, "text lost, ");
-
- else
- {
- if (tp->text_length != strlen(text))
- {
- char buf[64];
- sprintf(buf, "text length changed[%lu->%lu], ",
- (unsigned long)strlen(text), (unsigned long)tp->text_length);
- pos = safecat(msg, sizeof msg, pos, buf);
- }
-
- if (strcmp(tp->text, text) != 0)
- {
- pos = safecat(msg, sizeof msg, pos, "text becomes \"");
- pos = safecat(msg, sizeof msg, pos, tp->text);
- pos = safecat(msg, sizeof msg, pos, "\" (was \"");
- pos = safecat(msg, sizeof msg, pos, text);
- pos = safecat(msg, sizeof msg, pos, "\"), ");
- }
- }
-
- if (tp->itxt_length != 0)
- pos = safecat(msg, sizeof msg, pos, "iTXt length set, ");
-
- if (tp->lang != NULL)
- {
- pos = safecat(msg, sizeof msg, pos, "iTXt language \"");
- pos = safecat(msg, sizeof msg, pos, tp->lang);
- pos = safecat(msg, sizeof msg, pos, "\", ");
- }
-
- if (tp->lang_key != NULL)
- {
- pos = safecat(msg, sizeof msg, pos, "iTXt keyword \"");
- pos = safecat(msg, sizeof msg, pos, tp->lang_key);
- pos = safecat(msg, sizeof msg, pos, "\", ");
- }
-
- if (pos > ok)
- {
- msg[pos-2] = '\0'; /* Remove the ", " at the end */
- png_error(pp, msg);
- }
-}
-
-static void
-standard_text_validate(standard_display *dp, png_const_structp pp,
- png_infop pi, int check_end)
-{
- png_textp tp = NULL;
- png_uint_32 num_text = png_get_text(pp, pi, &tp, NULL);
-
- if (num_text == 2 && tp != NULL)
- {
- standard_check_text(pp, tp, "image name", dp->ps->current->name);
-
- /* This exists because prior to 1.5.18 the progressive reader left the
- * png_struct z_stream unreset at the end of the image, so subsequent
- * attempts to use it simply returns Z_STREAM_END.
- */
- if (check_end)
- standard_check_text(pp, tp+1, "end marker", "end");
- }
-
- else
- {
- char msg[64];
-
- sprintf(msg, "expected two text items, got %lu",
- (unsigned long)num_text);
- png_error(pp, msg);
- }
-}
-#else
-# define standard_text_validate(dp,pp,pi,check_end) ((void)0)
-#endif
-
-static void
-standard_row_validate(standard_display *dp, png_const_structp pp,
- int iImage, int iDisplay, png_uint_32 y)
-{
- int where;
- png_byte std[STANDARD_ROWMAX];
-
- /* The row must be pre-initialized to the magic number here for the size
- * tests to pass:
- */
- memset(std, 178, sizeof std);
- standard_row(pp, std, dp->id, y);
-
- /* At the end both the 'row' and 'display' arrays should end up identical.
- * In earlier passes 'row' will be partially filled in, with only the pixels
- * that have been read so far, but 'display' will have those pixels
- * replicated to fill the unread pixels while reading an interlaced image.
- */
- if (iImage >= 0 &&
- (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y),
- dp->bit_width)) != 0)
- {
- char msg[64];
- sprintf(msg, "PNG image row[%lu][%d] changed from %.2x to %.2x",
- (unsigned long)y, where-1, std[where-1],
- store_image_row(dp->ps, pp, iImage, y)[where-1]);
- png_error(pp, msg);
- }
-
- if (iDisplay >= 0 &&
- (where = pixel_cmp(std, store_image_row(dp->ps, pp, iDisplay, y),
- dp->bit_width)) != 0)
- {
- char msg[64];
- sprintf(msg, "display row[%lu][%d] changed from %.2x to %.2x",
- (unsigned long)y, where-1, std[where-1],
- store_image_row(dp->ps, pp, iDisplay, y)[where-1]);
- png_error(pp, msg);
- }
-}
-
-static void
-standard_image_validate(standard_display *dp, png_const_structp pp, int iImage,
- int iDisplay)
-{
- png_uint_32 y;
-
- if (iImage >= 0)
- store_image_check(dp->ps, pp, iImage);
-
- if (iDisplay >= 0)
- store_image_check(dp->ps, pp, iDisplay);
-
- for (y=0; y<dp->h; ++y)
- standard_row_validate(dp, pp, iImage, iDisplay, y);
-
- /* This avoids false positives if the validation code is never called! */
- dp->ps->validated = 1;
-}
-
-static void PNGCBAPI
-standard_end(png_structp ppIn, png_infop pi)
-{
- png_const_structp pp = ppIn;
- standard_display *dp = voidcast(standard_display*,
- png_get_progressive_ptr(pp));
-
- UNUSED(pi)
-
- /* Validate the image - progressive reading only produces one variant for
- * interlaced images.
- */
- standard_text_validate(dp, pp, pi,
- PNG_LIBPNG_VER >= 10518/*check_end: see comments above*/);
- standard_image_validate(dp, pp, 0, -1);
-}
-
-/* A single test run checking the standard image to ensure it is not damaged. */
-static void
-standard_test(png_store* const psIn, png_uint_32 const id,
- int do_interlace, int use_update_info)
-{
- standard_display d;
- context(psIn, fault);
-
- /* Set up the display (stack frame) variables from the arguments to the
- * function and initialize the locals that are filled in later.
- */
- standard_display_init(&d, psIn, id, do_interlace, use_update_info);
-
- /* Everything is protected by a Try/Catch. The functions called also
- * typically have local Try/Catch blocks.
- */
- Try
- {
- png_structp pp;
- png_infop pi;
-
- /* Get a png_struct for reading the image. This will throw an error if it
- * fails, so we don't need to check the result.
- */
- pp = set_store_for_read(d.ps, &pi, d.id,
- d.do_interlace ? (d.ps->progressive ?
- "pngvalid progressive deinterlacer" :
- "pngvalid sequential deinterlacer") : (d.ps->progressive ?
- "progressive reader" : "sequential reader"));
-
- /* Initialize the palette correctly from the png_store_file. */
- standard_palette_init(&d);
-
- /* Introduce the correct read function. */
- if (d.ps->progressive)
- {
- png_set_progressive_read_fn(pp, &d, standard_info, progressive_row,
- standard_end);
-
- /* Now feed data into the reader until we reach the end: */
- store_progressive_read(d.ps, pp, pi);
- }
- else
- {
- /* Note that this takes the store, not the display. */
- png_set_read_fn(pp, d.ps, store_read);
-
- /* Check the header values: */
- png_read_info(pp, pi);
-
- /* The code tests both versions of the images that the sequential
- * reader can produce.
- */
- standard_info_imp(&d, pp, pi, 2 /*images*/);
-
- /* Need the total bytes in the image below; we can't get to this point
- * unless the PNG file values have been checked against the expected
- * values.
- */
- {
- sequential_row(&d, pp, pi, 0, 1);
-
- /* After the last pass loop over the rows again to check that the
- * image is correct.
- */
- if (!d.speed)
- {
- standard_text_validate(&d, pp, pi, 1/*check_end*/);
- standard_image_validate(&d, pp, 0, 1);
- }
- else
- d.ps->validated = 1;
- }
- }
-
- /* Check for validation. */
- if (!d.ps->validated)
- png_error(pp, "image read failed silently");
-
- /* Successful completion. */
- }
-
- Catch(fault)
- d.ps = fault; /* make sure this hasn't been clobbered. */
-
- /* In either case clean up the store. */
- store_read_reset(d.ps);
-}
-
-static int
-test_standard(png_modifier* const pm, png_byte const colour_type,
- int bdlo, int const bdhi)
-{
- for (; bdlo <= bdhi; ++bdlo)
- {
- int interlace_type;
-
- for (interlace_type = PNG_INTERLACE_NONE;
- interlace_type < INTERLACE_LAST; ++interlace_type)
- {
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info);
-
- if (fail(pm))
- return 0;
- }
- }
-
- return 1; /* keep going */
-}
-
-static void
-perform_standard_test(png_modifier *pm)
-{
- /* Test each colour type over the valid range of bit depths (expressed as
- * log2(bit_depth) in turn, stop as soon as any error is detected.
- */
- if (!test_standard(pm, 0, 0, READ_BDHI))
- return;
-
- if (!test_standard(pm, 2, 3, READ_BDHI))
- return;
-
- if (!test_standard(pm, 3, 0, 3))
- return;
-
- if (!test_standard(pm, 4, 3, READ_BDHI))
- return;
-
- if (!test_standard(pm, 6, 3, READ_BDHI))
- return;
-}
-
-
-/********************************** SIZE TESTS ********************************/
-static int
-test_size(png_modifier* const pm, png_byte const colour_type,
- int bdlo, int const bdhi)
-{
- /* Run the tests on each combination.
- *
- * NOTE: on my 32 bit x86 each of the following blocks takes
- * a total of 3.5 seconds if done across every combo of bit depth
- * width and height. This is a waste of time in practice, hence the
- * hinc and winc stuff:
- */
- static const png_byte hinc[] = {1, 3, 11, 1, 5};
- static const png_byte winc[] = {1, 9, 5, 7, 1};
- int save_bdlo = bdlo;
-
- for (; bdlo <= bdhi; ++bdlo)
- {
- png_uint_32 h, w;
-
- for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
- {
- /* First test all the 'size' images against the sequential
- * reader using libpng to deinterlace (where required.) This
- * validates the write side of libpng. There are four possibilities
- * to validate.
- */
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,
- pm->use_update_info);
-
- if (fail(pm))
- return 0;
-
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,
- pm->use_update_info);
-
- if (fail(pm))
- return 0;
-
- /* Now validate the interlaced read side - do_interlace true,
- * in the progressive case this does actually make a difference
- * to the code used in the non-interlaced case too.
- */
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,
- pm->use_update_info);
-
- if (fail(pm))
- return 0;
-
-# if CAN_WRITE_INTERLACE
- /* Validate the pngvalid code itself: */
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/,
- pm->use_update_info);
-
- if (fail(pm))
- return 0;
-# endif
- }
- }
-
- /* Now do the tests of libpng interlace handling, after we have made sure
- * that the pngvalid version works:
- */
- for (bdlo = save_bdlo; bdlo <= bdhi; ++bdlo)
- {
- png_uint_32 h, w;
-
- for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
- {
-# ifdef PNG_READ_INTERLACING_SUPPORTED
- /* Test with pngvalid generated interlaced images first; we have
- * already verify these are ok (unless pngvalid has self-consistent
- * read/write errors, which is unlikely), so this detects errors in the
- * read side first:
- */
-# if CAN_WRITE_INTERLACE
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,
- pm->use_update_info);
-
- if (fail(pm))
- return 0;
-# endif
-# endif /* READ_INTERLACING */
-
-# ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* Test the libpng write side against the pngvalid read side: */
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
- pm->use_update_info);
-
- if (fail(pm))
- return 0;
-# endif
-
-# ifdef PNG_READ_INTERLACING_SUPPORTED
-# ifdef PNG_WRITE_INTERLACING_SUPPORTED
- /* Test both together: */
- standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
- PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
- pm->use_update_info);
-
- if (fail(pm))
- return 0;
-# endif
-# endif /* READ_INTERLACING */
- }
- }
-
- return 1; /* keep going */
-}
-
-static void
-perform_size_test(png_modifier *pm)
-{
- /* Test each colour type over the valid range of bit depths (expressed as
- * log2(bit_depth) in turn, stop as soon as any error is detected.
- */
- if (!test_size(pm, 0, 0, READ_BDHI))
- return;
-
- if (!test_size(pm, 2, 3, READ_BDHI))
- return;
-
- /* For the moment don't do the palette test - it's a waste of time when
- * compared to the grayscale test.
- */
-#if 0
- if (!test_size(pm, 3, 0, 3))
- return;
-#endif
-
- if (!test_size(pm, 4, 3, READ_BDHI))
- return;
-
- if (!test_size(pm, 6, 3, READ_BDHI))
- return;
-}
-
-
-/******************************* TRANSFORM TESTS ******************************/
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-/* A set of tests to validate libpng image transforms. The possibilities here
- * are legion because the transforms can be combined in a combinatorial
- * fashion. To deal with this some measure of restraint is required, otherwise
- * the tests would take forever.
- */
-typedef struct image_pixel
-{
- /* A local (pngvalid) representation of a PNG pixel, in all its
- * various forms.
- */
- unsigned int red, green, blue, alpha; /* For non-palette images. */
- unsigned int palette_index; /* For a palette image. */
- png_byte colour_type; /* As in the spec. */
- png_byte bit_depth; /* Defines bit size in row */
- png_byte sample_depth; /* Scale of samples */
- unsigned int have_tRNS :1; /* tRNS chunk may need processing */
- unsigned int swap_rgb :1; /* RGB swapped to BGR */
- unsigned int alpha_first :1; /* Alpha at start, not end */
- unsigned int alpha_inverted :1; /* Alpha channel inverted */
- unsigned int mono_inverted :1; /* Gray channel inverted */
- unsigned int swap16 :1; /* Byte swap 16-bit components */
- unsigned int littleendian :1; /* High bits on right */
- unsigned int sig_bits :1; /* Pixel shifted (sig bits only) */
-
- /* For checking the code calculates double precision floating point values
- * along with an error value, accumulated from the transforms. Because an
- * sBIT setting allows larger error bounds (indeed, by the spec, apparently
- * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each
- * channel is stored. This sBIT value is folded in to the stored error value
- * at the end of the application of the transforms to the pixel.
- *
- * If sig_bits is set above the red, green, blue and alpha values have been
- * scaled so they only contain the significant bits of the component values.
- */
- double redf, greenf, bluef, alphaf;
- double rede, greene, bluee, alphae;
- png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT;
-} image_pixel;
-
-/* Shared utility function, see below. */
-static void
-image_pixel_setf(image_pixel *this, unsigned int rMax, unsigned int gMax,
- unsigned int bMax, unsigned int aMax)
-{
- this->redf = this->red / (double)rMax;
- this->greenf = this->green / (double)gMax;
- this->bluef = this->blue / (double)bMax;
- this->alphaf = this->alpha / (double)aMax;
-
- if (this->red < rMax)
- this->rede = this->redf * DBL_EPSILON;
- else
- this->rede = 0;
- if (this->green < gMax)
- this->greene = this->greenf * DBL_EPSILON;
- else
- this->greene = 0;
- if (this->blue < bMax)
- this->bluee = this->bluef * DBL_EPSILON;
- else
- this->bluee = 0;
- if (this->alpha < aMax)
- this->alphae = this->alphaf * DBL_EPSILON;
- else
- this->alphae = 0;
-}
-
-/* Initialize the structure for the next pixel - call this before doing any
- * transforms and call it for each pixel since all the fields may need to be
- * reset.
- */
-static void
-image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
- png_byte bit_depth, png_uint_32 x, store_palette palette,
- const image_pixel *format /*from pngvalid transform of input*/)
-{
- png_byte sample_depth =
- (png_byte)(colour_type == PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
- unsigned int max = (1U<<sample_depth)-1;
- int swap16 = (format != 0 && format->swap16);
- int littleendian = (format != 0 && format->littleendian);
- int sig_bits = (format != 0 && format->sig_bits);
-
- /* Initially just set everything to the same number and the alpha to opaque.
- * Note that this currently assumes a simple palette where entry x has colour
- * rgb(x,x,x)!
- */
- this->palette_index = this->red = this->green = this->blue =
- sample(row, colour_type, bit_depth, x, 0, swap16, littleendian);
- this->alpha = max;
- this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT =
- sample_depth;
-
- /* Then override as appropriate: */
- if (colour_type == 3) /* palette */
- {
- /* This permits the caller to default to the sample value. */
- if (palette != 0)
- {
- unsigned int i = this->palette_index;
-
- this->red = palette[i].red;
- this->green = palette[i].green;
- this->blue = palette[i].blue;
- this->alpha = palette[i].alpha;
- }
- }
-
- else /* not palette */
- {
- unsigned int i = 0;
-
- if ((colour_type & 4) != 0 && format != 0 && format->alpha_first)
- {
- this->alpha = this->red;
- /* This handles the gray case for 'AG' pixels */
- this->palette_index = this->red = this->green = this->blue =
- sample(row, colour_type, bit_depth, x, 1, swap16, littleendian);
- i = 1;
- }
-
- if (colour_type & 2)
- {
- /* Green is second for both BGR and RGB: */
- this->green = sample(row, colour_type, bit_depth, x, ++i, swap16,
- littleendian);
-
- if (format != 0 && format->swap_rgb) /* BGR */
- this->red = sample(row, colour_type, bit_depth, x, ++i, swap16,
- littleendian);
- else
- this->blue = sample(row, colour_type, bit_depth, x, ++i, swap16,
- littleendian);
- }
-
- else /* grayscale */ if (format != 0 && format->mono_inverted)
- this->red = this->green = this->blue = this->red ^ max;
-
- if ((colour_type & 4) != 0) /* alpha */
- {
- if (format == 0 || !format->alpha_first)
- this->alpha = sample(row, colour_type, bit_depth, x, ++i, swap16,
- littleendian);
-
- if (format != 0 && format->alpha_inverted)
- this->alpha ^= max;
- }
- }
-
- /* Calculate the scaled values, these are simply the values divided by
- * 'max' and the error is initialized to the double precision epsilon value
- * from the header file.
- */
- image_pixel_setf(this,
- sig_bits ? (1U << format->red_sBIT)-1 : max,
- sig_bits ? (1U << format->green_sBIT)-1 : max,
- sig_bits ? (1U << format->blue_sBIT)-1 : max,
- sig_bits ? (1U << format->alpha_sBIT)-1 : max);
-
- /* Store the input information for use in the transforms - these will
- * modify the information.
- */
- this->colour_type = colour_type;
- this->bit_depth = bit_depth;
- this->sample_depth = sample_depth;
- this->have_tRNS = 0;
- this->swap_rgb = 0;
- this->alpha_first = 0;
- this->alpha_inverted = 0;
- this->mono_inverted = 0;
- this->swap16 = 0;
- this->littleendian = 0;
- this->sig_bits = 0;
-}
-
-#if defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_GRAY_TO_RGB_SUPPORTED\
- || defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_EXPAND_16_SUPPORTED\
- || defined PNG_READ_BACKGROUND_SUPPORTED
-/* Convert a palette image to an rgb image. This necessarily converts the tRNS
- * chunk at the same time, because the tRNS will be in palette form. The way
- * palette validation works means that the original palette is never updated,
- * instead the image_pixel value from the row contains the RGB of the
- * corresponding palette entry and *this* is updated. Consequently this routine
- * only needs to change the colour type information.
- */
-static void
-image_pixel_convert_PLTE(image_pixel *this)
-{
- if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
- {
- if (this->have_tRNS)
- {
- this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
- this->have_tRNS = 0;
- }
- else
- this->colour_type = PNG_COLOR_TYPE_RGB;
-
- /* The bit depth of the row changes at this point too (notice that this is
- * the row format, not the sample depth, which is separate.)
- */
- this->bit_depth = 8;
- }
-}
-
-/* Add an alpha channel; this will import the tRNS information because tRNS is
- * not valid in an alpha image. The bit depth will invariably be set to at
- * least 8 prior to 1.7.0. Palette images will be converted to alpha (using
- * the above API). With png_set_background the alpha channel is never expanded
- * but this routine is used by pngvalid to simplify code; 'for_background'
- * records this.
- */
-static void
-image_pixel_add_alpha(image_pixel *this, const standard_display *display,
- int for_background)
-{
- if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
- image_pixel_convert_PLTE(this);
-
- if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
- {
- if (this->colour_type == PNG_COLOR_TYPE_GRAY)
- {
-# if PNG_LIBPNG_VER < 10700
- if (!for_background && this->bit_depth < 8)
- this->bit_depth = this->sample_depth = 8;
-# endif
-
- if (this->have_tRNS)
- {
- /* After 1.7 the expansion of bit depth only happens if there is a
- * tRNS chunk to expand at this point.
- */
-# if PNG_LIBPNG_VER >= 10700
- if (!for_background && this->bit_depth < 8)
- this->bit_depth = this->sample_depth = 8;
-# endif
-
- this->have_tRNS = 0;
-
- /* Check the input, original, channel value here against the
- * original tRNS gray chunk valie.
- */
- if (this->red == display->transparent.red)
- this->alphaf = 0;
- else
- this->alphaf = 1;
- }
- else
- this->alphaf = 1;
-
- this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- }
-
- else if (this->colour_type == PNG_COLOR_TYPE_RGB)
- {
- if (this->have_tRNS)
- {
- this->have_tRNS = 0;
-
- /* Again, check the exact input values, not the current transformed
- * value!
- */
- if (this->red == display->transparent.red &&
- this->green == display->transparent.green &&
- this->blue == display->transparent.blue)
- this->alphaf = 0;
- else
- this->alphaf = 1;
- }
- else
- this->alphaf = 1;
-
- this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
- }
-
- /* The error in the alpha is zero and the sBIT value comes from the
- * original sBIT data (actually it will always be the original bit depth).
- */
- this->alphae = 0;
- this->alpha_sBIT = display->alpha_sBIT;
- }
-}
-#endif /* transforms that need image_pixel_add_alpha */
-
-struct transform_display;
-typedef struct image_transform
-{
- /* The name of this transform: a string. */
- const char *name;
-
- /* Each transform can be disabled from the command line: */
- int enable;
-
- /* The global list of transforms; read only. */
- struct image_transform *const list;
-
- /* The global count of the number of times this transform has been set on an
- * image.
- */
- unsigned int global_use;
-
- /* The local count of the number of times this transform has been set. */
- unsigned int local_use;
-
- /* The next transform in the list, each transform must call its own next
- * transform after it has processed the pixel successfully.
- */
- const struct image_transform *next;
-
- /* A single transform for the image, expressed as a series of function
- * callbacks and some space for values.
- *
- * First a callback to add any required modifications to the png_modifier;
- * this gets called just before the modifier is set up for read.
- */
- void (*ini)(const struct image_transform *this,
- struct transform_display *that);
-
- /* And a callback to set the transform on the current png_read_struct:
- */
- void (*set)(const struct image_transform *this,
- struct transform_display *that, png_structp pp, png_infop pi);
-
- /* Then a transform that takes an input pixel in one PNG format or another
- * and modifies it by a pngvalid implementation of the transform (thus
- * duplicating the libpng intent without, we hope, duplicating the bugs
- * in the libpng implementation!) The png_structp is solely to allow error
- * reporting via png_error and png_warning.
- */
- void (*mod)(const struct image_transform *this, image_pixel *that,
- png_const_structp pp, const struct transform_display *display);
-
- /* Add this transform to the list and return true if the transform is
- * meaningful for this colour type and bit depth - if false then the
- * transform should have no effect on the image so there's not a lot of
- * point running it.
- */
- int (*add)(struct image_transform *this,
- const struct image_transform **that, png_byte colour_type,
- png_byte bit_depth);
-} image_transform;
-
-typedef struct transform_display
-{
- standard_display this;
-
- /* Parameters */
- png_modifier* pm;
- const image_transform* transform_list;
- unsigned int max_gamma_8;
-
- /* Local variables */
- png_byte output_colour_type;
- png_byte output_bit_depth;
- png_byte unpacked;
-
- /* Modifications (not necessarily used.) */
- gama_modification gama_mod;
- chrm_modification chrm_mod;
- srgb_modification srgb_mod;
-} transform_display;
-
-/* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */
-static void
-transform_set_encoding(transform_display *this)
-{
- /* Set up the png_modifier '_current' fields then use these to determine how
- * to add appropriate chunks.
- */
- png_modifier *pm = this->pm;
-
- modifier_set_encoding(pm);
-
- if (modifier_color_encoding_is_set(pm))
- {
- if (modifier_color_encoding_is_sRGB(pm))
- srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE);
-
- else
- {
- /* Set gAMA and cHRM separately. */
- gama_modification_init(&this->gama_mod, pm, pm->current_gamma);
-
- if (pm->current_encoding != 0)
- chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding);
- }
- }
-}
-
-/* Three functions to end the list: */
-static void
-image_transform_ini_end(const image_transform *this,
- transform_display *that)
-{
- UNUSED(this)
- UNUSED(that)
-}
-
-static void
-image_transform_set_end(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- UNUSED(this)
- UNUSED(that)
- UNUSED(pp)
- UNUSED(pi)
-}
-
-/* At the end of the list recalculate the output image pixel value from the
- * double precision values set up by the preceding 'mod' calls:
- */
-static unsigned int
-sample_scale(double sample_value, unsigned int scale)
-{
- sample_value = floor(sample_value * scale + .5);
-
- /* Return NaN as 0: */
- if (!(sample_value > 0))
- sample_value = 0;
- else if (sample_value > scale)
- sample_value = scale;
-
- return (unsigned int)sample_value;
-}
-
-static void
-image_transform_mod_end(const image_transform *this, image_pixel *that,
- png_const_structp pp, const transform_display *display)
-{
- unsigned int scale = (1U<<that->sample_depth)-1;
- int sig_bits = that->sig_bits;
-
- UNUSED(this)
- UNUSED(pp)
- UNUSED(display)
-
- /* At the end recalculate the digitized red green and blue values according
- * to the current sample_depth of the pixel.
- *
- * The sample value is simply scaled to the maximum, checking for over
- * and underflow (which can both happen for some image transforms,
- * including simple size scaling, though libpng doesn't do that at present.
- */
- that->red = sample_scale(that->redf, scale);
-
- /* This is a bit bogus; really the above calculation should use the red_sBIT
- * value, not sample_depth, but because libpng does png_set_shift by just
- * shifting the bits we get errors if we don't do it the same way.
- */
- if (sig_bits && that->red_sBIT < that->sample_depth)
- that->red >>= that->sample_depth - that->red_sBIT;
-
- /* The error value is increased, at the end, according to the lowest sBIT
- * value seen. Common sense tells us that the intermediate integer
- * representations are no more accurate than +/- 0.5 in the integral values,
- * the sBIT allows the implementation to be worse than this. In addition the
- * PNG specification actually permits any error within the range (-1..+1),
- * but that is ignored here. Instead the final digitized value is compared,
- * below to the digitized value of the error limits - this has the net effect
- * of allowing (almost) +/-1 in the output value. It's difficult to see how
- * any algorithm that digitizes intermediate results can be more accurate.
- */
- that->rede += 1./(2*((1U<<that->red_sBIT)-1));
-
- if (that->colour_type & PNG_COLOR_MASK_COLOR)
- {
- that->green = sample_scale(that->greenf, scale);
- if (sig_bits && that->green_sBIT < that->sample_depth)
- that->green >>= that->sample_depth - that->green_sBIT;
-
- that->blue = sample_scale(that->bluef, scale);
- if (sig_bits && that->blue_sBIT < that->sample_depth)
- that->blue >>= that->sample_depth - that->blue_sBIT;
-
- that->greene += 1./(2*((1U<<that->green_sBIT)-1));
- that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));
- }
- else
- {
- that->blue = that->green = that->red;
- that->bluef = that->greenf = that->redf;
- that->bluee = that->greene = that->rede;
- }
-
- if ((that->colour_type & PNG_COLOR_MASK_ALPHA) ||
- that->colour_type == PNG_COLOR_TYPE_PALETTE)
- {
- that->alpha = sample_scale(that->alphaf, scale);
- that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1));
- }
- else
- {
- that->alpha = scale; /* opaque */
- that->alphaf = 1; /* Override this. */
- that->alphae = 0; /* It's exact ;-) */
- }
-
- if (sig_bits && that->alpha_sBIT < that->sample_depth)
- that->alpha >>= that->sample_depth - that->alpha_sBIT;
-}
-
-/* Static 'end' structure: */
-static image_transform image_transform_end =
-{
- "(end)", /* name */
- 1, /* enable */
- 0, /* list */
- 0, /* global_use */
- 0, /* local_use */
- 0, /* next */
- image_transform_ini_end,
- image_transform_set_end,
- image_transform_mod_end,
- 0 /* never called, I want it to crash if it is! */
-};
-
-/* Reader callbacks and implementations, where they differ from the standard
- * ones.
- */
-static void
-transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id,
- const image_transform *transform_list)
-{
- memset(dp, 0, sizeof *dp);
-
- /* Standard fields */
- standard_display_init(&dp->this, &pm->this, id, do_read_interlace,
- pm->use_update_info);
-
- /* Parameter fields */
- dp->pm = pm;
- dp->transform_list = transform_list;
- dp->max_gamma_8 = 16;
-
- /* Local variable fields */
- dp->output_colour_type = 255; /* invalid */
- dp->output_bit_depth = 255; /* invalid */
- dp->unpacked = 0; /* not unpacked */
-}
-
-static void
-transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
-{
- /* Reuse the standard stuff as appropriate. */
- standard_info_part1(&dp->this, pp, pi);
-
- /* Now set the list of transforms. */
- dp->transform_list->set(dp->transform_list, dp, pp, pi);
-
- /* Update the info structure for these transforms: */
- {
- int i = dp->this.use_update_info;
- /* Always do one call, even if use_update_info is 0. */
- do
- png_read_update_info(pp, pi);
- while (--i > 0);
- }
-
- /* And get the output information into the standard_display */
- standard_info_part2(&dp->this, pp, pi, 1/*images*/);
-
- /* Plus the extra stuff we need for the transform tests: */
- dp->output_colour_type = png_get_color_type(pp, pi);
- dp->output_bit_depth = png_get_bit_depth(pp, pi);
-
- /* If png_set_filler is in action then fake the output color type to include
- * an alpha channel where appropriate.
- */
- if (dp->output_bit_depth >= 8 &&
- (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
- dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
- dp->output_colour_type |= 4;
-
- /* Validate the combination of colour type and bit depth that we are getting
- * out of libpng; the semantics of something not in the PNG spec are, at
- * best, unclear.
- */
- switch (dp->output_colour_type)
- {
- case PNG_COLOR_TYPE_PALETTE:
- if (dp->output_bit_depth > 8) goto error;
- /* FALLTHROUGH */
- case PNG_COLOR_TYPE_GRAY:
- if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 ||
- dp->output_bit_depth == 4)
- break;
- /* FALLTHROUGH */
- default:
- if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16)
- break;
- /* FALLTHROUGH */
- error:
- {
- char message[128];
- size_t pos;
-
- pos = safecat(message, sizeof message, 0,
- "invalid final bit depth: colour type(");
- pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
- pos = safecat(message, sizeof message, pos, ") with bit depth: ");
- pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
-
- png_error(pp, message);
- }
- }
-
- /* Use a test pixel to check that the output agrees with what we expect -
- * this avoids running the whole test if the output is unexpected. This also
- * checks for internal errors.
- */
- {
- image_pixel test_pixel;
-
- memset(&test_pixel, 0, sizeof test_pixel);
- test_pixel.colour_type = dp->this.colour_type; /* input */
- test_pixel.bit_depth = dp->this.bit_depth;
- if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
- test_pixel.sample_depth = 8;
- else
- test_pixel.sample_depth = test_pixel.bit_depth;
- /* Don't need sBIT here, but it must be set to non-zero to avoid
- * arithmetic overflows.
- */
- test_pixel.have_tRNS = dp->this.is_transparent != 0;
- test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT =
- test_pixel.alpha_sBIT = test_pixel.sample_depth;
-
- dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp);
-
- if (test_pixel.colour_type != dp->output_colour_type)
- {
- char message[128];
- size_t pos = safecat(message, sizeof message, 0, "colour type ");
-
- pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
- pos = safecat(message, sizeof message, pos, " expected ");
- pos = safecatn(message, sizeof message, pos, test_pixel.colour_type);
-
- png_error(pp, message);
- }
-
- if (test_pixel.bit_depth != dp->output_bit_depth)
- {
- char message[128];
- size_t pos = safecat(message, sizeof message, 0, "bit depth ");
-
- pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
- pos = safecat(message, sizeof message, pos, " expected ");
- pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
-
- png_error(pp, message);
- }
-
- /* If both bit depth and colour type are correct check the sample depth.
- */
- if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE &&
- test_pixel.sample_depth != 8) /* oops - internal error! */
- png_error(pp, "pngvalid: internal: palette sample depth not 8");
- else if (dp->unpacked && test_pixel.bit_depth != 8)
- png_error(pp, "pngvalid: internal: bad unpacked pixel depth");
- else if (!dp->unpacked && test_pixel.colour_type != PNG_COLOR_TYPE_PALETTE
- && test_pixel.bit_depth != test_pixel.sample_depth)
- {
- char message[128];
- size_t pos = safecat(message, sizeof message, 0,
- "internal: sample depth ");
-
- /* Because unless something has set 'unpacked' or the image is palette
- * mapped we expect the transform to keep sample depth and bit depth
- * the same.
- */
- pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);
- pos = safecat(message, sizeof message, pos, " expected ");
- pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
-
- png_error(pp, message);
- }
- else if (test_pixel.bit_depth != dp->output_bit_depth)
- {
- /* This could be a libpng error too; libpng has not produced what we
- * expect for the output bit depth.
- */
- char message[128];
- size_t pos = safecat(message, sizeof message, 0,
- "internal: bit depth ");
-
- pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
- pos = safecat(message, sizeof message, pos, " expected ");
- pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
-
- png_error(pp, message);
- }
- }
-}
-
-static void PNGCBAPI
-transform_info(png_structp pp, png_infop pi)
-{
- transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)),
- pp, pi);
-}
-
-static void
-transform_range_check(png_const_structp pp, unsigned int r, unsigned int g,
- unsigned int b, unsigned int a, unsigned int in_digitized, double in,
- unsigned int out, png_byte sample_depth, double err, double limit,
- const char *name, double digitization_error)
-{
- /* Compare the scaled, digitzed, values of our local calculation (in+-err)
- * with the digitized values libpng produced; 'sample_depth' is the actual
- * digitization depth of the libpng output colors (the bit depth except for
- * palette images where it is always 8.) The check on 'err' is to detect
- * internal errors in pngvalid itself.
- */
- unsigned int max = (1U<<sample_depth)-1;
- double in_min = ceil((in-err)*max - digitization_error);
- double in_max = floor((in+err)*max + digitization_error);
- if (debugonly(err > limit ||) !(out >= in_min && out <= in_max))
- {
- char message[256];
- size_t pos;
-
- pos = safecat(message, sizeof message, 0, name);
- pos = safecat(message, sizeof message, pos, " output value error: rgba(");
- pos = safecatn(message, sizeof message, pos, r);
- pos = safecat(message, sizeof message, pos, ",");
- pos = safecatn(message, sizeof message, pos, g);
- pos = safecat(message, sizeof message, pos, ",");
- pos = safecatn(message, sizeof message, pos, b);
- pos = safecat(message, sizeof message, pos, ",");
- pos = safecatn(message, sizeof message, pos, a);
- pos = safecat(message, sizeof message, pos, "): ");
- pos = safecatn(message, sizeof message, pos, out);
- pos = safecat(message, sizeof message, pos, " expected: ");
- pos = safecatn(message, sizeof message, pos, in_digitized);
- pos = safecat(message, sizeof message, pos, " (");
- pos = safecatd(message, sizeof message, pos, (in-err)*max, 3);
- pos = safecat(message, sizeof message, pos, "..");
- pos = safecatd(message, sizeof message, pos, (in+err)*max, 3);
- pos = safecat(message, sizeof message, pos, ")");
-
- png_error(pp, message);
- }
-
- UNUSED(limit)
-}
-
-static void
-transform_image_validate(transform_display *dp, png_const_structp pp,
- png_infop pi)
-{
- /* Constants for the loop below: */
- const png_store* const ps = dp->this.ps;
- png_byte in_ct = dp->this.colour_type;
- png_byte in_bd = dp->this.bit_depth;
- png_uint_32 w = dp->this.w;
- png_uint_32 h = dp->this.h;
- png_byte out_ct = dp->output_colour_type;
- png_byte out_bd = dp->output_bit_depth;
- png_byte sample_depth =
- (png_byte)(out_ct == PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);
- png_byte red_sBIT = dp->this.red_sBIT;
- png_byte green_sBIT = dp->this.green_sBIT;
- png_byte blue_sBIT = dp->this.blue_sBIT;
- png_byte alpha_sBIT = dp->this.alpha_sBIT;
- int have_tRNS = dp->this.is_transparent;
- double digitization_error;
-
- store_palette out_palette;
- png_uint_32 y;
-
- UNUSED(pi)
-
- /* Check for row overwrite errors */
- store_image_check(dp->this.ps, pp, 0);
-
- /* Read the palette corresponding to the output if the output colour type
- * indicates a palette, otherwise set out_palette to garbage.
- */
- if (out_ct == PNG_COLOR_TYPE_PALETTE)
- {
- /* Validate that the palette count itself has not changed - this is not
- * expected.
- */
- int npalette = (-1);
-
- (void)read_palette(out_palette, &npalette, pp, pi);
- if (npalette != dp->this.npalette)
- png_error(pp, "unexpected change in palette size");
-
- digitization_error = .5;
- }
- else
- {
- png_byte in_sample_depth;
-
- memset(out_palette, 0x5e, sizeof out_palette);
-
- /* use-input-precision means assume that if the input has 8 bit (or less)
- * samples and the output has 16 bit samples the calculations will be done
- * with 8 bit precision, not 16.
- */
- if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16)
- in_sample_depth = 8;
- else
- in_sample_depth = in_bd;
-
- if (sample_depth != 16 || in_sample_depth > 8 ||
- !dp->pm->calculations_use_input_precision)
- digitization_error = .5;
-
- /* Else calculations are at 8 bit precision, and the output actually
- * consists of scaled 8-bit values, so scale .5 in 8 bits to the 16 bits:
- */
- else
- digitization_error = .5 * 257;
- }
-
- for (y=0; y<h; ++y)
- {
- png_const_bytep const pRow = store_image_row(ps, pp, 0, y);
- png_uint_32 x;
-
- /* The original, standard, row pre-transforms. */
- png_byte std[STANDARD_ROWMAX];
-
- transform_row(pp, std, in_ct, in_bd, y);
-
- /* Go through each original pixel transforming it and comparing with what
- * libpng did to the same pixel.
- */
- for (x=0; x<w; ++x)
- {
- image_pixel in_pixel, out_pixel;
- unsigned int r, g, b, a;
-
- /* Find out what we think the pixel should be: */
- image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette,
- NULL);
-
- in_pixel.red_sBIT = red_sBIT;
- in_pixel.green_sBIT = green_sBIT;
- in_pixel.blue_sBIT = blue_sBIT;
- in_pixel.alpha_sBIT = alpha_sBIT;
- in_pixel.have_tRNS = have_tRNS != 0;
-
- /* For error detection, below. */
- r = in_pixel.red;
- g = in_pixel.green;
- b = in_pixel.blue;
- a = in_pixel.alpha;
-
- /* This applies the transforms to the input data, including output
- * format operations which must be used when reading the output
- * pixel that libpng produces.
- */
- dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp);
-
- /* Read the output pixel and compare it to what we got, we don't
- * use the error field here, so no need to update sBIT. in_pixel
- * says whether we expect libpng to change the output format.
- */
- image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette,
- &in_pixel);
-
- /* We don't expect changes to the index here even if the bit depth is
- * changed.
- */
- if (in_ct == PNG_COLOR_TYPE_PALETTE &&
- out_ct == PNG_COLOR_TYPE_PALETTE)
- {
- if (in_pixel.palette_index != out_pixel.palette_index)
- png_error(pp, "unexpected transformed palette index");
- }
-
- /* Check the colours for palette images too - in fact the palette could
- * be separately verified itself in most cases.
- */
- if (in_pixel.red != out_pixel.red)
- transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf,
- out_pixel.red, sample_depth, in_pixel.rede,
- dp->pm->limit + 1./(2*((1U<<in_pixel.red_sBIT)-1)), "red/gray",
- digitization_error);
-
- if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
- in_pixel.green != out_pixel.green)
- transform_range_check(pp, r, g, b, a, in_pixel.green,
- in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene,
- dp->pm->limit + 1./(2*((1U<<in_pixel.green_sBIT)-1)), "green",
- digitization_error);
-
- if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
- in_pixel.blue != out_pixel.blue)
- transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef,
- out_pixel.blue, sample_depth, in_pixel.bluee,
- dp->pm->limit + 1./(2*((1U<<in_pixel.blue_sBIT)-1)), "blue",
- digitization_error);
-
- if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 &&
- in_pixel.alpha != out_pixel.alpha)
- transform_range_check(pp, r, g, b, a, in_pixel.alpha,
- in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae,
- dp->pm->limit + 1./(2*((1U<<in_pixel.alpha_sBIT)-1)), "alpha",
- digitization_error);
- } /* pixel (x) loop */
- } /* row (y) loop */
-
- /* Record that something was actually checked to avoid a false positive. */
- dp->this.ps->validated = 1;
-}
-
-static void PNGCBAPI
-transform_end(png_structp ppIn, png_infop pi)
-{
- png_const_structp pp = ppIn;
- transform_display *dp = voidcast(transform_display*,
- png_get_progressive_ptr(pp));
-
- if (!dp->this.speed)
- transform_image_validate(dp, pp, pi);
- else
- dp->this.ps->validated = 1;
-}
-
-/* A single test run. */
-static void
-transform_test(png_modifier *pmIn, png_uint_32 idIn,
- const image_transform* transform_listIn, const char * const name)
-{
- transform_display d;
- context(&pmIn->this, fault);
-
- transform_display_init(&d, pmIn, idIn, transform_listIn);
-
- Try
- {
- size_t pos = 0;
- png_structp pp;
- png_infop pi;
- char full_name[256];
-
- /* Make sure the encoding fields are correct and enter the required
- * modifications.
- */
- transform_set_encoding(&d);
-
- /* Add any modifications required by the transform list. */
- d.transform_list->ini(d.transform_list, &d);
-
- /* Add the color space information, if any, to the name. */
- pos = safecat(full_name, sizeof full_name, pos, name);
- pos = safecat_current_encoding(full_name, sizeof full_name, pos, d.pm);
-
- /* Get a png_struct for reading the image. */
- pp = set_modifier_for_read(d.pm, &pi, d.this.id, full_name);
- standard_palette_init(&d.this);
-
-# if 0
- /* Logging (debugging only) */
- {
- char buffer[256];
-
- (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0,
- "running test");
-
- fprintf(stderr, "%s\n", buffer);
- }
-# endif
-
- /* Introduce the correct read function. */
- if (d.pm->this.progressive)
- {
- /* Share the row function with the standard implementation. */
- png_set_progressive_read_fn(pp, &d, transform_info, progressive_row,
- transform_end);
-
- /* Now feed data into the reader until we reach the end: */
- modifier_progressive_read(d.pm, pp, pi);
- }
- else
- {
- /* modifier_read expects a png_modifier* */
- png_set_read_fn(pp, d.pm, modifier_read);
-
- /* Check the header values: */
- png_read_info(pp, pi);
-
- /* Process the 'info' requirements. Only one image is generated */
- transform_info_imp(&d, pp, pi);
-
- sequential_row(&d.this, pp, pi, -1, 0);
-
- if (!d.this.speed)
- transform_image_validate(&d, pp, pi);
- else
- d.this.ps->validated = 1;
- }
-
- modifier_reset(d.pm);
- }
-
- Catch(fault)
- {
- modifier_reset(voidcast(png_modifier*,(void*)fault));
- }
-}
-
-/* The transforms: */
-#define ITSTRUCT(name) image_transform_##name
-#define ITDATA(name) image_transform_data_##name
-#define image_transform_ini image_transform_default_ini
-#define IT(name)\
-static image_transform ITSTRUCT(name) =\
-{\
- #name,\
- 1, /*enable*/\
- &PT, /*list*/\
- 0, /*global_use*/\
- 0, /*local_use*/\
- 0, /*next*/\
- image_transform_ini,\
- image_transform_png_set_##name##_set,\
- image_transform_png_set_##name##_mod,\
- image_transform_png_set_##name##_add\
-}
-#define PT ITSTRUCT(end) /* stores the previous transform */
-
-/* To save code: */
-extern void image_transform_default_ini(const image_transform *this,
- transform_display *that); /* silence GCC warnings */
-
-void /* private, but almost always needed */
-image_transform_default_ini(const image_transform *this,
- transform_display *that)
-{
- this->next->ini(this->next, that);
-}
-
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-static int
-image_transform_default_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(colour_type)
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return 1;
-}
-#endif
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-/* png_set_palette_to_rgb */
-static void
-image_transform_png_set_palette_to_rgb_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_palette_to_rgb(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_palette_to_rgb_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
- image_pixel_convert_PLTE(that);
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_palette_to_rgb_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return colour_type == PNG_COLOR_TYPE_PALETTE;
-}
-
-IT(palette_to_rgb);
-#undef PT
-#define PT ITSTRUCT(palette_to_rgb)
-#endif /* PNG_READ_EXPAND_SUPPORTED */
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-/* png_set_tRNS_to_alpha */
-static void
-image_transform_png_set_tRNS_to_alpha_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_tRNS_to_alpha(pp);
-
- /* If there was a tRNS chunk that would get expanded and add an alpha
- * channel is_transparent must be updated:
- */
- if (that->this.has_tRNS)
- that->this.is_transparent = 1;
-
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_tRNS_to_alpha_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
-#if PNG_LIBPNG_VER < 10700
- /* LIBPNG BUG: this always forces palette images to RGB. */
- if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
- image_pixel_convert_PLTE(that);
-#endif
-
- /* This effectively does an 'expand' only if there is some transparency to
- * convert to an alpha channel.
- */
- if (that->have_tRNS)
-# if PNG_LIBPNG_VER >= 10700
- if (that->colour_type != PNG_COLOR_TYPE_PALETTE &&
- (that->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
-# endif
- image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
-
-#if PNG_LIBPNG_VER < 10700
- /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */
- else
- {
- if (that->bit_depth < 8)
- that->bit_depth =8;
- if (that->sample_depth < 8)
- that->sample_depth = 8;
- }
-#endif
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_tRNS_to_alpha_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- /* We don't know yet whether there will be a tRNS chunk, but we know that
- * this transformation should do nothing if there already is an alpha
- * channel. In addition, after the bug fix in 1.7.0, there is no longer
- * any action on a palette image.
- */
- return
-# if PNG_LIBPNG_VER >= 10700
- colour_type != PNG_COLOR_TYPE_PALETTE &&
-# endif
- (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
-}
-
-IT(tRNS_to_alpha);
-#undef PT
-#define PT ITSTRUCT(tRNS_to_alpha)
-#endif /* PNG_READ_EXPAND_SUPPORTED */
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-/* png_set_gray_to_rgb */
-static void
-image_transform_png_set_gray_to_rgb_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_gray_to_rgb(pp);
- /* NOTE: this doesn't result in tRNS expansion. */
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_gray_to_rgb_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- /* NOTE: we can actually pend the tRNS processing at this point because we
- * can correctly recognize the original pixel value even though we have
- * mapped the one gray channel to the three RGB ones, but in fact libpng
- * doesn't do this, so we don't either.
- */
- if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS)
- image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
-
- /* Simply expand the bit depth and alter the colour type as required. */
- if (that->colour_type == PNG_COLOR_TYPE_GRAY)
- {
- /* RGB images have a bit depth at least equal to '8' */
- if (that->bit_depth < 8)
- that->sample_depth = that->bit_depth = 8;
-
- /* And just changing the colour type works here because the green and blue
- * channels are being maintained in lock-step with the red/gray:
- */
- that->colour_type = PNG_COLOR_TYPE_RGB;
- }
-
- else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_gray_to_rgb_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return (colour_type & PNG_COLOR_MASK_COLOR) == 0;
-}
-
-IT(gray_to_rgb);
-#undef PT
-#define PT ITSTRUCT(gray_to_rgb)
-#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-/* png_set_expand */
-static void
-image_transform_png_set_expand_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_expand(pp);
-
- if (that->this.has_tRNS)
- that->this.is_transparent = 1;
-
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_expand_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- /* The general expand case depends on what the colour type is: */
- if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
- image_pixel_convert_PLTE(that);
- else if (that->bit_depth < 8) /* grayscale */
- that->sample_depth = that->bit_depth = 8;
-
- if (that->have_tRNS)
- image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_expand_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit
- * depth is at least 8 already.
- */
- return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
-}
-
-IT(expand);
-#undef PT
-#define PT ITSTRUCT(expand)
-#endif /* PNG_READ_EXPAND_SUPPORTED */
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-/* png_set_expand_gray_1_2_4_to_8
- * Pre 1.7.0 LIBPNG BUG: this just does an 'expand'
- */
-static void
-image_transform_png_set_expand_gray_1_2_4_to_8_set(
- const image_transform *this, transform_display *that, png_structp pp,
- png_infop pi)
-{
- png_set_expand_gray_1_2_4_to_8(pp);
- /* NOTE: don't expect this to expand tRNS */
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_expand_gray_1_2_4_to_8_mod(
- const image_transform *this, image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
-#if PNG_LIBPNG_VER < 10700
- image_transform_png_set_expand_mod(this, that, pp, display);
-#else
- /* Only expand grayscale of bit depth less than 8: */
- if (that->colour_type == PNG_COLOR_TYPE_GRAY &&
- that->bit_depth < 8)
- that->sample_depth = that->bit_depth = 8;
-
- this->next->mod(this->next, that, pp, display);
-#endif /* 1.7 or later */
-}
-
-static int
-image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
-#if PNG_LIBPNG_VER < 10700
- return image_transform_png_set_expand_add(this, that, colour_type,
- bit_depth);
-#else
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- /* This should do nothing unless the color type is gray and the bit depth is
- * less than 8:
- */
- return colour_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8;
-#endif /* 1.7 or later */
-}
-
-IT(expand_gray_1_2_4_to_8);
-#undef PT
-#define PT ITSTRUCT(expand_gray_1_2_4_to_8)
-#endif /* PNG_READ_EXPAND_SUPPORTED */
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-/* png_set_expand_16 */
-static void
-image_transform_png_set_expand_16_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_expand_16(pp);
-
- /* NOTE: prior to 1.7 libpng does SET_EXPAND as well, so tRNS is expanded. */
-# if PNG_LIBPNG_VER < 10700
- if (that->this.has_tRNS)
- that->this.is_transparent = 1;
-# endif
-
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_expand_16_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- /* Expect expand_16 to expand everything to 16 bits as a result of also
- * causing 'expand' to happen.
- */
- if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
- image_pixel_convert_PLTE(that);
-
- if (that->have_tRNS)
- image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
-
- if (that->bit_depth < 16)
- that->sample_depth = that->bit_depth = 16;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_expand_16_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(colour_type)
-
- this->next = *that;
- *that = this;
-
- /* expand_16 does something unless the bit depth is already 16. */
- return bit_depth < 16;
-}
-
-IT(expand_16);
-#undef PT
-#define PT ITSTRUCT(expand_16)
-#endif /* PNG_READ_EXPAND_16_SUPPORTED */
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED /* API added in 1.5.4 */
-/* png_set_scale_16 */
-static void
-image_transform_png_set_scale_16_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_scale_16(pp);
-# if PNG_LIBPNG_VER < 10700
- /* libpng will limit the gamma table size: */
- that->max_gamma_8 = PNG_MAX_GAMMA_8;
-# endif
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_scale_16_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->bit_depth == 16)
- {
- that->sample_depth = that->bit_depth = 8;
- if (that->red_sBIT > 8) that->red_sBIT = 8;
- if (that->green_sBIT > 8) that->green_sBIT = 8;
- if (that->blue_sBIT > 8) that->blue_sBIT = 8;
- if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
- }
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_scale_16_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(colour_type)
-
- this->next = *that;
- *that = this;
-
- return bit_depth > 8;
-}
-
-IT(scale_16);
-#undef PT
-#define PT ITSTRUCT(scale_16)
-#endif /* PNG_READ_SCALE_16_TO_8_SUPPORTED (1.5.4 on) */
-
-#ifdef PNG_READ_16_TO_8_SUPPORTED /* the default before 1.5.4 */
-/* png_set_strip_16 */
-static void
-image_transform_png_set_strip_16_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_strip_16(pp);
-# if PNG_LIBPNG_VER < 10700
- /* libpng will limit the gamma table size: */
- that->max_gamma_8 = PNG_MAX_GAMMA_8;
-# endif
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_strip_16_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->bit_depth == 16)
- {
- that->sample_depth = that->bit_depth = 8;
- if (that->red_sBIT > 8) that->red_sBIT = 8;
- if (that->green_sBIT > 8) that->green_sBIT = 8;
- if (that->blue_sBIT > 8) that->blue_sBIT = 8;
- if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
-
- /* Prior to 1.5.4 png_set_strip_16 would use an 'accurate' method if this
- * configuration option is set. From 1.5.4 the flag is never set and the
- * 'scale' API (above) must be used.
- */
-# ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED
-# if PNG_LIBPNG_VER >= 10504
-# error PNG_READ_ACCURATE_SCALE should not be set
-# endif
-
- /* The strip 16 algorithm drops the low 8 bits rather than calculating
- * 1/257, so we need to adjust the permitted errors appropriately:
- * Notice that this is only relevant prior to the addition of the
- * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!)
- */
- {
- const double d = (255-128.5)/65535;
- that->rede += d;
- that->greene += d;
- that->bluee += d;
- that->alphae += d;
- }
-# endif
- }
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_strip_16_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(colour_type)
-
- this->next = *that;
- *that = this;
-
- return bit_depth > 8;
-}
-
-IT(strip_16);
-#undef PT
-#define PT ITSTRUCT(strip_16)
-#endif /* PNG_READ_16_TO_8_SUPPORTED */
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-/* png_set_strip_alpha */
-static void
-image_transform_png_set_strip_alpha_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_strip_alpha(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_strip_alpha_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_GRAY;
- else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_RGB;
-
- that->have_tRNS = 0;
- that->alphaf = 1;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_strip_alpha_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return (colour_type & PNG_COLOR_MASK_ALPHA) != 0;
-}
-
-IT(strip_alpha);
-#undef PT
-#define PT ITSTRUCT(strip_alpha)
-#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-/* png_set_rgb_to_gray(png_structp, int err_action, double red, double green)
- * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red,
- * png_fixed_point green)
- * png_get_rgb_to_gray_status
- *
- * The 'default' test here uses values known to be used inside libpng prior to
- * 1.7.0:
- *
- * red: 6968
- * green: 23434
- * blue: 2366
- *
- * These values are being retained for compatibility, along with the somewhat
- * broken truncation calculation in the fast-and-inaccurate code path. Older
- * versions of libpng will fail the accuracy tests below because they use the
- * truncation algorithm everywhere.
- */
-#define data ITDATA(rgb_to_gray)
-static struct
-{
- double gamma; /* File gamma to use in processing */
-
- /* The following are the parameters for png_set_rgb_to_gray: */
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- double red_to_set;
- double green_to_set;
-# else
- png_fixed_point red_to_set;
- png_fixed_point green_to_set;
-# endif
-
- /* The actual coefficients: */
- double red_coefficient;
- double green_coefficient;
- double blue_coefficient;
-
- /* Set if the coeefficients have been overridden. */
- int coefficients_overridden;
-} data;
-
-#undef image_transform_ini
-#define image_transform_ini image_transform_png_set_rgb_to_gray_ini
-static void
-image_transform_png_set_rgb_to_gray_ini(const image_transform *this,
- transform_display *that)
-{
- png_modifier *pm = that->pm;
- const color_encoding *e = pm->current_encoding;
-
- UNUSED(this)
-
- /* Since we check the encoding this flag must be set: */
- pm->test_uses_encoding = 1;
-
- /* If 'e' is not NULL chromaticity information is present and either a cHRM
- * or an sRGB chunk will be inserted.
- */
- if (e != 0)
- {
- /* Coefficients come from the encoding, but may need to be normalized to a
- * white point Y of 1.0
- */
- const double whiteY = e->red.Y + e->green.Y + e->blue.Y;
-
- data.red_coefficient = e->red.Y;
- data.green_coefficient = e->green.Y;
- data.blue_coefficient = e->blue.Y;
-
- if (whiteY != 1)
- {
- data.red_coefficient /= whiteY;
- data.green_coefficient /= whiteY;
- data.blue_coefficient /= whiteY;
- }
- }
-
- else
- {
- /* The default (built in) coeffcients, as above: */
-# if PNG_LIBPNG_VER < 10700
- data.red_coefficient = 6968 / 32768.;
- data.green_coefficient = 23434 / 32768.;
- data.blue_coefficient = 2366 / 32768.;
-# else
- data.red_coefficient = .2126;
- data.green_coefficient = .7152;
- data.blue_coefficient = .0722;
-# endif
- }
-
- data.gamma = pm->current_gamma;
-
- /* If not set then the calculations assume linear encoding (implicitly): */
- if (data.gamma == 0)
- data.gamma = 1;
-
- /* The arguments to png_set_rgb_to_gray can override the coefficients implied
- * by the color space encoding. If doing exhaustive checks do the override
- * in each case, otherwise do it randomly.
- */
- if (pm->test_exhaustive)
- {
- /* First time in coefficients_overridden is 0, the following sets it to 1,
- * so repeat if it is set. If a test fails this may mean we subsequently
- * skip a non-override test, ignore that.
- */
- data.coefficients_overridden = !data.coefficients_overridden;
- pm->repeat = data.coefficients_overridden != 0;
- }
-
- else
- data.coefficients_overridden = random_choice();
-
- if (data.coefficients_overridden)
- {
- /* These values override the color encoding defaults, simply use random
- * numbers.
- */
- png_uint_32 ru;
- double total;
-
- ru = random_u32();
- data.green_coefficient = total = (ru & 0xffff) / 65535.;
- ru >>= 16;
- data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.;
- total += data.red_coefficient;
- data.blue_coefficient = 1 - total;
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- data.red_to_set = data.red_coefficient;
- data.green_to_set = data.green_coefficient;
-# else
- data.red_to_set = fix(data.red_coefficient);
- data.green_to_set = fix(data.green_coefficient);
-# endif
-
- /* The following just changes the error messages: */
- pm->encoding_ignored = 1;
- }
-
- else
- {
- data.red_to_set = -1;
- data.green_to_set = -1;
- }
-
- /* Adjust the error limit in the png_modifier because of the larger errors
- * produced in the digitization during the gamma handling.
- */
- if (data.gamma != 1) /* Use gamma tables */
- {
- if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations)
- {
- /* The computations have the form:
- *
- * r * rc + g * gc + b * bc
- *
- * Each component of which is +/-1/65535 from the gamma_to_1 table
- * lookup, resulting in a base error of +/-6. The gamma_from_1
- * conversion adds another +/-2 in the 16-bit case and
- * +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case.
- */
-# if PNG_LIBPNG_VER < 10700
- if (that->this.bit_depth < 16)
- that->max_gamma_8 = PNG_MAX_GAMMA_8;
-# endif
- that->pm->limit += pow(
- (that->this.bit_depth == 16 || that->max_gamma_8 > 14 ?
- 8. :
- 6. + (1<<(15-that->max_gamma_8))
- )/65535, data.gamma);
- }
-
- else
- {
- /* Rounding to 8 bits in the linear space causes massive errors which
- * will trigger the error check in transform_range_check. Fix that
- * here by taking the gamma encoding into account.
- *
- * When DIGITIZE is set because a pre-1.7 version of libpng is being
- * tested allow a bigger slack.
- *
- * NOTE: this number only affects the internal limit check in pngvalid,
- * it has no effect on the limits applied to the libpng values.
- */
-#if DIGITIZE
- that->pm->limit += pow( 2.0/255, data.gamma);
-#else
- that->pm->limit += pow( 1.0/255, data.gamma);
-#endif
- }
- }
-
- else
- {
- /* With no gamma correction a large error comes from the truncation of the
- * calculation in the 8 bit case, allow for that here.
- */
- if (that->this.bit_depth != 16 && !pm->assume_16_bit_calculations)
- that->pm->limit += 4E-3;
- }
-}
-
-static void
-image_transform_png_set_rgb_to_gray_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- int error_action = 1; /* no error, no defines in png.h */
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set);
-# else
- png_set_rgb_to_gray_fixed(pp, error_action, data.red_to_set,
- data.green_to_set);
-# endif
-
-# ifdef PNG_READ_cHRM_SUPPORTED
- if (that->pm->current_encoding != 0)
- {
- /* We have an encoding so a cHRM chunk may have been set; if so then
- * check that the libpng APIs give the correct (X,Y,Z) values within
- * some margin of error for the round trip through the chromaticity
- * form.
- */
-# ifdef PNG_FLOATING_POINT_SUPPORTED
-# define API_function png_get_cHRM_XYZ
-# define API_form "FP"
-# define API_type double
-# define API_cvt(x) (x)
-# else
-# define API_function png_get_cHRM_XYZ_fixed
-# define API_form "fixed"
-# define API_type png_fixed_point
-# define API_cvt(x) ((double)(x)/PNG_FP_1)
-# endif
-
- API_type rX, gX, bX;
- API_type rY, gY, bY;
- API_type rZ, gZ, bZ;
-
- if ((API_function(pp, pi, &rX, &rY, &rZ, &gX, &gY, &gZ, &bX, &bY, &bZ)
- & PNG_INFO_cHRM) != 0)
- {
- double maxe;
- const char *el;
- color_encoding e, o;
-
- /* Expect libpng to return a normalized result, but the original
- * color space encoding may not be normalized.
- */
- modifier_current_encoding(that->pm, &o);
- normalize_color_encoding(&o);
-
- /* Sanity check the pngvalid code - the coefficients should match
- * the normalized Y values of the encoding unless they were
- * overridden.
- */
- if (data.red_to_set == -1 && data.green_to_set == -1 &&
- (fabs(o.red.Y - data.red_coefficient) > DBL_EPSILON ||
- fabs(o.green.Y - data.green_coefficient) > DBL_EPSILON ||
- fabs(o.blue.Y - data.blue_coefficient) > DBL_EPSILON))
- png_error(pp, "internal pngvalid cHRM coefficient error");
-
- /* Generate a colour space encoding. */
- e.gamma = o.gamma; /* not used */
- e.red.X = API_cvt(rX);
- e.red.Y = API_cvt(rY);
- e.red.Z = API_cvt(rZ);
- e.green.X = API_cvt(gX);
- e.green.Y = API_cvt(gY);
- e.green.Z = API_cvt(gZ);
- e.blue.X = API_cvt(bX);
- e.blue.Y = API_cvt(bY);
- e.blue.Z = API_cvt(bZ);
-
- /* This should match the original one from the png_modifier, within
- * the range permitted by the libpng fixed point representation.
- */
- maxe = 0;
- el = "-"; /* Set to element name with error */
-
-# define CHECK(col,x)\
- {\
- double err = fabs(o.col.x - e.col.x);\
- if (err > maxe)\
- {\
- maxe = err;\
- el = #col "(" #x ")";\
- }\
- }
-
- CHECK(red,X)
- CHECK(red,Y)
- CHECK(red,Z)
- CHECK(green,X)
- CHECK(green,Y)
- CHECK(green,Z)
- CHECK(blue,X)
- CHECK(blue,Y)
- CHECK(blue,Z)
-
- /* Here in both fixed and floating cases to check the values read
- * from the cHRm chunk. PNG uses fixed point in the cHRM chunk, so
- * we can't expect better than +/-.5E-5 on the result, allow 1E-5.
- */
- if (maxe >= 1E-5)
- {
- size_t pos = 0;
- char buffer[256];
-
- pos = safecat(buffer, sizeof buffer, pos, API_form);
- pos = safecat(buffer, sizeof buffer, pos, " cHRM ");
- pos = safecat(buffer, sizeof buffer, pos, el);
- pos = safecat(buffer, sizeof buffer, pos, " error: ");
- pos = safecatd(buffer, sizeof buffer, pos, maxe, 7);
- pos = safecat(buffer, sizeof buffer, pos, " ");
- /* Print the color space without the gamma value: */
- pos = safecat_color_encoding(buffer, sizeof buffer, pos, &o, 0);
- pos = safecat(buffer, sizeof buffer, pos, " -> ");
- pos = safecat_color_encoding(buffer, sizeof buffer, pos, &e, 0);
-
- png_error(pp, buffer);
- }
- }
- }
-# endif /* READ_cHRM */
-
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0)
- {
- double gray, err;
-
-# if PNG_LIBPNG_VER < 10700
- if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
- image_pixel_convert_PLTE(that);
-# endif
-
- /* Image now has RGB channels... */
-# if DIGITIZE
- {
- png_modifier *pm = display->pm;
- unsigned int sample_depth = that->sample_depth;
- unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
- sample_depth);
- unsigned int gamma_depth =
- (sample_depth == 16 ?
- display->max_gamma_8 :
- (pm->assume_16_bit_calculations ?
- display->max_gamma_8 :
- sample_depth));
- int isgray;
- double r, g, b;
- double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi;
-
- /* Do this using interval arithmetic, otherwise it is too difficult to
- * handle the errors correctly.
- *
- * To handle the gamma correction work out the upper and lower bounds
- * of the digitized value. Assume rounding here - normally the values
- * will be identical after this operation if there is only one
- * transform, feel free to delete the png_error checks on this below in
- * the future (this is just me trying to ensure it works!)
- *
- * Interval arithmetic is exact, but to implement it it must be
- * possible to control the floating point implementation rounding mode.
- * This cannot be done in ANSI-C, so instead I reduce the 'lo' values
- * by DBL_EPSILON and increase the 'hi' values by the same.
- */
-# define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON))
-# define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON))
-
- r = rlo = rhi = that->redf;
- rlo -= that->rede;
- rlo = DD(rlo, calc_depth, 1/*round*/);
- rhi += that->rede;
- rhi = DU(rhi, calc_depth, 1/*round*/);
-
- g = glo = ghi = that->greenf;
- glo -= that->greene;
- glo = DD(glo, calc_depth, 1/*round*/);
- ghi += that->greene;
- ghi = DU(ghi, calc_depth, 1/*round*/);
-
- b = blo = bhi = that->bluef;
- blo -= that->bluee;
- blo = DD(blo, calc_depth, 1/*round*/);
- bhi += that->bluee;
- bhi = DU(bhi, calc_depth, 1/*round*/);
-
- isgray = r==g && g==b;
-
- if (data.gamma != 1)
- {
- const double power = 1/data.gamma;
- const double abse = .5/(sample_depth == 16 ? 65535 : 255);
-
- /* If a gamma calculation is done it is done using lookup tables of
- * precision gamma_depth, so the already digitized value above may
- * need to be further digitized here.
- */
- if (gamma_depth != calc_depth)
- {
- rlo = DD(rlo, gamma_depth, 0/*truncate*/);
- rhi = DU(rhi, gamma_depth, 0/*truncate*/);
- glo = DD(glo, gamma_depth, 0/*truncate*/);
- ghi = DU(ghi, gamma_depth, 0/*truncate*/);
- blo = DD(blo, gamma_depth, 0/*truncate*/);
- bhi = DU(bhi, gamma_depth, 0/*truncate*/);
- }
-
- /* 'abse' is the error in the gamma table calculation itself. */
- r = pow(r, power);
- rlo = DD(pow(rlo, power)-abse, calc_depth, 1);
- rhi = DU(pow(rhi, power)+abse, calc_depth, 1);
-
- g = pow(g, power);
- glo = DD(pow(glo, power)-abse, calc_depth, 1);
- ghi = DU(pow(ghi, power)+abse, calc_depth, 1);
-
- b = pow(b, power);
- blo = DD(pow(blo, power)-abse, calc_depth, 1);
- bhi = DU(pow(bhi, power)+abse, calc_depth, 1);
- }
-
- /* Now calculate the actual gray values. Although the error in the
- * coefficients depends on whether they were specified on the command
- * line (in which case truncation to 15 bits happened) or not (rounding
- * was used) the maximum error in an individual coefficient is always
- * 2/32768, because even in the rounding case the requirement that
- * coefficients add up to 32768 can cause a larger rounding error.
- *
- * The only time when rounding doesn't occur in 1.5.5 and later is when
- * the non-gamma code path is used for less than 16 bit data.
- */
- gray = r * data.red_coefficient + g * data.green_coefficient +
- b * data.blue_coefficient;
-
- {
- int do_round = data.gamma != 1 || calc_depth == 16;
- const double ce = 2. / 32768;
-
- graylo = DD(rlo * (data.red_coefficient-ce) +
- glo * (data.green_coefficient-ce) +
- blo * (data.blue_coefficient-ce), calc_depth, do_round);
- if (graylo > gray) /* always accept the right answer */
- graylo = gray;
-
- grayhi = DU(rhi * (data.red_coefficient+ce) +
- ghi * (data.green_coefficient+ce) +
- bhi * (data.blue_coefficient+ce), calc_depth, do_round);
- if (grayhi < gray)
- grayhi = gray;
- }
-
- /* And invert the gamma. */
- if (data.gamma != 1)
- {
- const double power = data.gamma;
-
- /* And this happens yet again, shifting the values once more. */
- if (gamma_depth != sample_depth)
- {
- rlo = DD(rlo, gamma_depth, 0/*truncate*/);
- rhi = DU(rhi, gamma_depth, 0/*truncate*/);
- glo = DD(glo, gamma_depth, 0/*truncate*/);
- ghi = DU(ghi, gamma_depth, 0/*truncate*/);
- blo = DD(blo, gamma_depth, 0/*truncate*/);
- bhi = DU(bhi, gamma_depth, 0/*truncate*/);
- }
-
- gray = pow(gray, power);
- graylo = DD(pow(graylo, power), sample_depth, 1);
- grayhi = DU(pow(grayhi, power), sample_depth, 1);
- }
-
-# undef DD
-# undef DU
-
- /* Now the error can be calculated.
- *
- * If r==g==b because there is no overall gamma correction libpng
- * currently preserves the original value.
- */
- if (isgray)
- err = (that->rede + that->greene + that->bluee)/3;
-
- else
- {
- err = fabs(grayhi-gray);
-
- if (fabs(gray - graylo) > err)
- err = fabs(graylo-gray);
-
-#if !RELEASE_BUILD
- /* Check that this worked: */
- if (err > pm->limit)
- {
- size_t pos = 0;
- char buffer[128];
-
- pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error ");
- pos = safecatd(buffer, sizeof buffer, pos, err, 6);
- pos = safecat(buffer, sizeof buffer, pos, " exceeds limit ");
- pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);
- png_warning(pp, buffer);
- pm->limit = err;
- }
-#endif /* !RELEASE_BUILD */
- }
- }
-# else /* !DIGITIZE */
- {
- double r = that->redf;
- double re = that->rede;
- double g = that->greenf;
- double ge = that->greene;
- double b = that->bluef;
- double be = that->bluee;
-
-# if PNG_LIBPNG_VER < 10700
- /* The true gray case involves no math in earlier versions (not
- * true, there was some if gamma correction was happening too.)
- */
- if (r == g && r == b)
- {
- gray = r;
- err = re;
- if (err < ge) err = ge;
- if (err < be) err = be;
- }
-
- else
-# endif /* before 1.7 */
- if (data.gamma == 1)
- {
- /* There is no need to do the conversions to and from linear space,
- * so the calculation should be a lot more accurate. There is a
- * built in error in the coefficients because they only have 15 bits
- * and are adjusted to make sure they add up to 32768. This
- * involves a integer calculation with truncation of the form:
- *
- * ((int)(coefficient * 100000) * 32768)/100000
- *
- * This is done to the red and green coefficients (the ones
- * provided to the API) then blue is calculated from them so the
- * result adds up to 32768. In the worst case this can result in
- * a -1 error in red and green and a +2 error in blue. Consequently
- * the worst case in the calculation below is 2/32768 error.
- *
- * TODO: consider fixing this in libpng by rounding the calculation
- * limiting the error to 1/32768.
- *
- * Handling this by adding 2/32768 here avoids needing to increase
- * the global error limits to take this into account.)
- */
- gray = r * data.red_coefficient + g * data.green_coefficient +
- b * data.blue_coefficient;
- err = re * data.red_coefficient + ge * data.green_coefficient +
- be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON;
- }
-
- else
- {
- /* The calculation happens in linear space, and this produces much
- * wider errors in the encoded space. These are handled here by
- * factoring the errors in to the calculation. There are two table
- * lookups in the calculation and each introduces a quantization
- * error defined by the table size.
- */
- png_modifier *pm = display->pm;
- double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255);
- double out_qe = (that->sample_depth > 8 ? .5/65535 :
- (pm->assume_16_bit_calculations ? .5/(1<<display->max_gamma_8) :
- .5/255));
- double rhi, ghi, bhi, grayhi;
- double g1 = 1/data.gamma;
-
- rhi = r + re + in_qe; if (rhi > 1) rhi = 1;
- r -= re + in_qe; if (r < 0) r = 0;
- ghi = g + ge + in_qe; if (ghi > 1) ghi = 1;
- g -= ge + in_qe; if (g < 0) g = 0;
- bhi = b + be + in_qe; if (bhi > 1) bhi = 1;
- b -= be + in_qe; if (b < 0) b = 0;
-
- r = pow(r, g1)*(1-DBL_EPSILON); rhi = pow(rhi, g1)*(1+DBL_EPSILON);
- g = pow(g, g1)*(1-DBL_EPSILON); ghi = pow(ghi, g1)*(1+DBL_EPSILON);
- b = pow(b, g1)*(1-DBL_EPSILON); bhi = pow(bhi, g1)*(1+DBL_EPSILON);
-
- /* Work out the lower and upper bounds for the gray value in the
- * encoded space, then work out an average and error. Remove the
- * previously added input quantization error at this point.
- */
- gray = r * data.red_coefficient + g * data.green_coefficient +
- b * data.blue_coefficient - 2./32768 - out_qe;
- if (gray <= 0)
- gray = 0;
- else
- {
- gray *= (1 - 6 * DBL_EPSILON);
- gray = pow(gray, data.gamma) * (1-DBL_EPSILON);
- }
-
- grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient +
- bhi * data.blue_coefficient + 2./32768 + out_qe;
- grayhi *= (1 + 6 * DBL_EPSILON);
- if (grayhi >= 1)
- grayhi = 1;
- else
- grayhi = pow(grayhi, data.gamma) * (1+DBL_EPSILON);
-
- err = (grayhi - gray) / 2;
- gray = (grayhi + gray) / 2;
-
- if (err <= in_qe)
- err = gray * DBL_EPSILON;
-
- else
- err -= in_qe;
-
-#if !RELEASE_BUILD
- /* Validate that the error is within limits (this has caused
- * problems before, it's much easier to detect them here.)
- */
- if (err > pm->limit)
- {
- size_t pos = 0;
- char buffer[128];
-
- pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error ");
- pos = safecatd(buffer, sizeof buffer, pos, err, 6);
- pos = safecat(buffer, sizeof buffer, pos, " exceeds limit ");
- pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);
- png_warning(pp, buffer);
- pm->limit = err;
- }
-#endif /* !RELEASE_BUILD */
- }
- }
-# endif /* !DIGITIZE */
-
- that->bluef = that->greenf = that->redf = gray;
- that->bluee = that->greene = that->rede = err;
-
- /* The sBIT is the minimum of the three colour channel sBITs. */
- if (that->red_sBIT > that->green_sBIT)
- that->red_sBIT = that->green_sBIT;
- if (that->red_sBIT > that->blue_sBIT)
- that->red_sBIT = that->blue_sBIT;
- that->blue_sBIT = that->green_sBIT = that->red_sBIT;
-
- /* And remove the colour bit in the type: */
- if (that->colour_type == PNG_COLOR_TYPE_RGB)
- that->colour_type = PNG_COLOR_TYPE_GRAY;
- else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- }
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_rgb_to_gray_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return (colour_type & PNG_COLOR_MASK_COLOR) != 0;
-}
-
-#undef data
-IT(rgb_to_gray);
-#undef PT
-#define PT ITSTRUCT(rgb_to_gray)
-#undef image_transform_ini
-#define image_transform_ini image_transform_default_ini
-#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */
-
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
-/* png_set_background(png_structp, png_const_color_16p background_color,
- * int background_gamma_code, int need_expand, double background_gamma)
- * png_set_background_fixed(png_structp, png_const_color_16p background_color,
- * int background_gamma_code, int need_expand,
- * png_fixed_point background_gamma)
- *
- * This ignores the gamma (at present.)
-*/
-#define data ITDATA(background)
-static image_pixel data;
-
-static void
-image_transform_png_set_background_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_byte colour_type, bit_depth;
- png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */
- int expand;
- png_color_16 back;
-
- /* We need a background colour, because we don't know exactly what transforms
- * have been set we have to supply the colour in the original file format and
- * so we need to know what that is! The background colour is stored in the
- * transform_display.
- */
- R8(random_bytes);
-
- /* Read the random value, for colour type 3 the background colour is actually
- * expressed as a 24bit rgb, not an index.
- */
- colour_type = that->this.colour_type;
- if (colour_type == 3)
- {
- colour_type = PNG_COLOR_TYPE_RGB;
- bit_depth = 8;
- expand = 0; /* passing in an RGB not a pixel index */
- }
-
- else
- {
- if (that->this.has_tRNS)
- that->this.is_transparent = 1;
-
- bit_depth = that->this.bit_depth;
- expand = 1;
- }
-
- image_pixel_init(&data, random_bytes, colour_type,
- bit_depth, 0/*x*/, 0/*unused: palette*/, NULL/*format*/);
-
- /* Extract the background colour from this image_pixel, but make sure the
- * unused fields of 'back' are garbage.
- */
- R8(back);
-
- if (colour_type & PNG_COLOR_MASK_COLOR)
- {
- back.red = (png_uint_16)data.red;
- back.green = (png_uint_16)data.green;
- back.blue = (png_uint_16)data.blue;
- }
-
- else
- back.gray = (png_uint_16)data.red;
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
-#else
- png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
-#endif
-
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_background_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- /* Check for tRNS first: */
- if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE)
- image_pixel_add_alpha(that, &display->this, 1/*for background*/);
-
- /* This is only necessary if the alpha value is less than 1. */
- if (that->alphaf < 1)
- {
- /* Now we do the background calculation without any gamma correction. */
- if (that->alphaf <= 0)
- {
- that->redf = data.redf;
- that->greenf = data.greenf;
- that->bluef = data.bluef;
-
- that->rede = data.rede;
- that->greene = data.greene;
- that->bluee = data.bluee;
-
- that->red_sBIT= data.red_sBIT;
- that->green_sBIT= data.green_sBIT;
- that->blue_sBIT= data.blue_sBIT;
- }
-
- else /* 0 < alpha < 1 */
- {
- double alf = 1 - that->alphaf;
-
- that->redf = that->redf * that->alphaf + data.redf * alf;
- that->rede = that->rede * that->alphaf + data.rede * alf +
- DBL_EPSILON;
- that->greenf = that->greenf * that->alphaf + data.greenf * alf;
- that->greene = that->greene * that->alphaf + data.greene * alf +
- DBL_EPSILON;
- that->bluef = that->bluef * that->alphaf + data.bluef * alf;
- that->bluee = that->bluee * that->alphaf + data.bluee * alf +
- DBL_EPSILON;
- }
-
- /* Remove the alpha type and set the alpha (not in that order.) */
- that->alphaf = 1;
- that->alphae = 0;
- }
-
- if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_RGB;
- else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_GRAY;
- /* PNG_COLOR_TYPE_PALETTE is not changed */
-
- this->next->mod(this->next, that, pp, display);
-}
-
-#define image_transform_png_set_background_add image_transform_default_add
-
-#undef data
-IT(background);
-#undef PT
-#define PT ITSTRUCT(background)
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
-
-/* png_set_quantize(png_structp, png_colorp palette, int num_palette,
- * int maximum_colors, png_const_uint_16p histogram, int full_quantize)
- *
- * Very difficult to validate this!
- */
-/*NOTE: TBD NYI */
-
-/* The data layout transforms are handled by swapping our own channel data,
- * necessarily these need to happen at the end of the transform list because the
- * semantic of the channels changes after these are executed. Some of these,
- * like set_shift and set_packing, can't be done at present because they change
- * the layout of the data at the sub-sample level so sample() won't get the
- * right answer.
- */
-/* png_set_invert_alpha */
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-/* Invert the alpha channel
- *
- * png_set_invert_alpha(png_structrp png_ptr)
- */
-static void
-image_transform_png_set_invert_alpha_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_invert_alpha(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_invert_alpha_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->colour_type & 4)
- that->alpha_inverted = 1;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_invert_alpha_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- /* Only has an effect on pixels with alpha: */
- return (colour_type & 4) != 0;
-}
-
-IT(invert_alpha);
-#undef PT
-#define PT ITSTRUCT(invert_alpha)
-
-#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
-
-/* png_set_bgr */
-#ifdef PNG_READ_BGR_SUPPORTED
-/* Swap R,G,B channels to order B,G,R.
- *
- * png_set_bgr(png_structrp png_ptr)
- *
- * This only has an effect on RGB and RGBA pixels.
- */
-static void
-image_transform_png_set_bgr_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_bgr(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_bgr_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->colour_type == PNG_COLOR_TYPE_RGB ||
- that->colour_type == PNG_COLOR_TYPE_RGBA)
- that->swap_rgb = 1;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_bgr_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return colour_type == PNG_COLOR_TYPE_RGB ||
- colour_type == PNG_COLOR_TYPE_RGBA;
-}
-
-IT(bgr);
-#undef PT
-#define PT ITSTRUCT(bgr)
-
-#endif /* PNG_READ_BGR_SUPPORTED */
-
-/* png_set_swap_alpha */
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-/* Put the alpha channel first.
- *
- * png_set_swap_alpha(png_structrp png_ptr)
- *
- * This only has an effect on GA and RGBA pixels.
- */
-static void
-image_transform_png_set_swap_alpha_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_swap_alpha(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_swap_alpha_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->colour_type == PNG_COLOR_TYPE_GA ||
- that->colour_type == PNG_COLOR_TYPE_RGBA)
- that->alpha_first = 1;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_swap_alpha_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return colour_type == PNG_COLOR_TYPE_GA ||
- colour_type == PNG_COLOR_TYPE_RGBA;
-}
-
-IT(swap_alpha);
-#undef PT
-#define PT ITSTRUCT(swap_alpha)
-
-#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED */
-
-/* png_set_swap */
-#ifdef PNG_READ_SWAP_SUPPORTED
-/* Byte swap 16-bit components.
- *
- * png_set_swap(png_structrp png_ptr)
- */
-static void
-image_transform_png_set_swap_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_swap(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_swap_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->bit_depth == 16)
- that->swap16 = 1;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_swap_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(colour_type)
-
- this->next = *that;
- *that = this;
-
- return bit_depth == 16;
-}
-
-IT(swap);
-#undef PT
-#define PT ITSTRUCT(swap)
-
-#endif /* PNG_READ_SWAP_SUPPORTED */
-
-#ifdef PNG_READ_FILLER_SUPPORTED
-/* Add a filler byte to 8-bit Gray or 24-bit RGB images.
- *
- * png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags));
- *
- * Flags:
- *
- * PNG_FILLER_BEFORE
- * PNG_FILLER_AFTER
- */
-#define data ITDATA(filler)
-static struct
-{
- png_uint_32 filler;
- int flags;
-} data;
-
-static void
-image_transform_png_set_filler_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- /* Need a random choice for 'before' and 'after' as well as for the
- * filler. The 'filler' value has all 32 bits set, but only bit_depth
- * will be used. At this point we don't know bit_depth.
- */
- data.filler = random_u32();
- data.flags = random_choice();
-
- png_set_filler(pp, data.filler, data.flags);
-
- /* The standard display handling stuff also needs to know that
- * there is a filler, so set that here.
- */
- that->this.filler = 1;
-
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_filler_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->bit_depth >= 8 &&
- (that->colour_type == PNG_COLOR_TYPE_RGB ||
- that->colour_type == PNG_COLOR_TYPE_GRAY))
- {
- unsigned int max = (1U << that->bit_depth)-1;
- that->alpha = data.filler & max;
- that->alphaf = ((double)that->alpha) / max;
- that->alphae = 0;
-
- /* The filler has been stored in the alpha channel, we must record
- * that this has been done for the checking later on, the color
- * type is faked to have an alpha channel, but libpng won't report
- * this; the app has to know the extra channel is there and this
- * was recording in standard_display::filler above.
- */
- that->colour_type |= 4; /* alpha added */
- that->alpha_first = data.flags == PNG_FILLER_BEFORE;
- }
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_filler_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- this->next = *that;
- *that = this;
-
- return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||
- colour_type == PNG_COLOR_TYPE_GRAY);
-}
-
-#undef data
-IT(filler);
-#undef PT
-#define PT ITSTRUCT(filler)
-
-/* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */
-/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
-#define data ITDATA(add_alpha)
-static struct
-{
- png_uint_32 filler;
- int flags;
-} data;
-
-static void
-image_transform_png_set_add_alpha_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- /* Need a random choice for 'before' and 'after' as well as for the
- * filler. The 'filler' value has all 32 bits set, but only bit_depth
- * will be used. At this point we don't know bit_depth.
- */
- data.filler = random_u32();
- data.flags = random_choice();
-
- png_set_add_alpha(pp, data.filler, data.flags);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_add_alpha_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->bit_depth >= 8 &&
- (that->colour_type == PNG_COLOR_TYPE_RGB ||
- that->colour_type == PNG_COLOR_TYPE_GRAY))
- {
- unsigned int max = (1U << that->bit_depth)-1;
- that->alpha = data.filler & max;
- that->alphaf = ((double)that->alpha) / max;
- that->alphae = 0;
-
- that->colour_type |= 4; /* alpha added */
- that->alpha_first = data.flags == PNG_FILLER_BEFORE;
- }
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_add_alpha_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- this->next = *that;
- *that = this;
-
- return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||
- colour_type == PNG_COLOR_TYPE_GRAY);
-}
-
-#undef data
-IT(add_alpha);
-#undef PT
-#define PT ITSTRUCT(add_alpha)
-
-#endif /* PNG_READ_FILLER_SUPPORTED */
-
-/* png_set_packing */
-#ifdef PNG_READ_PACK_SUPPORTED
-/* Use 1 byte per pixel in 1, 2, or 4-bit depth files.
- *
- * png_set_packing(png_structrp png_ptr)
- *
- * This should only affect grayscale and palette images with less than 8 bits
- * per pixel.
- */
-static void
-image_transform_png_set_packing_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_packing(pp);
- that->unpacked = 1;
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_packing_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- /* The general expand case depends on what the colour type is,
- * low bit-depth pixel values are unpacked into bytes without
- * scaling, so sample_depth is not changed.
- */
- if (that->bit_depth < 8) /* grayscale or palette */
- that->bit_depth = 8;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_packing_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(colour_type)
-
- this->next = *that;
- *that = this;
-
- /* Nothing should happen unless the bit depth is less than 8: */
- return bit_depth < 8;
-}
-
-IT(packing);
-#undef PT
-#define PT ITSTRUCT(packing)
-
-#endif /* PNG_READ_PACK_SUPPORTED */
-
-/* png_set_packswap */
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
-/* Swap pixels packed into bytes; reverses the order on screen so that
- * the high order bits correspond to the rightmost pixels.
- *
- * png_set_packswap(png_structrp png_ptr)
- */
-static void
-image_transform_png_set_packswap_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_packswap(pp);
- that->this.littleendian = 1;
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_packswap_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->bit_depth < 8)
- that->littleendian = 1;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_packswap_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(colour_type)
-
- this->next = *that;
- *that = this;
-
- return bit_depth < 8;
-}
-
-IT(packswap);
-#undef PT
-#define PT ITSTRUCT(packswap)
-
-#endif /* PNG_READ_PACKSWAP_SUPPORTED */
-
-
-/* png_set_invert_mono */
-#ifdef PNG_READ_INVERT_MONO_SUPPORTED
-/* Invert the gray channel
- *
- * png_set_invert_mono(png_structrp png_ptr)
- */
-static void
-image_transform_png_set_invert_mono_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_invert_mono(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_invert_mono_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- if (that->colour_type & 4)
- that->mono_inverted = 1;
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_invert_mono_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- /* Only has an effect on pixels with no colour: */
- return (colour_type & 2) == 0;
-}
-
-IT(invert_mono);
-#undef PT
-#define PT ITSTRUCT(invert_mono)
-
-#endif /* PNG_READ_INVERT_MONO_SUPPORTED */
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-/* png_set_shift(png_structp, png_const_color_8p true_bits)
- *
- * The output pixels will be shifted by the given true_bits
- * values.
- */
-#define data ITDATA(shift)
-static png_color_8 data;
-
-static void
-image_transform_png_set_shift_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- /* Get a random set of shifts. The shifts need to do something
- * to test the transform, so they are limited to the bit depth
- * of the input image. Notice that in the following the 'gray'
- * field is randomized independently. This acts as a check that
- * libpng does use the correct field.
- */
- unsigned int depth = that->this.bit_depth;
-
- data.red = (png_byte)/*SAFE*/(random_mod(depth)+1);
- data.green = (png_byte)/*SAFE*/(random_mod(depth)+1);
- data.blue = (png_byte)/*SAFE*/(random_mod(depth)+1);
- data.gray = (png_byte)/*SAFE*/(random_mod(depth)+1);
- data.alpha = (png_byte)/*SAFE*/(random_mod(depth)+1);
-
- png_set_shift(pp, &data);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_shift_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- /* Copy the correct values into the sBIT fields, libpng does not do
- * anything to palette data:
- */
- if (that->colour_type != PNG_COLOR_TYPE_PALETTE)
- {
- that->sig_bits = 1;
-
- /* The sBIT fields are reset to the values previously sent to
- * png_set_shift according to the colour type.
- * does.
- */
- if (that->colour_type & 2) /* RGB channels */
- {
- that->red_sBIT = data.red;
- that->green_sBIT = data.green;
- that->blue_sBIT = data.blue;
- }
-
- else /* One grey channel */
- that->red_sBIT = that->green_sBIT = that->blue_sBIT = data.gray;
-
- that->alpha_sBIT = data.alpha;
- }
-
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_shift_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- UNUSED(bit_depth)
-
- this->next = *that;
- *that = this;
-
- return colour_type != PNG_COLOR_TYPE_PALETTE;
-}
-
-IT(shift);
-#undef PT
-#define PT ITSTRUCT(shift)
-
-#endif /* PNG_READ_SHIFT_SUPPORTED */
-
-#ifdef THIS_IS_THE_PROFORMA
-static void
-image_transform_png_set_@_set(const image_transform *this,
- transform_display *that, png_structp pp, png_infop pi)
-{
- png_set_@(pp);
- this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_@_mod(const image_transform *this,
- image_pixel *that, png_const_structp pp,
- const transform_display *display)
-{
- this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_@_add(image_transform *this,
- const image_transform **that, png_byte colour_type, png_byte bit_depth)
-{
- this->next = *that;
- *that = this;
-
- return 1;
-}
-
-IT(@);
-#endif
-
-
-/* This may just be 'end' if all the transforms are disabled! */
-static image_transform *const image_transform_first = &PT;
-
-static void
-transform_enable(const char *name)
-{
- /* Everything starts out enabled, so if we see an 'enable' disabled
- * everything else the first time round.
- */
- static int all_disabled = 0;
- int found_it = 0;
- image_transform *list = image_transform_first;
-
- while (list != &image_transform_end)
- {
- if (strcmp(list->name, name) == 0)
- {
- list->enable = 1;
- found_it = 1;
- }
- else if (!all_disabled)
- list->enable = 0;
-
- list = list->list;
- }
-
- all_disabled = 1;
-
- if (!found_it)
- {
- fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n",
- name);
- exit(99);
- }
-}
-
-static void
-transform_disable(const char *name)
-{
- image_transform *list = image_transform_first;
-
- while (list != &image_transform_end)
- {
- if (strcmp(list->name, name) == 0)
- {
- list->enable = 0;
- return;
- }
-
- list = list->list;
- }
-
- fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n",
- name);
- exit(99);
-}
-
-static void
-image_transform_reset_count(void)
-{
- image_transform *next = image_transform_first;
- int count = 0;
-
- while (next != &image_transform_end)
- {
- next->local_use = 0;
- next->next = 0;
- next = next->list;
- ++count;
- }
-
- /* This can only happen if we every have more than 32 transforms (excluding
- * the end) in the list.
- */
- if (count > 32) abort();
-}
-
-static int
-image_transform_test_counter(png_uint_32 counter, unsigned int max)
-{
- /* Test the list to see if there is any point contining, given a current
- * counter and a 'max' value.
- */
- image_transform *next = image_transform_first;
-
- while (next != &image_transform_end)
- {
- /* For max 0 or 1 continue until the counter overflows: */
- counter >>= 1;
-
- /* Continue if any entry hasn't reacked the max. */
- if (max > 1 && next->local_use < max)
- return 1;
- next = next->list;
- }
-
- return max <= 1 && counter == 0;
-}
-
-static png_uint_32
-image_transform_add(const image_transform **this, unsigned int max,
- png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos,
- png_byte colour_type, png_byte bit_depth)
-{
- for (;;) /* until we manage to add something */
- {
- png_uint_32 mask;
- image_transform *list;
-
- /* Find the next counter value, if the counter is zero this is the start
- * of the list. This routine always returns the current counter (not the
- * next) so it returns 0 at the end and expects 0 at the beginning.
- */
- if (counter == 0) /* first time */
- {
- image_transform_reset_count();
- if (max <= 1)
- counter = 1;
- else
- counter = random_32();
- }
- else /* advance the counter */
- {
- switch (max)
- {
- case 0: ++counter; break;
- case 1: counter <<= 1; break;
- default: counter = random_32(); break;
- }
- }
-
- /* Now add all these items, if possible */
- *this = &image_transform_end;
- list = image_transform_first;
- mask = 1;
-
- /* Go through the whole list adding anything that the counter selects: */
- while (list != &image_transform_end)
- {
- if ((counter & mask) != 0 && list->enable &&
- (max == 0 || list->local_use < max))
- {
- /* Candidate to add: */
- if (list->add(list, this, colour_type, bit_depth) || max == 0)
- {
- /* Added, so add to the name too. */
- *pos = safecat(name, sizeof_name, *pos, " +");
- *pos = safecat(name, sizeof_name, *pos, list->name);
- }
-
- else
- {
- /* Not useful and max>0, so remove it from *this: */
- *this = list->next;
- list->next = 0;
-
- /* And, since we know it isn't useful, stop it being added again
- * in this run:
- */
- list->local_use = max;
- }
- }
-
- mask <<= 1;
- list = list->list;
- }
-
- /* Now if anything was added we have something to do. */
- if (*this != &image_transform_end)
- return counter;
-
- /* Nothing added, but was there anything in there to add? */
- if (!image_transform_test_counter(counter, max))
- return 0;
- }
-}
-
-static void
-perform_transform_test(png_modifier *pm)
-{
- png_byte colour_type = 0;
- png_byte bit_depth = 0;
- unsigned int palette_number = 0;
-
- while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg,
- pm->test_tRNS))
- {
- png_uint_32 counter = 0;
- size_t base_pos;
- char name[64];
-
- base_pos = safecat(name, sizeof name, 0, "transform:");
-
- for (;;)
- {
- size_t pos = base_pos;
- const image_transform *list = 0;
-
- /* 'max' is currently hardwired to '1'; this should be settable on the
- * command line.
- */
- counter = image_transform_add(&list, 1/*max*/, counter,
- name, sizeof name, &pos, colour_type, bit_depth);
-
- if (counter == 0)
- break;
-
- /* The command line can change this to checking interlaced images. */
- do
- {
- pm->repeat = 0;
- transform_test(pm, FILEID(colour_type, bit_depth, palette_number,
- pm->interlace_type, 0, 0, 0), list, name);
-
- if (fail(pm))
- return;
- }
- while (pm->repeat);
- }
- }
-}
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-/********************************* GAMMA TESTS ********************************/
-#ifdef PNG_READ_GAMMA_SUPPORTED
-/* Reader callbacks and implementations, where they differ from the standard
- * ones.
- */
-typedef struct gamma_display
-{
- standard_display this;
-
- /* Parameters */
- png_modifier* pm;
- double file_gamma;
- double screen_gamma;
- double background_gamma;
- png_byte sbit;
- int threshold_test;
- int use_input_precision;
- int scale16;
- int expand16;
- int do_background;
- png_color_16 background_color;
-
- /* Local variables */
- double maxerrout;
- double maxerrpc;
- double maxerrabs;
-} gamma_display;
-
-#define ALPHA_MODE_OFFSET 4
-
-static void
-gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id,
- double file_gamma, double screen_gamma, png_byte sbit, int threshold_test,
- int use_input_precision, int scale16, int expand16,
- int do_background, const png_color_16 *pointer_to_the_background_color,
- double background_gamma)
-{
- /* Standard fields */
- standard_display_init(&dp->this, &pm->this, id, do_read_interlace,
- pm->use_update_info);
-
- /* Parameter fields */
- dp->pm = pm;
- dp->file_gamma = file_gamma;
- dp->screen_gamma = screen_gamma;
- dp->background_gamma = background_gamma;
- dp->sbit = sbit;
- dp->threshold_test = threshold_test;
- dp->use_input_precision = use_input_precision;
- dp->scale16 = scale16;
- dp->expand16 = expand16;
- dp->do_background = do_background;
- if (do_background && pointer_to_the_background_color != 0)
- dp->background_color = *pointer_to_the_background_color;
- else
- memset(&dp->background_color, 0, sizeof dp->background_color);
-
- /* Local variable fields */
- dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0;
-}
-
-static void
-gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
-{
- /* Reuse the standard stuff as appropriate. */
- standard_info_part1(&dp->this, pp, pi);
-
- /* If requested strip 16 to 8 bits - this is handled automagically below
- * because the output bit depth is read from the library. Note that there
- * are interactions with sBIT but, internally, libpng makes sbit at most
- * PNG_MAX_GAMMA_8 prior to 1.7 when doing the following.
- */
- if (dp->scale16)
-# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
- png_set_scale_16(pp);
-# else
- /* The following works both in 1.5.4 and earlier versions: */
-# ifdef PNG_READ_16_TO_8_SUPPORTED
- png_set_strip_16(pp);
-# else
- png_error(pp, "scale16 (16 to 8 bit conversion) not supported");
-# endif
-# endif
-
- if (dp->expand16)
-# ifdef PNG_READ_EXPAND_16_SUPPORTED
- png_set_expand_16(pp);
-# else
- png_error(pp, "expand16 (8 to 16 bit conversion) not supported");
-# endif
-
- if (dp->do_background >= ALPHA_MODE_OFFSET)
- {
-# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- {
- /* This tests the alpha mode handling, if supported. */
- int mode = dp->do_background - ALPHA_MODE_OFFSET;
-
- /* The gamma value is the output gamma, and is in the standard,
- * non-inverted, representation. It provides a default for the PNG file
- * gamma, but since the file has a gAMA chunk this does not matter.
- */
- const double sg = dp->screen_gamma;
-# ifndef PNG_FLOATING_POINT_SUPPORTED
- png_fixed_point g = fix(sg);
-# endif
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_alpha_mode(pp, mode, sg);
-# else
- png_set_alpha_mode_fixed(pp, mode, g);
-# endif
-
- /* However, for the standard Porter-Duff algorithm the output defaults
- * to be linear, so if the test requires non-linear output it must be
- * corrected here.
- */
- if (mode == PNG_ALPHA_STANDARD && sg != 1)
- {
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_gamma(pp, sg, dp->file_gamma);
-# else
- png_fixed_point f = fix(dp->file_gamma);
- png_set_gamma_fixed(pp, g, f);
-# endif
- }
- }
-# else
- png_error(pp, "alpha mode handling not supported");
-# endif
- }
-
- else
- {
- /* Set up gamma processing. */
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_gamma(pp, dp->screen_gamma, dp->file_gamma);
-# else
- {
- png_fixed_point s = fix(dp->screen_gamma);
- png_fixed_point f = fix(dp->file_gamma);
- png_set_gamma_fixed(pp, s, f);
- }
-# endif
-
- if (dp->do_background)
- {
-# ifdef PNG_READ_BACKGROUND_SUPPORTED
- /* NOTE: this assumes the caller provided the correct background gamma!
- */
- const double bg = dp->background_gamma;
-# ifndef PNG_FLOATING_POINT_SUPPORTED
- png_fixed_point g = fix(bg);
-# endif
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_background(pp, &dp->background_color, dp->do_background,
- 0/*need_expand*/, bg);
-# else
- png_set_background_fixed(pp, &dp->background_color,
- dp->do_background, 0/*need_expand*/, g);
-# endif
-# else
- png_error(pp, "png_set_background not supported");
-# endif
- }
- }
-
- {
- int i = dp->this.use_update_info;
- /* Always do one call, even if use_update_info is 0. */
- do
- png_read_update_info(pp, pi);
- while (--i > 0);
- }
-
- /* Now we may get a different cbRow: */
- standard_info_part2(&dp->this, pp, pi, 1 /*images*/);
-}
-
-static void PNGCBAPI
-gamma_info(png_structp pp, png_infop pi)
-{
- gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp,
- pi);
-}
-
-/* Validate a single component value - the routine gets the input and output
- * sample values as unscaled PNG component values along with a cache of all the
- * information required to validate the values.
- */
-typedef struct validate_info
-{
- png_const_structp pp;
- gamma_display *dp;
- png_byte sbit;
- int use_input_precision;
- int do_background;
- int scale16;
- unsigned int sbit_max;
- unsigned int isbit_shift;
- unsigned int outmax;
-
- double gamma_correction; /* Overall correction required. */
- double file_inverse; /* Inverse of file gamma. */
- double screen_gamma;
- double screen_inverse; /* Inverse of screen gamma. */
-
- double background_red; /* Linear background value, red or gray. */
- double background_green;
- double background_blue;
-
- double maxabs;
- double maxpc;
- double maxcalc;
- double maxout;
- double maxout_total; /* Total including quantization error */
- double outlog;
- int outquant;
-}
-validate_info;
-
-static void
-init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,
- int in_depth, int out_depth)
-{
- unsigned int outmax = (1U<<out_depth)-1;
-
- vi->pp = pp;
- vi->dp = dp;
-
- if (dp->sbit > 0 && dp->sbit < in_depth)
- {
- vi->sbit = dp->sbit;
- vi->isbit_shift = in_depth - dp->sbit;
- }
-
- else
- {
- vi->sbit = (png_byte)in_depth;
- vi->isbit_shift = 0;
- }
-
- vi->sbit_max = (1U << vi->sbit)-1;
-
- /* This mimics the libpng threshold test, '0' is used to prevent gamma
- * correction in the validation test.
- */
- vi->screen_gamma = dp->screen_gamma;
- if (fabs(vi->screen_gamma-1) < PNG_GAMMA_THRESHOLD)
- vi->screen_gamma = vi->screen_inverse = 0;
- else
- vi->screen_inverse = 1/vi->screen_gamma;
-
- vi->use_input_precision = dp->use_input_precision;
- vi->outmax = outmax;
- vi->maxabs = abserr(dp->pm, in_depth, out_depth);
- vi->maxpc = pcerr(dp->pm, in_depth, out_depth);
- vi->maxcalc = calcerr(dp->pm, in_depth, out_depth);
- vi->maxout = outerr(dp->pm, in_depth, out_depth);
- vi->outquant = output_quantization_factor(dp->pm, in_depth, out_depth);
- vi->maxout_total = vi->maxout + vi->outquant * .5;
- vi->outlog = outlog(dp->pm, in_depth, out_depth);
-
- if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 ||
- (dp->this.colour_type == 3 && dp->this.is_transparent) ||
- ((dp->this.colour_type == 0 || dp->this.colour_type == 2) &&
- dp->this.has_tRNS))
- {
- vi->do_background = dp->do_background;
-
- if (vi->do_background != 0)
- {
- const double bg_inverse = 1/dp->background_gamma;
- double r, g, b;
-
- /* Caller must at least put the gray value into the red channel */
- r = dp->background_color.red; r /= outmax;
- g = dp->background_color.green; g /= outmax;
- b = dp->background_color.blue; b /= outmax;
-
-# if 0
- /* libpng doesn't do this optimization, if we do pngvalid will fail.
- */
- if (fabs(bg_inverse-1) >= PNG_GAMMA_THRESHOLD)
-# endif
- {
- r = pow(r, bg_inverse);
- g = pow(g, bg_inverse);
- b = pow(b, bg_inverse);
- }
-
- vi->background_red = r;
- vi->background_green = g;
- vi->background_blue = b;
- }
- }
- else /* Do not expect any background processing */
- vi->do_background = 0;
-
- if (vi->do_background == 0)
- vi->background_red = vi->background_green = vi->background_blue = 0;
-
- vi->gamma_correction = 1/(dp->file_gamma*dp->screen_gamma);
- if (fabs(vi->gamma_correction-1) < PNG_GAMMA_THRESHOLD)
- vi->gamma_correction = 0;
-
- vi->file_inverse = 1/dp->file_gamma;
- if (fabs(vi->file_inverse-1) < PNG_GAMMA_THRESHOLD)
- vi->file_inverse = 0;
-
- vi->scale16 = dp->scale16;
-}
-
-/* This function handles composition of a single non-alpha component. The
- * argument is the input sample value, in the range 0..1, and the alpha value.
- * The result is the composed, linear, input sample. If alpha is less than zero
- * this is the alpha component and the function should not be called!
- */
-static double
-gamma_component_compose(int do_background, double input_sample, double alpha,
- double background, int *compose)
-{
- switch (do_background)
- {
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
- case PNG_BACKGROUND_GAMMA_SCREEN:
- case PNG_BACKGROUND_GAMMA_FILE:
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- /* Standard PNG background processing. */
- if (alpha < 1)
- {
- if (alpha > 0)
- {
- input_sample = input_sample * alpha + background * (1-alpha);
- if (compose != NULL)
- *compose = 1;
- }
-
- else
- input_sample = background;
- }
- break;
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
- case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
- /* The components are premultiplied in either case and the output is
- * gamma encoded (to get standard Porter-Duff we expect the output
- * gamma to be set to 1.0!)
- */
- case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
- /* The optimization is that the partial-alpha entries are linear
- * while the opaque pixels are gamma encoded, but this only affects the
- * output encoding.
- */
- if (alpha < 1)
- {
- if (alpha > 0)
- {
- input_sample *= alpha;
- if (compose != NULL)
- *compose = 1;
- }
-
- else
- input_sample = 0;
- }
- break;
-#endif
-
- default:
- /* Standard cases where no compositing is done (so the component
- * value is already correct.)
- */
- UNUSED(alpha)
- UNUSED(background)
- UNUSED(compose)
- break;
- }
-
- return input_sample;
-}
-
-/* This API returns the encoded *input* component, in the range 0..1 */
-static double
-gamma_component_validate(const char *name, const validate_info *vi,
- unsigned int id, unsigned int od,
- const double alpha /* <0 for the alpha channel itself */,
- const double background /* component background value */)
-{
- unsigned int isbit = id >> vi->isbit_shift;
- unsigned int sbit_max = vi->sbit_max;
- unsigned int outmax = vi->outmax;
- int do_background = vi->do_background;
-
- double i;
-
- /* First check on the 'perfect' result obtained from the digitized input
- * value, id, and compare this against the actual digitized result, 'od'.
- * 'i' is the input result in the range 0..1:
- */
- i = isbit; i /= sbit_max;
-
- /* Check for the fast route: if we don't do any background composition or if
- * this is the alpha channel ('alpha' < 0) or if the pixel is opaque then
- * just use the gamma_correction field to correct to the final output gamma.
- */
- if (alpha == 1 /* opaque pixel component */ || !do_background
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- || do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_PNG
-#endif
- || (alpha < 0 /* alpha channel */
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- && do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN
-#endif
- ))
- {
- /* Then get the gamma corrected version of 'i' and compare to 'od', any
- * error less than .5 is insignificant - just quantization of the output
- * value to the nearest digital value (nevertheless the error is still
- * recorded - it's interesting ;-)
- */
- double encoded_sample = i;
- double encoded_error;
-
- /* alpha less than 0 indicates the alpha channel, which is always linear
- */
- if (alpha >= 0 && vi->gamma_correction > 0)
- encoded_sample = pow(encoded_sample, vi->gamma_correction);
- encoded_sample *= outmax;
-
- encoded_error = fabs(od-encoded_sample);
-
- if (encoded_error > vi->dp->maxerrout)
- vi->dp->maxerrout = encoded_error;
-
- if (encoded_error < vi->maxout_total && encoded_error < vi->outlog)
- return i;
- }
-
- /* The slow route - attempt to do linear calculations. */
- /* There may be an error, or background processing is required, so calculate
- * the actual sample values - unencoded light intensity values. Note that in
- * practice these are not completely unencoded because they include a
- * 'viewing correction' to decrease or (normally) increase the perceptual
- * contrast of the image. There's nothing we can do about this - we don't
- * know what it is - so assume the unencoded value is perceptually linear.
- */
- {
- double input_sample = i; /* In range 0..1 */
- double output, error, encoded_sample, encoded_error;
- double es_lo, es_hi;
- int compose = 0; /* Set to one if composition done */
- int output_is_encoded; /* Set if encoded to screen gamma */
- int log_max_error = 1; /* Check maximum error values */
- png_const_charp pass = 0; /* Reason test passes (or 0 for fail) */
-
- /* Convert to linear light (with the above caveat.) The alpha channel is
- * already linear.
- */
- if (alpha >= 0)
- {
- int tcompose;
-
- if (vi->file_inverse > 0)
- input_sample = pow(input_sample, vi->file_inverse);
-
- /* Handle the compose processing: */
- tcompose = 0;
- input_sample = gamma_component_compose(do_background, input_sample,
- alpha, background, &tcompose);
-
- if (tcompose)
- compose = 1;
- }
-
- /* And similarly for the output value, but we need to check the background
- * handling to linearize it correctly.
- */
- output = od;
- output /= outmax;
-
- output_is_encoded = vi->screen_gamma > 0;
-
- if (alpha < 0) /* The alpha channel */
- {
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- if (do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN)
-#endif
- {
- /* In all other cases the output alpha channel is linear already,
- * don't log errors here, they are much larger in linear data.
- */
- output_is_encoded = 0;
- log_max_error = 0;
- }
- }
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- else /* A component */
- {
- if (do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED &&
- alpha < 1) /* the optimized case - linear output */
- {
- if (alpha > 0) log_max_error = 0;
- output_is_encoded = 0;
- }
- }
-#endif
-
- if (output_is_encoded)
- output = pow(output, vi->screen_gamma);
-
- /* Calculate (or recalculate) the encoded_sample value and repeat the
- * check above (unnecessary if we took the fast route, but harmless.)
- */
- encoded_sample = input_sample;
- if (output_is_encoded)
- encoded_sample = pow(encoded_sample, vi->screen_inverse);
- encoded_sample *= outmax;
-
- encoded_error = fabs(od-encoded_sample);
-
- /* Don't log errors in the alpha channel, or the 'optimized' case,
- * neither are significant to the overall perception.
- */
- if (log_max_error && encoded_error > vi->dp->maxerrout)
- vi->dp->maxerrout = encoded_error;
-
- if (encoded_error < vi->maxout_total)
- {
- if (encoded_error < vi->outlog)
- return i;
-
- /* Test passed but error is bigger than the log limit, record why the
- * test passed:
- */
- pass = "less than maxout:\n";
- }
-
- /* i: the original input value in the range 0..1
- *
- * pngvalid calculations:
- * input_sample: linear result; i linearized and composed, range 0..1
- * encoded_sample: encoded result; input_sample scaled to output bit depth
- *
- * libpng calculations:
- * output: linear result; od scaled to 0..1 and linearized
- * od: encoded result from libpng
- */
-
- /* Now we have the numbers for real errors, both absolute values as as a
- * percentage of the correct value (output):
- */
- error = fabs(input_sample-output);
-
- if (log_max_error && error > vi->dp->maxerrabs)
- vi->dp->maxerrabs = error;
-
- /* The following is an attempt to ignore the tendency of quantization to
- * dominate the percentage errors for lower result values:
- */
- if (log_max_error && input_sample > .5)
- {
- double percentage_error = error/input_sample;
- if (percentage_error > vi->dp->maxerrpc)
- vi->dp->maxerrpc = percentage_error;
- }
-
- /* Now calculate the digitization limits for 'encoded_sample' using the
- * 'max' values. Note that maxout is in the encoded space but maxpc and
- * maxabs are in linear light space.
- *
- * First find the maximum error in linear light space, range 0..1:
- */
- {
- double tmp = input_sample * vi->maxpc;
- if (tmp < vi->maxabs) tmp = vi->maxabs;
- /* If 'compose' is true the composition was done in linear space using
- * integer arithmetic. This introduces an extra error of +/- 0.5 (at
- * least) in the integer space used. 'maxcalc' records this, taking
- * into account the possibility that even for 16 bit output 8 bit space
- * may have been used.
- */
- if (compose && tmp < vi->maxcalc) tmp = vi->maxcalc;
-
- /* The 'maxout' value refers to the encoded result, to compare with
- * this encode input_sample adjusted by the maximum error (tmp) above.
- */
- es_lo = encoded_sample - vi->maxout;
-
- if (es_lo > 0 && input_sample-tmp > 0)
- {
- double low_value = input_sample-tmp;
- if (output_is_encoded)
- low_value = pow(low_value, vi->screen_inverse);
- low_value *= outmax;
- if (low_value < es_lo) es_lo = low_value;
-
- /* Quantize this appropriately: */
- es_lo = ceil(es_lo / vi->outquant - .5) * vi->outquant;
- }
-
- else
- es_lo = 0;
-
- es_hi = encoded_sample + vi->maxout;
-
- if (es_hi < outmax && input_sample+tmp < 1)
- {
- double high_value = input_sample+tmp;
- if (output_is_encoded)
- high_value = pow(high_value, vi->screen_inverse);
- high_value *= outmax;
- if (high_value > es_hi) es_hi = high_value;
-
- es_hi = floor(es_hi / vi->outquant + .5) * vi->outquant;
- }
-
- else
- es_hi = outmax;
- }
-
- /* The primary test is that the final encoded value returned by the
- * library should be between the two limits (inclusive) that were
- * calculated above.
- */
- if (od >= es_lo && od <= es_hi)
- {
- /* The value passes, but we may need to log the information anyway. */
- if (encoded_error < vi->outlog)
- return i;
-
- if (pass == 0)
- pass = "within digitization limits:\n";
- }
-
- {
- /* There has been an error in processing, or we need to log this
- * value.
- */
- double is_lo, is_hi;
-
- /* pass is set at this point if either of the tests above would have
- * passed. Don't do these additional tests here - just log the
- * original [es_lo..es_hi] values.
- */
- if (pass == 0 && vi->use_input_precision && vi->dp->sbit)
- {
- /* Ok, something is wrong - this actually happens in current libpng
- * 16-to-8 processing. Assume that the input value (id, adjusted
- * for sbit) can be anywhere between value-.5 and value+.5 - quite a
- * large range if sbit is low.
- *
- * NOTE: at present because the libpng gamma table stuff has been
- * changed to use a rounding algorithm to correct errors in 8-bit
- * calculations the precise sbit calculation (a shift) has been
- * lost. This can result in up to a +/-1 error in the presence of
- * an sbit less than the bit depth.
- */
-# if PNG_LIBPNG_VER < 10700
-# define SBIT_ERROR .5
-# else
-# define SBIT_ERROR 1.
-# endif
- double tmp = (isbit - SBIT_ERROR)/sbit_max;
-
- if (tmp <= 0)
- tmp = 0;
-
- else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)
- tmp = pow(tmp, vi->file_inverse);
-
- tmp = gamma_component_compose(do_background, tmp, alpha, background,
- NULL);
-
- if (output_is_encoded && tmp > 0 && tmp < 1)
- tmp = pow(tmp, vi->screen_inverse);
-
- is_lo = ceil(outmax * tmp - vi->maxout_total);
-
- if (is_lo < 0)
- is_lo = 0;
-
- tmp = (isbit + SBIT_ERROR)/sbit_max;
-
- if (tmp >= 1)
- tmp = 1;
-
- else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)
- tmp = pow(tmp, vi->file_inverse);
-
- tmp = gamma_component_compose(do_background, tmp, alpha, background,
- NULL);
-
- if (output_is_encoded && tmp > 0 && tmp < 1)
- tmp = pow(tmp, vi->screen_inverse);
-
- is_hi = floor(outmax * tmp + vi->maxout_total);
-
- if (is_hi > outmax)
- is_hi = outmax;
-
- if (!(od < is_lo || od > is_hi))
- {
- if (encoded_error < vi->outlog)
- return i;
-
- pass = "within input precision limits:\n";
- }
-
- /* One last chance. If this is an alpha channel and the 16to8
- * option has been used and 'inaccurate' scaling is used then the
- * bit reduction is obtained by simply using the top 8 bits of the
- * value.
- *
- * This is only done for older libpng versions when the 'inaccurate'
- * (chop) method of scaling was used.
- */
-# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
-# if PNG_LIBPNG_VER < 10504
- /* This may be required for other components in the future,
- * but at present the presence of gamma correction effectively
- * prevents the errors in the component scaling (I don't quite
- * understand why, but since it's better this way I care not
- * to ask, JB 20110419.)
- */
- if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 &&
- vi->sbit + vi->isbit_shift == 16)
- {
- tmp = ((id >> 8) - .5)/255;
-
- if (tmp > 0)
- {
- is_lo = ceil(outmax * tmp - vi->maxout_total);
- if (is_lo < 0) is_lo = 0;
- }
-
- else
- is_lo = 0;
-
- tmp = ((id >> 8) + .5)/255;
-
- if (tmp < 1)
- {
- is_hi = floor(outmax * tmp + vi->maxout_total);
- if (is_hi > outmax) is_hi = outmax;
- }
-
- else
- is_hi = outmax;
-
- if (!(od < is_lo || od > is_hi))
- {
- if (encoded_error < vi->outlog)
- return i;
-
- pass = "within 8 bit limits:\n";
- }
- }
-# endif
-# endif
- }
- else /* !use_input_precision */
- is_lo = es_lo, is_hi = es_hi;
-
- /* Attempt to output a meaningful error/warning message: the message
- * output depends on the background/composite operation being performed
- * because this changes what parameters were actually used above.
- */
- {
- size_t pos = 0;
- /* Need either 1/255 or 1/65535 precision here; 3 or 6 decimal
- * places. Just use outmax to work out which.
- */
- int precision = (outmax >= 1000 ? 6 : 3);
- int use_input=1, use_background=0, do_compose=0;
- char msg[256];
-
- if (pass != 0)
- pos = safecat(msg, sizeof msg, pos, "\n\t");
-
- /* Set up the various flags, the output_is_encoded flag above
- * is also used below. do_compose is just a double check.
- */
- switch (do_background)
- {
-# ifdef PNG_READ_BACKGROUND_SUPPORTED
- case PNG_BACKGROUND_GAMMA_SCREEN:
- case PNG_BACKGROUND_GAMMA_FILE:
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- use_background = (alpha >= 0 && alpha < 1);
-# endif
-# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- /* FALLTHROUGH */
- case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
- case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
- case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
-# endif /* ALPHA_MODE_SUPPORTED */
- do_compose = (alpha > 0 && alpha < 1);
- use_input = (alpha != 0);
- break;
-
- default:
- break;
- }
-
- /* Check the 'compose' flag */
- if (compose != do_compose)
- png_error(vi->pp, "internal error (compose)");
-
- /* 'name' is the component name */
- pos = safecat(msg, sizeof msg, pos, name);
- pos = safecat(msg, sizeof msg, pos, "(");
- pos = safecatn(msg, sizeof msg, pos, id);
- if (use_input || pass != 0/*logging*/)
- {
- if (isbit != id)
- {
- /* sBIT has reduced the precision of the input: */
- pos = safecat(msg, sizeof msg, pos, ", sbit(");
- pos = safecatn(msg, sizeof msg, pos, vi->sbit);
- pos = safecat(msg, sizeof msg, pos, "): ");
- pos = safecatn(msg, sizeof msg, pos, isbit);
- }
- pos = safecat(msg, sizeof msg, pos, "/");
- /* The output is either "id/max" or "id sbit(sbit): isbit/max" */
- pos = safecatn(msg, sizeof msg, pos, vi->sbit_max);
- }
- pos = safecat(msg, sizeof msg, pos, ")");
-
- /* A component may have been multiplied (in linear space) by the
- * alpha value, 'compose' says whether this is relevant.
- */
- if (compose || pass != 0)
- {
- /* If any form of composition is being done report our
- * calculated linear value here (the code above doesn't record
- * the input value before composition is performed, so what
- * gets reported is the value after composition.)
- */
- if (use_input || pass != 0)
- {
- if (vi->file_inverse > 0)
- {
- pos = safecat(msg, sizeof msg, pos, "^");
- pos = safecatd(msg, sizeof msg, pos, vi->file_inverse, 2);
- }
-
- else
- pos = safecat(msg, sizeof msg, pos, "[linear]");
-
- pos = safecat(msg, sizeof msg, pos, "*(alpha)");
- pos = safecatd(msg, sizeof msg, pos, alpha, precision);
- }
-
- /* Now record the *linear* background value if it was used
- * (this function is not passed the original, non-linear,
- * value but it is contained in the test name.)
- */
- if (use_background)
- {
- pos = safecat(msg, sizeof msg, pos, use_input ? "+" : " ");
- pos = safecat(msg, sizeof msg, pos, "(background)");
- pos = safecatd(msg, sizeof msg, pos, background, precision);
- pos = safecat(msg, sizeof msg, pos, "*");
- pos = safecatd(msg, sizeof msg, pos, 1-alpha, precision);
- }
- }
-
- /* Report the calculated value (input_sample) and the linearized
- * libpng value (output) unless this is just a component gamma
- * correction.
- */
- if (compose || alpha < 0 || pass != 0)
- {
- pos = safecat(msg, sizeof msg, pos,
- pass != 0 ? " =\n\t" : " = ");
- pos = safecatd(msg, sizeof msg, pos, input_sample, precision);
- pos = safecat(msg, sizeof msg, pos, " (libpng: ");
- pos = safecatd(msg, sizeof msg, pos, output, precision);
- pos = safecat(msg, sizeof msg, pos, ")");
-
- /* Finally report the output gamma encoding, if any. */
- if (output_is_encoded)
- {
- pos = safecat(msg, sizeof msg, pos, " ^");
- pos = safecatd(msg, sizeof msg, pos, vi->screen_inverse, 2);
- pos = safecat(msg, sizeof msg, pos, "(to screen) =");
- }
-
- else
- pos = safecat(msg, sizeof msg, pos, " [screen is linear] =");
- }
-
- if ((!compose && alpha >= 0) || pass != 0)
- {
- if (pass != 0) /* logging */
- pos = safecat(msg, sizeof msg, pos, "\n\t[overall:");
-
- /* This is the non-composition case, the internal linear
- * values are irrelevant (though the log below will reveal
- * them.) Output a much shorter warning/error message and report
- * the overall gamma correction.
- */
- if (vi->gamma_correction > 0)
- {
- pos = safecat(msg, sizeof msg, pos, " ^");
- pos = safecatd(msg, sizeof msg, pos, vi->gamma_correction, 2);
- pos = safecat(msg, sizeof msg, pos, "(gamma correction) =");
- }
-
- else
- pos = safecat(msg, sizeof msg, pos,
- " [no gamma correction] =");
-
- if (pass != 0)
- pos = safecat(msg, sizeof msg, pos, "]");
- }
-
- /* This is our calculated encoded_sample which should (but does
- * not) match od:
- */
- pos = safecat(msg, sizeof msg, pos, pass != 0 ? "\n\t" : " ");
- pos = safecatd(msg, sizeof msg, pos, is_lo, 1);
- pos = safecat(msg, sizeof msg, pos, " < ");
- pos = safecatd(msg, sizeof msg, pos, encoded_sample, 1);
- pos = safecat(msg, sizeof msg, pos, " (libpng: ");
- pos = safecatn(msg, sizeof msg, pos, od);
- pos = safecat(msg, sizeof msg, pos, ")");
- pos = safecat(msg, sizeof msg, pos, "/");
- pos = safecatn(msg, sizeof msg, pos, outmax);
- pos = safecat(msg, sizeof msg, pos, " < ");
- pos = safecatd(msg, sizeof msg, pos, is_hi, 1);
-
- if (pass == 0) /* The error condition */
- {
-# ifdef PNG_WARNINGS_SUPPORTED
- png_warning(vi->pp, msg);
-# else
- store_warning(vi->pp, msg);
-# endif
- }
-
- else /* logging this value */
- store_verbose(&vi->dp->pm->this, vi->pp, pass, msg);
- }
- }
- }
-
- return i;
-}
-
-static void
-gamma_image_validate(gamma_display *dp, png_const_structp pp,
- png_infop pi)
-{
- /* Get some constants derived from the input and output file formats: */
- const png_store* const ps = dp->this.ps;
- png_byte in_ct = dp->this.colour_type;
- png_byte in_bd = dp->this.bit_depth;
- png_uint_32 w = dp->this.w;
- png_uint_32 h = dp->this.h;
- const size_t cbRow = dp->this.cbRow;
- png_byte out_ct = png_get_color_type(pp, pi);
- png_byte out_bd = png_get_bit_depth(pp, pi);
-
- /* There are three sources of error, firstly the quantization in the
- * file encoding, determined by sbit and/or the file depth, secondly
- * the output (screen) gamma and thirdly the output file encoding.
- *
- * Since this API receives the screen and file gamma in double
- * precision it is possible to calculate an exact answer given an input
- * pixel value. Therefore we assume that the *input* value is exact -
- * sample/maxsample - calculate the corresponding gamma corrected
- * output to the limits of double precision arithmetic and compare with
- * what libpng returns.
- *
- * Since the library must quantize the output to 8 or 16 bits there is
- * a fundamental limit on the accuracy of the output of +/-.5 - this
- * quantization limit is included in addition to the other limits
- * specified by the parameters to the API. (Effectively, add .5
- * everywhere.)
- *
- * The behavior of the 'sbit' parameter is defined by section 12.5
- * (sample depth scaling) of the PNG spec. That section forces the
- * decoder to assume that the PNG values have been scaled if sBIT is
- * present:
- *
- * png-sample = floor( input-sample * (max-out/max-in) + .5);
- *
- * This means that only a subset of the possible PNG values should
- * appear in the input. However, the spec allows the encoder to use a
- * variety of approximations to the above and doesn't require any
- * restriction of the values produced.
- *
- * Nevertheless the spec requires that the upper 'sBIT' bits of the
- * value stored in a PNG file be the original sample bits.
- * Consequently the code below simply scales the top sbit bits by
- * (1<<sbit)-1 to obtain an original sample value.
- *
- * Because there is limited precision in the input it is arguable that
- * an acceptable result is any valid result from input-.5 to input+.5.
- * The basic tests below do not do this, however if 'use_input_precision'
- * is set a subsequent test is performed above.
- */
- unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
- int processing;
- png_uint_32 y;
- const store_palette_entry *in_palette = dp->this.palette;
- int in_is_transparent = dp->this.is_transparent;
- int process_tRNS;
- int out_npalette = -1;
- int out_is_transparent = 0; /* Just refers to the palette case */
- store_palette out_palette;
- validate_info vi;
-
- /* Check for row overwrite errors */
- store_image_check(dp->this.ps, pp, 0);
-
- /* Supply the input and output sample depths here - 8 for an indexed image,
- * otherwise the bit depth.
- */
- init_validate_info(&vi, dp, pp, in_ct==3?8:in_bd, out_ct==3?8:out_bd);
-
- processing = (vi.gamma_correction > 0 && !dp->threshold_test)
- || in_bd != out_bd || in_ct != out_ct || vi.do_background;
- process_tRNS = dp->this.has_tRNS && vi.do_background;
-
- /* TODO: FIX THIS: MAJOR BUG! If the transformations all happen inside
- * the palette there is no way of finding out, because libpng fails to
- * update the palette on png_read_update_info. Indeed, libpng doesn't
- * even do the required work until much later, when it doesn't have any
- * info pointer. Oops. For the moment 'processing' is turned off if
- * out_ct is palette.
- */
- if (in_ct == 3 && out_ct == 3)
- processing = 0;
-
- if (processing && out_ct == 3)
- out_is_transparent = read_palette(out_palette, &out_npalette, pp, pi);
-
- for (y=0; y<h; ++y)
- {
- png_const_bytep pRow = store_image_row(ps, pp, 0, y);
- png_byte std[STANDARD_ROWMAX];
-
- transform_row(pp, std, in_ct, in_bd, y);
-
- if (processing)
- {
- unsigned int x;
-
- for (x=0; x<w; ++x)
- {
- double alpha = 1; /* serves as a flag value */
-
- /* Record the palette index for index images. */
- unsigned int in_index =
- in_ct == 3 ? sample(std, 3, in_bd, x, 0, 0, 0) : 256;
- unsigned int out_index =
- out_ct == 3 ? sample(std, 3, out_bd, x, 0, 0, 0) : 256;
-
- /* Handle input alpha - png_set_background will cause the output
- * alpha to disappear so there is nothing to check.
- */
- if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 ||
- (in_ct == 3 && in_is_transparent))
- {
- unsigned int input_alpha = in_ct == 3 ?
- dp->this.palette[in_index].alpha :
- sample(std, in_ct, in_bd, x, samples_per_pixel, 0, 0);
-
- unsigned int output_alpha = 65536 /* as a flag value */;
-
- if (out_ct == 3)
- {
- if (out_is_transparent)
- output_alpha = out_palette[out_index].alpha;
- }
-
- else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0)
- output_alpha = sample(pRow, out_ct, out_bd, x,
- samples_per_pixel, 0, 0);
-
- if (output_alpha != 65536)
- alpha = gamma_component_validate("alpha", &vi, input_alpha,
- output_alpha, -1/*alpha*/, 0/*background*/);
-
- else /* no alpha in output */
- {
- /* This is a copy of the calculation of 'i' above in order to
- * have the alpha value to use in the background calculation.
- */
- alpha = input_alpha >> vi.isbit_shift;
- alpha /= vi.sbit_max;
- }
- }
-
- else if (process_tRNS)
- {
- /* alpha needs to be set appropriately for this pixel, it is
- * currently 1 and needs to be 0 for an input pixel which matches
- * the values in tRNS.
- */
- switch (in_ct)
- {
- case 0: /* gray */
- if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
- dp->this.transparent.red)
- alpha = 0;
- break;
-
- case 2: /* RGB */
- if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
- dp->this.transparent.red &&
- sample(std, in_ct, in_bd, x, 1, 0, 0) ==
- dp->this.transparent.green &&
- sample(std, in_ct, in_bd, x, 2, 0, 0) ==
- dp->this.transparent.blue)
- alpha = 0;
- break;
-
- default:
- break;
- }
- }
-
- /* Handle grayscale or RGB components. */
- if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */
- (void)gamma_component_validate("gray", &vi,
- sample(std, in_ct, in_bd, x, 0, 0, 0),
- sample(pRow, out_ct, out_bd, x, 0, 0, 0),
- alpha/*component*/, vi.background_red);
- else /* RGB or palette */
- {
- (void)gamma_component_validate("red", &vi,
- in_ct == 3 ? in_palette[in_index].red :
- sample(std, in_ct, in_bd, x, 0, 0, 0),
- out_ct == 3 ? out_palette[out_index].red :
- sample(pRow, out_ct, out_bd, x, 0, 0, 0),
- alpha/*component*/, vi.background_red);
-
- (void)gamma_component_validate("green", &vi,
- in_ct == 3 ? in_palette[in_index].green :
- sample(std, in_ct, in_bd, x, 1, 0, 0),
- out_ct == 3 ? out_palette[out_index].green :
- sample(pRow, out_ct, out_bd, x, 1, 0, 0),
- alpha/*component*/, vi.background_green);
-
- (void)gamma_component_validate("blue", &vi,
- in_ct == 3 ? in_palette[in_index].blue :
- sample(std, in_ct, in_bd, x, 2, 0, 0),
- out_ct == 3 ? out_palette[out_index].blue :
- sample(pRow, out_ct, out_bd, x, 2, 0, 0),
- alpha/*component*/, vi.background_blue);
- }
- }
- }
-
- else if (memcmp(std, pRow, cbRow) != 0)
- {
- char msg[64];
-
- /* No transform is expected on the threshold tests. */
- sprintf(msg, "gamma: below threshold row %lu changed",
- (unsigned long)y);
-
- png_error(pp, msg);
- }
- } /* row (y) loop */
-
- dp->this.ps->validated = 1;
-}
-
-static void PNGCBAPI
-gamma_end(png_structp ppIn, png_infop pi)
-{
- png_const_structp pp = ppIn;
- gamma_display *dp = voidcast(gamma_display*, png_get_progressive_ptr(pp));
-
- if (!dp->this.speed)
- gamma_image_validate(dp, pp, pi);
- else
- dp->this.ps->validated = 1;
-}
-
-/* A single test run checking a gamma transformation.
- *
- * maxabs: maximum absolute error as a fraction
- * maxout: maximum output error in the output units
- * maxpc: maximum percentage error (as a percentage)
- */
-static void
-gamma_test(png_modifier *pmIn, png_byte colour_typeIn,
- png_byte bit_depthIn, int palette_numberIn,
- int interlace_typeIn,
- const double file_gammaIn, const double screen_gammaIn,
- png_byte sbitIn, int threshold_testIn,
- const char *name,
- int use_input_precisionIn, int scale16In,
- int expand16In, int do_backgroundIn,
- const png_color_16 *bkgd_colorIn, double bkgd_gammaIn)
-{
- gamma_display d;
- context(&pmIn->this, fault);
-
- gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn,
- palette_numberIn, interlace_typeIn, 0, 0, 0),
- file_gammaIn, screen_gammaIn, sbitIn,
- threshold_testIn, use_input_precisionIn, scale16In,
- expand16In, do_backgroundIn, bkgd_colorIn, bkgd_gammaIn);
-
- Try
- {
- png_structp pp;
- png_infop pi;
- gama_modification gama_mod;
- srgb_modification srgb_mod;
- sbit_modification sbit_mod;
-
- /* For the moment don't use the png_modifier support here. */
- d.pm->encoding_counter = 0;
- modifier_set_encoding(d.pm); /* Just resets everything */
- d.pm->current_gamma = d.file_gamma;
-
- /* Make an appropriate modifier to set the PNG file gamma to the
- * given gamma value and the sBIT chunk to the given precision.
- */
- d.pm->modifications = NULL;
- gama_modification_init(&gama_mod, d.pm, d.file_gamma);
- srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/);
- if (d.sbit > 0)
- sbit_modification_init(&sbit_mod, d.pm, d.sbit);
-
- modification_reset(d.pm->modifications);
-
- /* Get a png_struct for reading the image. */
- pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
- standard_palette_init(&d.this);
-
- /* Introduce the correct read function. */
- if (d.pm->this.progressive)
- {
- /* Share the row function with the standard implementation. */
- png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row,
- gamma_end);
-
- /* Now feed data into the reader until we reach the end: */
- modifier_progressive_read(d.pm, pp, pi);
- }
- else
- {
- /* modifier_read expects a png_modifier* */
- png_set_read_fn(pp, d.pm, modifier_read);
-
- /* Check the header values: */
- png_read_info(pp, pi);
-
- /* Process the 'info' requirements. Only one image is generated */
- gamma_info_imp(&d, pp, pi);
-
- sequential_row(&d.this, pp, pi, -1, 0);
-
- if (!d.this.speed)
- gamma_image_validate(&d, pp, pi);
- else
- d.this.ps->validated = 1;
- }
-
- modifier_reset(d.pm);
-
- if (d.pm->log && !d.threshold_test && !d.this.speed)
- fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n",
- d.this.bit_depth, colour_types[d.this.colour_type], name,
- d.maxerrout, d.maxerrabs, 100*d.maxerrpc);
-
- /* Log the summary values too. */
- if (d.this.colour_type == 0 || d.this.colour_type == 4)
- {
- switch (d.this.bit_depth)
- {
- case 1:
- break;
-
- case 2:
- if (d.maxerrout > d.pm->error_gray_2)
- d.pm->error_gray_2 = d.maxerrout;
-
- break;
-
- case 4:
- if (d.maxerrout > d.pm->error_gray_4)
- d.pm->error_gray_4 = d.maxerrout;
-
- break;
-
- case 8:
- if (d.maxerrout > d.pm->error_gray_8)
- d.pm->error_gray_8 = d.maxerrout;
-
- break;
-
- case 16:
- if (d.maxerrout > d.pm->error_gray_16)
- d.pm->error_gray_16 = d.maxerrout;
-
- break;
-
- default:
- png_error(pp, "bad bit depth (internal: 1)");
- }
- }
-
- else if (d.this.colour_type == 2 || d.this.colour_type == 6)
- {
- switch (d.this.bit_depth)
- {
- case 8:
-
- if (d.maxerrout > d.pm->error_color_8)
- d.pm->error_color_8 = d.maxerrout;
-
- break;
-
- case 16:
-
- if (d.maxerrout > d.pm->error_color_16)
- d.pm->error_color_16 = d.maxerrout;
-
- break;
-
- default:
- png_error(pp, "bad bit depth (internal: 2)");
- }
- }
-
- else if (d.this.colour_type == 3)
- {
- if (d.maxerrout > d.pm->error_indexed)
- d.pm->error_indexed = d.maxerrout;
- }
- }
-
- Catch(fault)
- modifier_reset(voidcast(png_modifier*,(void*)fault));
-}
-
-static void gamma_threshold_test(png_modifier *pm, png_byte colour_type,
- png_byte bit_depth, int interlace_type, double file_gamma,
- double screen_gamma)
-{
- size_t pos = 0;
- char name[64];
- pos = safecat(name, sizeof name, pos, "threshold ");
- pos = safecatd(name, sizeof name, pos, file_gamma, 3);
- pos = safecat(name, sizeof name, pos, "/");
- pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
-
- (void)gamma_test(pm, colour_type, bit_depth, 0/*palette*/, interlace_type,
- file_gamma, screen_gamma, 0/*sBIT*/, 1/*threshold test*/, name,
- 0 /*no input precision*/,
- 0 /*no scale16*/, 0 /*no expand16*/, 0 /*no background*/, 0 /*hence*/,
- 0 /*no background gamma*/);
-}
-
-static void
-perform_gamma_threshold_tests(png_modifier *pm)
-{
- png_byte colour_type = 0;
- png_byte bit_depth = 0;
- unsigned int palette_number = 0;
-
- /* Don't test more than one instance of each palette - it's pointless, in
- * fact this test is somewhat excessive since libpng doesn't make this
- * decision based on colour type or bit depth!
- *
- * CHANGED: now test two palettes and, as a side effect, images with and
- * without tRNS.
- */
- while (next_format(&colour_type, &bit_depth, &palette_number,
- pm->test_lbg_gamma_threshold, pm->test_tRNS))
- if (palette_number < 2)
- {
- double test_gamma = 1.0;
- while (test_gamma >= .4)
- {
- /* There's little point testing the interlacing vs non-interlacing,
- * but this can be set from the command line.
- */
- gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
- test_gamma, 1/test_gamma);
- test_gamma *= .95;
- }
-
- /* And a special test for sRGB */
- gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
- .45455, 2.2);
-
- if (fail(pm))
- return;
- }
-}
-
-static void gamma_transform_test(png_modifier *pm,
- png_byte colour_type, png_byte bit_depth,
- int palette_number,
- int interlace_type, const double file_gamma,
- const double screen_gamma, png_byte sbit,
- int use_input_precision, int scale16)
-{
- size_t pos = 0;
- char name[64];
-
- if (sbit != bit_depth && sbit != 0)
- {
- pos = safecat(name, sizeof name, pos, "sbit(");
- pos = safecatn(name, sizeof name, pos, sbit);
- pos = safecat(name, sizeof name, pos, ") ");
- }
-
- else
- pos = safecat(name, sizeof name, pos, "gamma ");
-
- if (scale16)
- pos = safecat(name, sizeof name, pos, "16to8 ");
-
- pos = safecatd(name, sizeof name, pos, file_gamma, 3);
- pos = safecat(name, sizeof name, pos, "->");
- pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
-
- gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,
- file_gamma, screen_gamma, sbit, 0, name, use_input_precision,
- scale16, pm->test_gamma_expand16, 0 , 0, 0);
-}
-
-static void perform_gamma_transform_tests(png_modifier *pm)
-{
- png_byte colour_type = 0;
- png_byte bit_depth = 0;
- unsigned int palette_number = 0;
-
- while (next_format(&colour_type, &bit_depth, &palette_number,
- pm->test_lbg_gamma_transform, pm->test_tRNS))
- {
- unsigned int i, j;
-
- for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
- if (i != j)
- {
- gamma_transform_test(pm, colour_type, bit_depth, palette_number,
- pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/,
- pm->use_input_precision, 0 /*do not scale16*/);
-
- if (fail(pm))
- return;
- }
- }
-}
-
-static void perform_gamma_sbit_tests(png_modifier *pm)
-{
- png_byte sbit;
-
- /* The only interesting cases are colour and grayscale, alpha is ignored here
- * for overall speed. Only bit depths where sbit is less than the bit depth
- * are tested.
- */
- for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit)
- {
- png_byte colour_type = 0, bit_depth = 0;
- unsigned int npalette = 0;
-
- while (next_format(&colour_type, &bit_depth, &npalette,
- pm->test_lbg_gamma_sbit, pm->test_tRNS))
- if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&
- ((colour_type == 3 && sbit < 8) ||
- (colour_type != 3 && sbit < bit_depth)))
- {
- unsigned int i;
-
- for (i=0; i<pm->ngamma_tests; ++i)
- {
- unsigned int j;
-
- for (j=0; j<pm->ngamma_tests; ++j) if (i != j)
- {
- gamma_transform_test(pm, colour_type, bit_depth, npalette,
- pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
- sbit, pm->use_input_precision_sbit, 0 /*scale16*/);
-
- if (fail(pm))
- return;
- }
- }
- }
- }
-}
-
-/* Note that this requires a 16 bit source image but produces 8 bit output, so
- * we only need the 16bit write support, but the 16 bit images are only
- * generated if DO_16BIT is defined.
- */
-#ifdef DO_16BIT
-static void perform_gamma_scale16_tests(png_modifier *pm)
-{
-# ifndef PNG_MAX_GAMMA_8
-# define PNG_MAX_GAMMA_8 11
-# endif
-# if defined PNG_MAX_GAMMA_8 || PNG_LIBPNG_VER < 10700
-# define SBIT_16_TO_8 PNG_MAX_GAMMA_8
-# else
-# define SBIT_16_TO_8 16
-# endif
- /* Include the alpha cases here. Note that sbit matches the internal value
- * used by the library - otherwise we will get spurious errors from the
- * internal sbit style approximation.
- *
- * The threshold test is here because otherwise the 16 to 8 conversion will
- * proceed *without* gamma correction, and the tests above will fail (but not
- * by much) - this could be fixed, it only appears with the -g option.
- */
- unsigned int i, j;
- for (i=0; i<pm->ngamma_tests; ++i)
- {
- for (j=0; j<pm->ngamma_tests; ++j)
- {
- if (i != j &&
- fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD)
- {
- gamma_transform_test(pm, 0, 16, 0, pm->interlace_type,
- 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
- pm->use_input_precision_16to8, 1 /*scale16*/);
-
- if (fail(pm))
- return;
-
- gamma_transform_test(pm, 2, 16, 0, pm->interlace_type,
- 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
- pm->use_input_precision_16to8, 1 /*scale16*/);
-
- if (fail(pm))
- return;
-
- gamma_transform_test(pm, 4, 16, 0, pm->interlace_type,
- 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
- pm->use_input_precision_16to8, 1 /*scale16*/);
-
- if (fail(pm))
- return;
-
- gamma_transform_test(pm, 6, 16, 0, pm->interlace_type,
- 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
- pm->use_input_precision_16to8, 1 /*scale16*/);
-
- if (fail(pm))
- return;
- }
- }
- }
-}
-#endif /* 16 to 8 bit conversion */
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
- defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-static void gamma_composition_test(png_modifier *pm,
- png_byte colour_type, png_byte bit_depth,
- int palette_number,
- int interlace_type, const double file_gamma,
- const double screen_gamma,
- int use_input_precision, int do_background,
- int expand_16)
-{
- size_t pos = 0;
- png_const_charp base;
- double bg;
- char name[128];
- png_color_16 background;
-
- /* Make up a name and get an appropriate background gamma value. */
- switch (do_background)
- {
- default:
- base = "";
- bg = 4; /* should not be used */
- break;
- case PNG_BACKGROUND_GAMMA_SCREEN:
- base = " bckg(Screen):";
- bg = 1/screen_gamma;
- break;
- case PNG_BACKGROUND_GAMMA_FILE:
- base = " bckg(File):";
- bg = file_gamma;
- break;
- case PNG_BACKGROUND_GAMMA_UNIQUE:
- base = " bckg(Unique):";
- /* This tests the handling of a unique value, the math is such that the
- * value tends to be <1, but is neither screen nor file (even if they
- * match!)
- */
- bg = (file_gamma + screen_gamma) / 3;
- break;
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- case ALPHA_MODE_OFFSET + PNG_ALPHA_PNG:
- base = " alpha(PNG)";
- bg = 4; /* should not be used */
- break;
- case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
- base = " alpha(Porter-Duff)";
- bg = 4; /* should not be used */
- break;
- case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
- base = " alpha(Optimized)";
- bg = 4; /* should not be used */
- break;
- case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
- base = " alpha(Broken)";
- bg = 4; /* should not be used */
- break;
-#endif
- }
-
- /* Use random background values - the background is always presented in the
- * output space (8 or 16 bit components).
- */
- if (expand_16 || bit_depth == 16)
- {
- png_uint_32 r = random_32();
-
- background.red = (png_uint_16)r;
- background.green = (png_uint_16)(r >> 16);
- r = random_32();
- background.blue = (png_uint_16)r;
- background.gray = (png_uint_16)(r >> 16);
-
- /* In earlier libpng versions, those where DIGITIZE is set, any background
- * gamma correction in the expand16 case was done using 8-bit gamma
- * correction tables, resulting in larger errors. To cope with those
- * cases use a 16-bit background value which will handle this gamma
- * correction.
- */
-# if DIGITIZE
- if (expand_16 && (do_background == PNG_BACKGROUND_GAMMA_UNIQUE ||
- do_background == PNG_BACKGROUND_GAMMA_FILE) &&
- fabs(bg*screen_gamma-1) > PNG_GAMMA_THRESHOLD)
- {
- /* The background values will be looked up in an 8-bit table to do
- * the gamma correction, so only select values which are an exact
- * match for the 8-bit table entries:
- */
- background.red = (png_uint_16)((background.red >> 8) * 257);
- background.green = (png_uint_16)((background.green >> 8) * 257);
- background.blue = (png_uint_16)((background.blue >> 8) * 257);
- background.gray = (png_uint_16)((background.gray >> 8) * 257);
- }
-# endif
- }
-
- else /* 8 bit colors */
- {
- png_uint_32 r = random_32();
-
- background.red = (png_byte)r;
- background.green = (png_byte)(r >> 8);
- background.blue = (png_byte)(r >> 16);
- background.gray = (png_byte)(r >> 24);
- }
-
- background.index = 193; /* rgb(193,193,193) to detect errors */
-
- if (!(colour_type & PNG_COLOR_MASK_COLOR))
- {
- /* Because, currently, png_set_background is always called with
- * 'need_expand' false in this case and because the gamma test itself
- * doesn't cause an expand to 8-bit for lower bit depths the colour must
- * be reduced to the correct range.
- */
- if (bit_depth < 8)
- background.gray &= (png_uint_16)((1U << bit_depth)-1);
-
- /* Grayscale input, we do not convert to RGB (TBD), so we must set the
- * background to gray - else libpng seems to fail.
- */
- background.red = background.green = background.blue = background.gray;
- }
-
- pos = safecat(name, sizeof name, pos, "gamma ");
- pos = safecatd(name, sizeof name, pos, file_gamma, 3);
- pos = safecat(name, sizeof name, pos, "->");
- pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
-
- pos = safecat(name, sizeof name, pos, base);
- if (do_background < ALPHA_MODE_OFFSET)
- {
- /* Include the background color and gamma in the name: */
- pos = safecat(name, sizeof name, pos, "(");
- /* This assumes no expand gray->rgb - the current code won't handle that!
- */
- if (colour_type & PNG_COLOR_MASK_COLOR)
- {
- pos = safecatn(name, sizeof name, pos, background.red);
- pos = safecat(name, sizeof name, pos, ",");
- pos = safecatn(name, sizeof name, pos, background.green);
- pos = safecat(name, sizeof name, pos, ",");
- pos = safecatn(name, sizeof name, pos, background.blue);
- }
- else
- pos = safecatn(name, sizeof name, pos, background.gray);
- pos = safecat(name, sizeof name, pos, ")^");
- pos = safecatd(name, sizeof name, pos, bg, 3);
- }
-
- gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,
- file_gamma, screen_gamma, 0/*sBIT*/, 0, name, use_input_precision,
- 0/*strip 16*/, expand_16, do_background, &background, bg);
-}
-
-
-static void
-perform_gamma_composition_tests(png_modifier *pm, int do_background,
- int expand_16)
-{
- png_byte colour_type = 0;
- png_byte bit_depth = 0;
- unsigned int palette_number = 0;
-
- /* Skip the non-alpha cases - there is no setting of a transparency colour at
- * present.
- *
- * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do,
- * however the palette case fails miserably so is commented out below.
- */
- while (next_format(&colour_type, &bit_depth, &palette_number,
- pm->test_lbg_gamma_composition, pm->test_tRNS))
- if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0
-#if 0 /* TODO: FIXME */
- /*TODO: FIXME: this should work */
- || colour_type == 3
-#endif
- || (colour_type != 3 && palette_number != 0))
- {
- unsigned int i, j;
-
- /* Don't skip the i==j case here - it's relevant. */
- for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
- {
- gamma_composition_test(pm, colour_type, bit_depth, palette_number,
- pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
- pm->use_input_precision, do_background, expand_16);
-
- if (fail(pm))
- return;
- }
- }
-}
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
-
-static void
-init_gamma_errors(png_modifier *pm)
-{
- /* Use -1 to catch tests that were not actually run */
- pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = -1.;
- pm->error_color_8 = -1.;
- pm->error_indexed = -1.;
- pm->error_gray_16 = pm->error_color_16 = -1.;
-}
-
-static void
-print_one(const char *leader, double err)
-{
- if (err != -1.)
- printf(" %s %.5f\n", leader, err);
-}
-
-static void
-summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth,
- int indexed)
-{
- fflush(stderr);
-
- if (who)
- printf("\nGamma correction with %s:\n", who);
-
- else
- printf("\nBasic gamma correction:\n");
-
- if (low_bit_depth)
- {
- print_one(" 2 bit gray: ", pm->error_gray_2);
- print_one(" 4 bit gray: ", pm->error_gray_4);
- print_one(" 8 bit gray: ", pm->error_gray_8);
- print_one(" 8 bit color:", pm->error_color_8);
- if (indexed)
- print_one(" indexed: ", pm->error_indexed);
- }
-
- print_one("16 bit gray: ", pm->error_gray_16);
- print_one("16 bit color:", pm->error_color_16);
-
- fflush(stdout);
-}
-
-static void
-perform_gamma_test(png_modifier *pm, int summary)
-{
- /*TODO: remove this*/
- /* Save certain values for the temporary overrides below. */
- unsigned int calculations_use_input_precision =
- pm->calculations_use_input_precision;
-# ifdef PNG_READ_BACKGROUND_SUPPORTED
- double maxout8 = pm->maxout8;
-# endif
-
- /* First some arbitrary no-transform tests: */
- if (!pm->this.speed && pm->test_gamma_threshold)
- {
- perform_gamma_threshold_tests(pm);
-
- if (fail(pm))
- return;
- }
-
- /* Now some real transforms. */
- if (pm->test_gamma_transform)
- {
- if (summary)
- {
- fflush(stderr);
- printf("Gamma correction error summary\n\n");
- printf("The printed value is the maximum error in the pixel values\n");
- printf("calculated by the libpng gamma correction code. The error\n");
- printf("is calculated as the difference between the output pixel\n");
- printf("value (always an integer) and the ideal value from the\n");
- printf("libpng specification (typically not an integer).\n\n");
-
- printf("Expect this value to be less than .5 for 8 bit formats,\n");
- printf("less than 1 for formats with fewer than 8 bits and a small\n");
- printf("number (typically less than 5) for the 16 bit formats.\n");
- printf("For performance reasons the value for 16 bit formats\n");
- printf("increases when the image file includes an sBIT chunk.\n");
- fflush(stdout);
- }
-
- init_gamma_errors(pm);
- /*TODO: remove this. Necessary because the current libpng
- * implementation works in 8 bits:
- */
- if (pm->test_gamma_expand16)
- pm->calculations_use_input_precision = 1;
- perform_gamma_transform_tests(pm);
- if (!calculations_use_input_precision)
- pm->calculations_use_input_precision = 0;
-
- if (summary)
- summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/);
-
- if (fail(pm))
- return;
- }
-
- /* The sbit tests produce much larger errors: */
- if (pm->test_gamma_sbit)
- {
- init_gamma_errors(pm);
- perform_gamma_sbit_tests(pm);
-
- if (summary)
- summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U, 1/*indexed*/);
-
- if (fail(pm))
- return;
- }
-
-#ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */
- if (pm->test_gamma_scale16)
- {
- /* The 16 to 8 bit strip operations: */
- init_gamma_errors(pm);
- perform_gamma_scale16_tests(pm);
-
- if (summary)
- {
- fflush(stderr);
- printf("\nGamma correction with 16 to 8 bit reduction:\n");
- printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
- printf(" 16 bit color: %.5f\n", pm->error_color_16);
- fflush(stdout);
- }
-
- if (fail(pm))
- return;
- }
-#endif
-
-#ifdef PNG_READ_BACKGROUND_SUPPORTED
- if (pm->test_gamma_background)
- {
- init_gamma_errors(pm);
-
- /*TODO: remove this. Necessary because the current libpng
- * implementation works in 8 bits:
- */
- if (pm->test_gamma_expand16)
- {
- pm->calculations_use_input_precision = 1;
- pm->maxout8 = .499; /* because the 16 bit background is smashed */
- }
- perform_gamma_composition_tests(pm, PNG_BACKGROUND_GAMMA_UNIQUE,
- pm->test_gamma_expand16);
- if (!calculations_use_input_precision)
- pm->calculations_use_input_precision = 0;
- pm->maxout8 = maxout8;
-
- if (summary)
- summarize_gamma_errors(pm, "background", 1, 0/*indexed*/);
-
- if (fail(pm))
- return;
- }
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- if (pm->test_gamma_alpha_mode)
- {
- int do_background;
-
- init_gamma_errors(pm);
-
- /*TODO: remove this. Necessary because the current libpng
- * implementation works in 8 bits:
- */
- if (pm->test_gamma_expand16)
- pm->calculations_use_input_precision = 1;
- for (do_background = ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD;
- do_background <= ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN && !fail(pm);
- ++do_background)
- perform_gamma_composition_tests(pm, do_background,
- pm->test_gamma_expand16);
- if (!calculations_use_input_precision)
- pm->calculations_use_input_precision = 0;
-
- if (summary)
- summarize_gamma_errors(pm, "alpha mode", 1, 0/*indexed*/);
-
- if (fail(pm))
- return;
- }
-#endif
-}
-#endif /* PNG_READ_GAMMA_SUPPORTED */
-#endif /* PNG_READ_SUPPORTED */
-
-/* INTERLACE MACRO VALIDATION */
-/* This is copied verbatim from the specification, it is simply the pass
- * number in which each pixel in each 8x8 tile appears. The array must
- * be indexed adam7[y][x] and notice that the pass numbers are based at
- * 1, not 0 - the base libpng uses.
- */
-static const
-png_byte adam7[8][8] =
-{
- { 1,6,4,6,2,6,4,6 },
- { 7,7,7,7,7,7,7,7 },
- { 5,6,5,6,5,6,5,6 },
- { 7,7,7,7,7,7,7,7 },
- { 3,6,4,6,3,6,4,6 },
- { 7,7,7,7,7,7,7,7 },
- { 5,6,5,6,5,6,5,6 },
- { 7,7,7,7,7,7,7,7 }
-};
-
-/* This routine validates all the interlace support macros in png.h for
- * a variety of valid PNG widths and heights. It uses a number of similarly
- * named internal routines that feed off the above array.
- */
-static png_uint_32
-png_pass_start_row(int pass)
-{
- int x, y;
- ++pass;
- for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
- return y;
- return 0xf;
-}
-
-static png_uint_32
-png_pass_start_col(int pass)
-{
- int x, y;
- ++pass;
- for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
- return x;
- return 0xf;
-}
-
-static int
-png_pass_row_shift(int pass)
-{
- int x, y, base=(-1), inc=8;
- ++pass;
- for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
- {
- if (base == (-1))
- base = y;
- else if (base == y)
- {}
- else if (inc == y-base)
- base=y;
- else if (inc == 8)
- inc = y-base, base=y;
- else if (inc != y-base)
- return 0xff; /* error - more than one 'inc' value! */
- }
-
- if (base == (-1)) return 0xfe; /* error - no row in pass! */
-
- /* The shift is always 1, 2 or 3 - no pass has all the rows! */
- switch (inc)
- {
-case 2: return 1;
-case 4: return 2;
-case 8: return 3;
-default: break;
- }
-
- /* error - unrecognized 'inc' */
- return (inc << 8) + 0xfd;
-}
-
-static int
-png_pass_col_shift(int pass)
-{
- int x, y, base=(-1), inc=8;
- ++pass;
- for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
- {
- if (base == (-1))
- base = x;
- else if (base == x)
- {}
- else if (inc == x-base)
- base=x;
- else if (inc == 8)
- inc = x-base, base=x;
- else if (inc != x-base)
- return 0xff; /* error - more than one 'inc' value! */
- }
-
- if (base == (-1)) return 0xfe; /* error - no row in pass! */
-
- /* The shift is always 1, 2 or 3 - no pass has all the rows! */
- switch (inc)
- {
-case 1: return 0; /* pass 7 has all the columns */
-case 2: return 1;
-case 4: return 2;
-case 8: return 3;
-default: break;
- }
-
- /* error - unrecognized 'inc' */
- return (inc << 8) + 0xfd;
-}
-
-static png_uint_32
-png_row_from_pass_row(png_uint_32 yIn, int pass)
-{
- /* By examination of the array: */
- switch (pass)
- {
-case 0: return yIn * 8;
-case 1: return yIn * 8;
-case 2: return yIn * 8 + 4;
-case 3: return yIn * 4;
-case 4: return yIn * 4 + 2;
-case 5: return yIn * 2;
-case 6: return yIn * 2 + 1;
-default: break;
- }
-
- return 0xff; /* bad pass number */
-}
-
-static png_uint_32
-png_col_from_pass_col(png_uint_32 xIn, int pass)
-{
- /* By examination of the array: */
- switch (pass)
- {
-case 0: return xIn * 8;
-case 1: return xIn * 8 + 4;
-case 2: return xIn * 4;
-case 3: return xIn * 4 + 2;
-case 4: return xIn * 2;
-case 5: return xIn * 2 + 1;
-case 6: return xIn;
-default: break;
- }
-
- return 0xff; /* bad pass number */
-}
-
-static int
-png_row_in_interlace_pass(png_uint_32 y, int pass)
-{
- /* Is row 'y' in pass 'pass'? */
- int x;
- y &= 7;
- ++pass;
- for (x=0; x<8; ++x) if (adam7[y][x] == pass)
- return 1;
-
- return 0;
-}
-
-static int
-png_col_in_interlace_pass(png_uint_32 x, int pass)
-{
- /* Is column 'x' in pass 'pass'? */
- int y;
- x &= 7;
- ++pass;
- for (y=0; y<8; ++y) if (adam7[y][x] == pass)
- return 1;
-
- return 0;
-}
-
-static png_uint_32
-png_pass_rows(png_uint_32 height, int pass)
-{
- png_uint_32 tiles = height>>3;
- png_uint_32 rows = 0;
- unsigned int x, y;
-
- height &= 7;
- ++pass;
- for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
- {
- rows += tiles;
- if (y < height) ++rows;
- break; /* i.e. break the 'x', column, loop. */
- }
-
- return rows;
-}
-
-static png_uint_32
-png_pass_cols(png_uint_32 width, int pass)
-{
- png_uint_32 tiles = width>>3;
- png_uint_32 cols = 0;
- unsigned int x, y;
-
- width &= 7;
- ++pass;
- for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
- {
- cols += tiles;
- if (x < width) ++cols;
- break; /* i.e. break the 'y', row, loop. */
- }
-
- return cols;
-}
-
-static void
-perform_interlace_macro_validation(void)
-{
- /* The macros to validate, first those that depend only on pass:
- *
- * PNG_PASS_START_ROW(pass)
- * PNG_PASS_START_COL(pass)
- * PNG_PASS_ROW_SHIFT(pass)
- * PNG_PASS_COL_SHIFT(pass)
- */
- int pass;
-
- for (pass=0; pass<7; ++pass)
- {
- png_uint_32 m, f, v;
-
- m = PNG_PASS_START_ROW(pass);
- f = png_pass_start_row(pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f);
- exit(99);
- }
-
- m = PNG_PASS_START_COL(pass);
- f = png_pass_start_col(pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f);
- exit(99);
- }
-
- m = PNG_PASS_ROW_SHIFT(pass);
- f = png_pass_row_shift(pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f);
- exit(99);
- }
-
- m = PNG_PASS_COL_SHIFT(pass);
- f = png_pass_col_shift(pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f);
- exit(99);
- }
-
- /* Macros that depend on the image or sub-image height too:
- *
- * PNG_PASS_ROWS(height, pass)
- * PNG_PASS_COLS(width, pass)
- * PNG_ROW_FROM_PASS_ROW(yIn, pass)
- * PNG_COL_FROM_PASS_COL(xIn, pass)
- * PNG_ROW_IN_INTERLACE_PASS(y, pass)
- * PNG_COL_IN_INTERLACE_PASS(x, pass)
- */
- for (v=0;;)
- {
- /* The first two tests overflow if the pass row or column is outside
- * the possible range for a 32-bit result. In fact the values should
- * never be outside the range for a 31-bit result, but checking for 32
- * bits here ensures that if an app uses a bogus pass row or column
- * (just so long as it fits in a 32 bit integer) it won't get a
- * possibly dangerous overflow.
- */
- /* First the base 0 stuff: */
- if (v < png_pass_rows(0xFFFFFFFFU, pass))
- {
- m = PNG_ROW_FROM_PASS_ROW(v, pass);
- f = png_row_from_pass_row(v, pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n",
- v, pass, m, f);
- exit(99);
- }
- }
-
- if (v < png_pass_cols(0xFFFFFFFFU, pass))
- {
- m = PNG_COL_FROM_PASS_COL(v, pass);
- f = png_col_from_pass_col(v, pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n",
- v, pass, m, f);
- exit(99);
- }
- }
-
- m = PNG_ROW_IN_INTERLACE_PASS(v, pass);
- f = png_row_in_interlace_pass(v, pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
- v, pass, m, f);
- exit(99);
- }
-
- m = PNG_COL_IN_INTERLACE_PASS(v, pass);
- f = png_col_in_interlace_pass(v, pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
- v, pass, m, f);
- exit(99);
- }
-
- /* Then the base 1 stuff: */
- ++v;
- m = PNG_PASS_ROWS(v, pass);
- f = png_pass_rows(v, pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n",
- v, pass, m, f);
- exit(99);
- }
-
- m = PNG_PASS_COLS(v, pass);
- f = png_pass_cols(v, pass);
- if (m != f)
- {
- fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n",
- v, pass, m, f);
- exit(99);
- }
-
- /* Move to the next v - the stepping algorithm starts skipping
- * values above 1024.
- */
- if (v > 1024)
- {
- if (v == PNG_UINT_31_MAX)
- break;
-
- v = (v << 1) ^ v;
- if (v >= PNG_UINT_31_MAX)
- v = PNG_UINT_31_MAX-1;
- }
- }
- }
-}
-
-/* Test color encodings. These values are back-calculated from the published
- * chromaticities. The values are accurate to about 14 decimal places; 15 are
- * given. These values are much more accurate than the ones given in the spec,
- * which typically don't exceed 4 decimal places. This allows testing of the
- * libpng code to its theoretical accuracy of 4 decimal places. (If pngvalid
- * used the published errors the 'slack' permitted would have to be +/-.5E-4 or
- * more.)
- *
- * The png_modifier code assumes that encodings[0] is sRGB and treats it
- * specially: do not change the first entry in this list!
- */
-static const color_encoding test_encodings[] =
-{
-/* sRGB: must be first in this list! */
-/*gamma:*/ { 1/2.2,
-/*red: */ { 0.412390799265959, 0.212639005871510, 0.019330818715592 },
-/*green:*/ { 0.357584339383878, 0.715168678767756, 0.119194779794626 },
-/*blue: */ { 0.180480788401834, 0.072192315360734, 0.950532152249660} },
-/* Kodak ProPhoto (wide gamut) */
-/*gamma:*/ { 1/1.6 /*approximate: uses 1.8 power law compared to sRGB 2.4*/,
-/*red: */ { 0.797760489672303, 0.288071128229293, 0.000000000000000 },
-/*green:*/ { 0.135185837175740, 0.711843217810102, 0.000000000000000 },
-/*blue: */ { 0.031349349581525, 0.000085653960605, 0.825104602510460} },
-/* Adobe RGB (1998) */
-/*gamma:*/ { 1/(2+51./256),
-/*red: */ { 0.576669042910131, 0.297344975250536, 0.027031361386412 },
-/*green:*/ { 0.185558237906546, 0.627363566255466, 0.070688852535827 },
-/*blue: */ { 0.188228646234995, 0.075291458493998, 0.991337536837639} },
-/* Adobe Wide Gamut RGB */
-/*gamma:*/ { 1/(2+51./256),
-/*red: */ { 0.716500716779386, 0.258728243040113, 0.000000000000000 },
-/*green:*/ { 0.101020574397477, 0.724682314948566, 0.051211818965388 },
-/*blue: */ { 0.146774385252705, 0.016589442011321, 0.773892783545073} },
-/* Fake encoding which selects just the green channel */
-/*gamma:*/ { 1.45/2.2, /* the 'Mac' gamma */
-/*red: */ { 0.716500716779386, 0.000000000000000, 0.000000000000000 },
-/*green:*/ { 0.101020574397477, 1.000000000000000, 0.051211818965388 },
-/*blue: */ { 0.146774385252705, 0.000000000000000, 0.773892783545073} },
-};
-
-/* signal handler
- *
- * This attempts to trap signals and escape without crashing. It needs a
- * context pointer so that it can throw an exception (call longjmp) to recover
- * from the condition; this is handled by making the png_modifier used by 'main'
- * into a global variable.
- */
-static png_modifier pm;
-
-static void signal_handler(int signum)
-{
-
- size_t pos = 0;
- char msg[64];
-
- pos = safecat(msg, sizeof msg, pos, "caught signal: ");
-
- switch (signum)
- {
- case SIGABRT:
- pos = safecat(msg, sizeof msg, pos, "abort");
- break;
-
- case SIGFPE:
- pos = safecat(msg, sizeof msg, pos, "floating point exception");
- break;
-
- case SIGILL:
- pos = safecat(msg, sizeof msg, pos, "illegal instruction");
- break;
-
- case SIGINT:
- pos = safecat(msg, sizeof msg, pos, "interrupt");
- break;
-
- case SIGSEGV:
- pos = safecat(msg, sizeof msg, pos, "invalid memory access");
- break;
-
- case SIGTERM:
- pos = safecat(msg, sizeof msg, pos, "termination request");
- break;
-
- default:
- pos = safecat(msg, sizeof msg, pos, "unknown ");
- pos = safecatn(msg, sizeof msg, pos, signum);
- break;
- }
-
- store_log(&pm.this, NULL/*png_structp*/, msg, 1/*error*/);
-
- /* And finally throw an exception so we can keep going, unless this is
- * SIGTERM in which case stop now.
- */
- if (signum != SIGTERM)
- {
- struct exception_context *the_exception_context =
- &pm.this.exception_context;
-
- Throw &pm.this;
- }
-
- else
- exit(1);
-}
-
-/* main program */
-int main(int argc, char **argv)
-{
- int summary = 1; /* Print the error summary at the end */
- int memstats = 0; /* Print memory statistics at the end */
-
- /* Create the given output file on success: */
- const char *touch = NULL;
-
- /* This is an array of standard gamma values (believe it or not I've seen
- * every one of these mentioned somewhere.)
- *
- * In the following list the most useful values are first!
- */
- static double
- gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9};
-
- /* This records the command and arguments: */
- size_t cp = 0;
- char command[1024];
-
- anon_context(&pm.this);
-
- gnu_volatile(summary)
- gnu_volatile(memstats)
- gnu_volatile(touch)
-
- /* Add appropriate signal handlers, just the ANSI specified ones: */
- signal(SIGABRT, signal_handler);
- signal(SIGFPE, signal_handler);
- signal(SIGILL, signal_handler);
- signal(SIGINT, signal_handler);
- signal(SIGSEGV, signal_handler);
- signal(SIGTERM, signal_handler);
-
-#ifdef HAVE_FEENABLEEXCEPT
- /* Only required to enable FP exceptions on platforms where they start off
- * disabled; this is not necessary but if it is not done pngvalid will likely
- * end up ignoring FP conditions that other platforms fault.
- */
- feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
-#endif
-
- modifier_init(&pm);
-
- /* Preallocate the image buffer, because we know how big it needs to be,
- * note that, for testing purposes, it is deliberately mis-aligned by tag
- * bytes either side. All rows have an additional five bytes of padding for
- * overwrite checking.
- */
- store_ensure_image(&pm.this, NULL, 2, TRANSFORM_ROWMAX, TRANSFORM_HEIGHTMAX);
-
- /* Don't give argv[0], it's normally some horrible libtool string: */
- cp = safecat(command, sizeof command, cp, "pngvalid");
-
- /* Default to error on warning: */
- pm.this.treat_warnings_as_errors = 1;
-
- /* Default assume_16_bit_calculations appropriately; this tells the checking
- * code that 16-bit arithmetic is used for 8-bit samples when it would make a
- * difference.
- */
- pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700;
-
- /* Currently 16 bit expansion happens at the end of the pipeline, so the
- * calculations are done in the input bit depth not the output.
- *
- * TODO: fix this
- */
- pm.calculations_use_input_precision = 1U;
-
- /* Store the test gammas */
- pm.gammas = gammas;
- pm.ngammas = ARRAY_SIZE(gammas);
- pm.ngamma_tests = 0; /* default to off */
-
- /* Low bit depth gray images don't do well in the gamma tests, until
- * this is fixed turn them off for some gamma cases:
- */
-# ifdef PNG_WRITE_tRNS_SUPPORTED
- pm.test_tRNS = 1;
-# endif
- pm.test_lbg = PNG_LIBPNG_VER >= 10600;
- pm.test_lbg_gamma_threshold = 1;
- pm.test_lbg_gamma_transform = PNG_LIBPNG_VER >= 10600;
- pm.test_lbg_gamma_sbit = 1;
- pm.test_lbg_gamma_composition = PNG_LIBPNG_VER >= 10700;
-
- /* And the test encodings */
- pm.encodings = test_encodings;
- pm.nencodings = ARRAY_SIZE(test_encodings);
-
-# if PNG_LIBPNG_VER < 10700
- pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
-# else
- pm.sbitlow = 1U;
-# endif
-
- /* The following allows results to pass if they correspond to anything in the
- * transformed range [input-.5,input+.5]; this is is required because of the
- * way libpng treates the 16_TO_8 flag when building the gamma tables in
- * releases up to 1.6.0.
- *
- * TODO: review this
- */
- pm.use_input_precision_16to8 = 1U;
- pm.use_input_precision_sbit = 1U; /* because libpng now rounds sBIT */
-
- /* Some default values (set the behavior for 'make check' here).
- * These values simply control the maximum error permitted in the gamma
- * transformations. The practical limits for human perception are described
- * below (the setting for maxpc16), however for 8 bit encodings it isn't
- * possible to meet the accepted capabilities of human vision - i.e. 8 bit
- * images can never be good enough, regardless of encoding.
- */
- pm.maxout8 = .1; /* Arithmetic error in *encoded* value */
- pm.maxabs8 = .00005; /* 1/20000 */
- pm.maxcalc8 = 1./255; /* +/-1 in 8 bits for compose errors */
- pm.maxpc8 = .499; /* I.e., .499% fractional error */
- pm.maxout16 = .499; /* Error in *encoded* value */
- pm.maxabs16 = .00005;/* 1/20000 */
- pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */
-# if PNG_LIBPNG_VER < 10700
- pm.maxcalcG = 1./((1<<PNG_MAX_GAMMA_8)-1);
-# else
- pm.maxcalcG = 1./((1<<16)-1);
-# endif
-
- /* NOTE: this is a reasonable perceptual limit. We assume that humans can
- * perceive light level differences of 1% over a 100:1 range, so we need to
- * maintain 1 in 10000 accuracy (in linear light space), which is what the
- * following guarantees. It also allows significantly higher errors at
- * higher 16 bit values, which is important for performance. The actual
- * maximum 16 bit error is about +/-1.9 in the fixed point implementation but
- * this is only allowed for values >38149 by the following:
- */
- pm.maxpc16 = .005; /* I.e., 1/200% - 1/20000 */
-
- /* Now parse the command line options. */
- while (--argc >= 1)
- {
- int catmore = 0; /* Set if the argument has an argument. */
-
- /* Record each argument for posterity: */
- cp = safecat(command, sizeof command, cp, " ");
- cp = safecat(command, sizeof command, cp, *++argv);
-
- if (strcmp(*argv, "-v") == 0)
- pm.this.verbose = 1;
-
- else if (strcmp(*argv, "-l") == 0)
- pm.log = 1;
-
- else if (strcmp(*argv, "-q") == 0)
- summary = pm.this.verbose = pm.log = 0;
-
- else if (strcmp(*argv, "-w") == 0 ||
- strcmp(*argv, "--strict") == 0)
- pm.this.treat_warnings_as_errors = 1; /* NOTE: this is the default! */
-
- else if (strcmp(*argv, "--nostrict") == 0)
- pm.this.treat_warnings_as_errors = 0;
-
- else if (strcmp(*argv, "--speed") == 0)
- pm.this.speed = 1, pm.ngamma_tests = pm.ngammas, pm.test_standard = 0,
- summary = 0;
-
- else if (strcmp(*argv, "--memory") == 0)
- memstats = 1;
-
- else if (strcmp(*argv, "--size") == 0)
- pm.test_size = 1;
-
- else if (strcmp(*argv, "--nosize") == 0)
- pm.test_size = 0;
-
- else if (strcmp(*argv, "--standard") == 0)
- pm.test_standard = 1;
-
- else if (strcmp(*argv, "--nostandard") == 0)
- pm.test_standard = 0;
-
- else if (strcmp(*argv, "--transform") == 0)
- pm.test_transform = 1;
-
- else if (strcmp(*argv, "--notransform") == 0)
- pm.test_transform = 0;
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
- else if (strncmp(*argv, "--transform-disable=",
- sizeof "--transform-disable") == 0)
- {
- pm.test_transform = 1;
- transform_disable(*argv + sizeof "--transform-disable");
- }
-
- else if (strncmp(*argv, "--transform-enable=",
- sizeof "--transform-enable") == 0)
- {
- pm.test_transform = 1;
- transform_enable(*argv + sizeof "--transform-enable");
- }
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
- else if (strcmp(*argv, "--gamma") == 0)
- {
- /* Just do two gamma tests here (2.2 and linear) for speed: */
- pm.ngamma_tests = 2U;
- pm.test_gamma_threshold = 1;
- pm.test_gamma_transform = 1;
- pm.test_gamma_sbit = 1;
- pm.test_gamma_scale16 = 1;
- pm.test_gamma_background = 1; /* composition */
- pm.test_gamma_alpha_mode = 1;
- }
-
- else if (strcmp(*argv, "--nogamma") == 0)
- pm.ngamma_tests = 0;
-
- else if (strcmp(*argv, "--gamma-threshold") == 0)
- pm.ngamma_tests = 2U, pm.test_gamma_threshold = 1;
-
- else if (strcmp(*argv, "--nogamma-threshold") == 0)
- pm.test_gamma_threshold = 0;
-
- else if (strcmp(*argv, "--gamma-transform") == 0)
- pm.ngamma_tests = 2U, pm.test_gamma_transform = 1;
-
- else if (strcmp(*argv, "--nogamma-transform") == 0)
- pm.test_gamma_transform = 0;
-
- else if (strcmp(*argv, "--gamma-sbit") == 0)
- pm.ngamma_tests = 2U, pm.test_gamma_sbit = 1;
-
- else if (strcmp(*argv, "--nogamma-sbit") == 0)
- pm.test_gamma_sbit = 0;
-
- else if (strcmp(*argv, "--gamma-16-to-8") == 0)
- pm.ngamma_tests = 2U, pm.test_gamma_scale16 = 1;
-
- else if (strcmp(*argv, "--nogamma-16-to-8") == 0)
- pm.test_gamma_scale16 = 0;
-
- else if (strcmp(*argv, "--gamma-background") == 0)
- pm.ngamma_tests = 2U, pm.test_gamma_background = 1;
-
- else if (strcmp(*argv, "--nogamma-background") == 0)
- pm.test_gamma_background = 0;
-
- else if (strcmp(*argv, "--gamma-alpha-mode") == 0)
- pm.ngamma_tests = 2U, pm.test_gamma_alpha_mode = 1;
-
- else if (strcmp(*argv, "--nogamma-alpha-mode") == 0)
- pm.test_gamma_alpha_mode = 0;
-
- else if (strcmp(*argv, "--expand16") == 0)
- pm.test_gamma_expand16 = 1;
-
- else if (strcmp(*argv, "--noexpand16") == 0)
- pm.test_gamma_expand16 = 0;
-
- else if (strcmp(*argv, "--low-depth-gray") == 0)
- pm.test_lbg = pm.test_lbg_gamma_threshold =
- pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
- pm.test_lbg_gamma_composition = 1;
-
- else if (strcmp(*argv, "--nolow-depth-gray") == 0)
- pm.test_lbg = pm.test_lbg_gamma_threshold =
- pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
- pm.test_lbg_gamma_composition = 0;
-
-# ifdef PNG_WRITE_tRNS_SUPPORTED
- else if (strcmp(*argv, "--tRNS") == 0)
- pm.test_tRNS = 1;
-# endif
-
- else if (strcmp(*argv, "--notRNS") == 0)
- pm.test_tRNS = 0;
-
- else if (strcmp(*argv, "--more-gammas") == 0)
- pm.ngamma_tests = 3U;
-
- else if (strcmp(*argv, "--all-gammas") == 0)
- pm.ngamma_tests = pm.ngammas;
-
- else if (strcmp(*argv, "--progressive-read") == 0)
- pm.this.progressive = 1;
-
- else if (strcmp(*argv, "--use-update-info") == 0)
- ++pm.use_update_info; /* Can call multiple times */
-
- else if (strcmp(*argv, "--interlace") == 0)
- {
-# if CAN_WRITE_INTERLACE
- pm.interlace_type = PNG_INTERLACE_ADAM7;
-# else /* !CAN_WRITE_INTERLACE */
- fprintf(stderr, "pngvalid: no write interlace support\n");
- return SKIP;
-# endif /* !CAN_WRITE_INTERLACE */
- }
-
- else if (strcmp(*argv, "--use-input-precision") == 0)
- pm.use_input_precision = 1U;
-
- else if (strcmp(*argv, "--use-calculation-precision") == 0)
- pm.use_input_precision = 0;
-
- else if (strcmp(*argv, "--calculations-use-input-precision") == 0)
- pm.calculations_use_input_precision = 1U;
-
- else if (strcmp(*argv, "--assume-16-bit-calculations") == 0)
- pm.assume_16_bit_calculations = 1U;
-
- else if (strcmp(*argv, "--calculations-follow-bit-depth") == 0)
- pm.calculations_use_input_precision =
- pm.assume_16_bit_calculations = 0;
-
- else if (strcmp(*argv, "--exhaustive") == 0)
- pm.test_exhaustive = 1;
-
- else if (argc > 1 && strcmp(*argv, "--sbitlow") == 0)
- --argc, pm.sbitlow = (png_byte)atoi(*++argv), catmore = 1;
-
- else if (argc > 1 && strcmp(*argv, "--touch") == 0)
- --argc, touch = *++argv, catmore = 1;
-
- else if (argc > 1 && strncmp(*argv, "--max", 5) == 0)
- {
- --argc;
-
- if (strcmp(5+*argv, "abs8") == 0)
- pm.maxabs8 = atof(*++argv);
-
- else if (strcmp(5+*argv, "abs16") == 0)
- pm.maxabs16 = atof(*++argv);
-
- else if (strcmp(5+*argv, "calc8") == 0)
- pm.maxcalc8 = atof(*++argv);
-
- else if (strcmp(5+*argv, "calc16") == 0)
- pm.maxcalc16 = atof(*++argv);
-
- else if (strcmp(5+*argv, "out8") == 0)
- pm.maxout8 = atof(*++argv);
-
- else if (strcmp(5+*argv, "out16") == 0)
- pm.maxout16 = atof(*++argv);
-
- else if (strcmp(5+*argv, "pc8") == 0)
- pm.maxpc8 = atof(*++argv);
-
- else if (strcmp(5+*argv, "pc16") == 0)
- pm.maxpc16 = atof(*++argv);
-
- else
- {
- fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv);
- exit(99);
- }
-
- catmore = 1;
- }
-
- else if (strcmp(*argv, "--log8") == 0)
- --argc, pm.log8 = atof(*++argv), catmore = 1;
-
- else if (strcmp(*argv, "--log16") == 0)
- --argc, pm.log16 = atof(*++argv), catmore = 1;
-
-#ifdef PNG_SET_OPTION_SUPPORTED
- else if (strncmp(*argv, "--option=", 9) == 0)
- {
- /* Syntax of the argument is <option>:{on|off} */
- const char *arg = 9+*argv;
- unsigned char option=0, setting=0;
-
-#ifdef PNG_ARM_NEON
- if (strncmp(arg, "arm-neon:", 9) == 0)
- option = PNG_ARM_NEON, arg += 9;
-
- else
-#endif
-#ifdef PNG_EXTENSIONS
- if (strncmp(arg, "extensions:", 11) == 0)
- option = PNG_EXTENSIONS, arg += 11;
-
- else
-#endif
-#ifdef PNG_MAXIMUM_INFLATE_WINDOW
- if (strncmp(arg, "max-inflate-window:", 19) == 0)
- option = PNG_MAXIMUM_INFLATE_WINDOW, arg += 19;
-
- else
-#endif
- {
- fprintf(stderr, "pngvalid: %s: %s: unknown option\n", *argv, arg);
- exit(99);
- }
-
- if (strcmp(arg, "off") == 0)
- setting = PNG_OPTION_OFF;
-
- else if (strcmp(arg, "on") == 0)
- setting = PNG_OPTION_ON;
-
- else
- {
- fprintf(stderr,
- "pngvalid: %s: %s: unknown setting (use 'on' or 'off')\n",
- *argv, arg);
- exit(99);
- }
-
- pm.this.options[pm.this.noptions].option = option;
- pm.this.options[pm.this.noptions++].setting = setting;
- }
-#endif /* PNG_SET_OPTION_SUPPORTED */
-
- else
- {
- fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv);
- exit(99);
- }
-
- if (catmore) /* consumed an extra *argv */
- {
- cp = safecat(command, sizeof command, cp, " ");
- cp = safecat(command, sizeof command, cp, *argv);
- }
- }
-
- /* If pngvalid is run with no arguments default to a reasonable set of the
- * tests.
- */
- if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 &&
- pm.ngamma_tests == 0)
- {
- /* Make this do all the tests done in the test shell scripts with the same
- * parameters, where possible. The limitation is that all the progressive
- * read and interlace stuff has to be done in separate runs, so only the
- * basic 'standard' and 'size' tests are done.
- */
- pm.test_standard = 1;
- pm.test_size = 1;
- pm.test_transform = 1;
- pm.ngamma_tests = 2U;
- }
-
- if (pm.ngamma_tests > 0 &&
- pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 &&
- pm.test_gamma_sbit == 0 && pm.test_gamma_scale16 == 0 &&
- pm.test_gamma_background == 0 && pm.test_gamma_alpha_mode == 0)
- {
- pm.test_gamma_threshold = 1;
- pm.test_gamma_transform = 1;
- pm.test_gamma_sbit = 1;
- pm.test_gamma_scale16 = 1;
- pm.test_gamma_background = 1;
- pm.test_gamma_alpha_mode = 1;
- }
-
- else if (pm.ngamma_tests == 0)
- {
- /* Nothing to test so turn everything off: */
- pm.test_gamma_threshold = 0;
- pm.test_gamma_transform = 0;
- pm.test_gamma_sbit = 0;
- pm.test_gamma_scale16 = 0;
- pm.test_gamma_background = 0;
- pm.test_gamma_alpha_mode = 0;
- }
-
- Try
- {
- /* Make useful base images */
- make_transform_images(&pm);
-
- /* Perform the standard and gamma tests. */
- if (pm.test_standard)
- {
- perform_interlace_macro_validation();
- perform_formatting_test(&pm.this);
-# ifdef PNG_READ_SUPPORTED
- perform_standard_test(&pm);
-# endif
- perform_error_test(&pm);
- }
-
- /* Various oddly sized images: */
- if (pm.test_size)
- {
- make_size_images(&pm.this);
-# ifdef PNG_READ_SUPPORTED
- perform_size_test(&pm);
-# endif
- }
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
- /* Combinatorial transforms: */
- if (pm.test_transform)
- perform_transform_test(&pm);
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (pm.ngamma_tests > 0)
- perform_gamma_test(&pm, summary);
-#endif
- }
-
- Catch_anonymous
- {
- fprintf(stderr, "pngvalid: test aborted (probably failed in cleanup)\n");
- if (!pm.this.verbose)
- {
- if (pm.this.error[0] != 0)
- fprintf(stderr, "pngvalid: first error: %s\n", pm.this.error);
-
- fprintf(stderr, "pngvalid: run with -v to see what happened\n");
- }
- exit(1);
- }
-
- if (summary)
- {
- printf("%s: %s (%s point arithmetic)\n",
- (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
- pm.this.nwarnings)) ? "FAIL" : "PASS",
- command,
-#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500
- "floating"
-#else
- "fixed"
-#endif
- );
- }
-
- if (memstats)
- {
- printf("Allocated memory statistics (in bytes):\n"
- "\tread %lu maximum single, %lu peak, %lu total\n"
- "\twrite %lu maximum single, %lu peak, %lu total\n",
- (unsigned long)pm.this.read_memory_pool.max_max,
- (unsigned long)pm.this.read_memory_pool.max_limit,
- (unsigned long)pm.this.read_memory_pool.max_total,
- (unsigned long)pm.this.write_memory_pool.max_max,
- (unsigned long)pm.this.write_memory_pool.max_limit,
- (unsigned long)pm.this.write_memory_pool.max_total);
- }
-
- /* Do this here to provoke memory corruption errors in memory not directly
- * allocated by libpng - not a complete test, but better than nothing.
- */
- store_delete(&pm.this);
-
- /* Error exit if there are any errors, and maybe if there are any
- * warnings.
- */
- if (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
- pm.this.nwarnings))
- {
- if (!pm.this.verbose)
- fprintf(stderr, "pngvalid: %s\n", pm.this.error);
-
- fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors,
- pm.this.nwarnings);
-
- exit(1);
- }
-
- /* Success case. */
- if (touch != NULL)
- {
- FILE *fsuccess = fopen(touch, "wt");
-
- if (fsuccess != NULL)
- {
- int error = 0;
- fprintf(fsuccess, "PNG validation succeeded\n");
- fflush(fsuccess);
- error = ferror(fsuccess);
-
- if (fclose(fsuccess) || error)
- {
- fprintf(stderr, "%s: write failed\n", touch);
- exit(1);
- }
- }
-
- else
- {
- fprintf(stderr, "%s: open failed\n", touch);
- exit(1);
- }
- }
-
- /* This is required because some very minimal configurations do not use it:
- */
- UNUSED(fail)
- return 0;
-}
-#else /* write or low level APIs not supported */
-int main(void)
-{
- fprintf(stderr,
- "pngvalid: no low level write support in libpng, all tests skipped\n");
- /* So the test is skipped: */
- return SKIP;
-}
-#endif
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/readpng.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/readpng.c
deleted file mode 100644
index 60a2d46c56f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/readpng.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* readpng.c
- *
- * Copyright (c) 2013 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.1 [March 28, 2013]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Load an arbitrary number of PNG files (from the command line, or, if there
- * are no arguments on the command line, from stdin) then run a time test by
- * reading each file by row. The test does nothing with the read result and
- * does no transforms. The only output is a time as a floating point number of
- * seconds with 9 decimal digits.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
-# include <config.h>
-#endif
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-static int
-read_png(FILE *fp)
-{
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
- png_infop info_ptr = NULL;
- png_bytep row = NULL, display = NULL;
-
- if (png_ptr == NULL)
- return 0;
-
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- if (row != NULL) free(row);
- if (display != NULL) free(display);
- return 0;
- }
-
- png_init_io(png_ptr, fp);
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- png_error(png_ptr, "OOM allocating info structure");
-
- png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0);
-
- png_read_info(png_ptr, info_ptr);
-
- {
- size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
-
- /* Failure to initialize these is harmless */
- row = malloc(rowbytes);
- display = malloc(rowbytes);
-
- if (row == NULL || display == NULL)
- png_error(png_ptr, "OOM allocating row buffers");
-
- {
- png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
-# ifdef PNG_READ_INTERLACING_SUPPORTED
- int passes = png_set_interlace_handling(png_ptr);
-# else /* !READ_INTERLACING */
- int passes = png_get_interlace_type(png_ptr, info_ptr) ==
- PNG_INTERLACE_ADAM7 ? PNG_INTERLACE_ADAM7_PASSES : 1;
-# endif /* !READ_INTERLACING */
- int pass;
-
- png_start_read_image(png_ptr);
-
- for (pass = 0; pass < passes; ++pass)
- {
- png_uint_32 y = height;
-
-# ifndef PNG_READ_INTERLACING_SUPPORTED
- if (passes == PNG_INTERLACE_ADAM7_PASSES)
- y = PNG_PASS_ROWS(y, pass);
-# endif /* READ_INTERLACING */
-
- /* NOTE: this trashes the row each time; interlace handling won't
- * work, but this avoids memory thrashing for speed testing.
- */
- while (y-- > 0)
- png_read_row(png_ptr, row, display);
- }
- }
- }
-
- /* Make sure to read to the end of the file: */
- png_read_end(png_ptr, info_ptr);
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- free(row);
- free(display);
- return 1;
-}
-
-int
-main(void)
-{
- /* Exit code 0 on success. */
- return !read_png(stdin);
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/tarith.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/tarith.c
deleted file mode 100644
index c03f05a80bd..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/tarith.c
+++ /dev/null
@@ -1,999 +0,0 @@
-
-/* tarith.c
- *
- * Copyright (c) 2011-2013 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Test internal arithmetic functions of libpng.
- *
- * This code must be linked against a math library (-lm), but does not require
- * libpng or zlib to work. Because it includes the complete source of 'png.c'
- * it tests the code with whatever compiler options are used to build it.
- * Changing these options can substantially change the errors in the
- * calculations that the compiler chooses!
- */
-#define _POSIX_SOURCE 1
-#define _ISOC99_SOURCE 1
-
-/* Obtain a copy of the code to be tested (plus other things), disabling
- * stuff that is not required.
- */
-#include <math.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-
-#include "../../pngpriv.h"
-
-#define png_error png_warning
-
-void png_warning(png_const_structrp png_ptr, png_const_charp msg)
-{
- fprintf(stderr, "validation: %s\n", msg);
-}
-
-#define png_fixed_error png_fixed_warning
-
-void png_fixed_warning(png_const_structrp png_ptr, png_const_charp msg)
-{
- fprintf(stderr, "overflow in: %s\n", msg);
-}
-
-#define png_set_error_fn(pp, ep, efp, wfp) ((void)0)
-#define png_malloc(pp, s) malloc(s)
-#define png_malloc_warn(pp, s) malloc(s)
-#define png_malloc_base(pp, s) malloc(s)
-#define png_calloc(pp, s) calloc(1, (s))
-#define png_free(pp, s) free(s)
-
-#define png_safecat(b, sb, pos, str) (pos)
-#define png_format_number(start, end, format, number) (start)
-
-#define crc32(crc, pp, s) (crc)
-#define inflateReset(zs) Z_OK
-
-#define png_create_struct(type) (0)
-#define png_destroy_struct(pp) ((void)0)
-#define png_create_struct_2(type, m, mm) (0)
-#define png_destroy_struct_2(pp, f, mm) ((void)0)
-
-#undef PNG_SIMPLIFIED_READ_SUPPORTED
-#undef PNG_SIMPLIFIED_WRITE_SUPPORTED
-#undef PNG_USER_MEM_SUPPORTED
-
-#include "../../png.c"
-
-/* Validate ASCII to fp routines. */
-static int verbose = 0;
-
-int validation_ascii_to_fp(int count, int argc, char **argv)
-{
- int showall = 0;
- double max_error=2; /* As a percentage error-in-last-digit/.5 */
- double max_error_abs=17; /* Used when precision is DBL_DIG */
- double max = 0;
- double max_abs = 0;
- double test = 0; /* Important to test this. */
- int precision = 5;
- int nonfinite = 0;
- int finite = 0;
- int ok = 0;
- int failcount = 0;
- int minorarith = 0;
-
- while (--argc > 0)
- if (strcmp(*++argv, "-a") == 0)
- showall = 1;
- else if (strcmp(*argv, "-e") == 0 && argc > 0)
- {
- --argc;
- max_error = atof(*++argv);
- }
- else if (strcmp(*argv, "-E") == 0 && argc > 0)
- {
- --argc;
- max_error_abs = atof(*++argv);
- }
- else
- {
- fprintf(stderr, "unknown argument %s\n", *argv);
- return 1;
- }
-
- do
- {
- size_t index;
- int state, failed = 0;
- char buffer[64];
-
- if (isfinite(test))
- ++finite;
- else
- ++nonfinite;
-
- if (verbose)
- fprintf(stderr, "%.*g %d\n", DBL_DIG, test, precision);
-
- /* Check for overflow in the buffer by setting a marker. */
- memset(buffer, 71, sizeof buffer);
-
- png_ascii_from_fp(0, buffer, precision+10, test, precision);
-
- /* Allow for a three digit exponent, this stuff will fail if
- * the exponent is bigger than this!
- */
- if (buffer[precision+7] != 71)
- {
- fprintf(stderr, "%g[%d] -> '%s'[%lu] buffer overflow\n", test,
- precision, buffer, (unsigned long)strlen(buffer));
- failed = 1;
- }
-
- /* Following are used for the number parser below and must be
- * initialized to zero.
- */
- state = 0;
- index = 0;
- if (!isfinite(test))
- {
- /* Expect 'inf' */
- if (test >= 0 && strcmp(buffer, "inf") ||
- test < 0 && strcmp(buffer, "-inf"))
- {
- fprintf(stderr, "%g[%d] -> '%s' but expected 'inf'\n", test,
- precision, buffer);
- failed = 1;
- }
- }
- else if (!png_check_fp_number(buffer, precision+10, &state, &index) ||
- buffer[index] != 0)
- {
- fprintf(stderr, "%g[%d] -> '%s' but has bad format ('%c')\n", test,
- precision, buffer, buffer[index]);
- failed = 1;
- }
- else if (PNG_FP_IS_NEGATIVE(state) && !(test < 0))
- {
- fprintf(stderr, "%g[%d] -> '%s' but negative value not so reported\n",
- test, precision, buffer);
- failed = 1;
- assert(!PNG_FP_IS_ZERO(state));
- assert(!PNG_FP_IS_POSITIVE(state));
- }
- else if (PNG_FP_IS_ZERO(state) && !(test == 0))
- {
- fprintf(stderr, "%g[%d] -> '%s' but zero value not so reported\n",
- test, precision, buffer);
- failed = 1;
- assert(!PNG_FP_IS_NEGATIVE(state));
- assert(!PNG_FP_IS_POSITIVE(state));
- }
- else if (PNG_FP_IS_POSITIVE(state) && !(test > 0))
- {
- fprintf(stderr, "%g[%d] -> '%s' but positive value not so reported\n",
- test, precision, buffer);
- failed = 1;
- assert(!PNG_FP_IS_NEGATIVE(state));
- assert(!PNG_FP_IS_ZERO(state));
- }
- else
- {
- /* Check the result against the original. */
- double out = atof(buffer);
- double change = fabs((out - test)/test);
- double allow = .5/pow(10,
- (precision >= DBL_DIG) ? DBL_DIG-1 : precision-1);
-
- /* NOTE: if you hit this error case are you compiling with gcc
- * and -O0? Try -O2 - the errors can accumulate if the FP
- * code above is not optimized and may drift outside the .5 in
- * DBL_DIG allowed. In any case a small number of errors may
- * occur (very small ones - 1 or 2%) because of rounding in the
- * calculations, either in the conversion API or in atof.
- */
- if (change >= allow && (isfinite(out) ||
- fabs(test/DBL_MAX) <= 1-allow))
- {
- double percent = (precision >= DBL_DIG) ? max_error_abs : max_error;
- double allowp = (change-allow)*100/allow;
-
- if (precision >= DBL_DIG)
- {
- if (max_abs < allowp) max_abs = allowp;
- }
-
- else
- {
- if (max < allowp) max = allowp;
- }
-
- if (showall || allowp >= percent)
- {
- fprintf(stderr,
- "%.*g[%d] -> '%s' -> %.*g number changed (%g > %g (%d%%))\n",
- DBL_DIG, test, precision, buffer, DBL_DIG, out, change, allow,
- (int)round(allowp));
- failed = 1;
- }
- else
- ++minorarith;
- }
- }
-
- if (failed)
- ++failcount;
- else
- ++ok;
-
-skip:
- /* Generate a new number and precision. */
- precision = rand();
- if (precision & 1) test = -test;
- precision >>= 1;
-
- /* Generate random numbers. */
- if (test == 0 || !isfinite(test))
- test = precision+1;
- else
- {
- /* Derive the exponent from the previous rand() value. */
- int exponent = precision % (DBL_MAX_EXP - DBL_MIN_EXP) + DBL_MIN_EXP;
- int tmp;
- test = frexp(test * rand(), &tmp);
- test = ldexp(test, exponent);
- precision >>= 8; /* arbitrary */
- }
-
- /* This limits the precision to 32 digits, enough for standard
- * IEEE implementations which have at most 15 digits.
- */
- precision = (precision & 0x1f) + 1;
- }
- while (--count);
-
- printf("Tested %d finite values, %d non-finite, %d OK (%d failed) %d minor "
- "arithmetic errors\n", finite, nonfinite, ok, failcount, minorarith);
- printf(" Error with >=%d digit precision %.2f%%\n", DBL_DIG, max_abs);
- printf(" Error with < %d digit precision %.2f%%\n", DBL_DIG, max);
-
- return 0;
-}
-
-/* Observe that valid FP numbers have the forms listed in the PNG extensions
- * specification:
- *
- * [+,-]{integer,integer.fraction,.fraction}[{e,E}[+,-]integer]
- *
- * Test each of these in turn, including invalid cases.
- */
-typedef enum checkfp_state
-{
- start, fraction, exponent, states
-} checkfp_state;
-
-/* The characters (other than digits) that characterize the states: */
-static const char none[] = "";
-static const char hexdigits[16] = "0123456789ABCDEF";
-
-static const struct
-{
- const char *start; /* Characters valid at the start */
- const char *end; /* Valid characters that end the state */
- const char *tests; /* Characters to test after 2 digits seen */
-}
-state_characters[states] =
-{
- /* start: */ { "+-.", ".eE", "+-.e*0369" },
- /* fraction: */ { none, "eE", "+-.E#0147" },
- /* exponent: */ { "+-", none, "+-.eE^0258" }
-};
-
-typedef struct
-{
- char number[1024]; /* Buffer for number being tested */
- int limit; /* Command line limit */
- int verbose; /* Shadows global variable */
- int ctimes; /* Number of numbers tested */
- int cmillions; /* Count of millions of numbers */
- int cinvalid; /* Invalid strings checked */
- int cnoaccept; /* Characters not accepted */
-}
-checkfp_command;
-
-typedef struct
-{
- int cnumber; /* Index into number string */
- checkfp_state check_state; /* Current number state */
- int at_start; /* At start (first character) of state */
- int cdigits_in_state; /* Digits seen in that state */
- int limit; /* Limit on same for checking all chars */
- int state; /* Current parser state */
- int is_negative; /* Number is negative */
- int is_zero; /* Number is (still) zero */
- int number_was_valid; /* Previous character validity */
-}
-checkfp_control;
-
-static int check_all_characters(checkfp_command *co, checkfp_control c);
-
-static int check_some_characters(checkfp_command *co, checkfp_control c,
- const char *tests);
-
-static int check_one_character(checkfp_command *co, checkfp_control c, int ch)
-{
- /* Test this character (ch) to ensure the parser does the correct thing.
- */
- size_t index = 0;
- const char test = (char)ch;
- int number_is_valid = png_check_fp_number(&test, 1, &c.state, &index);
- int character_accepted = (index == 1);
-
- if (c.check_state != exponent && isdigit(ch) && ch != '0')
- c.is_zero = 0;
-
- if (c.check_state == start && c.at_start && ch == '-')
- c.is_negative = 1;
-
- if (isprint(ch))
- co->number[c.cnumber++] = (char)ch;
- else
- {
- co->number[c.cnumber++] = '<';
- co->number[c.cnumber++] = hexdigits[(ch >> 4) & 0xf];
- co->number[c.cnumber++] = hexdigits[ch & 0xf];
- co->number[c.cnumber++] = '>';
- }
- co->number[c.cnumber] = 0;
-
- if (co->verbose > 1)
- fprintf(stderr, "%s\n", co->number);
-
- if (++(co->ctimes) == 1000000)
- {
- if (co->verbose == 1)
- fputc('.', stderr);
- co->ctimes = 0;
- ++(co->cmillions);
- }
-
- if (!number_is_valid)
- ++(co->cinvalid);
-
- if (!character_accepted)
- ++(co->cnoaccept);
-
- /* This should never fail (it's a serious bug if it does): */
- if (index != 0 && index != 1)
- {
- fprintf(stderr, "%s: read beyond end of string (%lu)\n", co->number,
- (unsigned long)index);
- return 0;
- }
-
- /* Validate the new state, note that the PNG_FP_IS_ macros all return
- * false unless the number is valid.
- */
- if (PNG_FP_IS_NEGATIVE(c.state) !=
- (number_is_valid && !c.is_zero && c.is_negative))
- {
- fprintf(stderr, "%s: negative when it is not\n", co->number);
- return 0;
- }
-
- if (PNG_FP_IS_ZERO(c.state) != (number_is_valid && c.is_zero))
- {
- fprintf(stderr, "%s: zero when it is not\n", co->number);
- return 0;
- }
-
- if (PNG_FP_IS_POSITIVE(c.state) !=
- (number_is_valid && !c.is_zero && !c.is_negative))
- {
- fprintf(stderr, "%s: positive when it is not\n", co->number);
- return 0;
- }
-
- /* Testing a digit */
- if (isdigit(ch))
- {
- if (!character_accepted)
- {
- fprintf(stderr, "%s: digit '%c' not accepted\n", co->number, ch);
- return 0;
- }
-
- if (!number_is_valid)
- {
- fprintf(stderr, "%s: saw a digit (%c) but number not valid\n",
- co->number, ch);
- return 0;
- }
-
- ++c.cdigits_in_state;
- c.at_start = 0;
- c.number_was_valid = 1;
-
- /* Continue testing characters in this state. Either test all of
- * them or, if we have already seen one digit in this state, just test a
- * limited set.
- */
- if (c.cdigits_in_state < 1)
- return check_all_characters(co, c);
-
- else
- return check_some_characters(co, c,
- state_characters[c.check_state].tests);
- }
-
- /* A non-digit; is it allowed here? */
- else if (((ch == '+' || ch == '-') && c.check_state != fraction &&
- c.at_start) ||
- (ch == '.' && c.check_state == start) ||
- ((ch == 'e' || ch == 'E') && c.number_was_valid &&
- c.check_state != exponent))
- {
- if (!character_accepted)
- {
- fprintf(stderr, "%s: character '%c' not accepted\n", co->number, ch);
- return 0;
- }
-
- /* The number remains valid after start of fraction but nowhere else. */
- if (number_is_valid && (c.check_state != start || ch != '.'))
- {
- fprintf(stderr, "%s: saw a non-digit (%c) but number valid\n",
- co->number, ch);
- return 0;
- }
-
- c.number_was_valid = number_is_valid;
-
- /* Check for a state change. When changing to 'fraction' if the number
- * is valid at this point set the at_start to false to allow an exponent
- * 'e' to come next.
- */
- if (c.check_state == start && ch == '.')
- {
- c.check_state = fraction;
- c.at_start = !number_is_valid;
- c.cdigits_in_state = 0;
- c.limit = co->limit;
- return check_all_characters(co, c);
- }
-
- else if (c.check_state < exponent && (ch == 'e' || ch == 'E'))
- {
- c.check_state = exponent;
- c.at_start = 1;
- c.cdigits_in_state = 0;
- c.limit = co->limit;
- return check_all_characters(co, c);
- }
-
- /* Else it was a sign, and the state doesn't change. */
- else
- {
- if (ch != '-' && ch != '+')
- {
- fprintf(stderr, "checkfp: internal error (1)\n");
- return 0;
- }
-
- c.at_start = 0;
- return check_all_characters(co, c);
- }
- }
-
- /* Testing an invalid character */
- else
- {
- if (character_accepted)
- {
- fprintf(stderr, "%s: character '%c' [0x%.2x] accepted\n", co->number,
- ch, ch);
- return 0;
- }
-
- if (number_is_valid != c.number_was_valid)
- {
- fprintf(stderr,
- "%s: character '%c' [0x%.2x] changed number validity\n", co->number,
- ch, ch);
- return 0;
- }
-
- /* Do nothing - the parser has stuck; return success and keep going with
- * the next character.
- */
- }
-
- /* Successful return (the caller will try the next character.) */
- return 1;
-}
-
-static int check_all_characters(checkfp_command *co, checkfp_control c)
-{
- int ch;
-
- if (c.cnumber+4 < sizeof co->number) for (ch=0; ch<256; ++ch)
- {
- if (!check_one_character(co, c, ch))
- return 0;
- }
-
- return 1;
-}
-
-static int check_some_characters(checkfp_command *co, checkfp_control c,
- const char *tests)
-{
- int i;
-
- --(c.limit);
-
- if (c.cnumber+4 < sizeof co->number && c.limit >= 0)
- {
- if (c.limit > 0) for (i=0; tests[i]; ++i)
- {
- if (!check_one_character(co, c, tests[i]))
- return 0;
- }
-
- /* At the end check all the characters. */
- else
- return check_all_characters(co, c);
- }
-
- return 1;
-}
-
-int validation_checkfp(int count, int argc, char **argv)
-{
- int result;
- checkfp_command command;
- checkfp_control control;
-
- command.number[0] = 0;
- command.limit = 3;
- command.verbose = verbose;
- command.ctimes = 0;
- command.cmillions = 0;
- command.cinvalid = 0;
- command.cnoaccept = 0;
-
- while (--argc > 0)
- {
- ++argv;
- if (argc > 1 && strcmp(*argv, "-l") == 0)
- {
- --argc;
- command.limit = atoi(*++argv);
- }
-
- else
- {
- fprintf(stderr, "unknown argument %s\n", *argv);
- return 1;
- }
- }
-
- control.cnumber = 0;
- control.check_state = start;
- control.at_start = 1;
- control.cdigits_in_state = 0;
- control.limit = command.limit;
- control.state = 0;
- control.is_negative = 0;
- control.is_zero = 1;
- control.number_was_valid = 0;
-
- result = check_all_characters(&command, control);
-
- printf("checkfp: %s: checked %d,%.3d,%.3d,%.3d strings (%d invalid)\n",
- result ? "pass" : "FAIL", command.cmillions / 1000,
- command.cmillions % 1000, command.ctimes / 1000, command.ctimes % 1000,
- command.cinvalid);
-
- return result;
-}
-
-int validation_muldiv(int count, int argc, char **argv)
-{
- int tested = 0;
- int overflow = 0;
- int error = 0;
- int error64 = 0;
- int passed = 0;
- int randbits = 0;
- png_uint_32 randbuffer;
- png_fixed_point a;
- png_int_32 times, div;
-
- while (--argc > 0)
- {
- fprintf(stderr, "unknown argument %s\n", *++argv);
- return 1;
- }
-
- /* Find out about the random number generator. */
- randbuffer = RAND_MAX;
- while (randbuffer != 0) ++randbits, randbuffer >>= 1;
- printf("Using random number generator that makes %d bits\n", randbits);
- for (div=0; div<32; div += randbits)
- randbuffer = (randbuffer << randbits) ^ rand();
-
- a = 0;
- times = div = 0;
- do
- {
- png_fixed_point result;
- /* NOTE: your mileage may vary, a type is required below that can
- * hold 64 bits or more, if floating point is used a 64-bit or
- * better mantissa is required.
- */
- long long int fp, fpround;
- unsigned long hi, lo;
- int ok;
-
- /* Check the values, png_64bit_product can only handle positive
- * numbers, so correct for that here.
- */
- {
- long u1, u2;
- int n = 0;
- if (a < 0) u1 = -a, n = 1; else u1 = a;
- if (times < 0) u2 = -times, n = !n; else u2 = times;
- png_64bit_product(u1, u2, &hi, &lo);
- if (n)
- {
- /* -x = ~x+1 */
- lo = ((~lo) + 1) & 0xffffffff;
- hi = ~hi;
- if (lo == 0) ++hi;
- }
- }
-
- fp = a;
- fp *= times;
- if ((fp & 0xffffffff) != lo || ((fp >> 32) & 0xffffffff) != hi)
- {
- fprintf(stderr, "png_64bit_product %d * %d -> %lx|%.8lx not %llx\n",
- a, times, hi, lo, fp);
- ++error64;
- }
-
- if (div != 0)
- {
- /* Round - this is C round to zero. */
- if ((fp < 0) != (div < 0))
- fp -= div/2;
- else
- fp += div/2;
-
- fp /= div;
- fpround = fp;
- /* Assume 2's complement here: */
- ok = fpround <= PNG_UINT_31_MAX &&
- fpround >= -1-(long long int)PNG_UINT_31_MAX;
- if (!ok) ++overflow;
- }
- else
- ok = 0, ++overflow, fpround = fp/*misleading*/;
-
- if (verbose)
- fprintf(stderr, "TEST %d * %d / %d -> %lld (%s)\n", a, times, div,
- fp, ok ? "ok" : "overflow");
-
- ++tested;
- if (png_muldiv(&result, a, times, div) != ok)
- {
- ++error;
- if (ok)
- fprintf(stderr, "%d * %d / %d -> overflow (expected %lld)\n", a,
- times, div, fp);
- else
- fprintf(stderr, "%d * %d / %d -> %d (expected overflow %lld)\n", a,
- times, div, result, fp);
- }
- else if (ok && result != fpround)
- {
- ++error;
- fprintf(stderr, "%d * %d / %d -> %d not %lld\n", a, times, div, result,
- fp);
- }
- else
- ++passed;
-
- /* Generate three new values, this uses rand() and rand() only returns
- * up to RAND_MAX.
- */
- /* CRUDE */
- a += times;
- times += div;
- div = randbuffer;
- randbuffer = (randbuffer << randbits) ^ rand();
- }
- while (--count > 0);
-
- printf("%d tests including %d overflows, %d passed, %d failed (%d 64-bit "
- "errors)\n", tested, overflow, passed, error, error64);
- return 0;
-}
-
-/* When FP is on this just becomes a speed test - compile without FP to get real
- * validation.
- */
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-#define LN2 .000010576586617430806112933839 /* log(2)/65536 */
-#define L2INV 94548.46219969910586572651 /* 65536/log(2) */
-
-/* For speed testing, need the internal functions too: */
-static png_uint_32 png_log8bit(unsigned x)
-{
- if (x > 0)
- return (png_uint_32)floor(.5-log(x/255.)*L2INV);
-
- return 0xffffffff;
-}
-
-static png_uint_32 png_log16bit(png_uint_32 x)
-{
- if (x > 0)
- return (png_uint_32)floor(.5-log(x/65535.)*L2INV);
-
- return 0xffffffff;
-}
-
-static png_uint_32 png_exp(png_uint_32 x)
-{
- return (png_uint_32)floor(.5 + exp(x * -LN2) * 0xffffffffU);
-}
-
-static png_byte png_exp8bit(png_uint_32 log)
-{
- return (png_byte)floor(.5 + exp(log * -LN2) * 255);
-}
-
-static png_uint_16 png_exp16bit(png_uint_32 log)
-{
- return (png_uint_16)floor(.5 + exp(log * -LN2) * 65535);
-}
-#endif /* FLOATING_ARITHMETIC */
-
-int validation_gamma(int argc, char **argv)
-{
- double gamma[9] = { 2.2, 1.8, 1.52, 1.45, 1., 1/1.45, 1/1.52, 1/1.8, 1/2.2 };
- double maxerr;
- int i, silent=0, onlygamma=0;
-
- /* Silence the output with -s, just test the gamma functions with -g: */
- while (--argc > 0)
- if (strcmp(*++argv, "-s") == 0)
- silent = 1;
- else if (strcmp(*argv, "-g") == 0)
- onlygamma = 1;
- else
- {
- fprintf(stderr, "unknown argument %s\n", *argv);
- return 1;
- }
-
- if (!onlygamma)
- {
- /* First validate the log functions: */
- maxerr = 0;
- for (i=0; i<256; ++i)
- {
- double correct = -log(i/255.)/log(2.)*65536;
- double error = png_log8bit(i) - correct;
-
- if (i != 0 && fabs(error) > maxerr)
- maxerr = fabs(error);
-
- if (i == 0 && png_log8bit(i) != 0xffffffff ||
- i != 0 && png_log8bit(i) != floor(correct+.5))
- {
- fprintf(stderr, "8-bit log error: %d: got %u, expected %f\n",
- i, png_log8bit(i), correct);
- }
- }
-
- if (!silent)
- printf("maximum 8-bit log error = %f\n", maxerr);
-
- maxerr = 0;
- for (i=0; i<65536; ++i)
- {
- double correct = -log(i/65535.)/log(2.)*65536;
- double error = png_log16bit(i) - correct;
-
- if (i != 0 && fabs(error) > maxerr)
- maxerr = fabs(error);
-
- if (i == 0 && png_log16bit(i) != 0xffffffff ||
- i != 0 && png_log16bit(i) != floor(correct+.5))
- {
- if (error > .68) /* By experiment error is less than .68 */
- {
- fprintf(stderr, "16-bit log error: %d: got %u, expected %f"
- " error: %f\n", i, png_log16bit(i), correct, error);
- }
- }
- }
-
- if (!silent)
- printf("maximum 16-bit log error = %f\n", maxerr);
-
- /* Now exponentiations. */
- maxerr = 0;
- for (i=0; i<=0xfffff; ++i)
- {
- double correct = exp(-i/65536. * log(2.)) * (65536. * 65536);
- double error = png_exp(i) - correct;
-
- if (fabs(error) > maxerr)
- maxerr = fabs(error);
- if (fabs(error) > 1883) /* By experiment. */
- {
- fprintf(stderr, "32-bit exp error: %d: got %u, expected %f"
- " error: %f\n", i, png_exp(i), correct, error);
- }
- }
-
- if (!silent)
- printf("maximum 32-bit exp error = %f\n", maxerr);
-
- maxerr = 0;
- for (i=0; i<=0xfffff; ++i)
- {
- double correct = exp(-i/65536. * log(2.)) * 255;
- double error = png_exp8bit(i) - correct;
-
- if (fabs(error) > maxerr)
- maxerr = fabs(error);
- if (fabs(error) > .50002) /* By experiment */
- {
- fprintf(stderr, "8-bit exp error: %d: got %u, expected %f"
- " error: %f\n", i, png_exp8bit(i), correct, error);
- }
- }
-
- if (!silent)
- printf("maximum 8-bit exp error = %f\n", maxerr);
-
- maxerr = 0;
- for (i=0; i<=0xfffff; ++i)
- {
- double correct = exp(-i/65536. * log(2.)) * 65535;
- double error = png_exp16bit(i) - correct;
-
- if (fabs(error) > maxerr)
- maxerr = fabs(error);
- if (fabs(error) > .524) /* By experiment */
- {
- fprintf(stderr, "16-bit exp error: %d: got %u, expected %f"
- " error: %f\n", i, png_exp16bit(i), correct, error);
- }
- }
-
- if (!silent)
- printf("maximum 16-bit exp error = %f\n", maxerr);
- } /* !onlygamma */
-
- /* Test the overall gamma correction. */
- for (i=0; i<9; ++i)
- {
- unsigned j;
- double g = gamma[i];
- png_fixed_point gfp = floor(g * PNG_FP_1 + .5);
-
- if (!silent)
- printf("Test gamma %f\n", g);
-
- maxerr = 0;
- for (j=0; j<256; ++j)
- {
- double correct = pow(j/255., g) * 255;
- png_byte out = png_gamma_8bit_correct(j, gfp);
- double error = out - correct;
-
- if (fabs(error) > maxerr)
- maxerr = fabs(error);
- if (out != floor(correct+.5))
- {
- fprintf(stderr, "8bit %d ^ %f: got %d expected %f error %f\n",
- j, g, out, correct, error);
- }
- }
-
- if (!silent)
- printf("gamma %f: maximum 8-bit error %f\n", g, maxerr);
-
- maxerr = 0;
- for (j=0; j<65536; ++j)
- {
- double correct = pow(j/65535., g) * 65535;
- png_uint_16 out = png_gamma_16bit_correct(j, gfp);
- double error = out - correct;
-
- if (fabs(error) > maxerr)
- maxerr = fabs(error);
- if (fabs(error) > 1.62)
- {
- fprintf(stderr, "16bit %d ^ %f: got %d expected %f error %f\n",
- j, g, out, correct, error);
- }
- }
-
- if (!silent)
- printf("gamma %f: maximum 16-bit error %f\n", g, maxerr);
- }
-
- return 0;
-}
-
-/**************************** VALIDATION TESTS ********************************/
-/* Various validation routines are included herein, they require some
- * definition for png_warning and png_error, seetings of VALIDATION:
- *
- * 1: validates the ASCII to floating point conversions
- * 2: validates png_muldiv
- * 3: accuracy test of fixed point gamma tables
- */
-
-/* The following COUNT (10^8) takes about 1 hour on a 1GHz Pentium IV
- * processor.
- */
-#define COUNT 1000000000
-
-int main(int argc, char **argv)
-{
- int count = COUNT;
-
- while (argc > 1)
- {
- if (argc > 2 && strcmp(argv[1], "-c") == 0)
- {
- count = atoi(argv[2]);
- argc -= 2;
- argv += 2;
- }
-
- else if (strcmp(argv[1], "-v") == 0)
- {
- ++verbose;
- --argc;
- ++argv;
- }
-
- else
- break;
- }
-
- if (count > 0 && argc > 1)
- {
- if (strcmp(argv[1], "ascii") == 0)
- return validation_ascii_to_fp(count, argc-1, argv+1);
- else if (strcmp(argv[1], "checkfp") == 0)
- return validation_checkfp(count, argc-1, argv+1);
- else if (strcmp(argv[1], "muldiv") == 0)
- return validation_muldiv(count, argc-1, argv+1);
- else if (strcmp(argv[1], "gamma") == 0)
- return validation_gamma(argc-1, argv+1);
- }
-
- /* Bad argument: */
- fprintf(stderr,
- "usage: tarith [-v] [-c count] {ascii,muldiv,gamma} [args]\n");
- fprintf(stderr, " arguments: ascii [-a (all results)] [-e error%%]\n");
- fprintf(stderr, " checkfp [-l max-number-chars]\n");
- fprintf(stderr, " muldiv\n");
- fprintf(stderr, " gamma -s (silent) -g (only gamma; no log)\n");
- return 1;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/libtests/timepng.c b/Build/source/libs/libpng/libpng-src/contrib/libtests/timepng.c
deleted file mode 100644
index 23d8b17b139..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/libtests/timepng.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/* timepng.c
- *
- * Copyright (c) 2013,2016 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.22 [May 26, 2016]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Load an arbitrary number of PNG files (from the command line, or, if there
- * are no arguments on the command line, from stdin) then run a time test by
- * reading each file by row or by image (possibly with transforms in the latter
- * case). The only output is a time as a floating point number of seconds with
- * 9 decimal digits.
- */
-#define _POSIX_C_SOURCE 199309L /* for clock_gettime */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-
-#include <time.h>
-
-#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
-# include <config.h>
-#endif
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-/* The following is to support direct compilation of this file as C++ */
-#ifdef __cplusplus
-# define voidcast(type, value) static_cast<type>(value)
-#else
-# define voidcast(type, value) (value)
-#endif /* __cplusplus */
-
-/* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime. It
- * need not be supported even when clock_gettime is available. It returns the
- * 'CPU' time the process has consumed. 'CPU' time is assumed to include time
- * when the CPU is actually blocked by a pending cache fill but not time
- * waiting for page faults. The attempt is to get a measure of the actual time
- * the implementation takes to read a PNG ignoring the potentially very large IO
- * overhead.
- */
-#if defined (CLOCK_PROCESS_CPUTIME_ID) && defined(PNG_STDIO_SUPPORTED) &&\
- defined(PNG_EASY_ACCESS_SUPPORTED) &&\
- (PNG_LIBPNG_VER >= 10700 ? defined(PNG_READ_PNG_SUPPORTED) :\
- defined (PNG_SEQUENTIAL_READ_SUPPORTED) &&\
- defined(PNG_INFO_IMAGE_SUPPORTED))
-
-typedef struct
-{
- FILE *input;
- FILE *output;
-} io_data;
-
-static PNG_CALLBACK(void, read_and_copy,
- (png_structp png_ptr, png_bytep buffer, size_t cb))
-{
- io_data *io = (io_data*)png_get_io_ptr(png_ptr);
-
- if (fread(buffer, cb, 1, io->input) != 1)
- png_error(png_ptr, strerror(errno));
-
- if (fwrite(buffer, cb, 1, io->output) != 1)
- {
- perror("temporary file");
- fprintf(stderr, "temporary file PNG write failed\n");
- exit(1);
- }
-}
-
-static void read_by_row(png_structp png_ptr, png_infop info_ptr,
- FILE *write_ptr, FILE *read_ptr)
-{
- /* These don't get freed on error, this is fine; the program immediately
- * exits.
- */
- png_bytep row = NULL, display = NULL;
- io_data io_copy;
-
- if (write_ptr != NULL)
- {
- /* Set up for a copy to the temporary file: */
- io_copy.input = read_ptr;
- io_copy.output = write_ptr;
- png_set_read_fn(png_ptr, &io_copy, read_and_copy);
- }
-
- png_read_info(png_ptr, info_ptr);
-
- {
- size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
-
- row = voidcast(png_bytep,malloc(rowbytes));
- display = voidcast(png_bytep,malloc(rowbytes));
-
- if (row == NULL || display == NULL)
- png_error(png_ptr, "OOM allocating row buffers");
-
- {
- png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
- int passes = png_set_interlace_handling(png_ptr);
- int pass;
-
- png_start_read_image(png_ptr);
-
- for (pass = 0; pass < passes; ++pass)
- {
- png_uint_32 y = height;
-
- /* NOTE: this trashes the row each time; interlace handling won't
- * work, but this avoids memory thrashing for speed testing and is
- * somewhat representative of an application that works row-by-row.
- */
- while (y-- > 0)
- png_read_row(png_ptr, row, display);
- }
- }
- }
-
- /* Make sure to read to the end of the file: */
- png_read_end(png_ptr, info_ptr);
-
- /* Free this up: */
- free(row);
- free(display);
-}
-
-static PNG_CALLBACK(void, no_warnings, (png_structp png_ptr,
- png_const_charp warning))
-{
- (void)png_ptr;
- (void)warning;
-}
-
-static int read_png(FILE *fp, png_int_32 transforms, FILE *write_file)
-{
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,
- no_warnings);
- png_infop info_ptr = NULL;
-
- if (png_ptr == NULL)
- return 0;
-
- if (setjmp(png_jmpbuf(png_ptr)))
- {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return 0;
- }
-
-# ifdef PNG_BENIGN_ERRORS_SUPPORTED
- png_set_benign_errors(png_ptr, 1/*allowed*/);
-# endif
- png_init_io(png_ptr, fp);
-
- info_ptr = png_create_info_struct(png_ptr);
-
- if (info_ptr == NULL)
- png_error(png_ptr, "OOM allocating info structure");
-
- if (transforms < 0)
- read_by_row(png_ptr, info_ptr, write_file, fp);
-
- else
- png_read_png(png_ptr, info_ptr, transforms, NULL/*params*/);
-
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return 1;
-}
-
-static int mytime(struct timespec *t)
-{
- /* Do the timing using clock_gettime and the per-process timer. */
- if (!clock_gettime(CLOCK_PROCESS_CPUTIME_ID, t))
- return 1;
-
- perror("CLOCK_PROCESS_CPUTIME_ID");
- fprintf(stderr, "timepng: could not get the time\n");
- return 0;
-}
-
-static int perform_one_test(FILE *fp, int nfiles, png_int_32 transforms)
-{
- int i;
- struct timespec before, after;
-
- /* Clear out all errors: */
- rewind(fp);
-
- if (mytime(&before))
- {
- for (i=0; i<nfiles; ++i)
- {
- if (read_png(fp, transforms, NULL/*write*/))
- {
- if (ferror(fp))
- {
- perror("temporary file");
- fprintf(stderr, "file %d: error reading PNG data\n", i);
- return 0;
- }
- }
-
- else
- {
- perror("temporary file");
- fprintf(stderr, "file %d: error from libpng\n", i);
- return 0;
- }
- }
- }
-
- else
- return 0;
-
- if (mytime(&after))
- {
- /* Work out the time difference and print it - this is the only output,
- * so flush it immediately.
- */
- unsigned long s = after.tv_sec - before.tv_sec;
- long ns = after.tv_nsec - before.tv_nsec;
-
- if (ns < 0)
- {
- --s;
- ns += 1000000000;
-
- if (ns < 0)
- {
- fprintf(stderr, "timepng: bad clock from kernel\n");
- return 0;
- }
- }
-
- printf("%lu.%.9ld\n", s, ns);
- fflush(stdout);
- if (ferror(stdout))
- {
- fprintf(stderr, "timepng: error writing output\n");
- return 0;
- }
-
- /* Successful return */
- return 1;
- }
-
- else
- return 0;
-}
-
-static int add_one_file(FILE *fp, char *name)
-{
- FILE *ip = fopen(name, "rb");
-
- if (ip != NULL)
- {
- /* Read the file using libpng; this detects errors and also deals with
- * files which contain data beyond the end of the file.
- */
- int ok = 0;
- fpos_t pos;
-
- if (fgetpos(fp, &pos))
- {
- /* Fatal error reading the start: */
- perror("temporary file");
- fprintf(stderr, "temporary file fgetpos error\n");
- exit(1);
- }
-
- if (read_png(ip, -1/*by row*/, fp/*output*/))
- {
- if (ferror(ip))
- {
- perror(name);
- fprintf(stderr, "%s: read error\n", name);
- }
-
- else
- ok = 1; /* read ok */
- }
-
- else
- fprintf(stderr, "%s: file not added\n", name);
-
- (void)fclose(ip);
-
- /* An error in the output is fatal; exit immediately: */
- if (ferror(fp))
- {
- perror("temporary file");
- fprintf(stderr, "temporary file write error\n");
- exit(1);
- }
-
- if (ok)
- return 1;
-
- /* Did not read the file successfully, simply rewind the temporary
- * file. This must happen after the ferror check above to avoid clearing
- * the error.
- */
- if (fsetpos(fp, &pos))
- {
- perror("temporary file");
- fprintf(stderr, "temporary file fsetpos error\n");
- exit(1);
- }
- }
-
- else
- {
- /* file open error: */
- perror(name);
- fprintf(stderr, "%s: open failed\n", name);
- }
-
- return 0; /* file not added */
-}
-
-static void
-usage(FILE *fp)
-{
- if (fp != NULL) fclose(fp);
-
- fprintf(stderr,
-"Usage:\n"
-" timepng --assemble <assembly> {files}\n"
-" Read the files into <assembly>, output the count. Options are ignored.\n"
-" timepng --dissemble <assembly> <count> [options]\n"
-" Time <count> files from <assembly>, additional files may not be given.\n"
-" Otherwise:\n"
-" Read the files into a temporary file and time the decode\n"
-"Transforms:\n"
-" --by-image: read by image with png_read_png\n"
-" --<transform>: implies by-image, use PNG_TRANSFORM_<transform>\n"
-" Otherwise: read by row using png_read_row (to a single row buffer)\n"
- /* ISO C90 string length max 509 */);fprintf(stderr,
-"{files}:\n"
-" PNG files to copy into the assembly and time. Invalid files are skipped\n"
-" with appropriate error messages. If no files are given the list of files\n"
-" is read from stdin with each file name terminated by a newline\n"
-"Output:\n"
-" For --assemble the output is the name of the assembly file followed by the\n"
-" count of the files it contains; the arguments for --dissemble. Otherwise\n"
-" the output is the total decode time in seconds.\n");
-
- exit(99);
-}
-
-int main(int argc, char **argv)
-{
- int ok = 0;
- int err = 0;
- int nfiles = 0;
- int transforms = -1; /* by row */
- const char *assembly = NULL;
- FILE *fp;
-
- if (argc > 2 && strcmp(argv[1], "--assemble") == 0)
- {
- /* Just build the test file, argv[2] is the file name. */
- assembly = argv[2];
- fp = fopen(assembly, "wb");
- if (fp == NULL)
- {
- perror(assembly);
- fprintf(stderr, "timepng --assemble %s: could not open for write\n",
- assembly);
- usage(NULL);
- }
-
- argv += 2;
- argc -= 2;
- }
-
- else if (argc > 3 && strcmp(argv[1], "--dissemble") == 0)
- {
- fp = fopen(argv[2], "rb");
-
- if (fp == NULL)
- {
- perror(argv[2]);
- fprintf(stderr, "timepng --dissemble %s: could not open for read\n",
- argv[2]);
- usage(NULL);
- }
-
- nfiles = atoi(argv[3]);
- if (nfiles <= 0)
- {
- fprintf(stderr,
- "timepng --dissemble <file> <count>: %s is not a count\n",
- argv[3]);
- exit(99);
- }
-#ifdef __COVERITY__
- else
- {
- nfiles &= PNG_UINT_31_MAX;
- }
-#endif
-
- argv += 3;
- argc -= 3;
- }
-
- else /* Else use a temporary file */
- {
-#ifndef __COVERITY__
- fp = tmpfile();
-#else
- /* Experimental. Coverity says tmpfile() is insecure because it
- * generates predictable names.
- *
- * It is possible to satisfy Coverity by using mkstemp(); however,
- * any platform supporting mkstemp() undoubtedly has a secure tmpfile()
- * implementation as well, and doesn't need the fix. Note that
- * the fix won't work on platforms that don't support mkstemp().
- *
- * https://www.securecoding.cert.org/confluence/display/c/
- * FIO21-C.+Do+not+create+temporary+files+in+shared+directories
- * says that most historic implementations of tmpfile() provide
- * only a limited number of possible temporary file names
- * (usually 26) before file names are recycled. That article also
- * provides a secure solution that unfortunately depends upon mkstemp().
- */
- char tmpfile[] = "timepng-XXXXXX";
- int filedes;
- umask(0177);
- filedes = mkstemp(tmpfile);
- if (filedes < 0)
- fp = NULL;
- else
- {
- fp = fdopen(filedes,"w+");
- /* Hide the filename immediately and ensure that the file does
- * not exist after the program ends
- */
- (void) unlink(tmpfile);
- }
-#endif
-
- if (fp == NULL)
- {
- perror("tmpfile");
- fprintf(stderr, "timepng: could not open the temporary file\n");
- exit(1); /* not a user error */
- }
- }
-
- /* Handle the transforms: */
- while (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-')
- {
- const char *opt = *++argv + 2;
-
- --argc;
-
- /* Transforms turn on the by-image processing and maybe set some
- * transforms:
- */
- if (transforms == -1)
- transforms = PNG_TRANSFORM_IDENTITY;
-
- if (strcmp(opt, "by-image") == 0)
- {
- /* handled above */
- }
-
-# define OPT(name) else if (strcmp(opt, #name) == 0)\
- transforms |= PNG_TRANSFORM_ ## name
-
- OPT(STRIP_16);
- OPT(STRIP_ALPHA);
- OPT(PACKING);
- OPT(PACKSWAP);
- OPT(EXPAND);
- OPT(INVERT_MONO);
- OPT(SHIFT);
- OPT(BGR);
- OPT(SWAP_ALPHA);
- OPT(SWAP_ENDIAN);
- OPT(INVERT_ALPHA);
- OPT(STRIP_FILLER);
- OPT(STRIP_FILLER_BEFORE);
- OPT(STRIP_FILLER_AFTER);
- OPT(GRAY_TO_RGB);
- OPT(EXPAND_16);
- OPT(SCALE_16);
-
- else
- {
- fprintf(stderr, "timepng %s: unrecognized transform\n", opt);
- usage(fp);
- }
- }
-
- /* Handle the files: */
- if (argc > 1 && nfiles > 0)
- usage(fp); /* Additional files not valid with --dissemble */
-
- else if (argc > 1)
- {
- int i;
-
- for (i=1; i<argc; ++i)
- {
- if (nfiles == INT_MAX)
- {
- fprintf(stderr, "%s: skipped, too many files\n", argv[i]);
- break;
- }
-
- else if (add_one_file(fp, argv[i]))
- ++nfiles;
- }
- }
-
- else if (nfiles == 0) /* Read from stdin withoout --dissemble */
- {
- char filename[FILENAME_MAX+1];
-
- while (fgets(filename, FILENAME_MAX+1, stdin))
- {
- size_t len = strlen(filename);
-
- if (filename[len-1] == '\n')
- {
- filename[len-1] = 0;
- if (nfiles == INT_MAX)
- {
- fprintf(stderr, "%s: skipped, too many files\n", filename);
- break;
- }
-
- else if (add_one_file(fp, filename))
- ++nfiles;
- }
-
- else
- {
- fprintf(stderr, "timepng: file name too long: ...%s\n",
- filename+len-32);
- err = 1;
- break;
- }
- }
-
- if (ferror(stdin))
- {
- fprintf(stderr, "timepng: stdin: read error\n");
- err = 1;
- }
- }
-
- /* Perform the test, or produce the --assemble output: */
- if (!err)
- {
- if (nfiles > 0)
- {
- if (assembly != NULL)
- {
- if (fflush(fp) && !ferror(fp) && fclose(fp))
- {
- perror(assembly);
- fprintf(stderr, "%s: close failed\n", assembly);
- }
-
- else
- {
- printf("%s %d\n", assembly, nfiles);
- fflush(stdout);
- ok = !ferror(stdout);
- }
- }
-
- else
- {
- ok = perform_one_test(fp, nfiles, transforms);
- (void)fclose(fp);
- }
- }
-
- else
- usage(fp);
- }
-
- else
- (void)fclose(fp);
-
- /* Exit code 0 on success. */
- return ok == 0;
-}
-#else /* !sufficient support */
-int main(void) { return 77; }
-#endif /* !sufficient support */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/mips-msa/README b/Build/source/libs/libpng/libpng-src/contrib/mips-msa/README
deleted file mode 100644
index 10acc936465..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/mips-msa/README
+++ /dev/null
@@ -1,83 +0,0 @@
-OPERATING SYSTEM SPECIFIC MIPS MSA DETECTION
---------------------------------------------
-
-Detection of the ability to execute MIPS MSA on an MIPS processor requires
-operating system support. (The information is not available in user mode.)
-
-HOW TO USE THIS
----------------
-
-This directory contains C code fragments that can be included in mips/mips_init.c
-by setting the macro PNG_MIPS_MSA_FILE to the file name in "" or <> at build
-time. This setting is not recorded in pnglibconf.h and can be changed simply by
-rebuilding mips/msa_init.o with the required macro definition.
-
-For any of this code to be used the MIPS MSA code must be enabled and run time
-checks must be supported. I.e.:
-
-#if PNG_MIPS_MSA_OPT > 0
-#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
-
-This is done in a 'configure' build by passing configure the argument:
-
- --enable-mips-msa=check
-
-Apart from the basic Linux implementation in contrib/mips-msa/linux.c this code
-is unsupported. That means that it is not even compiled on a regular basis and
-may be broken in any given minor release.
-
-FILE FORMAT
------------
-
-Each file documents its testing status as of the last time it was tested (which
-may have been a long time ago):
-
-STATUS: one of:
- SUPPORTED: This indicates that the file is included in the regularly
- performed test builds and bugs are fixed when discovered.
- COMPILED: This indicates that the code did compile at least once. See the
- more detailed description for the extent to which the result was
- successful.
- TESTED: This means the code was fully compiled into the libpng test programs
- and these were run at least once.
-
-BUG REPORTS: an email address to which to send reports of problems
-
-The file is a fragment of C code. It should not define any 'extern' symbols;
-everything should be static. It must define the function:
-
-static int png_have_msa(png_structp png_ptr);
-
-That function must return 1 if MIPS MSA instructions are supported, 0 if not.
-It must not execute png_error unless it detects a bug. A png_error will prevent
-the reading of the PNG and in the future, writing too.
-
-BUG REPORTS
------------
-
-If you mail a bug report for any file that is not SUPPORTED there may only be
-limited response. Consider fixing it and sending a patch to fix the problem -
-this is more likely to result in action.
-
-CONTRIBUTIONS
--------------
-
-You may send contributions of new implementations to
-png-mng-implement@sourceforge.net. Please write code in strict C90 C where
-possible. Obviously OS dependencies are to be expected. If you submit code you
-must have the authors permission and it must have a license that is acceptable
-to the current maintainer; in particular that license must permit modification
-and redistribution.
-
-Please try to make the contribution a single file and give the file a clear and
-unambiguous name that identifies the target OS. If multiple files really are
-required put them all in a sub-directory.
-
-You must also be prepared to handle bug reports from users of the code, either
-by joining the png-mng-implement mailing list or by providing an email for the
-"BUG REPORTS" entry or both. Please make sure that the header of the file
-contains the STATUS and BUG REPORTS fields as above.
-
-Please list the OS requirements as precisely as possible. Ideally you should
-also list the environment in which the code has been tested and certainly list
-any environments where you suspect it might not work.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c b/Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c
deleted file mode 100644
index 140215c4ea6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* contrib/mips-msa/linux.c
- *
- * Copyright (c) 2016 Glenn Randers-Pehrson
- * Written by Mandar Sahastrabuddhe, 2016.
- * Last changed in libpng 1.6.25beta03 [August 29, 2016]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * SEE contrib/mips-msa/README before reporting bugs
- *
- * STATUS: SUPPORTED
- * BUG REPORTS: png-mng-implement@sourceforge.net
- *
- * png_have_msa implemented for Linux by reading the widely available
- * pseudo-file /proc/cpuinfo.
- *
- * This code is strict ANSI-C and is probably moderately portable; it does
- * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-static int
-png_have_msa(png_structp png_ptr)
-{
- FILE *f = fopen("/proc/cpuinfo", "rb");
-
- char *string = "msa";
- char word[10];
-
- if (f != NULL)
- {
- while(!feof(f))
- {
- int ch = fgetc(f);
- static int i = 0;
-
- while(!(ch <= 32))
- {
- word[i++] = ch;
- ch = fgetc(f);
- }
-
- int val = strcmp(string, word);
-
- if (val == 0)
- return 1;
-
- i = 0;
- memset(word, 0, 10);
- }
-
- fclose(f);
- }
-#ifdef PNG_WARNINGS_SUPPORTED
- else
- png_warning(png_ptr, "/proc/cpuinfo open failed");
-#endif
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/Dockerfile b/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/Dockerfile
deleted file mode 100644
index f5bc1a985d3..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/Dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2016 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-################################################################################
-
-FROM gcr.io/oss-fuzz-base/base-builder
-MAINTAINER glennrp@gmail.com
-RUN apt-get update && \
- apt-get install -y make autoconf automake libtool
-
-RUN git clone --depth 1 https://github.com/madler/zlib.git
-RUN git clone --depth 1 https://github.com/glennrp/libpng.git
-RUN cp libpng/contrib/oss-fuzz/build.sh $SRC
-WORKDIR libpng
diff --git a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/README.txt b/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/README.txt
deleted file mode 100644
index 3b3656fbb60..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/README.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-Last changed in libpng 1.6.33 [September 28, 2017]
-Copyright (c) 2017 Glenn Randers-Pehrson
-
-This code is released under the libpng license.
-For conditions of distribution and use, see the disclaimer
-and license in png.h
-
-Files in this directory are used by the oss-fuzz project
-(https://github.com/google/oss-fuzz/tree/master/projects/libpng).
-for "fuzzing" libpng.
-
-They were licensed by Google Inc, using the BSD-like Chromium license,
-which may be found at https://cs.chromium.org/chromium/src/LICENSE, or, if
-noted in the source, under the Apache-2.0 license, which may
-be found at http://www.apache.org/licenses/LICENSE-2.0 .
-If they have been modified, the derivatives are copyright Glenn Randers-Pehrson
-and are released under the same licenses as the originals. Several of
-the original files (libpng_read_fuzzer.options, png.dict, project.yaml)
-had no licensing information; we assumed that these were under the Chromium
-license. Any new files are released under the libpng license (see png.h).
-
-The files are
- Original
- Filename or derived Copyright License
- ========================= ========== ================ ==========
- Dockerfile* derived 2017, Glenn R-P Apache 2.0
- build.sh derived 2017, Glenn R-P Apache 2.0
- libpng_read_fuzzer.cc derived 2017, Glenn R-P Chromium
- libpng_read_fuzzer.options original 2015, Chrome Devs Chromium
- png.dict original 2015, Chrome Devs Chromium
- README.txt (this file) original 2017, Glenn R-P libpng
-
- * Dockerfile is a copy of the file used by oss-fuzz. build.sh,
- png.dict and libpng_read_fuzzer.* are the actual files used by oss-fuzz,
- which retrieves them from the libpng repository at Github.
-
-To do: exercise the progressive reader and the png encoder.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/build.sh b/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/build.sh
deleted file mode 100755
index f9e1b0776d0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/build.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash -eu
-# Copyright 2017-2018 Glenn Randers-Pehrson
-# Copyright 2016 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Last changed in libpng 1.6.35 [July 15, 2018]
-#
-# Revisions by Glenn Randers-Pehrson, 2017:
-# 1. Build only the library, not the tools (changed "make -j$(nproc) all" to
-# "make -j$(nproc) libpng16.la").
-# 2. Disabled WARNING and WRITE options in pnglibconf.dfa.
-# 3. Build zlib alongside libpng
-################################################################################
-
-# Disable logging via library build configuration control.
-cat scripts/pnglibconf.dfa | \
- sed -e "s/option STDIO/option STDIO disabled/" \
- -e "s/option WARNING /option WARNING disabled/" \
- -e "s/option WRITE enables WRITE_INT_FUNCTIONS/option WRITE disabled/" \
-> scripts/pnglibconf.dfa.temp
-mv scripts/pnglibconf.dfa.temp scripts/pnglibconf.dfa
-
-# build the libpng library.
-autoreconf -f -i
-./configure --with-libpng-prefix=OSS_FUZZ_
-make -j$(nproc) clean
-make -j$(nproc) libpng16.la
-
-# build libpng_read_fuzzer.
-$CXX $CXXFLAGS -std=c++11 -I. \
- $SRC/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc \
- -o $OUT/libpng_read_fuzzer \
- -lFuzzingEngine .libs/libpng16.a -lz
-
-# add seed corpus.
-find $SRC/libpng -name "*.png" | grep -v crashers | \
- xargs zip $OUT/libpng_read_fuzzer_seed_corpus.zip
-
-cp $SRC/libpng/contrib/oss-fuzz/*.dict \
- $SRC/libpng/contrib/oss-fuzz/*.options $OUT/
diff --git a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.cc b/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.cc
deleted file mode 100644
index 7b305509cde..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-
-// libpng_read_fuzzer.cc
-// Copyright 2017-2018 Glenn Randers-Pehrson
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that may
-// be found in the LICENSE file https://cs.chromium.org/chromium/src/LICENSE
-
-// Last changed in libpng 1.6.35 [July 15, 2018]
-
-// The modifications in 2017 by Glenn Randers-Pehrson include
-// 1. addition of a PNG_CLEANUP macro,
-// 2. setting the option to ignore ADLER32 checksums,
-// 3. adding "#include <string.h>" which is needed on some platforms
-// to provide memcpy().
-// 4. adding read_end_info() and creating an end_info structure.
-// 5. adding calls to png_set_*() transforms commonly used by browsers.
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <vector>
-
-#define PNG_INTERNAL
-#include "png.h"
-
-#define PNG_CLEANUP \
- if(png_handler.png_ptr) \
- { \
- if (png_handler.row_ptr) \
- png_free(png_handler.png_ptr, png_handler.row_ptr); \
- if (png_handler.end_info_ptr) \
- png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\
- &png_handler.end_info_ptr); \
- else if (png_handler.info_ptr) \
- png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\
- nullptr); \
- else \
- png_destroy_read_struct(&png_handler.png_ptr, nullptr, nullptr); \
- png_handler.png_ptr = nullptr; \
- png_handler.row_ptr = nullptr; \
- png_handler.info_ptr = nullptr; \
- png_handler.end_info_ptr = nullptr; \
- }
-
-struct BufState {
- const uint8_t* data;
- size_t bytes_left;
-};
-
-struct PngObjectHandler {
- png_infop info_ptr = nullptr;
- png_structp png_ptr = nullptr;
- png_infop end_info_ptr = nullptr;
- png_voidp row_ptr = nullptr;
- BufState* buf_state = nullptr;
-
- ~PngObjectHandler() {
- if (row_ptr)
- png_free(png_ptr, row_ptr);
- if (end_info_ptr)
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
- else if (info_ptr)
- png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
- else
- png_destroy_read_struct(&png_ptr, nullptr, nullptr);
- delete buf_state;
- }
-};
-
-void user_read_data(png_structp png_ptr, png_bytep data, size_t length) {
- BufState* buf_state = static_cast<BufState*>(png_get_io_ptr(png_ptr));
- if (length > buf_state->bytes_left) {
- png_error(png_ptr, "read error");
- }
- memcpy(data, buf_state->data, length);
- buf_state->bytes_left -= length;
- buf_state->data += length;
-}
-
-static const int kPngHeaderSize = 8;
-
-// Entry point for LibFuzzer.
-// Roughly follows the libpng book example:
-// http://www.libpng.org/pub/png/book/chapter13.html
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- if (size < kPngHeaderSize) {
- return 0;
- }
-
- std::vector<unsigned char> v(data, data + size);
- if (png_sig_cmp(v.data(), 0, kPngHeaderSize)) {
- // not a PNG.
- return 0;
- }
-
- PngObjectHandler png_handler;
- png_handler.png_ptr = nullptr;
- png_handler.row_ptr = nullptr;
- png_handler.info_ptr = nullptr;
- png_handler.end_info_ptr = nullptr;
-
- png_handler.png_ptr = png_create_read_struct
- (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
- if (!png_handler.png_ptr) {
- return 0;
- }
-
- png_handler.info_ptr = png_create_info_struct(png_handler.png_ptr);
- if (!png_handler.info_ptr) {
- PNG_CLEANUP
- return 0;
- }
-
- png_handler.end_info_ptr = png_create_info_struct(png_handler.png_ptr);
- if (!png_handler.end_info_ptr) {
- PNG_CLEANUP
- return 0;
- }
-
- png_set_crc_action(png_handler.png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
-#ifdef PNG_IGNORE_ADLER32
- png_set_option(png_handler.png_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
-#endif
-
- // Setting up reading from buffer.
- png_handler.buf_state = new BufState();
- png_handler.buf_state->data = data + kPngHeaderSize;
- png_handler.buf_state->bytes_left = size - kPngHeaderSize;
- png_set_read_fn(png_handler.png_ptr, png_handler.buf_state, user_read_data);
- png_set_sig_bytes(png_handler.png_ptr, kPngHeaderSize);
-
- if (setjmp(png_jmpbuf(png_handler.png_ptr))) {
- PNG_CLEANUP
- return 0;
- }
-
- // Reading.
- png_read_info(png_handler.png_ptr, png_handler.info_ptr);
-
- // reset error handler to put png_deleter into scope.
- if (setjmp(png_jmpbuf(png_handler.png_ptr))) {
- PNG_CLEANUP
- return 0;
- }
-
- png_uint_32 width, height;
- int bit_depth, color_type, interlace_type, compression_type;
- int filter_type;
-
- if (!png_get_IHDR(png_handler.png_ptr, png_handler.info_ptr, &width,
- &height, &bit_depth, &color_type, &interlace_type,
- &compression_type, &filter_type)) {
- PNG_CLEANUP
- return 0;
- }
-
- // This is going to be too slow.
- if (width && height > 100000000 / width) {
- PNG_CLEANUP
- return 0;
- }
-
- // Set several transforms that browsers typically use:
- png_set_gray_to_rgb(png_handler.png_ptr);
- png_set_expand(png_handler.png_ptr);
- png_set_packing(png_handler.png_ptr);
- png_set_scale_16(png_handler.png_ptr);
- png_set_tRNS_to_alpha(png_handler.png_ptr);
-
- int passes = png_set_interlace_handling(png_handler.png_ptr);
-
- png_read_update_info(png_handler.png_ptr, png_handler.info_ptr);
-
- png_handler.row_ptr = png_malloc(
- png_handler.png_ptr, png_get_rowbytes(png_handler.png_ptr,
- png_handler.info_ptr));
-
- for (int pass = 0; pass < passes; ++pass) {
- for (png_uint_32 y = 0; y < height; ++y) {
- png_read_row(png_handler.png_ptr,
- static_cast<png_bytep>(png_handler.row_ptr), nullptr);
- }
- }
-
- png_read_end(png_handler.png_ptr, png_handler.end_info_ptr);
-
- PNG_CLEANUP
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.options b/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.options
deleted file mode 100644
index 2005291a0f7..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/libpng_read_fuzzer.options
+++ /dev/null
@@ -1,2 +0,0 @@
-[libfuzzer]
-dict = png.dict
diff --git a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/png.dict b/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/png.dict
deleted file mode 100644
index 3a8a113830f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/oss-fuzz/png.dict
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# AFL dictionary for PNG images
-# -----------------------------
-#
-# Just the basic, standard-originating sections; does not include vendor
-# extensions.
-#
-# Created by Michal Zalewski <lcamtuf@google.com>
-#
-
-header_png="\x89PNG\x0d\x0a\x1a\x0a"
-
-section_IDAT="IDAT"
-section_IEND="IEND"
-section_IHDR="IHDR"
-section_PLTE="PLTE"
-section_bKGD="bKGD"
-section_cHRM="cHRM"
-section_eXIf="eXIf"
-section_fRAc="fRAc"
-section_gAMA="gAMA"
-section_gIFg="gIFg"
-section_gIFt="gIFt"
-section_gIFx="gIFx"
-section_hIST="hIST"
-section_iCCP="iCCP"
-section_iTXt="iTXt"
-section_oFFs="oFFs"
-section_pCAL="pCAL"
-section_pHYs="pHYs"
-section_sBIT="sBIT"
-section_sCAL="sCAL"
-section_sPLT="sPLT"
-section_sRGB="sRGB"
-section_sTER="sTER"
-section_tEXt="tEXt"
-section_tIME="tIME"
-section_tRNS="tRNS"
-section_zTXt="zTXt"
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/README b/Build/source/libs/libpng/libpng-src/contrib/pngminim/README
deleted file mode 100644
index e17fe35b6a8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/README
+++ /dev/null
@@ -1,5 +0,0 @@
-
-This demonstrates the use of PNG_USER_CONFIG, pngusr.h and pngusr.dfa
-to build minimal decoder, encoder, and progressive reader applications.
-
-See the individual README and pngusr.dfa files for more explanation.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/README b/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/README
deleted file mode 100644
index fa979fcb727..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/README
+++ /dev/null
@@ -1,10 +0,0 @@
-This demonstrates the use of PNG_USER_CONFIG, pngusr.h and pngusr.dfa
-
-The makefile builds a minimal read-only decoder with embedded libpng
-and zlib.
-
-Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC
-on the make command line.
-
-If you prefer to use the shared libraries, go to contrib/pngminus
-and build the png2pnm application there.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/makefile b/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/makefile
deleted file mode 100644
index 4acf3c1779b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/makefile
+++ /dev/null
@@ -1,151 +0,0 @@
-# Makefile for PngMinus (pngm2pnm)
-# Linux / Unix
-
-#CC=cc
-CC=gcc
-LD=$(CC)
-
-# If awk fails try
-# make AWK=nawk
-
-# If cpp fails try
-# make CPP=/lib/cpp
-
-RM=rm -f
-COPY=cp
-
-CPPFLAGS=-I. -DPNG_USER_CONFIG -DNO_GZCOMPRESS -DZ_SOLO -DNO_GZIP
-CFLAGS=-O1 -Wall
-
-C=.c
-O=.o
-L=.a
-E=
-
-# Where to find the source code:
-PNGSRC =../../..
-ZLIBSRC=$(PNGSRC)/../zlib
-PROGSRC=$(PNGSRC)/contrib/pngminus
-
-# Zlib (minimal inflate requirements - crc32 is used by libpng)
-# zutil can be eliminated if you provide your own zcalloc and zcfree
-ZSRCS = adler32$(C) crc32$(C) \
- inffast$(C) inflate$(C) inftrees$(C) \
- zutil$(C)
-
-# Standard headers
-ZH = zlib.h crc32.h inffast.h inffixed.h \
- inflate.h inftrees.h zutil.h
-
-# Machine generated headers
-ZCONF = zconf.h
-
-# Headers callers use
-ZINC = zlib.h $(ZCONF)
-
-# Headers the Zlib source uses
-ZHDRS = $(ZH) $(ZCONF)
-
-ZOBJS = adler32$(O) crc32$(O) \
- inffast$(O) inflate$(O) inftrees$(O) \
- zutil$(O)
-
-# libpng
-PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \
- pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \
- pngset$(C) pngtrans$(C)
-
-# Standard headers
-PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h
-
-# Machine generated headers
-PNGCONF=pnglibconf.h
-
-# Headers callers use
-PNGINC= png.h pngconf.h pngusr.h $(PNGCONF)
-
-# Headers the PNG library uses
-PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h
-
-PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
- pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
- pngset$(O) pngtrans$(O)
-
-PROGSRCS= pngm2pnm$(C)
-PROGHDRS=
-PROGDOCS=
-PROGOBJS= pngm2pnm$(O)
-
-OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
-
-# implicit make rules -------------------------------------------------------
-
-# note: dependencies do not work on implicit rule lines
-.c$(O):
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-# dependencies
-
-all: pngm2pnm$(E)
-
-pngm2pnm$(E): $(OBJS)
- $(LD) -o pngm2pnm$(E) $(OBJS)
-
-# The DFA_XTRA setting turns all libpng options off then
-# turns on those required for this minimal build.
-# The CPP_FLAGS setting causes pngusr.h to be included in
-# both the build of pnglibconf.h and, subsequently, when
-# building libpng itself.
-$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak $(ZH)\
- $(PNGSRC)/scripts/pnglibconf.dfa \
- $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa
- $(RM) pnglibconf.h pnglibconf.dfn
- $(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\
- srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG -I."\
- DFA_XTRA="pngusr.dfa" $@
-
-clean:
- $(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\
- srcdir=$(PNGSRC) clean
- $(RM) pngm2pnm$(O)
- $(RM) pngm2pnm$(E)
- $(RM) $(OBJS)
-
-# distclean also removes the copied source and headers
-distclean: clean
- $(RM) -r scripts # historical reasons
- $(RM) $(PNGSRCS) $(PNGH)
- $(RM) $(ZSRCS) $(ZH) $(ZCONF)
- $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)
-
-# Header file dependencies:
-$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)
-$(PNGOBJS): $(PNGHDRS) $(ZINC)
-$(ZOBJS): $(ZHDRS)
-
-# Gather the source code from the respective directories
-$(PNGSRCS) $(PNGH): $(PNGSRC)/$@
- $(RM) $@
- $(COPY) $(PNGSRC)/$@ $@
-
-# No dependency on the ZLIBSRC target so that it only needs
-# to be specified once.
-$(ZSRCS) $(ZH):
- $(RM) $@
- $(COPY) $(ZLIBSRC)/$@ $@
-
-# The unconfigured zconf.h varies in name according to the
-# zlib release
-$(ZCONF):
- $(RM) $@
- @for f in zconf.h.in zconf.in.h zconf.h; do\
- test -r $(ZLIBSRC)/$$f &&\
- echo $(COPY) $(ZLIBSRC)/$$f $@ &&\
- $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\
- done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1
-
-pngm2pnm.c: $(PROGSRC)/png2pnm.c
- $(RM) $@
- $(COPY) $(PROGSRC)/png2pnm.c $@
-
-# End of makefile for pngm2pnm
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.dfa b/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.dfa
deleted file mode 100644
index 4f402721ab0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.dfa
+++ /dev/null
@@ -1,40 +0,0 @@
-# pngminim/decoder/pngusr.dfa
-#
-# Copyright (c) 2010-2013 Glenn Randers-Pehrson
-#
-# This code is released under the libpng license.
-# For conditions of distribution and use, see the disclaimer
-# and license in png.h
-
-# First all the build options off:
-
-everything = off
-
-# All that is required is some read code. This example switches
-# on the sequential read code (see ../preader for a progressive
-# read example).
-
-option SEQUENTIAL_READ on
-
-# You must choose fixed or floating point arithmetic:
-# option FLOATING_POINT on
-
-option FIXED_POINT on
-
-# You must chose the internal fixed point implementation or to
-# use the system floating point. The latter is considerably
-# smaller (by about 1kbyte on an x86 system):
-# option FLOATING_ARITHMETIC on
-
-option FLOATING_ARITHMETIC off
-
-# Your program will probably need other options. The example
-# program here, pngm2pnm, requires the following. Take a look
-# at pnglibconf.h to find out the full set of what has to be
-# enabled to make the following work.
-
-option SETJMP on
-option STDIO on
-option READ_EXPAND on
-option READ_STRIP_16_TO_8 on
-option USER_LIMITS on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.h b/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.h
deleted file mode 100644
index cbd7890c7d6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/decoder/pngusr.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* minrdpngconf.h: headers to make a minimal png-read-only library
- *
- * Copyright (c) 2007, 2010-2013 Glenn Randers-Pehrson
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson
- */
-
-#ifndef MINRDPNGCONF_H
-#define MINRDPNGCONF_H
-
-/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */
-
-/* List options to turn off features of the build that do not
- * affect the API (so are not recorded in pnglibconf.h)
- */
-
-#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
-
-#endif /* MINRDPNGCONF_H */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/README b/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/README
deleted file mode 100644
index d8d9a6466e2..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/README
+++ /dev/null
@@ -1,10 +0,0 @@
-This demonstrates the use of PNG_USER_CONFIG and pngusr.h
-
-The makefile builds a minimal write-only encoder with embedded libpng
-and zlib.
-
-Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC
-on the make command line.
-
-If you prefer to use the shared libraries, go to contrib/pngminus
-and build the pnm2png application there.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/makefile b/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/makefile
deleted file mode 100644
index 41b205c284a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/makefile
+++ /dev/null
@@ -1,150 +0,0 @@
-# Makefile for PngMinus (pnm2pngm)
-# Linux / Unix
-
-#CC=cc
-CC=gcc
-LD=$(CC)
-
-# If awk fails try
-# make AWK=nawk
-
-# If cpp fails try
-# make CPP=/lib/cpp
-
-RM=rm -f
-COPY=cp
-
-CPPFLAGS=-I. -DPNG_USER_CONFIG -DNO_GZCOMPRESS -DZ_SOLO -DNO_GZIP
-CFLAGS=-O1 -Wall
-
-C=.c
-O=.o
-L=.a
-E=
-
-# Where to find the source code:
-PNGSRC =../../..
-ZLIBSRC=$(PNGSRC)/../zlib
-PROGSRC=$(PNGSRC)/contrib/pngminus
-
-# Zlib
-ZSRCS = adler32$(C) compress$(C) crc32$(C) deflate$(C) \
- trees$(C) zutil$(C)
-
-# Standard headers
-#ZH = zlib.h crc32.h deflate.h trees.h zutil.h
-ZH = zlib.h crc32.h deflate.h trees.h zutil.h
-
-# Machine generated headers
-ZCONF = zconf.h
-
-# Headers callers use
-ZINC = zlib.h $(ZCONF)
-
-# Headers the Zlib source uses
-ZHDRS = $(ZH) $(ZCONF)
-
-# compress is not required; it is needed to link the zlib
-# code because deflate defines an unused API function deflateBound
-# which itself calls compressBound from compress.
-ZOBJS = adler32$(O) compress$(O) crc32$(O) deflate$(O) \
- trees$(O) zutil$(O)
-
-# libpng
-PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \
- pngset$(C) pngtrans$(C) pngwio$(C) pngwrite$(C) \
- pngwtran$(C) pngwutil$(C)
-
-# Standard headers
-PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h
-
-# Machine generated headers
-PNGCONF=pnglibconf.h
-
-# Headers callers use
-PNGINC= png.h pngconf.h pngusr.h $(PNGCONF)
-
-# Headers the PNG library uses
-PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h
-
-PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
- pngset$(O) pngtrans$(O) pngwio$(O) pngwrite$(O) \
- pngwtran$(O) pngwutil$(O)
-
-PROGSRCS= pnm2pngm$(C)
-PROGHDRS=
-PROGDOCS=
-PROGOBJS= pnm2pngm$(O)
-
-OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
-
-# implicit make rules -------------------------------------------------------
-
-.c$(O):
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-# dependencies
-
-all: pnm2pngm$(E)
-
-pnm2pngm$(E): $(OBJS)
- $(LD) -o pnm2pngm$(E) $(OBJS)
-
-# The DFA_XTRA setting turns all libpng options off then
-# turns on those required for this minimal build.
-# The CPP_FLAGS setting causes pngusr.h to be included in
-# both the build of pnglibconf.h and, subsequently, when
-# building libpng itself.
-$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak $(ZH)\
- $(PNGSRC)/scripts/pnglibconf.dfa \
- $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa
- $(RM) pnglibconf.h pnglibconf.dfn
- $(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\
- srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG -I."\
- DFA_XTRA="pngusr.dfa" $@
-
-clean:
- $(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\
- srcdir=$(PNGSRC) clean
- $(RM) pnm2pngm$(O)
- $(RM) pnm2pngm$(E)
- $(RM) $(OBJS)
-
-# distclean also removes the copied source and headers
-distclean: clean
- $(RM) -r scripts # historical reasons
- $(RM) $(PNGSRCS) $(PNGH)
- $(RM) $(ZSRCS) $(ZH) $(ZCONF)
- $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)
-
-# Header file dependencies:
-$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)
-$(PNGOBJS): $(PNGHDRS) $(ZINC)
-$(ZOBJS): $(ZHDRS)
-
-# Gather the source code from the respective directories
-$(PNGSRCS) $(PNGH): $(PNGSRC)/$@
- $(RM) $@
- $(COPY) $(PNGSRC)/$@ $@
-
-# No dependency on the ZLIBSRC target so that it only needs
-# to be specified once.
-$(ZSRCS) $(ZH):
- $(RM) $@
- $(COPY) $(ZLIBSRC)/$@ $@
-
-# The unconfigured zconf.h varies in name according to the
-# zlib release
-$(ZCONF):
- $(RM) $@
- @for f in zconf.h.in zconf.in.h zconf.h; do\
- test -r $(ZLIBSRC)/$$f &&\
- echo $(COPY) $(ZLIBSRC)/$$f $@ &&\
- $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\
- done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1
-
-pnm2pngm.c: $(PROGSRC)/pnm2png.c
- $(RM) $@
- $(COPY) $(PROGSRC)/pnm2png.c $@
-
-# End of makefile for pnm2pngm
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.dfa b/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.dfa
deleted file mode 100644
index 1fc24f3f2a8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.dfa
+++ /dev/null
@@ -1,39 +0,0 @@
-# pngminim/encoder/pngusr.dfa
-#
-# Copyright (c) 2010-2013 Glenn Randers-Pehrson
-#
-# This code is released under the libpng license.
-# For conditions of distribution and use, see the disclaimer
-# and license in png.h
-
-# First all the build options off:
-
-everything = off
-
-# Switch on the write code - this makes a minimalist encoder
-
-option WRITE on
-
-# These 2 options are required if you need to read PBM (P1 or P4) files.
-option WRITE_INVERT on
-option WRITE_PACK on
-
-# You must choose fixed or floating point arithmetic:
-# option FLOATING_POINT on
-
-option FIXED_POINT on
-
-# You must chose the internal fixed point implementation or to
-# use the system floating point. The latter is considerably
-# smaller (by about 1kbyte on an x86 system):
-# option FLOATING_ARITHMETIC on
-
-option FLOATING_ARITHMETIC off
-
-# Your program will probably need other options. The example
-# program here, pnm2pngm, requires the following. Take a look
-# at pnglibconf.h to find out the full set of what has to be
-# enabled to make the following work.
-
-option SETJMP on
-option STDIO on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.h b/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.h
deleted file mode 100644
index 997d44fe904..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/encoder/pngusr.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* minwrpngconf.h: headers to make a minimal png-write-only library
- *
- * Copyright (c) 2007, 2010-2013 Glenn Randers-Pehrson
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson
- */
-
-#ifndef MINWRPNGCONF_H
-#define MINWRPNGCONF_H
-
-/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */
-
-/* List options to turn off features of the build that do not
- * affect the API (so are not recorded in pnglibconf.h)
- */
-
-#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
-
-#endif /* MINWRPNGCONF_H */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/README b/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/README
deleted file mode 100644
index faa83560a72..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/README
+++ /dev/null
@@ -1,15 +0,0 @@
-This demonstrates the use of PNG_USER_CONFIG and pngusr.h
-
-The makefile builds a minimal read-only progressive decoder with
-embedded libpng, zlib and your system's X library.
-
-Specify the location of the zlib source (1.2.1 or later) as ZLIBSRC
-on the make command line.
-
-Edit makefile if required, to find your X library and include files,
-then
-
- make ZLIBSRC=directory
-
-If you prefer to use the shared libraries, go to contrib/gregbook
-and build the rpng2-x application there.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/makefile b/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/makefile
deleted file mode 100644
index b625199114c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/makefile
+++ /dev/null
@@ -1,166 +0,0 @@
-# Makefile for PngMinus (rpng2)
-# Linux / Unix
-
-#CC=cc
-CC=gcc
-LD=$(CC)
-
-# If awk fails try
-# make AWK=nawk
-
-# If cpp fails try
-# make CPP=/lib/cpp
-
-RM=rm -f
-COPY=cp
-
-#XINC = -I/usr/include # old-style, stock X distributions
-#XLIB = -L/usr/lib/X11 -lX11 # (including SGI IRIX)
-
-#XINC = -I/usr/openwin/include # Sun workstations (OpenWindows)
-#XLIB = -L/usr/openwin/lib -lX11
-
-XINC = -I/usr/X11R6/include # new X distributions (X.org, etc.)
-XLIB = -L/usr/X11R6/lib -lX11
-#XLIB = -L/usr/X11R6/lib64 -lX11 # e.g., Red Hat on AMD64
-
-#XINC = -I/usr/local/include # FreeBSD
-#XLIB = -L/usr/local/lib -lX11
-
-#LIBS = $(XLIB)
-LIBS = $(XLIB) -lm #platforms that need libm
-
-CPPFLAGS=-I. $(XINC) -DPNG_USER_CONFIG -DNO_GZCOMPRESS -DZ_SOLO -DNO_GZIP
-CFLAGS=-O1 -Wall
-
-C=.c
-O=.o
-L=.a
-E=
-
-# Where to find the source code:
-PNGSRC =../../..
-ZLIBSRC=$(PNGSRC)/../zlib
-PROGSRC=$(PNGSRC)/contrib/gregbook
-
-# Zlib (minimal inflate requirements - crc32 is used by libpng)
-# zutil can be eliminated if you provide your own zcalloc and zcfree
-ZSRCS = adler32$(C) crc32$(C) \
- inffast$(C) inflate$(C) inftrees$(C) \
- zutil$(C)
-
-# Standard headers
-ZH = zlib.h crc32.h inffast.h inffixed.h \
- inflate.h inftrees.h zutil.h
-
-# Machine generated headers
-ZCONF = zconf.h
-
-# Headers callers use
-ZINC = zlib.h $(ZCONF)
-
-# Headers the Zlib source uses
-ZHDRS = $(ZH) $(ZCONF)
-
-ZOBJS = adler32$(O) crc32$(O) \
- inffast$(O) inflate$(O) inftrees$(O) \
- zutil$(O)
-
-# libpng
-PNGSRCS=png$(C) pngerror$(C) pngget$(C) pngmem$(C) \
- pngpread$(C) pngread$(C) pngrio$(C) pngrtran$(C) pngrutil$(C) \
- pngset$(C) pngtrans$(C)
-
-# Standard headers
-PNGH =png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h
-
-# Machine generated headers
-PNGCONF=pnglibconf.h
-
-# Headers callers use
-PNGINC= png.h pngconf.h pngusr.h $(PNGCONF)
-
-# Headers the PNG library uses
-PNGHDRS=$(PNGH) $(PNGCONF) pngusr.h
-
-PNGOBJS=png$(O) pngerror$(O) pngget$(O) pngmem$(O) \
- pngpread$(O) pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) \
- pngset$(O) pngtrans$(O)
-
-PROGSRCS= rpng2-x$(C) readpng2$(C)
-PROGHDRS= readpng2.h
-PROGDOCS= COPYING LICENSE
-PROGOBJS= rpng2-x$(O) readpng2$(O)
-
-OBJS = $(PROGOBJS) $(PNGOBJS) $(ZOBJS)
-
-# implicit make rules -------------------------------------------------------
-
-.c$(O):
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
-
-# dependencies
-
-all: $(PROGDOCS) rpng2-x$(E)
-
-rpng2-x$(E): $(OBJS)
- $(LD) -o rpng2-x$(E) $(OBJS) $(LIBS)
-
-# The DFA_XTRA setting turns all libpng options off then
-# turns on those required for this minimal build.
-# The CPP_FLAGS setting causes pngusr.h to be included in
-# both the build of pnglibconf.h and, subsequently, when
-# building libpng itself.
-$(PNGCONF): $(PNGSRC)/scripts/pnglibconf.mak $(ZH)\
- $(PNGSRC)/scripts/pnglibconf.dfa \
- $(PNGSRC)/scripts/options.awk pngusr.h pngusr.dfa
- $(RM) pnglibconf.h pnglibconf.dfn
- $(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\
- srcdir=$(PNGSRC) CPPFLAGS="-DPNG_USER_CONFIG -I."\
- DFA_XTRA="pngusr.dfa" $@
-
-clean:
- $(MAKE) -f $(PNGSRC)/scripts/pnglibconf.mak $(MAKEFLAGS)\
- srcdir=$(PNGSRC) clean
- $(RM) rpng2-x$(O)
- $(RM) rpng2-x$(E)
- $(RM) $(OBJS)
-
-# distclean also removes the copied source and headers
-distclean: clean
- $(RM) -r scripts # historical reasons
- $(RM) $(PNGSRCS) $(PNGH)
- $(RM) $(ZSRCS) $(ZH) $(ZCONF)
- $(RM) $(PROGSRCS) $(PROGHDRS) $(PROGDOCS)
-
-# Header file dependencies:
-$(PROGOBJS): $(PROGHDRS) $(PNGINC) $(ZINC)
-$(PNGOBJS): $(PNGHDRS) $(ZINC)
-$(ZOBJS): $(ZHDRS)
-
-# Gather the source code from the respective directories
-$(PNGSRCS) $(PNGH): $(PNGSRC)/$@
- $(RM) $@
- $(COPY) $(PNGSRC)/$@ $@
-
-# No dependency on the ZLIBSRC target so that it only needs
-# to be specified once.
-$(ZSRCS) $(ZH):
- $(RM) $@
- $(COPY) $(ZLIBSRC)/$@ $@
-
-# The unconfigured zconf.h varies in name according to the
-# zlib release
-$(ZCONF):
- $(RM) $@
- @for f in zconf.h.in zconf.in.h zconf.h; do\
- test -r $(ZLIBSRC)/$$f &&\
- echo $(COPY) $(ZLIBSRC)/$$f $@ &&\
- $(COPY) $(ZLIBSRC)/$$f $@ && exit 0;\
- done; echo copy: $(ZLIBSRC)/zconf.h not found; exit 1
-
-$(PROGSRCS) $(PROGHDRS) $(PROGDOCS): $(PROGSRC)/$@
- $(RM) $@
- $(COPY) $(PROGSRC)/$@ $@
-
-# End of makefile for rpng2-x
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.dfa b/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.dfa
deleted file mode 100644
index ac297f41bd7..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.dfa
+++ /dev/null
@@ -1,40 +0,0 @@
-# pngminim/preader/pngusr.dfa
-#
-# Copyright (c) 2010-2013 Glenn Randers-Pehrson
-#
-# This code is released under the libpng license.
-# For conditions of distribution and use, see the disclaimer
-# and license in png.h
-
-# First all the build options off:
-
-everything = off
-
-# Just switch on the progressive read code
-
-option PROGRESSIVE_READ on
-
-# You may choose fixed or floating point APIs:
-# option FLOATING_POINT on
-
-option FIXED_POINT on
-
-# You must chose the internal fixed point implementation or to
-# use the system floating point. The latter is considerably
-# smaller (by about 1kbyte on an x86 system):
-
-option FLOATING_ARITHMETIC on
-# option FLOATING_ARITHMETIC off
-
-# Your program will probably need other options. The example
-# program here, rpng2-x, requires the following. Take a look
-# at pnglibconf.h to find out the full set of what has to be
-# enabled to make the following work.
-
-option SETJMP on
-option STDIO on
-option READ_bKGD on
-option READ_GAMMA on
-option READ_EXPAND on
-option READ_STRIP_16_TO_8 on
-option READ_GRAY_TO_RGB on
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.h b/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.h
deleted file mode 100644
index 80db3bb1719..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminim/preader/pngusr.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* minrdpngconf.h: headers to make a minimal png-read-only library
- *
- * Copyright (c) 2009, 2010-2013 Glenn Randers-Pehrson
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Derived from pngcrush.h, Copyright 1998-2007, Glenn Randers-Pehrson
- */
-
-#ifndef MINPRDPNGCONF_H
-#define MINPRDPNGCONF_H
-
-/* To include pngusr.h set -DPNG_USER_CONFIG in CPPFLAGS */
-
-/* List options to turn off features of the build that do not
- * affect the API (so are not recorded in pnglibconf.h)
- */
-
-#define PNG_ALIGN_TYPE PNG_ALIGN_NONE
-
-#endif /* MINPRDPNGCONF_H */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt b/Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt
deleted file mode 100644
index 4e64e5ee614..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-
-pnm2png / png2pnm --- conversion from PBM/PGM/PPM-file to PNG-file
-copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
-
-version 1.0 - 1999.10.15 - First version.
- 1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson)
- 1.2 - 2017.04.22 - Add buffer-size check
- 1.3 - 2017.08.24 - Fix potential overflow in buffer-size check
- (Glenn Randers-Pehrson)
- 1.4 - 2017.08.28 - Add PNGMINUS_UNUSED (Christian Hesse)
- 1.5 - 2018.08.05 - Fix buffer overflow in tokenizer (Cosmin Truta)
- 1.6 - 2018.08.05 - Improve portability and fix style (Cosmin Truta)
- 1.7 - 2019.01.22 - Change license to MIT (Willem van Schaik)
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt b/Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt
deleted file mode 100644
index 1f815a58251..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-cmake_minimum_required(VERSION 3.1)
-cmake_policy(VERSION 3.1)
-
-project(PNGMINUS C)
-
-option(PNGMINUS_USE_STATIC_LIBRARIES "Use the static library builds" ON)
-
-# libpng
-add_subdirectory(../.. libpng)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..)
-include_directories(${CMAKE_CURRENT_BINARY_DIR}/libpng)
-if(PNGMINUS_USE_STATIC_LIBRARIES)
- set(PNGMINUS_PNG_LIBRARY png_static)
-else()
- set(PNGMINUS_PNG_LIBRARY png)
-endif()
-
-# png2pnm
-add_executable(png2pnm png2pnm.c)
-target_link_libraries(png2pnm ${PNGMINUS_PNG_LIBRARY})
-
-# pnm2png
-add_executable(pnm2png pnm2png.c)
-target_link_libraries(pnm2png ${PNGMINUS_PNG_LIBRARY})
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/LICENSE.txt b/Build/source/libs/libpng/libpng-src/contrib/pngminus/LICENSE.txt
deleted file mode 100644
index 00878a9a604..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-pnm2png / png2pnm --- conversion from PBM/PGM/PPM-file to PNG-file
-
-copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The software is provided "as is", without warranty of any kind, express or
-implied, including but not limited to the warranties of merchantability,
-fitness for a particular purpose and noninfringement. In no event shall the
-authors or copyight holders be liable for any claim, damages or other
-liability, whether in an action of contract, tort or otherwise, arising from,
-out of or in connection with the software or the use or other dealings in the
-software.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/Makefile b/Build/source/libs/libpng/libpng-src/contrib/pngminus/Makefile
deleted file mode 100644
index 4bba0796113..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-# Makefile for PngMinus (png2pnm and pnm2png)
-# Linux / Unix
-
-#CC = cc
-CC = gcc
-LD = $(CC)
-
-RM = rm -f
-
-PNGINC = -I../..
-PNGLIB_SHARED = -L../.. -lpng
-PNGLIB_STATIC = ../../libpng.a
-
-# Uncomment the following if you have a custom zlib build at ../../../zlib
-#ZINC = -I../../../zlib
-#ZLIB_SHARED = -L../../../zlib -lz
-#ZLIB_STATIC = ../../../zlib/libz.a
-
-# Use the system zlib otherwise
-ZLIB_SHARED = -lz
-ZLIB_STATIC = -lz
-
-CPPFLAGS = $(PNGINC) $(ZINC)
-CFLAGS =
-LDFLAGS =
-LIBS_SHARED = $(PNGLIB_SHARED) $(ZLIB_SHARED)
-LIBS_STATIC = $(PNGLIB_STATIC) $(ZLIB_STATIC)
-
-EXEEXT =
-#EXEEXT = .exe
-
-# dependencies
-
-all: png2pnm$(EXEEXT) pnm2png$(EXEEXT) png2pnm-static$(EXEEXT) pnm2png-static$(EXEEXT)
-
-png2pnm.o: png2pnm.c
- $(CC) -c $(CPPFLAGS) $(CFLAGS) png2pnm.c
-
-pnm2png.o: pnm2png.c
- $(CC) -c $(CPPFLAGS) $(CFLAGS) pnm2png.c
-
-png2pnm$(EXEEXT): png2pnm.o
- $(LD) $(LDFLAGS) -o png2pnm$(EXEEXT) png2pnm.o $(LIBS_SHARED) -lm
-
-pnm2png$(EXEEXT): pnm2png.o
- $(LD) $(LDFLAGS) -o pnm2png$(EXEEXT) pnm2png.o $(LIBS_SHARED) -lm
-
-png2pnm-static$(EXEEXT): png2pnm.o
- $(LD) $(LDFLAGS) -o png2pnm-static$(EXEEXT) png2pnm.o $(LIBS_STATIC) -lm
-
-pnm2png-static$(EXEEXT): pnm2png.o
- $(LD) $(LDFLAGS) -o pnm2png-static$(EXEEXT) pnm2png.o $(LIBS_STATIC) -lm
-
-clean:
- $(RM) png2pnm.o
- $(RM) pnm2png.o
- $(RM) png2pnm$(EXEEXT)
- $(RM) pnm2png$(EXEEXT)
- $(RM) png2pnm-static$(EXEEXT)
- $(RM) pnm2png-static$(EXEEXT)
-
-# End of makefile for png2pnm / pnm2png
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/README.txt b/Build/source/libs/libpng/libpng-src/contrib/pngminus/README.txt
deleted file mode 100644
index f7f6ecb3a5a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/README.txt
+++ /dev/null
@@ -1,120 +0,0 @@
-PngMinus
---------
-(copyright Willem van Schaik, 1999-2019)
-
-
-
-Some history
-------------
-Soon after the creation of PNG in 1995, the need was felt for a set of
-pnmtopng / pngtopnm utilities. Independently Alexander Lehmann and I
-(Willem van Schaik) started such a project. Luckily we discovered this
-and merged the two, which later became part of NetPBM, available from
-SourceForge.
-
-These two utilities have many, many options and make use of most of the
-features of PNG, like gamma, alpha, sbit, text-chunks, etc. This makes
-the utilities quite complex and by now not anymore very maintainable.
-When we wrote these programs, libpng was still in an early stage.
-Therefore, lots of the functionality that we put in our software can now
-be done using transform-functions in libpng.
-
-Finally, to compile these programs, you need to have installed and
-compiled three libraries: libpng, zlib and netpbm. Especially the latter
-makes the whole setup a bit bulky. But that's unavoidable given the many
-features of pnmtopng.
-
-
-What now (1999)
----------------
-At this moment libpng is in a very stable state and can do much of the
-work done in pnmtopng. Also, pnmtopng needs to be upgraded to the new
-interface of libpng. Hence, it is time for a rewrite from the ground up
-of pnmtopng and pngtopnm. This will happen in the near future (stay
-tuned). The new package will get a different name to distinguish it from
-the old one: PngPlus.
-
-To experiment a bit with the new interface of libpng, I started off with
-a small prototype that contains only the basic functionality. It doesn't
-have any of the options to read or write special chunks and it will do
-no gamma correction. But this makes it also a simple program that is
-quite easy to understand and can serve well as a template for other
-software developments. By now there are of course a couple of programs,
-like Greg Roelofs' rpng/wpng, that can be used just as good.
-
-
-Can and can not
----------------
-As this is the small brother of the future PngPlus, I called this fellow
-PngMinus. Because I started this development in good-old Turbo-C, I
-avoided the use the netpbm library, which requires DOS extenders. Again,
-another reason to call it PngMinus (minus netpbm :-). So, part of the
-program are some elementary routines to read / write pgm- and ppm-files.
-It does not handle B&W pbm-files, but instead you could do pgm with bit-
-depth 1.
-
-The downside of this approach is that you can not use them on images
-that require blocks of memory bigger than 64k (the DOS version). For
-larger images you will get an out-of-memory error.
-
-As said before, PngMinus doesn't correct for gamma. When reading
-png-files you can do this just as well by piping the output of png2pnm
-to pnmgamma, one of the standard PbmPlus tools. This same scenario will
-most probably also be followed in the full-blown future PngPlus, with
-the addition of course of the possibility to create gamma-chunks when
-writing png-files.
-
-On the other hand it supports alpha-channels. When reading a png-image
-you can write the alpha-channel into a pgm-file. And when creating an
-RGB+A png-image, you just combine a ppm-file with a corresponding
-pgm-file containing the alpha-channel. When reading, transparency chunks
-are converted into an alpha-channel and from there on treated the same
-way.
-
-Finally you can opt for writing ascii or binary pgm- and ppm-files. When
-the bit-depth is 16, the format will always be ascii.
-
-
-Using it
---------
-To distinguish them from pnmtopng and PngPlus, the utilities are named
-png2pnm and pnm2png (2 instead of to). The input- and output-files can
-be given as parameters or through redirection. Therefore the programs
-can be part of a pipe.
-
-To list the options type "png2pnm -h" or "pnm2png -h".
-
-
-Just like Scandinavian furniture
---------------------------------
-You have to put it together yourself. I developed the software on MS-DOS
-with Turbo-C 3.0 and RedHat Linux 4.2 with gcc. In both cases I used
-libpng-1.0.4 and zlib-1.1.3. By now (2019) it is twenty years later and
-more current versions are OK.
-
-The makefile assumes that the libpng libraries can be found in ../.. and
-libz in ../../../zlib. But you can change this to for example ../libpng
-and ../zlib. The makefile creates two versions of each program, one with
-static library support and the other using shared libraries.
-
-If you create a ../pngsuite directory and then store the basn####.png
-files from PngSuite (http://www.schaik.com/pngsuite/) in there, you can
-test the proper functioning of PngMinus by running pngminus.sh.
-
-
-Warranty
--------
-Please, remember that this was just a small experiment to learn a few
-things. It will have many unforeseen features <vbg> ... who said bugs? Use
-it when you are in need for something simple or when you want a starting
-point for developing your own stuff.
-
-
-The end
--------
-Willem van Schaik
-mailto:willem at schaik dot com
-http://www.schaik.com/png/
-
-Oct 1999, Jan 2019
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/makevms.com b/Build/source/libs/libpng/libpng-src/contrib/pngminus/makevms.com
deleted file mode 100644
index 00561bcd0d7..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/makevms.com
+++ /dev/null
@@ -1,92 +0,0 @@
-$!------------------------------------------------------------------------------
-$! make Contrib programs of libpng under OpenVMS
-$!
-$!
-$! Look for the compiler used
-$!
-$ zlibsrc = "[---.zlib]"
-$ ccopt="/include=(''zlibsrc',[--])"
-$ if f$getsyi("HW_MODEL").ge.1024
-$ then
-$ ccopt = "/prefix=all"+ccopt
-$ comp = "__decc__=1"
-$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
-$ else
-$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
-$ then
-$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
-$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs.""
-$ then
-$ comp = "__gcc__=1"
-$ CC :== GCC
-$ else
-$ comp = "__vaxc__=1"
-$ endif
-$ else
-$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
-$ ccopt = "/decc/prefix=all"+ccopt
-$ comp = "__decc__=1"
-$ endif
-$ endif
-$ open/write lopt lib.opt
-$ write lopt "[--]libpng.olb/lib"
-$ write lopt "''zlibsrc'libz.olb/lib"
-$ close lopt
-$ open/write xopt x11.opt
-$ write xopt "sys$library:decw$xlibshr.exe/share"
-$ close xopt
-$ write sys$output "Compiling PNG contrib programs ..."
-$ write sys$output "Building pnm2png..."
-$ CALL MAKE pnm2png.OBJ "cc ''CCOPT' pnm2png" -
- pnm2png.c
-$ call make pnm2png.exe -
- "LINK pnm2png,lib.opt/opt" -
- pnm2png.obj
-$ write sys$output "Building png2pnm..."
-$ CALL MAKE png2pnm.OBJ "cc ''CCOPT' png2pnm" -
- png2pnm.c
-$ call make png2pnm.exe -
- "LINK png2pnm,lib.opt/opt" -
- png2pnm.obj
-$ exit
-$!
-$!
-$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
-$ V = 'F$Verify(0)
-$! P1 = What we are trying to make
-$! P2 = Command to make it
-$! P3 - P8 What it depends on
-$
-$ If F$Search(P1) .Eqs. "" Then Goto Makeit
-$ Time = F$CvTime(F$File(P1,"RDT"))
-$arg=3
-$Loop:
-$ Argument = P'arg
-$ If Argument .Eqs. "" Then Goto Exit
-$ El=0
-$Loop2:
-$ File = F$Element(El," ",Argument)
-$ If File .Eqs. " " Then Goto Endl
-$ AFile = ""
-$Loop3:
-$ OFile = AFile
-$ AFile = F$Search(File)
-$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
-$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
-$ Goto Loop3
-$NextEL:
-$ El = El + 1
-$ Goto Loop2
-$EndL:
-$ arg=arg+1
-$ If arg .Le. 8 Then Goto Loop
-$ Goto Exit
-$
-$Makeit:
-$ VV=F$VERIFY(0)
-$ write sys$output P2
-$ 'P2
-$ VV='F$Verify(VV)
-$Exit:
-$ If V Then Set Verify
-$ENDSUBROUTINE
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.bat b/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.bat
deleted file mode 100644
index a2798c34032..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-REM -- grayscale
-png2pnm.exe -noraw ..\pngsuite\basn0g01.png basn0g01.pgm
-png2pnm.exe -noraw ..\pngsuite\basn0g02.png basn0g02.pgm
-png2pnm.exe -noraw ..\pngsuite\basn0g04.png basn0g04.pgm
-png2pnm.exe -noraw ..\pngsuite\basn0g08.png basn0g08.pgm
-png2pnm.exe -noraw ..\pngsuite\basn0g16.png basn0g16.pgm
-REM -- full-color
-png2pnm.exe -noraw ..\pngsuite\basn2c08.png basn2c08.ppm
-png2pnm.exe -noraw ..\pngsuite\basn2c16.png basn2c16.ppm
-REM -- paletted
-png2pnm.exe -noraw ..\pngsuite\basn3p01.png basn3p01.ppm
-png2pnm.exe -noraw ..\pngsuite\basn3p02.png basn3p02.ppm
-png2pnm.exe -noraw ..\pngsuite\basn3p04.png basn3p04.ppm
-png2pnm.exe -noraw ..\pngsuite\basn3p08.png basn3p08.ppm
-REM -- gray with alpha-channel
-png2pnm.exe -noraw ..\pngsuite\basn4a08.png basn4a08.pgm
-png2pnm.exe -noraw ..\pngsuite\basn4a16.png basn4a16.pgm
-REM -- color with alpha-channel
-png2pnm.exe -noraw -alpha basn6a08.pgm ..\pngsuite\basn6a08.png basn6a08.ppm
-png2pnm.exe -noraw -alpha basn6a16.pgm ..\pngsuite\basn6a16.png basn6a16.ppm
-REM -- grayscale
-png2pnm.exe -raw ..\pngsuite\basn0g01.png rawn0g01.pgm
-png2pnm.exe -raw ..\pngsuite\basn0g02.png rawn0g02.pgm
-png2pnm.exe -raw ..\pngsuite\basn0g04.png rawn0g04.pgm
-png2pnm.exe -raw ..\pngsuite\basn0g08.png rawn0g08.pgm
-png2pnm.exe -raw ..\pngsuite\basn0g16.png rawn0g16.pgm
-REM -- full-color
-png2pnm.exe -raw ..\pngsuite\basn2c08.png rawn2c08.ppm
-png2pnm.exe -raw ..\pngsuite\basn2c16.png rawn2c16.ppm
-REM -- paletted
-png2pnm.exe -raw ..\pngsuite\basn3p01.png rawn3p01.ppm
-png2pnm.exe -raw ..\pngsuite\basn3p02.png rawn3p02.ppm
-png2pnm.exe -raw ..\pngsuite\basn3p04.png rawn3p04.ppm
-png2pnm.exe -raw ..\pngsuite\basn3p08.png rawn3p08.ppm
-REM -- gray with alpha-channel
-png2pnm.exe -raw ..\pngsuite\basn4a08.png rawn4a08.pgm
-png2pnm.exe -raw ..\pngsuite\basn4a16.png rawn4a16.pgm
-REM -- color with alpha-channel
-png2pnm.exe -noraw -alpha rawn6a08.pgm ..\pngsuite\basn6a08.png rawn6a08.ppm
-png2pnm.exe -noraw -alpha rawn6a16.pgm ..\pngsuite\basn6a16.png rawn6a16.ppm
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c b/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c
deleted file mode 100644
index 5fef7ed1425..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * png2pnm.c --- conversion from PNG-file to PGM/PPM-file
- * copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
- *
- * This software is released under the MIT license. For conditions of
- * distribution and use, see the LICENSE file part of this package.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-
-#ifndef BOOL
-#define BOOL unsigned char
-#endif
-#ifndef TRUE
-#define TRUE (BOOL) 1
-#endif
-#ifndef FALSE
-#define FALSE (BOOL) 0
-#endif
-
-/* make png2pnm verbose so we can find problems (needs to be before png.h) */
-#ifndef PNG_DEBUG
-#define PNG_DEBUG 0
-#endif
-
-#include "png.h"
-
-/* function prototypes */
-
-int main (int argc, char *argv[]);
-void usage ();
-BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
- BOOL raw, BOOL alpha);
-
-/*
- * main
- */
-
-int main (int argc, char *argv[])
-{
- FILE *fp_rd = stdin;
- FILE *fp_wr = stdout;
- FILE *fp_al = NULL;
- BOOL raw = TRUE;
- BOOL alpha = FALSE;
- int argi;
-
- for (argi = 1; argi < argc; argi++)
- {
- if (argv[argi][0] == '-')
- {
- switch (argv[argi][1])
- {
- case 'n':
- raw = FALSE;
- break;
- case 'r':
- raw = TRUE;
- break;
- case 'a':
- alpha = TRUE;
- argi++;
- if ((fp_al = fopen (argv[argi], "wb")) == NULL)
- {
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: cannot create alpha-channel file %s\n",
- argv[argi]);
- exit (1);
- }
- break;
- case 'h':
- case '?':
- usage ();
- exit (0);
- break;
- default:
- fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, "Error: unknown option %s\n", argv[argi]);
- usage ();
- exit (1);
- break;
- } /* end switch */
- }
- else if (fp_rd == stdin)
- {
- if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
- {
- fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, "Error: file %s does not exist\n", argv[argi]);
- exit (1);
- }
- }
- else if (fp_wr == stdout)
- {
- if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
- {
- fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, "Error: cannot create file %s\n", argv[argi]);
- exit (1);
- }
- }
- else
- {
- fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, "Error: too many parameters\n");
- usage ();
- exit (1);
- }
- } /* end for */
-
-#if defined(O_BINARY) && (O_BINARY != 0)
- /* set stdin/stdout if required to binary */
- if (fp_rd == stdin)
- setmode (fileno (stdin), O_BINARY);
- if ((raw) && (fp_wr == stdout))
- setmode (fileno (stdout), O_BINARY);
-#endif
-
- /* call the conversion program itself */
- if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE)
- {
- fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n");
- exit (1);
- }
-
- /* close input file */
- fclose (fp_rd);
- /* close output file */
- fclose (fp_wr);
- /* close alpha file */
- if (alpha)
- fclose (fp_al);
-
- return 0;
-}
-
-/*
- * usage
- */
-
-void usage ()
-{
- fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, " by Willem van Schaik, 1999\n");
- fprintf (stderr, "Usage: png2pnm [options] <file>.png [<file>.pnm]\n");
- fprintf (stderr, " or: ... | png2pnm [options]\n");
- fprintf (stderr, "Options:\n");
- fprintf (stderr,
- " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n");
- fprintf (stderr, " -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n");
- fprintf (stderr,
- " -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n");
- fprintf (stderr, " -h | -? print this help-information\n");
-}
-
-/*
- * png2pnm
- */
-
-BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
- BOOL raw, BOOL alpha)
-{
- png_struct *png_ptr = NULL;
- png_info *info_ptr = NULL;
- png_byte buf[8];
- png_byte *png_pixels = NULL;
- png_byte **row_pointers = NULL;
- png_byte *pix_ptr = NULL;
- png_uint_32 row_bytes;
-
- png_uint_32 width;
- png_uint_32 height;
- int bit_depth;
- int channels;
- int color_type;
- int alpha_present;
- int row, col;
- int ret;
- int i;
- long dep_16;
-
- /* read and check signature in PNG file */
- ret = fread (buf, 1, 8, png_file);
- if (ret != 8)
- return FALSE;
-
- ret = png_sig_cmp (buf, 0, 8);
- if (ret != 0)
- return FALSE;
-
- /* create png and info structures */
-
- png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),
- NULL, NULL, NULL);
- if (!png_ptr)
- return FALSE; /* out of memory */
-
- info_ptr = png_create_info_struct (png_ptr);
- if (!info_ptr)
- {
- png_destroy_read_struct (&png_ptr, NULL, NULL);
- return FALSE; /* out of memory */
- }
-
- if (setjmp (png_jmpbuf (png_ptr)))
- {
- png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
- return FALSE;
- }
-
- /* set up the input control for C streams */
- png_init_io (png_ptr, png_file);
- png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */
-
- /* read the file information */
- png_read_info (png_ptr, info_ptr);
-
- /* get size and bit-depth of the PNG-image */
- png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
- NULL, NULL, NULL);
-
- /* set-up the transformations */
-
- /* transform paletted images into full-color rgb */
- if (color_type == PNG_COLOR_TYPE_PALETTE)
- png_set_expand (png_ptr);
- /* expand images to bit-depth 8 (only applicable for grayscale images) */
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
- png_set_expand (png_ptr);
- /* transform transparency maps into full alpha-channel */
- if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand (png_ptr);
-
-#ifdef NJET
- /* downgrade 16-bit images to 8-bit */
- if (bit_depth == 16)
- png_set_strip_16 (png_ptr);
- /* transform grayscale images into full-color */
- if (color_type == PNG_COLOR_TYPE_GRAY ||
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb (png_ptr);
- /* only if file has a file gamma, we do a correction */
- if (png_get_gAMA (png_ptr, info_ptr, &file_gamma))
- png_set_gamma (png_ptr, (double) 2.2, file_gamma);
-#endif
-
- /* all transformations have been registered; now update info_ptr data,
- * get rowbytes and channels, and allocate image memory */
-
- png_read_update_info (png_ptr, info_ptr);
-
- /* get the new color-type and bit-depth (after expansion/stripping) */
- png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
- NULL, NULL, NULL);
-
- /* check for 16-bit files */
- if (bit_depth == 16)
- {
- raw = FALSE;
-#if defined(O_BINARY) && (O_BINARY != 0)
- setmode (fileno (pnm_file), O_BINARY);
-#endif
- }
-
- /* calculate new number of channels and store alpha-presence */
- if (color_type == PNG_COLOR_TYPE_GRAY)
- channels = 1;
- else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- channels = 2;
- else if (color_type == PNG_COLOR_TYPE_RGB)
- channels = 3;
- else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- channels = 4;
- else
- channels = 0; /* should never happen */
- alpha_present = (channels - 1) % 2;
-
- /* check if alpha is expected to be present in file */
- if (alpha && !alpha_present)
- {
- fprintf (stderr, "PNG2PNM\n");
- fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n");
- exit (1);
- }
-
- /* row_bytes is the width x number of channels x (bit-depth / 8) */
- row_bytes = png_get_rowbytes (png_ptr, info_ptr);
-
- if ((row_bytes == 0) ||
- ((size_t) height > (size_t) (-1) / (size_t) row_bytes))
- {
- /* too big */
- png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
- return FALSE;
- }
- if ((png_pixels = (png_byte *)
- malloc ((size_t) row_bytes * (size_t) height)) == NULL)
- {
- png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
- return FALSE;
- }
-
- if ((row_pointers = (png_byte **)
- malloc ((size_t) height * sizeof (png_byte *))) == NULL)
- {
- png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
- free (png_pixels);
- return FALSE;
- }
-
- /* set the individual row_pointers to point at the correct offsets */
- for (i = 0; i < ((int) height); i++)
- row_pointers[i] = png_pixels + i * row_bytes;
-
- /* now we can go ahead and just read the whole image */
- png_read_image (png_ptr, row_pointers);
-
- /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
- png_read_end (png_ptr, info_ptr);
-
- /* clean up after the read, and free any memory allocated - REQUIRED */
- png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
-
- /* write header of PNM file */
-
- if ((color_type == PNG_COLOR_TYPE_GRAY) ||
- (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
- {
- fprintf (pnm_file, "%s\n", (raw) ? "P5" : "P2");
- fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
- fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
- }
- else if ((color_type == PNG_COLOR_TYPE_RGB) ||
- (color_type == PNG_COLOR_TYPE_RGB_ALPHA))
- {
- fprintf (pnm_file, "%s\n", (raw) ? "P6" : "P3");
- fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
- fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
- }
-
- /* write header of PGM file with alpha channel */
-
- if ((alpha) &&
- ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
- (color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
- {
- fprintf (alpha_file, "%s\n", (raw) ? "P5" : "P2");
- fprintf (alpha_file, "%d %d\n", (int) width, (int) height);
- fprintf (alpha_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
- }
-
- /* write data to PNM file */
- pix_ptr = png_pixels;
-
- for (row = 0; row < (int) height; row++)
- {
- for (col = 0; col < (int) width; col++)
- {
- for (i = 0; i < (channels - alpha_present); i++)
- {
- if (raw)
- {
- fputc ((int) *pix_ptr++, pnm_file);
- }
- else
- {
- if (bit_depth == 16)
- {
- dep_16 = (long) *pix_ptr++;
- fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++));
- }
- else
- {
- fprintf (pnm_file, "%ld ", (long) *pix_ptr++);
- }
- }
- }
- if (alpha_present)
- {
- if (!alpha)
- {
- pix_ptr++; /* alpha */
- if (bit_depth == 16)
- pix_ptr++;
- }
- else /* output alpha-channel as pgm file */
- {
- if (raw)
- {
- fputc ((int) *pix_ptr++, alpha_file);
- }
- else
- {
- if (bit_depth == 16)
- {
- dep_16 = (long) *pix_ptr++;
- fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++);
- }
- else
- {
- fprintf (alpha_file, "%ld ", (long) *pix_ptr++);
- }
- }
- }
- } /* end if alpha_present */
-
- if (!raw)
- if (col % 4 == 3)
- fprintf (pnm_file, "\n");
- } /* end for col */
-
- if (!raw)
- if (col % 4 != 0)
- fprintf (pnm_file, "\n");
- } /* end for row */
-
- if (row_pointers != NULL)
- free (row_pointers);
- if (png_pixels != NULL)
- free (png_pixels);
-
- return TRUE;
-
-} /* end of source */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.sh b/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.sh
deleted file mode 100755
index 756126a53c2..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-# -- grayscale
-./png2pnm -noraw ../pngsuite/basn0g01.png basn0g01.pgm
-./png2pnm -noraw ../pngsuite/basn0g02.png basn0g02.pgm
-./png2pnm -noraw ../pngsuite/basn0g04.png basn0g04.pgm
-./png2pnm -noraw ../pngsuite/basn0g08.png basn0g08.pgm
-./png2pnm -noraw ../pngsuite/basn0g16.png basn0g16.pgm
-# -- full-color
-./png2pnm -noraw ../pngsuite/basn2c08.png basn2c08.ppm
-./png2pnm -noraw ../pngsuite/basn2c16.png basn2c16.ppm
-# -- paletted
-./png2pnm -noraw ../pngsuite/basn3p01.png basn3p01.ppm
-./png2pnm -noraw ../pngsuite/basn3p02.png basn3p02.ppm
-./png2pnm -noraw ../pngsuite/basn3p04.png basn3p04.ppm
-./png2pnm -noraw ../pngsuite/basn3p08.png basn3p08.ppm
-# -- gray with alpha-channel
-./png2pnm -noraw ../pngsuite/basn4a08.png basn4a08.pgm
-./png2pnm -noraw ../pngsuite/basn4a16.png basn4a16.pgm
-# -- color with alpha-channel
-./png2pnm -noraw -alpha basn6a08.pgm ../pngsuite/basn6a08.png basn6a08.ppm
-./png2pnm -noraw -alpha basn6a16.pgm ../pngsuite/basn6a16.png basn6a16.ppm
-# -- grayscale
-./png2pnm -raw ../pngsuite/basn0g01.png rawn0g01.pgm
-./png2pnm -raw ../pngsuite/basn0g02.png rawn0g02.pgm
-./png2pnm -raw ../pngsuite/basn0g04.png rawn0g04.pgm
-./png2pnm -raw ../pngsuite/basn0g08.png rawn0g08.pgm
-./png2pnm -raw ../pngsuite/basn0g16.png rawn0g16.pgm
-# -- full-color
-./png2pnm -raw ../pngsuite/basn2c08.png rawn2c08.ppm
-./png2pnm -raw ../pngsuite/basn2c16.png rawn2c16.ppm
-# -- paletted
-./png2pnm -raw ../pngsuite/basn3p01.png rawn3p01.ppm
-./png2pnm -raw ../pngsuite/basn3p02.png rawn3p02.ppm
-./png2pnm -raw ../pngsuite/basn3p04.png rawn3p04.ppm
-./png2pnm -raw ../pngsuite/basn3p08.png rawn3p08.ppm
-# -- gray with alpha-channel
-./png2pnm -raw ../pngsuite/basn4a08.png rawn4a08.pgm
-./png2pnm -raw ../pngsuite/basn4a16.png rawn4a16.pgm
-# -- color with alpha-channel
-./png2pnm -noraw -alpha rawn6a08.pgm ../pngsuite/basn6a08.png rawn6a08.ppm
-./png2pnm -noraw -alpha rawn6a16.pgm ../pngsuite/basn6a16.png rawn6a16.ppm
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.bat b/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.bat
deleted file mode 100644
index fa60e7de07f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-make
-call png2pnm.bat
-call pnm2png.bat
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.sh b/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.sh
deleted file mode 100755
index cc9b4a56e37..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-make
-sh png2pnm.sh
-sh pnm2png.sh
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.bat b/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.bat
deleted file mode 100644
index c02b80beccd..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-REM -- grayscale
-pnm2png.exe basn0g01.pgm basn0g01.png
-pnm2png.exe basn0g02.pgm basn0g02.png
-pnm2png.exe basn0g04.pgm basn0g04.png
-pnm2png.exe basn0g08.pgm basn0g08.png
-pnm2png.exe basn0g16.pgm basn0g16.png
-REM -- full-color
-pnm2png.exe basn2c08.ppm basn2c08.png
-pnm2png.exe basn2c16.ppm basn2c16.png
-REM -- paletted
-pnm2png.exe basn3p01.ppm basn3p01.png
-pnm2png.exe basn3p02.ppm basn3p02.png
-pnm2png.exe basn3p04.ppm basn3p04.png
-pnm2png.exe basn3p08.ppm basn3p08.png
-REM -- gray with alpha-channel
-pnm2png.exe -alpha basn6a08.pgm basn4a08.pgm basn4a08.png
-pnm2png.exe -alpha basn6a16.pgm basn4a16.pgm basn4a16.png
-REM -- color with alpha-channel
-pnm2png.exe -alpha basn6a08.pgm basn6a08.ppm basn6a08.png
-pnm2png.exe -alpha basn6a16.pgm basn6a16.ppm basn6a16.png
-REM -- grayscale
-pnm2png.exe rawn0g01.pgm rawn0g01.png
-pnm2png.exe rawn0g02.pgm rawn0g02.png
-pnm2png.exe rawn0g04.pgm rawn0g04.png
-pnm2png.exe rawn0g08.pgm rawn0g08.png
-pnm2png.exe rawn0g16.pgm rawn0g16.png
-REM -- full-color
-pnm2png.exe rawn2c08.ppm rawn2c08.png
-pnm2png.exe rawn2c16.ppm rawn2c16.png
-REM -- paletted
-pnm2png.exe rawn3p01.ppm rawn3p01.png
-pnm2png.exe rawn3p02.ppm rawn3p02.png
-pnm2png.exe rawn3p04.ppm rawn3p04.png
-pnm2png.exe rawn3p08.ppm rawn3p08.png
-REM -- gray with alpha-channel
-pnm2png.exe -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png
-pnm2png.exe -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png
-REM -- color with alpha-channel
-pnm2png.exe -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png
-pnm2png.exe -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c b/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c
deleted file mode 100644
index a2c2551da92..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file
- * copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
- *
- * This software is released under the MIT license. For conditions of
- * distribution and use, see the LICENSE file part of this package.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-
-#ifndef BOOL
-#define BOOL unsigned char
-#endif
-#ifndef TRUE
-#define TRUE (BOOL) 1
-#endif
-#ifndef FALSE
-#define FALSE (BOOL) 0
-#endif
-
-/* make pnm2png verbose so we can find problems (needs to be before png.h) */
-#ifndef PNG_DEBUG
-#define PNG_DEBUG 0
-#endif
-
-#include "png.h"
-
-/* function prototypes */
-
-int main (int argc, char *argv[]);
-void usage ();
-BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
- BOOL interlace, BOOL alpha);
-void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size);
-png_uint_32 get_data (FILE *pnm_file, int depth);
-png_uint_32 get_value (FILE *pnm_file, int depth);
-
-/*
- * main
- */
-
-int main (int argc, char *argv[])
-{
- FILE *fp_rd = stdin;
- FILE *fp_al = NULL;
- FILE *fp_wr = stdout;
- BOOL interlace = FALSE;
- BOOL alpha = FALSE;
- int argi;
-
- for (argi = 1; argi < argc; argi++)
- {
- if (argv[argi][0] == '-')
- {
- switch (argv[argi][1])
- {
- case 'i':
- interlace = TRUE;
- break;
- case 'a':
- alpha = TRUE;
- argi++;
- if ((fp_al = fopen (argv[argi], "rb")) == NULL)
- {
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: alpha-channel file %s does not exist\n",
- argv[argi]);
- exit (1);
- }
- break;
- case 'h':
- case '?':
- usage ();
- exit (0);
- break;
- default:
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: unknown option %s\n", argv[argi]);
- usage ();
- exit (1);
- break;
- } /* end switch */
- }
- else if (fp_rd == stdin)
- {
- if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
- {
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: file %s does not exist\n", argv[argi]);
- exit (1);
- }
- }
- else if (fp_wr == stdout)
- {
- if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
- {
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: cannot create PNG-file %s\n", argv[argi]);
- exit (1);
- }
- }
- else
- {
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: too many parameters\n");
- usage ();
- exit (1);
- }
- } /* end for */
-
-#if defined(O_BINARY) && (O_BINARY != 0)
- /* set stdin/stdout to binary,
- * we're reading the PNM always! in binary format
- */
- if (fp_rd == stdin)
- setmode (fileno (stdin), O_BINARY);
- if (fp_wr == stdout)
- setmode (fileno (stdout), O_BINARY);
-#endif
-
- /* call the conversion program itself */
- if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE)
- {
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, "Error: unsuccessful converting to PNG-image\n");
- exit (1);
- }
-
- /* close input file */
- fclose (fp_rd);
- /* close output file */
- fclose (fp_wr);
- /* close alpha file */
- if (alpha)
- fclose (fp_al);
-
- return 0;
-}
-
-/*
- * usage
- */
-
-void usage ()
-{
- fprintf (stderr, "PNM2PNG\n");
- fprintf (stderr, " by Willem van Schaik, 1999\n");
- fprintf (stderr, "Usage: pnm2png [options] <file>.<pnm> [<file>.png]\n");
- fprintf (stderr, " or: ... | pnm2png [options]\n");
- fprintf (stderr, "Options:\n");
- fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n");
- fprintf (stderr,
- " -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n");
- fprintf (stderr, " -h | -? print this help-information\n");
-}
-
-/*
- * pnm2png
- */
-
-BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file,
- BOOL interlace, BOOL alpha)
-{
- png_struct *png_ptr = NULL;
- png_info *info_ptr = NULL;
- png_byte *png_pixels = NULL;
- png_byte **row_pointers = NULL;
- png_byte *pix_ptr = NULL;
- volatile png_uint_32 row_bytes;
-
- char type_token[16];
- char width_token[16];
- char height_token[16];
- char maxval_token[16];
- volatile int color_type = 1;
- unsigned long ul_width = 0, ul_alpha_width = 0;
- unsigned long ul_height = 0, ul_alpha_height = 0;
- unsigned long ul_maxval = 0;
- volatile png_uint_32 width = 0, height = 0;
- volatile png_uint_32 alpha_width = 0, alpha_height = 0;
- png_uint_32 maxval;
- volatile int bit_depth = 0;
- int channels = 0;
- int alpha_depth = 0;
- int alpha_present = 0;
- int row, col;
- BOOL raw, alpha_raw = FALSE;
-#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
- BOOL packed_bitmap = FALSE;
-#endif
- png_uint_32 tmp16;
- int i;
-
- /* read header of PNM file */
-
- get_token (pnm_file, type_token, sizeof (type_token));
- if (type_token[0] != 'P')
- {
- return FALSE;
- }
- else if ((type_token[1] == '1') || (type_token[1] == '4'))
- {
-#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
- raw = (type_token[1] == '4');
- color_type = PNG_COLOR_TYPE_GRAY;
- get_token (pnm_file, width_token, sizeof (width_token));
- sscanf (width_token, "%lu", &ul_width);
- width = (png_uint_32) ul_width;
- get_token (pnm_file, height_token, sizeof (height_token));
- sscanf (height_token, "%lu", &ul_height);
- height = (png_uint_32) ul_height;
- bit_depth = 1;
- packed_bitmap = TRUE;
-#else
- fprintf (stderr, "PNM2PNG built without PNG_WRITE_INVERT_SUPPORTED and\n");
- fprintf (stderr, "PNG_WRITE_PACK_SUPPORTED can't read PBM (P1,P4) files\n");
- return FALSE;
-#endif
- }
- else if ((type_token[1] == '2') || (type_token[1] == '5'))
- {
- raw = (type_token[1] == '5');
- color_type = PNG_COLOR_TYPE_GRAY;
- get_token (pnm_file, width_token, sizeof (width_token));
- sscanf (width_token, "%lu", &ul_width);
- width = (png_uint_32) ul_width;
- get_token (pnm_file, height_token, sizeof (height_token));
- sscanf (height_token, "%lu", &ul_height);
- height = (png_uint_32) ul_height;
- get_token (pnm_file, maxval_token, sizeof (maxval_token));
- sscanf (maxval_token, "%lu", &ul_maxval);
- maxval = (png_uint_32) ul_maxval;
-
- if (maxval <= 1)
- bit_depth = 1;
- else if (maxval <= 3)
- bit_depth = 2;
- else if (maxval <= 15)
- bit_depth = 4;
- else if (maxval <= 255)
- bit_depth = 8;
- else if (maxval <= 65535U)
- bit_depth = 16;
- else /* maxval > 65535U */
- return FALSE;
- }
- else if ((type_token[1] == '3') || (type_token[1] == '6'))
- {
- raw = (type_token[1] == '6');
- color_type = PNG_COLOR_TYPE_RGB;
- get_token (pnm_file, width_token, sizeof (width_token));
- sscanf (width_token, "%lu", &ul_width);
- width = (png_uint_32) ul_width;
- get_token (pnm_file, height_token, sizeof (height_token));
- sscanf (height_token, "%lu", &ul_height);
- height = (png_uint_32) ul_height;
- get_token (pnm_file, maxval_token, sizeof (maxval_token));
- sscanf (maxval_token, "%lu", &ul_maxval);
- maxval = (png_uint_32) ul_maxval;
- if (maxval <= 1)
- bit_depth = 1;
- else if (maxval <= 3)
- bit_depth = 2;
- else if (maxval <= 15)
- bit_depth = 4;
- else if (maxval <= 255)
- bit_depth = 8;
- else if (maxval <= 65535U)
- bit_depth = 16;
- else /* maxval > 65535U */
- return FALSE;
- }
- else
- {
- return FALSE;
- }
-
- /* read header of PGM file with alpha channel */
-
- if (alpha)
- {
- if (color_type == PNG_COLOR_TYPE_GRAY)
- color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- if (color_type == PNG_COLOR_TYPE_RGB)
- color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-
- get_token (alpha_file, type_token, sizeof (type_token));
- if (type_token[0] != 'P')
- {
- return FALSE;
- }
- else if ((type_token[1] == '2') || (type_token[1] == '5'))
- {
- alpha_raw = (type_token[1] == '5');
- get_token (alpha_file, width_token, sizeof (width_token));
- sscanf (width_token, "%lu", &ul_alpha_width);
- alpha_width = (png_uint_32) ul_alpha_width;
- if (alpha_width != width)
- return FALSE;
- get_token (alpha_file, height_token, sizeof (height_token));
- sscanf (height_token, "%lu", &ul_alpha_height);
- alpha_height = (png_uint_32) ul_alpha_height;
- if (alpha_height != height)
- return FALSE;
- get_token (alpha_file, maxval_token, sizeof (maxval_token));
- sscanf (maxval_token, "%lu", &ul_maxval);
- maxval = (png_uint_32) ul_maxval;
- if (maxval <= 1)
- alpha_depth = 1;
- else if (maxval <= 3)
- alpha_depth = 2;
- else if (maxval <= 15)
- alpha_depth = 4;
- else if (maxval <= 255)
- alpha_depth = 8;
- else if (maxval <= 65535U)
- alpha_depth = 16;
- else /* maxval > 65535U */
- return FALSE;
- if (alpha_depth != bit_depth)
- return FALSE;
- }
- else
- {
- return FALSE;
- }
- } /* end if alpha */
-
- /* calculate the number of channels and store alpha-presence */
- if (color_type == PNG_COLOR_TYPE_GRAY)
- channels = 1;
- else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- channels = 2;
- else if (color_type == PNG_COLOR_TYPE_RGB)
- channels = 3;
- else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- channels = 4;
-#if 0
- else
- channels = 0; /* cannot happen */
-#endif
-
- alpha_present = (channels - 1) % 2;
-
-#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
- if (packed_bitmap)
- {
- /* row data is as many bytes as can fit width x channels x bit_depth */
- row_bytes = (width * channels * bit_depth + 7) / 8;
- }
- else
-#endif
- {
- /* row_bytes is the width x number of channels x (bit-depth / 8) */
- row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
- }
-
- if ((row_bytes == 0) ||
- ((size_t) height > (size_t) (-1) / (size_t) row_bytes))
- {
- /* too big */
- return FALSE;
- }
- if ((png_pixels = (png_byte *)
- malloc ((size_t) row_bytes * (size_t) height)) == NULL)
- {
- /* out of memory */
- return FALSE;
- }
-
- /* read data from PNM file */
- pix_ptr = png_pixels;
-
- for (row = 0; row < (int) height; row++)
- {
-#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
- if (packed_bitmap)
- {
- for (i = 0; i < (int) row_bytes; i++)
- {
- /* png supports this format natively so no conversion is needed */
- *pix_ptr++ = get_data (pnm_file, 8);
- }
- }
- else
-#endif
- {
- for (col = 0; col < (int) width; col++)
- {
- for (i = 0; i < (channels - alpha_present); i++)
- {
- if (raw)
- {
- *pix_ptr++ = get_data (pnm_file, bit_depth);
- }
- else
- {
- if (bit_depth <= 8)
- {
- *pix_ptr++ = get_value (pnm_file, bit_depth);
- }
- else
- {
- tmp16 = get_value (pnm_file, bit_depth);
- *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
- pix_ptr++;
- *pix_ptr = (png_byte) (tmp16 & 0xFF);
- pix_ptr++;
- }
- }
- }
-
- if (alpha) /* read alpha-channel from pgm file */
- {
- if (alpha_raw)
- {
- *pix_ptr++ = get_data (alpha_file, alpha_depth);
- }
- else
- {
- if (alpha_depth <= 8)
- {
- *pix_ptr++ = get_value (alpha_file, bit_depth);
- }
- else
- {
- tmp16 = get_value (alpha_file, bit_depth);
- *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
- *pix_ptr++ = (png_byte) (tmp16 & 0xFF);
- }
- }
- } /* end if alpha */
- } /* end if packed_bitmap */
- } /* end for col */
- } /* end for row */
-
- /* prepare the standard PNG structures */
- png_ptr = png_create_write_struct (png_get_libpng_ver(NULL),
- NULL, NULL, NULL);
- if (!png_ptr)
- {
- free (png_pixels);
- return FALSE;
- }
- info_ptr = png_create_info_struct (png_ptr);
- if (!info_ptr)
- {
- png_destroy_write_struct (&png_ptr, NULL);
- free (png_pixels);
- return FALSE;
- }
-
-#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
- if (packed_bitmap == TRUE)
- {
- png_set_packing (png_ptr);
- png_set_invert_mono (png_ptr);
- }
-#endif
-
- if (setjmp (png_jmpbuf (png_ptr)))
- {
- png_destroy_write_struct (&png_ptr, &info_ptr);
- free (png_pixels);
- return FALSE;
- }
-
- /* initialize the png structure */
- png_init_io (png_ptr, png_file);
-
- /* we're going to write more or less the same PNG as the input file */
- png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,
- (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
- /* write the file header information */
- png_write_info (png_ptr, info_ptr);
-
- /* if needed we will allocate memory for an new array of row-pointers */
- if (row_pointers == NULL)
- {
- if ((row_pointers = (png_byte **)
- malloc (height * sizeof (png_byte *))) == NULL)
- {
- png_destroy_write_struct (&png_ptr, &info_ptr);
- free (png_pixels);
- return FALSE;
- }
- }
-
- /* set the individual row_pointers to point at the correct offsets */
- for (i = 0; i < (int) height; i++)
- row_pointers[i] = png_pixels + i * row_bytes;
-
- /* write out the entire image data in one call */
- png_write_image (png_ptr, row_pointers);
-
- /* write the additional chunks to the PNG file (not really needed) */
- png_write_end (png_ptr, info_ptr);
-
- /* clean up after the write, and free any memory allocated */
- png_destroy_write_struct (&png_ptr, &info_ptr);
-
- if (row_pointers != NULL)
- free (row_pointers);
- if (png_pixels != NULL)
- free (png_pixels);
-
- return TRUE;
-} /* end of pnm2png */
-
-/*
- * get_token - gets the first string after whitespace
- */
-
-void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size)
-{
- size_t i = 0;
- int ret;
-
- /* remove white-space and comment lines */
- do
- {
- ret = fgetc (pnm_file);
- if (ret == '#')
- {
- /* the rest of this line is a comment */
- do
- {
- ret = fgetc (pnm_file);
- }
- while ((ret != '\n') && (ret != '\r') && (ret != EOF));
- }
- if (ret == EOF) break;
- token_buf[i] = (char) ret;
- }
- while ((ret == '\n') || (ret == '\r') || (ret == ' '));
-
- /* read string */
- do
- {
- ret = fgetc (pnm_file);
- if (ret == EOF) break;
- if (++i == token_buf_size - 1) break;
- token_buf[i] = (char) ret;
- }
- while ((ret != '\n') && (ret != '\r') && (ret != ' '));
-
- token_buf[i] = '\0';
-
- return;
-}
-
-/*
- * get_data - takes first byte and converts into next pixel value,
- * taking as much bits as defined by bit-depth and
- * using the bit-depth to fill up a byte (0Ah -> AAh)
- */
-
-png_uint_32 get_data (FILE *pnm_file, int depth)
-{
- static int bits_left = 0;
- static int old_value = 0;
- static int mask = 0;
- int i;
- png_uint_32 ret_value;
-
- if (mask == 0)
- for (i = 0; i < depth; i++)
- mask = (mask >> 1) | 0x80;
-
- if (bits_left <= 0)
- {
- old_value = fgetc (pnm_file);
- bits_left = 8;
- }
-
- ret_value = old_value & mask;
- for (i = 1; i < (8 / depth); i++)
- ret_value = ret_value || (ret_value >> depth);
-
- old_value = (old_value << depth) & 0xFF;
- bits_left -= depth;
-
- return ret_value;
-}
-
-/*
- * get_value - takes first (numeric) string and converts into number,
- * using the bit-depth to fill up a byte (0Ah -> AAh)
- */
-
-png_uint_32 get_value (FILE *pnm_file, int depth)
-{
- static png_uint_32 mask = 0;
- char token[16];
- unsigned long ul_ret_value;
- png_uint_32 ret_value;
- int i = 0;
-
- if (mask == 0)
- for (i = 0; i < depth; i++)
- mask = (mask << 1) | 0x01;
-
- get_token (pnm_file, token, sizeof (token));
- sscanf (token, "%lu", &ul_ret_value);
- ret_value = (png_uint_32) ul_ret_value;
-
- ret_value &= mask;
-
- if (depth < 8)
- for (i = 0; i < (8 / depth); i++)
- ret_value = (ret_value << depth) || ret_value;
-
- return ret_value;
-}
-
-/* end of source */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.sh b/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.sh
deleted file mode 100755
index 2ad17a608c9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-# -- grayscale
-./pnm2png basn0g01.pgm basn0g01.png
-./pnm2png basn0g02.pgm basn0g02.png
-./pnm2png basn0g04.pgm basn0g04.png
-./pnm2png basn0g08.pgm basn0g08.png
-./pnm2png basn0g16.pgm basn0g16.png
-# -- full-color
-./pnm2png basn2c08.ppm basn2c08.png
-./pnm2png basn2c16.ppm basn2c16.png
-# -- paletted
-./pnm2png basn3p01.ppm basn3p01.png
-./pnm2png basn3p02.ppm basn3p02.png
-./pnm2png basn3p04.ppm basn3p04.png
-./pnm2png basn3p08.ppm basn3p08.png
-# -- gray with alpha-channel
-./pnm2png -alpha basn6a08.pgm basn4a08.pgm basn4a08.png
-./pnm2png -alpha basn6a16.pgm basn4a16.pgm basn4a16.png
-# -- color with alpha-channel
-./pnm2png -alpha basn6a08.pgm basn6a08.ppm basn6a08.png
-./pnm2png -alpha basn6a16.pgm basn6a16.ppm basn6a16.png
-# -- grayscale
-./pnm2png rawn0g01.pgm rawn0g01.png
-./pnm2png rawn0g02.pgm rawn0g02.png
-./pnm2png rawn0g04.pgm rawn0g04.png
-./pnm2png rawn0g08.pgm rawn0g08.png
-./pnm2png rawn0g16.pgm rawn0g16.png
-# -- full-color
-./pnm2png rawn2c08.ppm rawn2c08.png
-./pnm2png rawn2c16.ppm rawn2c16.png
-# -- paletted
-./pnm2png rawn3p01.ppm rawn3p01.png
-./pnm2png rawn3p02.ppm rawn3p02.png
-./pnm2png rawn3p04.ppm rawn3p04.png
-./pnm2png rawn3p08.ppm rawn3p08.png
-# -- gray with alpha-channel
-./pnm2png -alpha rawn6a08.pgm rawn4a08.pgm rawn4a08.png
-./pnm2png -alpha rawn6a16.pgm rawn4a16.pgm rawn4a16.png
-# -- color with alpha-channel
-./pnm2png -alpha rawn6a08.pgm rawn6a08.ppm rawn6a08.png
-./pnm2png -alpha rawn6a16.pgm rawn6a16.ppm rawn6a16.png
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/README b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/README
deleted file mode 100644
index d236b02e7c6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/README
+++ /dev/null
@@ -1,107 +0,0 @@
-
-pngsuite
---------
-Copyright (c) Willem van Schaik, 1999, 2011, 2012
-Two images (ftbbn0g01.png and ftbbn0g02.png) are by Glenn Randers-Pehrson, 2012
-
-Permission to use, copy, modify, and distribute these images for any
-purpose and without fee is hereby granted.
-
-The 15 "bas*.png" images are part of the much larger PngSuite test-set of
-images, available for developers of PNG supporting software. The
-complete set, available at http:/www.schaik.com/pngsuite/, contains
-a variety of images to test interlacing, gamma settings, ancillary
-chunks, etc.
-
-The "ft*.png" images are "free/libre" replacements for the transparent
-corresponding t*.png images in the PngSuite.
-
-The "i*.png" images are the same images, but interlaced.
-
-The images in this directory represent the basic PNG color-types:
-grayscale (1-16 bit deep), full color (8 or 16 bit), paletted
-(1-8 bit) and grayscale or color images with alpha channel. You
-can use them to test the proper functioning of PNG software.
-
- filename depth type
- ------------ ------ --------------
- basn0g01.png 1-bit grayscale
- basn0g02.png 2-bit grayscale
- basn0g04.png 4-bit grayscale
- basn0g08.png 8-bit grayscale
- basn0g16.png 16-bit grayscale
- basn2c08.png 8-bit truecolor
- basn2c16.png 16-bit truecolor
- basn3p01.png 1-bit paletted
- basn3p02.png 2-bit paletted
- basn3p04.png 4-bit paletted
- basn3p08.png 8-bit paletted
- basn4a08.png 8-bit gray with alpha
- basn4a16.png 16-bit gray with alpha
- basn6a08.png 8-bit RGBA
- basn6a16.png 16-bit RGBA
-
- ftbbn0g01.png 1-bit grayscale, black bKGD
- ftbbn0g02.png 2-bit grayscale, black bKGD
- ftbbn0g04.png 4-bit grayscale, black bKGD
- ftbbn2c16.png 16-bit truecolor, black bKGD
- ftbbn3p08.png 8-bit paletted, black bKGD
- ftbgn2c16.png 16-bit truecolor, gray bKGD
- ftbgn3p08.png 8-bit paletted, gray bKGD
- ftbrn2c08.png 8-bit truecolor, red bKGD
- ftbwn0g16.png 16-bit gray, white bKGD
- ftbwn3p08.png 8-bit paletted, white bKGD
- ftbyn3p08.png 8-bit paletted, yellow bKGD
- ftp0n0g08.png 8-bit grayscale, opaque
- ftp0n2c08.png 8-bit truecolor, opaque
- ftp0n3p08.png 8-bit paletted, opaque
- ftp1n3p08.png 8-bit paletted, no bKGD
-
-Here is the correct result of typing "pngtest -m bas*.png" in
-this directory:
-
-Testing basn0g01.png: PASS (524 zero samples)
- Filter 0 was used 32 times
-Testing basn0g02.png: PASS (448 zero samples)
- Filter 0 was used 32 times
-Testing basn0g04.png: PASS (520 zero samples)
- Filter 0 was used 32 times
-Testing basn0g08.png: PASS (3 zero samples)
- Filter 1 was used 9 times
- Filter 4 was used 23 times
-Testing basn0g16.png: PASS (1 zero samples)
- Filter 1 was used 1 times
- Filter 2 was used 31 times
-Testing basn2c08.png: PASS (6 zero samples)
- Filter 1 was used 5 times
- Filter 4 was used 27 times
-Testing basn2c16.png: PASS (592 zero samples)
- Filter 1 was used 1 times
- Filter 4 was used 31 times
-Testing basn3p01.png: PASS (512 zero samples)
- Filter 0 was used 32 times
-Testing basn3p02.png: PASS (448 zero samples)
- Filter 0 was used 32 times
-Testing basn3p04.png: PASS (544 zero samples)
- Filter 0 was used 32 times
-Testing basn3p08.png: PASS (4 zero samples)
- Filter 0 was used 32 times
-Testing basn4a08.png: PASS (32 zero samples)
- Filter 1 was used 1 times
- Filter 4 was used 31 times
-Testing basn4a16.png: PASS (64 zero samples)
- Filter 0 was used 1 times
- Filter 1 was used 2 times
- Filter 2 was used 1 times
- Filter 4 was used 28 times
-Testing basn6a08.png: PASS (160 zero samples)
- Filter 1 was used 1 times
- Filter 4 was used 31 times
-Testing basn6a16.png: PASS (1072 zero samples)
- Filter 1 was used 4 times
- Filter 4 was used 28 times
-libpng passes test
-
-Willem van Schaik
-<willem at schaik.com>
-October 1999
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/bad_interlace_conversions.txt b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/bad_interlace_conversions.txt
deleted file mode 100644
index 8afbde79018..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/bad_interlace_conversions.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-basn0g01.png
-basn0g02.png
-basn0g04.png
-basn3p01.png
-basn3p02.png
-basn3p04.png
-ftbbn0g01.png
-ftbbn0g02.png
-ftbbn0g04.png
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g01.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g01.png
deleted file mode 100644
index e31e1c7a635..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g01.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g02.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g02.png
deleted file mode 100644
index 68809dd8fc0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g02.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g04.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g04.png
deleted file mode 100644
index 6fa089cb8a4..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g04.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g08.png
deleted file mode 100644
index bf522eef001..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g16.png
deleted file mode 100644
index 318ebcadf4f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn0g16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c08.png
deleted file mode 100644
index 21d2f91a868..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c16.png
deleted file mode 100644
index 1bd4a4d0e2c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn2c16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p01.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p01.png
deleted file mode 100644
index a21db597746..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p01.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p02.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p02.png
deleted file mode 100644
index 1d0ab6197cc..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p02.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p04.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p04.png
deleted file mode 100644
index 6dc6eac83f3..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p04.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p08.png
deleted file mode 100644
index 0e07f483c0e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a08.png
deleted file mode 100644
index 3bb0dd06b51..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a16.png
deleted file mode 100644
index 6dbee9fbdb9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn4a16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a08.png
deleted file mode 100644
index 61062308548..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a16.png
deleted file mode 100644
index a9bf3cb4612..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/basn6a16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g01.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g01.png
deleted file mode 100644
index ba746ffb2f5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g01.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g02.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g02.png
deleted file mode 100644
index 3d83bd6900b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g02.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g04.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g04.png
deleted file mode 100644
index 39a7050d27a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn0g04.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn2c16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn2c16.png
deleted file mode 100644
index dd3168e5c86..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn2c16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn3p08.png
deleted file mode 100644
index 0ede3574db0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbbn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn2c16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn2c16.png
deleted file mode 100644
index 85cec395c01..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn2c16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn3p08.png
deleted file mode 100644
index 8cf2e6fb6aa..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbgn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbrn2c08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbrn2c08.png
deleted file mode 100644
index 5cca0d62104..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbrn2c08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn0g16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn0g16.png
deleted file mode 100644
index 99bdeed2b3b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn0g16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn3p08.png
deleted file mode 100644
index eacab7a144c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbwn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbyn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbyn3p08.png
deleted file mode 100644
index 656db0989ad..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftbyn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n0g08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n0g08.png
deleted file mode 100644
index 333465fcdc9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n0g08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n2c08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n2c08.png
deleted file mode 100644
index fc6e42cb420..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n2c08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n3p08.png
deleted file mode 100644
index 69a69e58722..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp0n3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp1n3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp1n3p08.png
deleted file mode 100644
index a6c9f35a862..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ftp1n3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g08.png
deleted file mode 100644
index 90b5305e651..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g16.png
deleted file mode 100644
index c82f230eef5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn0g16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c08.png
deleted file mode 100644
index 05d4688853e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c16.png
deleted file mode 100644
index 399f1be5edd..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn2c16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn3p08.png
deleted file mode 100644
index 6df8370aaf8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a08.png
deleted file mode 100644
index bda8e3c6517..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a16.png
deleted file mode 100644
index 500f9128e6e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn4a16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a08.png
deleted file mode 100644
index 258f94050cc..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a16.png
deleted file mode 100644
index e4de69fef1d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/ibasn6a16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn2c16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn2c16.png
deleted file mode 100644
index 64a9cdf2f7f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn2c16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn3p08.png
deleted file mode 100644
index 47d6eeb3c0f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbbn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn2c16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn2c16.png
deleted file mode 100644
index 64a9cdf2f7f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn2c16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn3p08.png
deleted file mode 100644
index 47d6eeb3c0f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbgn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbrn2c08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbrn2c08.png
deleted file mode 100644
index 08ebbae2c8c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbrn2c08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn0g16.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn0g16.png
deleted file mode 100644
index 4b7537e3050..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn0g16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn3p08.png
deleted file mode 100644
index 47d6eeb3c0f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbwn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbyn3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbyn3p08.png
deleted file mode 100644
index 47d6eeb3c0f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftbyn3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n0g08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n0g08.png
deleted file mode 100644
index aa826b86308..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n0g08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n2c08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n2c08.png
deleted file mode 100644
index b12bd0a7fa9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n2c08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n3p08.png
deleted file mode 100644
index 37aa0cb0d92..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp0n3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp1n3p08.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp1n3p08.png
deleted file mode 100644
index 47d6eeb3c0f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/iftp1n3p08.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/README b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/README
deleted file mode 100644
index f171eee01aa..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/README
+++ /dev/null
@@ -1,2 +0,0 @@
-
-These images fail the "pngimage-quick" and "pngimage-full" tests.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g01.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g01.png
deleted file mode 100644
index 828fa760369..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g01.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g02.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g02.png
deleted file mode 100644
index 7fc17e3a1ee..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g02.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g04.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g04.png
deleted file mode 100644
index 1beade28f57..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn0g04.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p01.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p01.png
deleted file mode 100644
index f91e7233e70..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p01.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p02.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p02.png
deleted file mode 100644
index 0f9ce76e6b3..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p02.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p04.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p04.png
deleted file mode 100644
index b2ca720747a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/ibasn3p04.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g01.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g01.png
deleted file mode 100644
index 6eb27d10e8d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g01.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g02.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g02.png
deleted file mode 100644
index 46ba4977792..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g02.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g04.png b/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g04.png
deleted file mode 100644
index e9db0ad50d0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/pngsuite/interlaced/iftbbn0g04.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/README b/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/README
deleted file mode 100644
index 4970a52c692..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/README
+++ /dev/null
@@ -1,81 +0,0 @@
-OPERATING SYSTEM SPECIFIC POWERPC DETECTION
---------------------------------------------
-
-Detection of the ability to execute POWERPC on processor requires
-operating system support. (The information is not available in user mode.)
-
-Currently only this feature is supported only for linux platform.
-
-HOW TO USE THIS
----------------
-
-This directory contains C code fragments that can be included in powerpc/powerpc_init.c
-by setting the macro PNG_POWERPC_VSX_FILE to the file name in "" or <> at build
-time. This setting is not recorded in pnglibconf.h and can be changed simply by
-rebuilding arm/arm_init.o with the required macro definition.
-
-For any of this code to be used the POWERPC code must be enabled and run time
-checks must be supported. I.e.:
-
-#if PNG_POWERPC_VSX_OPT > 0
-#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED
-
-This is done in a 'configure' build by passing configure the argument:
-
- --enable-powerpc-vsx=check
-
-FILE FORMAT
------------
-
-Each file documents its testing status as of the last time it was tested (which
-may have been a long time ago):
-
-STATUS: one of:
- SUPPORTED: This indicates that the file is included in the regularly
- performed test builds and bugs are fixed when discovered.
- COMPILED: This indicates that the code did compile at least once. See the
- more detailed description for the extent to which the result was
- successful.
- TESTED: This means the code was fully compiled into the libpng test programs
- and these were run at least once.
-
-BUG REPORTS: an email address to which to send reports of problems
-
-The file is a fragment of C code. It should not define any 'extern' symbols;
-everything should be static. It must define the function:
-
-static int png_have_vsx(png_structp png_ptr);
-
-That function must return 1 if POWERPC_VSX instructions are supported, 0 if not.
-It must not execute png_error unless it detects a bug. A png_error will prevent
-the reading of the PNG and in the future, writing too.
-
-BUG REPORTS
------------
-
-If you mail a bug report for any file that is not SUPPORTED there may only be
-limited response. Consider fixing it and sending a patch to fix the problem -
-this is more likely to result in action.
-
-CONTRIBUTIONS
--------------
-
-You may send contributions of new implementations to
-png-mng-implement@sourceforge.net. Please write code in strict C90 C where
-possible. Obviously OS dependencies are to be expected. If you submit code you
-must have the authors permission and it must have a license that is acceptable
-to the current maintainer; in particular that license must permit modification
-and redistribution.
-
-Please try to make the contribution a single file and give the file a clear and
-unambiguous name that identifies the target OS. If multiple files really are
-required put them all in a sub-directory.
-
-You must also be prepared to handle bug reports from users of the code, either
-by joining the png-mng-implement mailing list or by providing an email for the
-"BUG REPORTS" entry or both. Please make sure that the header of the file
-contains the STATUS and BUG REPORTS fields as above.
-
-Please list the OS requirements as precisely as possible. Ideally you should
-also list the environment in which the code has been tested and certainly list
-any environments where you suspect it might not work.
diff --git a/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux.c b/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux.c
deleted file mode 100644
index 32ed9d7491d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* contrib/powerpc-vsx/linux.c
- *
- * Copyright (c) 2017 Glenn Randers-Pehrson
- * Written by Vadim Barkov, 2017.
- * Last changed in libpng 1.6.29 [March 16, 2017]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * STATUS: TESTED
- * BUG REPORTS: png-mng-implement@sourceforge.net
- *
- * png_have_vsx implemented for Linux by reading the widely available
- * pseudo-file /proc/cpuinfo.
- *
- * This code is strict ANSI-C and is probably moderately portable; it does
- * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "png.h"
-
-#ifndef MAXLINE
-# define MAXLINE 1024
-#endif
-
-static int
-png_have_vsx(png_structp png_ptr)
-{
- FILE *f;
-
- const char *string = "altivec supported";
- char input[MAXLINE];
- char *token = NULL;
-
- PNG_UNUSED(png_ptr)
-
- f = fopen("/proc/cpuinfo", "r");
- if (f != NULL)
- {
- memset(input,0,MAXLINE);
- while(fgets(input,MAXLINE,f) != NULL)
- {
- token = strstr(input,string);
- if(token != NULL)
- return 1;
- }
- }
-#ifdef PNG_WARNINGS_SUPPORTED
- else
- png_warning(png_ptr, "/proc/cpuinfo open failed");
-#endif
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux_aux.c b/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux_aux.c
deleted file mode 100644
index 7828acafb84..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/powerpc-vsx/linux_aux.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* contrib/powerpc-vsx/linux_aux.c
- *
- * Copyright (c) 2017 Glenn Randers-Pehrson
- * Written by Vadim Barkov, 2017.
- * Last changed in libpng 1.6.29 [March 16, 2017]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * STATUS: TESTED
- * BUG REPORTS: png-mng-implement@sourceforge.net
- *
- * png_have_vsx implemented for Linux by using the auxiliary vector mechanism.
- *
- * This code is strict ANSI-C and is probably moderately portable; it does
- * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
- */
-
-#include "sys/auxv.h"
-#include "png.h"
-
-static int
-png_have_vsx(png_structp png_ptr)
-{
- unsigned long auxv = getauxval(AT_HWCAP);
-
- PNG_UNUSED(png_ptr)
-
- if(auxv & (PPC_FEATURE_HAS_ALTIVEC|PPC_FEATURE_HAS_VSX))
- return 1;
- else
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/bad_iCCP.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/bad_iCCP.png
deleted file mode 100644
index 0b7b863795a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/bad_iCCP.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badadler.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badadler.png
deleted file mode 100644
index 2bcbcc926ab..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badadler.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badcrc.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badcrc.png
deleted file mode 100644
index 45d02680454..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/badcrc.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/empty_ancillary_chunks.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/empty_ancillary_chunks.png
deleted file mode 100644
index d76477c6a86..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/empty_ancillary_chunks.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_IDAT.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_IDAT.png
deleted file mode 100644
index efee66cf369..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_IDAT.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_bKGD_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_bKGD_chunk.png
deleted file mode 100644
index fd571fd2c93..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_bKGD_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_cHRM_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_cHRM_chunk.png
deleted file mode 100644
index 698e7c46dd7..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_cHRM_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_eXIf_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_eXIf_chunk.png
deleted file mode 100644
index 7d416019668..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_eXIf_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_gAMA_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_gAMA_chunk.png
deleted file mode 100644
index b089c185971..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_gAMA_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_hIST_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_hIST_chunk.png
deleted file mode 100644
index 6d6fcb53343..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_hIST_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iCCP_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iCCP_chunk.png
deleted file mode 100644
index fbcb7615395..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iCCP_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iTXt_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iTXt_chunk.png
deleted file mode 100644
index 098262017ef..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_iTXt_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png
deleted file mode 100644
index 0cb106f4a2b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png
deleted file mode 100644
index 85252b7dc54..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pCAL_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pCAL_chunk.png
deleted file mode 100644
index bc12a8f2473..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pCAL_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pHYs_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pHYs_chunk.png
deleted file mode 100644
index 343b977e9df..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_pHYs_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sCAL_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sCAL_chunk.png
deleted file mode 100644
index 61f2f824d1c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sCAL_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sPLT_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sPLT_chunk.png
deleted file mode 100644
index 75d383a2e47..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sPLT_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sRGB_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sRGB_chunk.png
deleted file mode 100644
index bc1db336308..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sRGB_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sTER_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sTER_chunk.png
deleted file mode 100644
index 39219fed73f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_sTER_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tEXt_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tEXt_chunk.png
deleted file mode 100644
index 947fc373e41..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tEXt_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tIME_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tIME_chunk.png
deleted file mode 100644
index 16452fba26e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_tIME_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_zTXt_chunk.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_zTXt_chunk.png
deleted file mode 100644
index 52f09530894..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/crashers/huge_zTXt_chunk.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8-tRNS.png
deleted file mode 100644
index 0fc6cb7dba1..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8.png
deleted file mode 100644
index 5db4d7915c6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear-tRNS.png
deleted file mode 100644
index 5beb9d1df20..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear.png
deleted file mode 100644
index 36a89a5abb6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB-tRNS.png
deleted file mode 100644
index 80cec4b5eda..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB.png
deleted file mode 100644
index 484fd18c4f6..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-tRNS.png
deleted file mode 100644
index a988db9686e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1.png
deleted file mode 100644
index 71e37a33638..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-1.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8-tRNS.png
deleted file mode 100644
index 06cc0c138e8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8.png
deleted file mode 100644
index 06cc0c138e8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear-tRNS.png
deleted file mode 100644
index beb4e96e25f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear.png
deleted file mode 100644
index beb4e96e25f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB-tRNS.png
deleted file mode 100644
index 315db86a6ad..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB.png
deleted file mode 100644
index 315db86a6ad..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-tRNS.png
deleted file mode 100644
index 4826d61eb7f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16.png
deleted file mode 100644
index 4826d61eb7f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8-tRNS.png
deleted file mode 100644
index a1c6854c96c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8.png
deleted file mode 100644
index 4cc811cdf7e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear-tRNS.png
deleted file mode 100644
index 3c29ec6d97a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear.png
deleted file mode 100644
index 6ca6fb74dd8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB-tRNS.png
deleted file mode 100644
index b418c8fbb60..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB.png
deleted file mode 100644
index a6bde60afe4..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-tRNS.png
deleted file mode 100644
index 8e04cb5020c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2.png
deleted file mode 100644
index 9d85a2ace35..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-2.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8-tRNS.png
deleted file mode 100644
index 402d699fbc5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8.png
deleted file mode 100644
index bc8da98761c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear-tRNS.png
deleted file mode 100644
index 45c063d8542..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear.png
deleted file mode 100644
index 0bd068d73fe..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB-tRNS.png
deleted file mode 100644
index be8521049c4..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB.png
deleted file mode 100644
index 38a79228d93..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-tRNS.png
deleted file mode 100644
index 14c4f1fb3aa..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4.png
deleted file mode 100644
index 16bcada820e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-4.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8-tRNS.png
deleted file mode 100644
index 2b3892458a4..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8.png
deleted file mode 100644
index 4bba74cfa63..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear-tRNS.png
deleted file mode 100644
index a801abdaaa7..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear.png
deleted file mode 100644
index 91be367ee5c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB-tRNS.png
deleted file mode 100644
index f54f23d6bc8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB.png
deleted file mode 100644
index 2ae6377ff95..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-tRNS.png
deleted file mode 100644
index 842245f1d9f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8.png
deleted file mode 100644
index 23af27e141a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-1.8.png
deleted file mode 100644
index e0d36b7f09c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-linear.png
deleted file mode 100644
index 26aa32cee15..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-sRGB.png
deleted file mode 100644
index f1e811ba342..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16.png
deleted file mode 100644
index 689879737fc..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-1.8.png
deleted file mode 100644
index 68883a52d5c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-linear.png
deleted file mode 100644
index cdc07031d7f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-sRGB.png
deleted file mode 100644
index 7c37c88836f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8.png
deleted file mode 100644
index eb0a9249981..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/gray-alpha-8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh b/Build/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh
deleted file mode 100755
index eb1c15fc951..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/sh
-#
-# Make a set of test PNG files, MAKEPNG is the name of the makepng executable
-# built from contrib/libtests/makepng.c
-
-# Copyright (c) 2015 John Cunningham Bowler
-
-# Last changed in libpng 1.6.20 [December 3, 2015]
-
-# This code is released under the libpng license.
-# For conditions of distribution and use, see the disclaimer
-# and license in png.h
-
-# The arguments say whether to build all the files or whether just to build the
-# ones that extend the code-coverage of libpng from the existing test files in
-# contrib/pngsuite.
-test -n "$MAKEPNG" || MAKEPNG=./makepng
-opts=
-
-mp(){
- ${MAKEPNG} $opts $1 "$3" "$4" "$3-$4$2.png"
-}
-
-mpg(){
- if test "$1" = "none"
- then
- mp "" "" "$2" "$3"
- else
- mp "--$1" "-$1" "$2" "$3"
- fi
-}
-
-mptrans(){
- if test "$1" = "none"
- then
- mp "--tRNS" "-tRNS" "$2" "$3"
- else
- mp "--tRNS --$1" "-$1-tRNS" "$2" "$3"
- fi
-}
-
-case "$1" in
- --small)
- opts="--small";;&
-
- --all|--small)
- for g in none sRGB linear 1.8
- do
- for c in gray palette
- do
- for b in 1 2 4
- do
- mpg "$g" "$c" "$b"
- mptrans "$g" "$c" "$b"
- done
- done
-
- mpg "$g" palette 8
- mptrans "$g" palette 8
-
- for b in 8 16
- do
- for c in gray gray-alpha rgb rgb-alpha
- do
- mpg "$g" "$c" "$b"
- done
- for c in gray rgb
- do
- mptrans "$g" "$c" "$b"
- done
- done
- done;;
-
- --coverage)
- # Comments below indicate cases known to be required and not duplicated
- # in other (required) cases; the aim is to get a minimal set that gives
- # the maximum code coverage.
- mpg none gray-alpha 8 # required: code coverage, sRGB opaque component
- mpg none palette 8 # required: basic palette read
- mpg 1.8 gray 2 # required: tests gamma threshold code
- mpg 1.8 palette 2 # required: code coverage
- mpg 1.8 palette 4 # required: code coverage
- mpg 1.8 palette 8 # error limits only
- mpg linear palette 8 # error limits only
- mpg linear rgb-alpha 16 # error limits only
- mpg sRGB palette 1 # required: code coverage
- mpg sRGB rgb-alpha 16 # required: code coverage: pngread.c:2422 untested
- :;;
-
- *)
- echo "$0 $1: unknown argument, usage:" >&2
- echo " $0 [--all|--coverage|--small]" >&2
- exit 1
-esac
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8-tRNS.png
deleted file mode 100644
index 7bf60410d52..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8.png
deleted file mode 100644
index 73965b724e4..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear-tRNS.png
deleted file mode 100644
index 9b0133dc9f5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear.png
deleted file mode 100644
index bf232fd33cf..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB-tRNS.png
deleted file mode 100644
index 1c6f262b336..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB.png
deleted file mode 100644
index fbadc097fff..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-tRNS.png
deleted file mode 100644
index 8f1642b7b01..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1.png
deleted file mode 100644
index a27d1362a2b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-1.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8-tRNS.png
deleted file mode 100644
index 9d2ab16564a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8.png
deleted file mode 100644
index cdcf28329b9..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear-tRNS.png
deleted file mode 100644
index d346d40071c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear.png
deleted file mode 100644
index 5c2f6d335df..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB-tRNS.png
deleted file mode 100644
index e5a491a7139..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB.png
deleted file mode 100644
index a3bf9a2f3b0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-tRNS.png
deleted file mode 100644
index c34a6986d00..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2.png
deleted file mode 100644
index eaf4536e09b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-2.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8-tRNS.png
deleted file mode 100644
index 20cb465cece..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8.png
deleted file mode 100644
index c2318ff82ed..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear-tRNS.png
deleted file mode 100644
index 4d96a472413..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear.png
deleted file mode 100644
index dfc5a868ee2..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB-tRNS.png
deleted file mode 100644
index 92d23e7ddab..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB.png
deleted file mode 100644
index 26ea9e5ab14..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-tRNS.png
deleted file mode 100644
index 429f6b95394..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4.png
deleted file mode 100644
index 82f3489940e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-4.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8-tRNS.png
deleted file mode 100644
index c10bb569739..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8.png
deleted file mode 100644
index cc09ee60f1e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear-tRNS.png
deleted file mode 100644
index 27f5a3336cf..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear.png
deleted file mode 100644
index 40d413cd660..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB-tRNS.png
deleted file mode 100644
index b8863ec2b8f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB.png
deleted file mode 100644
index 90f89120431..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-tRNS.png
deleted file mode 100644
index 9660e67765d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8.png
deleted file mode 100644
index 2502d305b57..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/palette-8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8-tRNS.png
deleted file mode 100644
index 03251b12ef0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8.png
deleted file mode 100644
index 03251b12ef0..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear-tRNS.png
deleted file mode 100644
index 3dfa6a6ad04..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear.png
deleted file mode 100644
index 3dfa6a6ad04..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB-tRNS.png
deleted file mode 100644
index 2cf2209e01d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB.png
deleted file mode 100644
index 2cf2209e01d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-tRNS.png
deleted file mode 100644
index 28643528d6b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16.png
deleted file mode 100644
index 28643528d6b..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8-tRNS.png
deleted file mode 100644
index afff9df2266..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8.png
deleted file mode 100644
index d4bb12afa11..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear-tRNS.png
deleted file mode 100644
index 5a2ed9f009a..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear.png
deleted file mode 100644
index 7c42b084083..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB-tRNS.png
deleted file mode 100644
index f8b4ecbdc69..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB.png
deleted file mode 100644
index 4acae649d38..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-tRNS.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-tRNS.png
deleted file mode 100644
index cdb1642ebad..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8-tRNS.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8.png
deleted file mode 100644
index e69c71bfd57..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-1.8.png
deleted file mode 100644
index ad65d150e23..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-linear.png
deleted file mode 100644
index 1f399003173..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-sRGB.png
deleted file mode 100644
index d9cea633a5e..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16.png
deleted file mode 100644
index 59262397eb5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-16.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-1.8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-1.8.png
deleted file mode 100644
index f4d08ec0471..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-1.8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-linear.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-linear.png
deleted file mode 100644
index b4f8bc82941..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-linear.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-sRGB.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-sRGB.png
deleted file mode 100644
index f06e7f837cb..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8-sRGB.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8.png
deleted file mode 100644
index e15d4913f2d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/rgb-alpha-8.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/README.txt b/Build/source/libs/libpng/libpng-src/contrib/tools/README.txt
deleted file mode 100644
index f53be6df9ba..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/README.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-This directory (contrib/tools) contains tools used by the authors of libpng.
-
-Code and data placed in this directory is not required to build libpng,
-however the code in this directory has been used to generate data or code in
-the body of the libpng source. The source code identifies where this has
-been done. Code in this directory may not compile on all operating systems
-that libpng supports.
-
-NO COPYRIGHT RIGHTS ARE CLAIMED TO ANY OF THE FILES IN THIS DIRECTORY.
-
-To the extent possible under law, the authors have waived all copyright and
-related or neighboring rights to this work. This work is published from:
-United States.
-
-The files may be used freely in any way.
-
-The source code and comments in this directory are the original work of the
-people named below. No other person or organization has made contributions to
-the work in this directory.
-
-ORIGINAL AUTHORS
- The following people have contributed to the code in this directory. None
- of the people below claim any rights with regard to the contents of this
- directory.
-
- John Bowler <jbowler at acm.org>
- Glenn Randers-Pehrson <glennrp at users.sourceforge.net>
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/checksum-icc.c b/Build/source/libs/libpng/libpng-src/contrib/tools/checksum-icc.c
deleted file mode 100644
index 581e7088a62..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/checksum-icc.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* checksum-icc.c
- *
- * Copyright (c) 2013 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Generate crc32 and adler32 checksums of the given input files, used to
- * generate check-codes for use when matching ICC profiles within libpng.
- */
-#include <stdio.h>
-
-#include <zlib.h>
-
-static int
-read_one_file(FILE *ip, const char *name)
-{
- uLong length = 0;
- uLong a32 = adler32(0, NULL, 0);
- uLong c32 = crc32(0, NULL, 0);
- Byte header[132];
-
- for (;;)
- {
- int ch = getc(ip);
- Byte b;
-
- if (ch == EOF) break;
-
- b = (Byte)ch;
-
- if (length < sizeof header)
- header[length] = b;
-
- ++length;
- a32 = adler32(a32, &b, 1);
- c32 = crc32(c32, &b, 1);
- }
-
- if (ferror(ip))
- return 0;
-
- /* Success */
- printf("PNG_ICC_CHECKSUM(0x%8.8lx, 0x%8.8lx,\n PNG_MD5("
- "0x%2.2x%2.2x%2.2x%2.2x, 0x%2.2x%2.2x%2.2x%2.2x, 0x%2.2x%2.2x%2.2x%2.2x,"
- " 0x%2.2x%2.2x%2.2x%2.2x), %d,\n"
- " \"%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d\", %lu, \"%s\")\n",
- (unsigned long)a32, (unsigned long)c32,
- header[84], header[85], header[86], header[87],
- header[88], header[89], header[90], header[91],
- header[92], header[93], header[94], header[95],
- header[96], header[97], header[98], header[99],
-# define u16(x) (header[x] * 256 + header[x+1])
-# define u32(x) (u16(x) * 65536 + u16(x+2))
- u32(64), u16(24), u16(26), u16(28), u16(30), u16(32), u16(34),
- (unsigned long)length, name);
-
- return 1;
-}
-
-int main(int argc, char **argv)
-{
- int err = 0;
-
- printf("/* adler32, crc32, MD5[16], intent, date, length, file-name */\n");
-
- if (argc > 1)
- {
- int i;
-
- for (i=1; i<argc; ++i)
- {
- FILE *ip = fopen(argv[i], "rb");
-
- if (ip == NULL || !read_one_file(ip, argv[i]))
- {
- err = 1;
- perror(argv[i]);
- fprintf(stderr, "%s: read error\n", argv[i]);
- printf("/* ERROR: %s */\n", argv[i]);
- }
-
- (void)fclose(ip);
- }
- }
-
- else
- {
- if (!read_one_file(stdin, "-"))
- {
- err = 1;
- perror("stdin");
- fprintf(stderr, "stdin: read error\n");
- printf("/* ERROR: stdin */\n");
- }
- }
-
- return err;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/chkfmt b/Build/source/libs/libpng/libpng-src/contrib/tools/chkfmt
deleted file mode 100644
index 95181fde2ed..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/chkfmt
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/bin/sh
-
-# chkfmt
-#
-# COPYRIGHT: Written by John Cunningham Bowler, 2010.
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Check the format of the source files in the current directory - checks for a
-# line length of 80 characters max and no tab characters.
-#
-# Optionally arguments are files or directories to check.
-#
-# -v: output the long lines (makes fixing them easier)
-# -e: spawn an editor for each file that needs a change ($EDITOR must be
-# defined). When using -e the script MUST be run from an interactive
-# command line.
-verbose=
-edit=
-vers=
-test "$1" = "-v" && {
- shift
- verbose=yes
-}
-test "$1" = "-e" && {
- shift
- if test -n "$EDITOR"
- then
- edit=yes
-
- # Copy the standard streams for the editor
- exec 3>&0 4>&1 5>&2
- else
- echo "chkfmt -e: EDITOR must be defined" >&2
- exit 1
- fi
-}
-
-# Function to edit a single file - if the file isn't changed ask the user
-# whether or not to continue. This stuff only works if the script is run from
-# the command line (otherwise, don't specify -e or you will be sorry).
-doed(){
- cp "$file" "$file".orig
- "$EDITOR" "$file" 0>&3 1>&4 2>&5 3>&- 4>&- 5>&- || exit 1
- if cmp -s "$file".orig "$file"
- then
- rm "$file".orig
- echo -n "$file: file not changed, type anything to continue: " >&5
- read ans 0>&3
- test -n "$ans" || return 1
- fi
- return 0
-}
-
-# In beta versions the version string which appears in files can be a little
-# long and cause spuriously overlong lines. To avoid this substitute the version
-# string with a 'standard' version a.b.cc before checking for long lines.
-if test -r png.h
-then
- vers="`sed -n -e \
- 's/^#define PNG_LIBPNG_VER_STRING .\([0-9]\.[0-9]\.[0-9][0-9a-z]*\).$/\1/p' \
- png.h`"
- echo "chkfmt: checking version $vers"
-fi
-if test -z "$vers"
-then
- echo "chkfmt: png.h not found, ignoring version number" >&2
-fi
-
-test -n "$1" || set -- .
-find "$@" \( -type d \( -name '.git' -o -name '.libs' -o -name 'projects' \) \
- -prune \) -o \( -type f \
- ! -name '*.[oa]' ! -name '*.l[oa]' ! -name '*.png' ! -name '*.out' \
- ! -name '*.jpg' ! -name '*.patch' ! -name '*.obj' ! -name '*.exe' \
- ! -name '*.com' ! -name '*.tar.*' ! -name '*.zip' ! -name '*.ico' \
- ! -name '*.res' ! -name '*.rc' ! -name '*.mms' ! -name '*.rej' \
- ! -name '*.dsp' ! -name '*.orig' ! -name '*.dfn' ! -name '*.swp' \
- ! -name '~*' ! -name '*.3' \
- ! -name 'missing' ! -name 'mkinstalldirs' ! -name 'depcomp' \
- ! -name 'aclocal.m4' ! -name 'install-sh' ! -name 'Makefile.in' \
- ! -name 'ltmain.sh' ! -name 'config*' -print \) | {
- st=0
- while read file
- do
- case "$file" in
- *.mak|*[Mm]akefile.*|*[Mm]akefile)
- # Makefiles require tabs, dependency lines can be this long.
- check_tabs=
- line_length=100;;
- *.awk)
- # Includes literal tabs
- check_tabs=
- # The following is arbitrary
- line_length=132;;
- *contrib/*/*.[ch])
- check_tabs=yes
- line_length=96;;
- *)
- check_tabs=yes
- line_length=80;;
- esac
-
- # Note that vers can only contain 0-9, . and a-z
- if test -n "$vers"
- then
- sed -e "s/$vers/a.b.cc/g" "$file" >"$file".$$
- else
- cp "$file" "$file".$$
- fi
- splt="`fold -$line_length "$file".$$ | diff -c "$file".$$ -`"
- rm "$file".$$
-
- if test -n "$splt"
- then
- echo "$file: lines too long"
- st=1
- if test -n "$EDITOR" -a -n "$edit"
- then
- doed "$file" || exit 1
- elif test -n "$verbose"
- then
- echo "$splt"
- fi
- fi
- if test -n "$check_tabs"
- then
- tab="`tr -c -d '\t' <"$file"`"
- if test -n "$tab"
- then
- echo "$file: file contains tab characters"
- st=1
- if test -n "$EDITOR" -a -n "$edit"
- then
- doed "$file" || exit 1
- elif test -n "$verbose"
- then
- echo "$splt"
- fi
- fi
- fi
- done
- exit $st
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/cvtcolor.c b/Build/source/libs/libpng/libpng-src/contrib/tools/cvtcolor.c
deleted file mode 100644
index e6793c7d596..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/cvtcolor.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*-
- * convert.c
- *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2013.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Convert 8-bit sRGB or 16-bit linear values to another format.
- */
-#define _ISOC99_SOURCE 1
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <stdio.h>
-
-#include <fenv.h>
-
-#include "sRGB.h"
-
-static void
-usage(const char *prog)
-{
- fprintf(stderr,
- "%s: usage: %s [-linear|-sRGB] [-gray|-color] component{1,4}\n",
- prog, prog);
- exit(1);
-}
-
-unsigned long
-component(const char *prog, const char *arg, int issRGB)
-{
- char *ep;
- unsigned long c = strtoul(arg, &ep, 0);
-
- if (ep <= arg || *ep || c > 65535 || (issRGB && c > 255))
- {
- fprintf(stderr, "%s: %s: invalid component value (%lu)\n", prog, arg, c);
- usage(prog);
- }
-
- return c;
-}
-
-int
-main(int argc, const char **argv)
-{
- const char *prog = *argv++;
- int to_linear = 0, to_gray = 0, to_color = 0;
- int channels = 0;
- double c[4];
-
- /* FE_TONEAREST is the IEEE754 round to nearest, preferring even, mode; i.e.
- * everything rounds to the nearest value except that '.5' rounds to the
- * nearest even value.
- */
- fesetround(FE_TONEAREST);
-
- c[3] = c[2] = c[1] = c[0] = 0;
-
- while (--argc > 0 && **argv == '-')
- {
- const char *arg = 1+*argv++;
-
- if (strcmp(arg, "sRGB") == 0)
- to_linear = 0;
-
- else if (strcmp(arg, "linear") == 0)
- to_linear = 1;
-
- else if (strcmp(arg, "gray") == 0)
- to_gray = 1, to_color = 0;
-
- else if (strcmp(arg, "color") == 0)
- to_gray = 0, to_color = 1;
-
- else
- usage(prog);
- }
-
- switch (argc)
- {
- default:
- usage(prog);
- break;
-
- case 4:
- c[3] = component(prog, argv[3], to_linear);
- ++channels;
- case 3:
- c[2] = component(prog, argv[2], to_linear);
- ++channels;
- case 2:
- c[1] = component(prog, argv[1], to_linear);
- ++channels;
- case 1:
- c[0] = component(prog, argv[0], to_linear);
- ++channels;
- break;
- }
-
- if (to_linear)
- {
- int i;
- int components = channels;
-
- if ((components & 1) == 0)
- --components;
-
- for (i=0; i<components; ++i) c[i] = linear_from_sRGB(c[i] / 255);
- if (components < channels)
- c[components] = c[components] / 255;
- }
-
- else
- {
- int i;
- for (i=0; i<4; ++i) c[i] /= 65535;
-
- if ((channels & 1) == 0)
- {
- double alpha = c[channels-1];
-
- if (alpha > 0)
- for (i=0; i<channels-1; ++i) c[i] /= alpha;
- else
- for (i=0; i<channels-1; ++i) c[i] = 1;
- }
- }
-
- if (to_gray)
- {
- if (channels < 3)
- {
- fprintf(stderr, "%s: too few channels (%d) for -gray\n",
- prog, channels);
- usage(prog);
- }
-
- c[0] = YfromRGB(c[0], c[1], c[2]);
- channels -= 2;
- }
-
- if (to_color)
- {
- if (channels > 2)
- {
- fprintf(stderr, "%s: too many channels (%d) for -color\n",
- prog, channels);
- usage(prog);
- }
-
- c[3] = c[1]; /* alpha, if present */
- c[2] = c[1] = c[0];
- }
-
- if (to_linear)
- {
- int i;
- if ((channels & 1) == 0)
- {
- double alpha = c[channels-1];
- for (i=0; i<channels-1; ++i) c[i] *= alpha;
- }
-
- for (i=0; i<channels; ++i) c[i] = nearbyint(c[i] * 65535);
- }
-
- else /* to sRGB */
- {
- int i = (channels+1)&~1;
- while (--i >= 0)
- c[i] = sRGB_from_linear(c[i]);
-
- for (i=0; i<channels; ++i) c[i] = nearbyint(c[i] * 255);
- }
-
- {
- int i;
- for (i=0; i<channels; ++i) printf(" %g", c[i]);
- }
- printf("\n");
-
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/genpng.c b/Build/source/libs/libpng/libpng-src/contrib/tools/genpng.c
deleted file mode 100644
index 0b3f9819645..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/genpng.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/*- genpng
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2015.
- * Revised by Glenn Randers-Pehrson, 2017, to add buffer-size check.
- * To the extent possible under law, the authors have waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Generate a PNG with an alpha channel, correctly.
- *
- * This is a test case generator; the resultant PNG files are only of interest
- * to those of us who care about whether the edges of circles are green, red,
- * or yellow.
- *
- * The program generates an RGB+Alpha PNG of a given size containing the given
- * shapes on a transparent background:
- *
- * genpng width height { shape }
- * shape ::= color width shape x1 y1 x2 y2
- *
- * 'color' is:
- *
- * black white red green yellow blue brown purple pink orange gray cyan
- *
- * The point is to have colors that are linguistically meaningful plus that old
- * bugbear of the department store dress murders, Cyan, the only color we argue
- * about.
- *
- * 'shape' is:
- *
- * circle: an ellipse
- * square: a rectangle
- * line: a straight line
- *
- * Each shape is followed by four numbers, these are two points in the output
- * coordinate space (as real numbers) which describe the circle, square, or
- * line. The shape is filled if it is preceded by 'filled' (not valid for
- * 'line') or is drawn with a line, in which case the width of the line must
- * precede the shape.
- *
- * The whole set of information can be repeated as many times as desired:
- *
- * shape ::= color width shape x1 y1 x2 y2
- *
- * color ::= black|white|red|green|yellow|blue
- * color ::= brown|purple|pink|orange|gray|cyan
- * width ::= filled
- * width ::= <number>
- * shape ::= circle|square|line
- * x1 ::= <number>
- * x2 ::= <number>
- * y1 ::= <number>
- * y2 ::= <number>
- *
- * The output PNG is generated by down-sampling a 4x supersampled image using
- * a bi-cubic filter. The bi-cubic has a 2 (output) pixel width, so an 8x8
- * array of super-sampled points contribute to each output pixel. The value of
- * a super-sampled point is found using an unfiltered, aliased, infinite
- * precision image: Each shape from the last to the first is checked to see if
- * the point is in the drawn area and, if it is, the color of the point is the
- * color of the shape and the alpha is 1, if not the previous shape is checked.
- *
- * This is an aliased algorithm because no filtering is done; a point is either
- * inside or outside each shape and 'close' points do not contribute to the
- * sample. The down-sampling is relied on to correct the error of not using
- * a filter.
- *
- * The line end-caps are 'flat'; they go through the points. The square line
- * joins are mitres; the outside of the lines are continued to the point of
- * intersection.
- */
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-
-/* Normally use <png.h> here to get the installed libpng, but this is done to
- * ensure the code picks up the local libpng implementation:
- */
-#include "../../png.h"
-
-#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
-
-static const struct color
-{
- const char *name;
- double red;
- double green;
- double blue;
-} colors[] =
-/* color ::= black|white|red|green|yellow|blue
- * color ::= brown|purple|pink|orange|gray|cyan
- */
-{
- { "black", 0, 0, 0 },
- { "white", 1, 1, 1 },
- { "red", 1, 0, 0 },
- { "green", 0, 1, 0 },
- { "yellow", 1, 1, 0 },
- { "blue", 0, 0, 1 },
- { "brown", .5, .125, 0 },
- { "purple", 1, 0, 1 },
- { "pink", 1, .5, .5 },
- { "orange", 1, .5, 0 },
- { "gray", 0, .5, .5 },
- { "cyan", 0, 1, 1 }
-};
-#define color_count ((sizeof colors)/(sizeof colors[0]))
-
-static const struct color *
-color_of(const char *arg)
-{
- int icolor = color_count;
-
- while (--icolor >= 0)
- {
- if (strcmp(colors[icolor].name, arg) == 0)
- return colors+icolor;
- }
-
- fprintf(stderr, "genpng: invalid color %s\n", arg);
- exit(1);
-}
-
-static double
-width_of(const char *arg)
-{
- if (strcmp(arg, "filled") == 0)
- return 0;
-
- else
- {
- char *ep = NULL;
- double w = strtod(arg, &ep);
-
- if (ep != NULL && *ep == 0 && w > 0)
- return w;
- }
-
- fprintf(stderr, "genpng: invalid line width %s\n", arg);
- exit(1);
-}
-
-static double
-coordinate_of(const char *arg)
-{
- char *ep = NULL;
- double w = strtod(arg, &ep);
-
- if (ep != NULL && *ep == 0)
- return w;
-
- fprintf(stderr, "genpng: invalid coordinate value %s\n", arg);
- exit(1);
-}
-
-struct arg; /* forward declaration */
-
-typedef int (*shape_fn_ptr)(const struct arg *arg, double x, double y);
- /* A function to determine if (x,y) is inside the shape.
- *
- * There are two implementations:
- *
- * inside_fn: returns true if the point is inside
- * check_fn: returns;
- * -1: the point is outside the shape by more than the filter width (2)
- * 0: the point may be inside the shape
- * +1: the point is inside the shape by more than the filter width
- */
-#define OUTSIDE (-1)
-#define INSIDE (1)
-
-struct arg
-{
- const struct color *color;
- shape_fn_ptr inside_fn;
- shape_fn_ptr check_fn;
- double width; /* line width, 0 for 'filled' */
- double x1, y1, x2, y2;
-};
-
-/* IMPLEMENTATION NOTE:
- *
- * We want the contribution of each shape to the sample corresponding to each
- * pixel. This could be obtained by super sampling the image to infinite
- * dimensions, finding each point within the shape and assigning that a value
- * '1' while leaving every point outside the shape with value '0' then
- * downsampling to the image size with sinc; computationally very expensive.
- *
- * Approximations are as follows:
- *
- * 1) If the pixel coordinate is within the shape assume the sample has the
- * shape color and is opaque, else assume there is no contribution from
- * the shape.
- *
- * This is the equivalent of aliased rendering or resampling an image with
- * a block filter. The maximum error in the calculated alpha (which will
- * always be 0 or 1) is 0.5.
- *
- * 2) If the shape is within a square of size 1x1 centered on the pixel assume
- * that the shape obscures an amount of the pixel equal to its area within
- * that square.
- *
- * This is the equivalent of 'pixel coverage' alpha calculation or resampling
- * an image with a bi-linear filter. The maximum error is over 0.2, but the
- * results are often acceptable.
- *
- * This can be approximated by applying (1) to a super-sampled image then
- * downsampling with a bi-linear filter. The error in the super-sampled
- * image is 0.5 per sample, but the resampling reduces this.
- *
- * 3) Use a better filter with a super-sampled image; in the limit this is the
- * sinc() approach.
- *
- * 4) Do the geometric calculation; a bivariate definite integral across the
- * shape, unfortunately this means evaluating Si(x), the integral of sinc(x),
- * which is still a lot of math.
- *
- * This code uses approach (3) with a bi-cubic filter and 8x super-sampling
- * and method (1) for the super-samples. This means that the sample is either
- * 0 or 1, depending on whether the sub-pixel is within or outside the shape.
- * The bi-cubic weights are also fixed and the 16 required weights are
- * pre-computed here (note that the 'scale' setting will need to be changed if
- * 'super' is increased).
- *
- * The code also calculates a sum to the edge of the filter. This is not
- * currently used by could be used to optimize the calculation.
- */
-#if 0 /* bc code */
-scale=10
-super=8
-define bicubic(x) {
- if (x <= 1) return (1.5*x - 2.5)*x*x + 1;
- if (x < 2) return (((2.5 - 0.5*x)*x - 4)*x + 2);
- return 0;
-}
-define sum(x) {
- auto s;
- s = 0;
- while (x < 2*super) {
- s = s + bicubic(x/super);
- x = x + 1;
- }
- return s;
-}
-define results(x) {
- auto b, s;
- b = bicubic(x/super);
- s = sum(x);
-
- print " /*", x, "*/ { ", b, ", ", s, " }";
- return 1;
-}
-x=0
-while (x<2*super) {
- x = x + results(x)
- if (x < 2*super) print ","
- print "\n"
-}
-quit
-#endif
-
-#define BICUBIC1(x) /* |x| <= 1 */ ((1.5*(x)* - 2.5)*(x)*(x) + 1)
-#define BICUBIC2(x) /* 1 < |x| < 2 */ (((2.5 - 0.5*(x))*(x) - 4)*(x) + 2)
-#define FILTER_WEIGHT 9 /* Twice the first sum below */
-#define FILTER_WIDTH 2 /* Actually half the width; -2..+2 */
-#define FILTER_STEPS 8 /* steps per filter unit */
-static const double
-bicubic[16][2] =
-{
- /* These numbers are exact; the weight for the filter is 1/9, but this
- * would make the numbers inexact, so it is not included here.
- */
- /* bicubic sum */
- /* 0*/ { 1.0000000000, 4.5000000000 },
- /* 1*/ { .9638671875, 3.5000000000 },
- /* 2*/ { .8671875000, 2.5361328125 },
- /* 3*/ { .7275390625, 1.6689453125 },
- /* 4*/ { .5625000000, .9414062500 },
- /* 5*/ { .3896484375, .3789062500 },
- /* 6*/ { .2265625000, -.0107421875 },
- /* 7*/ { .0908203125, -.2373046875 },
- /* 8*/ { 0, -.3281250000 },
- /* 9*/ { -.0478515625, -.3281250000 },
- /*10*/ { -.0703125000, -.2802734375 },
- /*11*/ { -.0732421875, -.2099609375 },
- /*12*/ { -.0625000000, -.1367187500 },
- /*13*/ { -.0439453125, -.0742187500 },
- /*14*/ { -.0234375000, -.0302734375 },
- /*15*/ { -.0068359375, -.0068359375 }
-};
-
-static double
-alpha_calc(const struct arg *arg, double x, double y)
-{
- /* For [x-2..x+2],[y-2,y+2] calculate the weighted bicubic given a function
- * which tells us whether a point is inside or outside the shape. First
- * check if we need to do this at all:
- */
- switch (arg->check_fn(arg, x, y))
- {
- case OUTSIDE:
- return 0; /* all samples outside the shape */
-
- case INSIDE:
- return 1; /* all samples inside the shape */
-
- default:
- {
- int dy;
- double alpha = 0;
-
-# define FILTER_D (FILTER_WIDTH*FILTER_STEPS-1)
- for (dy=-FILTER_D; dy<=FILTER_D; ++dy)
- {
- double wy = bicubic[abs(dy)][0];
-
- if (wy != 0)
- {
- double alphay = 0;
- int dx;
-
- for (dx=-FILTER_D; dx<=FILTER_D; ++dx)
- {
- double wx = bicubic[abs(dx)][0];
-
- if (wx != 0 && arg->inside_fn(arg, x+dx/16, y+dy/16))
- alphay += wx;
- }
-
- alpha += wy * alphay;
- }
- }
-
- /* This needs to be weighted for each dimension: */
- return alpha / (FILTER_WEIGHT*FILTER_WEIGHT);
- }
- }
-}
-
-/* These are the shape functions. */
-/* "square",
- * { inside_square_filled, check_square_filled },
- * { inside_square, check_square }
- */
-static int
-square_check(double x, double y, double x1, double y1, double x2, double y2)
- /* Is x,y inside the square (x1,y1)..(x2,y2)? */
-{
- /* Do a modified Cohen-Sutherland on one point, bit patterns that indicate
- * 'outside' are:
- *
- * x<x1 | x<y1 | x<x2 | x<y2
- * 0 x 0 x To the right
- * 1 x 1 x To the left
- * x 0 x 0 Below
- * x 1 x 1 Above
- *
- * So 'inside' is (x<x1) != (x<x2) && (y<y1) != (y<y2);
- */
- return ((x<x1) ^ (x<x2)) & ((y<y1) ^ (y<y2));
-}
-
-static int
-inside_square_filled(const struct arg *arg, double x, double y)
-{
- return square_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2);
-}
-
-static int
-square_check_line(const struct arg *arg, double x, double y, double w)
- /* Check for a point being inside the boundaries implied by the given arg
- * and assuming a width 2*w each side of the boundaries. This returns the
- * 'check' INSIDE/OUTSIDE/0 result but note the semantics:
- *
- * +--------------+
- * | | OUTSIDE
- * | INSIDE |
- * | |
- * +--------------+
- *
- * And '0' means within the line boundaries.
- */
-{
- double cx = (arg->x1+arg->x2)/2;
- double wx = fabs(arg->x1-arg->x2)/2;
- double cy = (arg->y1+arg->y2)/2;
- double wy = fabs(arg->y1-arg->y2)/2;
-
- if (square_check(x, y, cx-wx-w, cy-wy-w, cx+wx+w, cy+wy+w))
- {
- /* Inside, but maybe too far; check for the redundant case where
- * the lines overlap:
- */
- wx -= w;
- wy -= w;
- if (wx > 0 && wy > 0 && square_check(x, y, cx-wx, cy-wy, cx+wx, cy+wy))
- return INSIDE; /* between (inside) the boundary lines. */
-
- return 0; /* inside the lines themselves. */
- }
-
- return OUTSIDE; /* outside the boundary lines. */
-}
-
-static int
-check_square_filled(const struct arg *arg, double x, double y)
-{
- /* The filter extends +/-FILTER_WIDTH each side of each output point, so
- * the check has to expand and contract the square by that amount; '0'
- * means close enough to the edge of the square that the bicubic filter has
- * to be run, OUTSIDE means alpha==0, INSIDE means alpha==1.
- */
- return square_check_line(arg, x, y, FILTER_WIDTH);
-}
-
-static int
-inside_square(const struct arg *arg, double x, double y)
-{
- /* Return true if within the drawn lines, else false, no need to distinguish
- * INSIDE vs OUTSIDE here:
- */
- return square_check_line(arg, x, y, arg->width/2) == 0;
-}
-
-static int
-check_square(const struct arg *arg, double x, double y)
-{
- /* So for this function a result of 'INSIDE' means inside the actual lines.
- */
- double w = arg->width/2;
-
- if (square_check_line(arg, x, y, w+FILTER_WIDTH) == 0)
- {
- /* Somewhere close to the boundary lines. If far enough inside one of
- * them then we can return INSIDE:
- */
- w -= FILTER_WIDTH;
-
- if (w > 0 && square_check_line(arg, x, y, w) == 0)
- return INSIDE;
-
- /* Point is somewhere in the filter region: */
- return 0;
- }
-
- else /* Inside or outside the square by more than w+FILTER_WIDTH. */
- return OUTSIDE;
-}
-
-/* "circle",
- * { inside_circle_filled, check_circle_filled },
- * { inside_circle, check_circle }
- *
- * The functions here are analoguous to the square ones; however, they check
- * the corresponding ellipse as opposed to the rectangle.
- */
-static int
-circle_check(double x, double y, double x1, double y1, double x2, double y2)
-{
- if (square_check(x, y, x1, y1, x2, y2))
- {
- /* Inside the square, so maybe inside the circle too: */
- const double cx = (x1 + x2)/2;
- const double cy = (y1 + y2)/2;
- const double dx = x1 - x2;
- const double dy = y1 - y2;
-
- x = (x - cx)/dx;
- y = (y - cy)/dy;
-
- /* It is outside if the distance from the center is more than half the
- * diameter:
- */
- return x*x+y*y < .25;
- }
-
- return 0; /* outside */
-}
-
-static int
-inside_circle_filled(const struct arg *arg, double x, double y)
-{
- return circle_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2);
-}
-
-static int
-circle_check_line(const struct arg *arg, double x, double y, double w)
- /* Check for a point being inside the boundaries implied by the given arg
- * and assuming a width 2*w each side of the boundaries. This function has
- * the same semantic as square_check_line but tests the circle.
- */
-{
- double cx = (arg->x1+arg->x2)/2;
- double wx = fabs(arg->x1-arg->x2)/2;
- double cy = (arg->y1+arg->y2)/2;
- double wy = fabs(arg->y1-arg->y2)/2;
-
- if (circle_check(x, y, cx-wx-w, cy-wy-w, cx+wx+w, cy+wy+w))
- {
- /* Inside, but maybe too far; check for the redundant case where
- * the lines overlap:
- */
- wx -= w;
- wy -= w;
- if (wx > 0 && wy > 0 && circle_check(x, y, cx-wx, cy-wy, cx+wx, cy+wy))
- return INSIDE; /* between (inside) the boundary lines. */
-
- return 0; /* inside the lines themselves. */
- }
-
- return OUTSIDE; /* outside the boundary lines. */
-}
-
-static int
-check_circle_filled(const struct arg *arg, double x, double y)
-{
- return circle_check_line(arg, x, y, FILTER_WIDTH);
-}
-
-static int
-inside_circle(const struct arg *arg, double x, double y)
-{
- return circle_check_line(arg, x, y, arg->width/2) == 0;
-}
-
-static int
-check_circle(const struct arg *arg, double x, double y)
-{
- /* Exactly as the 'square' code. */
- double w = arg->width/2;
-
- if (circle_check_line(arg, x, y, w+FILTER_WIDTH) == 0)
- {
- w -= FILTER_WIDTH;
-
- if (w > 0 && circle_check_line(arg, x, y, w) == 0)
- return INSIDE;
-
- /* Point is somewhere in the filter region: */
- return 0;
- }
-
- else /* Inside or outside the square by more than w+FILTER_WIDTH. */
- return OUTSIDE;
-}
-
-/* "line",
- * { NULL, NULL }, There is no 'filled' line.
- * { inside_line, check_line }
- */
-static int
-line_check(double x, double y, double x1, double y1, double x2, double y2,
- double w, double expand)
-{
- /* Shift all the points to (arg->x1, arg->y1) */
- double lx = x2 - x1;
- double ly = y2 - y1;
- double len2 = lx*lx + ly*ly;
- double cross, dot;
-
- x -= x1;
- y -= y1;
-
- /* The dot product is the distance down the line, the cross product is
- * the distance away from the line:
- *
- * distance = |cross| / sqrt(len2)
- */
- cross = x * ly - y * lx;
-
- /* If 'distance' is more than w the point is definitely outside the line:
- *
- * distance >= w
- * |cross| >= w * sqrt(len2)
- * cross^2 >= w^2 * len2:
- */
- if (cross*cross >= (w+expand)*(w+expand)*len2)
- return 0; /* outside */
-
- /* Now find the distance *along* the line; this comes from the dot product
- * lx.x+ly.y. The actual distance (in pixels) is:
- *
- * distance = dot / sqrt(len2)
- */
- dot = lx * x + ly * y;
-
- /* The test for 'outside' is:
- *
- * distance < 0 || distance > sqrt(len2)
- * -> dot / sqrt(len2) > sqrt(len2)
- * -> dot > len2
- *
- * But 'expand' is used for the filter width and needs to be handled too:
- */
- return dot > -expand && dot < len2+expand;
-}
-
-static int
-inside_line(const struct arg *arg, double x, double y)
-{
- return line_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2, arg->width/2, 0);
-}
-
-static int
-check_line(const struct arg *arg, double x, double y)
-{
- /* The end caps of the line must be checked too; it's not enough just to
- * widen the line by FILTER_WIDTH; 'expand' exists for this purpose:
- */
- if (line_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2, arg->width/2,
- FILTER_WIDTH))
- {
- /* Inside the line+filter; far enough inside that the filter isn't
- * required?
- */
- if (arg->width > 2*FILTER_WIDTH &&
- line_check(x, y, arg->x1, arg->y1, arg->x2, arg->y2, arg->width/2,
- -FILTER_WIDTH))
- return INSIDE;
-
- return 0;
- }
-
- return OUTSIDE;
-}
-
-static const struct
-{
- const char *name;
- shape_fn_ptr function[2/*fill,line*/][2];
-# define FN_INSIDE 0
-# define FN_CHECK 1
-} shape_defs[] =
-{
- { "square",
- { { inside_square_filled, check_square_filled },
- { inside_square, check_square } }
- },
- { "circle",
- { { inside_circle_filled, check_circle_filled },
- { inside_circle, check_circle } }
- },
- { "line",
- { { NULL, NULL },
- { inside_line, check_line } }
- }
-};
-
-#define shape_count ((sizeof shape_defs)/(sizeof shape_defs[0]))
-
-static shape_fn_ptr
-shape_of(const char *arg, double width, int f)
-{
- unsigned int i;
-
- for (i=0; i<shape_count; ++i) if (strcmp(shape_defs[i].name, arg) == 0)
- {
- shape_fn_ptr fn = shape_defs[i].function[width != 0][f];
-
- if (fn != NULL)
- return fn;
-
- fprintf(stderr, "genpng: %s %s not supported\n",
- width == 0 ? "filled" : "unfilled", arg);
- exit(1);
- }
-
- fprintf(stderr, "genpng: %s: not a valid shape name\n", arg);
- exit(1);
-}
-
-static void
-parse_arg(struct arg *arg, const char **argv/*7 arguments*/)
-{
- /* shape ::= color width shape x1 y1 x2 y2 */
- arg->color = color_of(argv[0]);
- arg->width = width_of(argv[1]);
- arg->inside_fn = shape_of(argv[2], arg->width, FN_INSIDE);
- arg->check_fn = shape_of(argv[2], arg->width, FN_CHECK);
- arg->x1 = coordinate_of(argv[3]);
- arg->y1 = coordinate_of(argv[4]);
- arg->x2 = coordinate_of(argv[5]);
- arg->y2 = coordinate_of(argv[6]);
-}
-
-static png_uint_32
-read_wh(const char *name, const char *str)
- /* read a PNG width or height */
-{
- char *ep = NULL;
- unsigned long ul = strtoul(str, &ep, 10);
-
- if (ep != NULL && *ep == 0 && ul > 0 && ul <= 0x7fffffff)
- return (png_uint_32)/*SAFE*/ul;
-
- fprintf(stderr, "genpng: %s: invalid number %s\n", name, str);
- exit(1);
-}
-
-static void
-pixel(png_uint_16p p, struct arg *args, int nargs, double x, double y)
-{
- /* Fill in the pixel by checking each shape (args[nargs]) for effects on
- * the corresponding sample:
- */
- double r=0, g=0, b=0, a=0;
-
- while (--nargs >= 0 && a != 1)
- {
- /* NOTE: alpha_calc can return a value outside the range 0..1 with the
- * bicubic filter.
- */
- const double alpha = alpha_calc(args+nargs, x, y) * (1-a);
-
- r += alpha * args[nargs].color->red;
- g += alpha * args[nargs].color->green;
- b += alpha * args[nargs].color->blue;
- a += alpha;
- }
-
- /* 'a' may be negative or greater than 1; if it is, negative clamp the
- * pixel to 0 if >1 clamp r/g/b:
- */
- if (a > 0)
- {
- if (a > 1)
- {
- if (r > 1) r = 1;
- if (g > 1) g = 1;
- if (b > 1) b = 1;
- a = 1;
- }
-
- /* And fill in the pixel: */
- p[0] = (png_uint_16)/*SAFE*/round(r * 65535);
- p[1] = (png_uint_16)/*SAFE*/round(g * 65535);
- p[2] = (png_uint_16)/*SAFE*/round(b * 65535);
- p[3] = (png_uint_16)/*SAFE*/round(a * 65535);
- }
-
- else
- p[3] = p[2] = p[1] = p[0] = 0;
-}
-
-int
-main(int argc, const char **argv)
-{
- int convert_to_8bit = 0;
-
- /* There is one option: --8bit: */
- if (argc > 1 && strcmp(argv[1], "--8bit") == 0)
- --argc, ++argv, convert_to_8bit = 1;
-
- if (argc >= 3)
- {
- png_uint_16p buffer;
- int nshapes;
- png_image image;
-# define max_shapes 256
- struct arg arg_list[max_shapes];
-
- /* The libpng Simplified API write code requires a fully initialized
- * structure.
- */
- memset(&image, 0, sizeof image);
- image.version = PNG_IMAGE_VERSION;
- image.opaque = NULL;
- image.width = read_wh("width", argv[1]);
- image.height = read_wh("height", argv[2]);
- image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
- image.flags = 0;
- image.colormap_entries = 0;
-
- /* Check the remainder of the arguments */
- for (nshapes=0; 3+7*(nshapes+1) <= argc && nshapes < max_shapes;
- ++nshapes)
- parse_arg(arg_list+nshapes, argv+3+7*nshapes);
-
- if (3+7*nshapes != argc)
- {
- fprintf(stderr, "genpng: %s: too many arguments\n", argv[3+7*nshapes]);
- return 1;
- }
-
-#if 1
- /* TO do: determine whether this guard against overflow is necessary.
- * This comment in png.h indicates that it should be safe: "libpng will
- * refuse to process an image where such an overflow would occur", but
- * I don't see where the image gets rejected when the buffer is too
- * large before the malloc is attempted.
- */
- if (image.height > ((size_t)(-1))/(8*image.width)) {
- fprintf(stderr, "genpng: image buffer would be too big");
- return 1;
- }
-#endif
-
- /* Create the buffer: */
- buffer = malloc(PNG_IMAGE_SIZE(image));
-
- if (buffer != NULL)
- {
- png_uint_32 y;
-
- /* Write each row... */
- for (y=0; y<image.height; ++y)
- {
- png_uint_32 x;
-
- /* Each pixel in each row: */
- for (x=0; x<image.width; ++x)
- pixel(buffer + 4*(x + y*image.width), arg_list, nshapes, x, y);
- }
-
- /* Write the result (to stdout) */
- if (png_image_write_to_stdio(&image, stdout, convert_to_8bit,
- buffer, 0/*row_stride*/, NULL/*colormap*/))
- {
- free(buffer);
- return 0; /* success */
- }
-
- else
- fprintf(stderr, "genpng: write stdout: %s\n", image.message);
-
- free(buffer);
- }
-
- else
- fprintf(stderr, "genpng: out of memory: %lu bytes\n",
- (unsigned long)PNG_IMAGE_SIZE(image));
- }
-
- else
- {
- /* Wrong number of arguments */
- fprintf(stderr, "genpng: usage: genpng [--8bit] width height {shape}\n"
- " Generate a transparent PNG in RGBA (truecolor+alpha) format\n"
- " containing the given shape or shapes. Shapes are defined:\n"
- "\n"
- " shape ::= color width shape x1 y1 x2 y2\n"
- " color ::= black|white|red|green|yellow|blue\n"
- " color ::= brown|purple|pink|orange|gray|cyan\n"
- " width ::= filled|<number>\n"
- " shape ::= circle|square|line\n"
- " x1,x2 ::= <number>\n"
- " y1,y2 ::= <number>\n"
- "\n"
- " Numbers are floating point numbers describing points relative to\n"
- " the top left of the output PNG as pixel coordinates. The 'width'\n"
- " parameter is either the width of the line (in output pixels) used\n"
- " to draw the shape or 'filled' to indicate that the shape should\n"
- " be filled with the color.\n"
- "\n"
- " Colors are interpreted loosely to give access to the eight full\n"
- " intensity RGB values:\n"
- "\n"
- " black, red, green, blue, yellow, cyan, purple, white,\n"
- "\n"
- " Cyan is full intensity blue+green; RGB(0,1,1), plus the following\n"
- " lower intensity values:\n"
- "\n"
- " brown: red+orange: RGB(0.5, 0.125, 0) (dark red+orange)\n"
- " pink: red+white: RGB(1.0, 0.5, 0.5)\n"
- " orange: red+yellow: RGB(1.0, 0.5, 0)\n"
- " gray: black+white: RGB(0.5, 0.5, 0.5)\n"
- "\n"
- " The RGB values are selected to make detection of aliasing errors\n"
- " easy. The names are selected to make the description of errors\n"
- " easy.\n"
- "\n"
- " The PNG is written to stdout, if --8bit is given a 32bpp RGBA sRGB\n"
- " file is produced, otherwise a 64bpp RGBA linear encoded file is\n"
- " written.\n");
- }
-
- return 1;
-}
-#endif /* SIMPLIFIED_WRITE && STDIO */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh b/Build/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh
deleted file mode 100755
index 41c5d6dd278..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/bin/sh
-#
-# intgamma.sh
-#
-# Last changed in libpng 1.6.0 [February 14, 2013]
-#
-# COPYRIGHT: Written by John Cunningham Bowler, 2013.
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-#
-# Shell script to generate png.c 8-bit and 16-bit log tables (see the code in
-# png.c for details).
-#
-# This script uses the "bc" arbitrary precision calculator to calculate 32-bit
-# fixed point values of logarithms appropriate to finding the log of an 8-bit
-# (0..255) value and a similar table for the exponent calculation.
-#
-# "bc" must be on the path when the script is executed, and the math library
-# (-lm) must be available
-#
-# function to print out a list of numbers as integers; the function truncates
-# the integers which must be one-per-line
-function print(){
- awk 'BEGIN{
- str = ""
- }
- {
- sub("\\.[0-9]*$", "")
- if ($0 == "")
- $0 = "0"
-
- if (str == "")
- t = " " $0 "U"
- else
- t = str ", " $0 "U"
-
- if (length(t) >= 80) {
- print str ","
- str = " " $0 "U"
- } else
- str = t
- }
- END{
- print str
- }'
-}
-#
-# The logarithm table.
-cat <<END
-/* 8-bit log table: png_8bit_l2[128]
- * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
- * 255, so it's the base 2 logarithm of a normalized 8-bit floating point
- * mantissa. The numbers are 32-bit fractions.
- */
-static const png_uint_32
-png_8bit_l2[128] =
-{
-END
-#
-bc -lqws <<END | print
-f=65536*65536/l(2)
-for (i=128;i<256;++i) { .5 - l(i/255)*f; }
-END
-echo '};'
-echo
-#
-# The exponent table.
-cat <<END
-/* The 'exp()' case must invert the above, taking a 20-bit fixed point
- * logarithmic value and returning a 16 or 8-bit number as appropriate. In
- * each case only the low 16 bits are relevant - the fraction - since the
- * integer bits (the top 4) simply determine a shift.
- *
- * The worst case is the 16-bit distinction between 65535 and 65534; this
- * requires perhaps spurious accuracy in the decoding of the logarithm to
- * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance
- * of getting this accuracy in practice.
- *
- * To deal with this the following exp() function works out the exponent of the
- * frational part of the logarithm by using an accurate 32-bit value from the
- * top four fractional bits then multiplying in the remaining bits.
- */
-static const png_uint_32
-png_32bit_exp[16] =
-{
-END
-#
-bc -lqws <<END | print
-f=l(2)/16
-for (i=0;i<16;++i) {
- x = .5 + e(-i*f)*2^32;
- if (x >= 2^32) x = 2^32-1;
- x;
-}
-END
-echo '};'
-echo
-#
-# And the table of adjustment values.
-cat <<END
-/* Adjustment table; provided to explain the numbers in the code below. */
-#if 0
-END
-bc -lqws <<END | awk '{ printf "%5d %s\n", 12-NR, $0 }'
-for (i=11;i>=0;--i){
- (1 - e(-(2^i)/65536*l(2))) * 2^(32-i)
-}
-END
-echo '#endif'
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/makesRGB.c b/Build/source/libs/libpng/libpng-src/contrib/tools/makesRGB.c
deleted file mode 100644
index d0c0ca93149..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/makesRGB.c
+++ /dev/null
@@ -1,430 +0,0 @@
-/* makesRGB.c -- build sRGB-to-linear and linear-to-sRGB conversion tables
- *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2013.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Make a table to convert 8-bit sRGB encoding values into the closest 16-bit
- * linear value.
- *
- * Make two tables to take a linear value scaled to 255*65535 and return an
- * approximation to the 8-bit sRGB encoded value. Calculate the error in these
- * tables and display it.
- */
-#define _C99_SOURCE 1
-#include <stdio.h>
-#include <math.h>
-#include <stdlib.h>
-
-/* pngpriv.h includes the definition of 'PNG_sRGB_FROM_LINEAR' which is required
- * to verify the actual code.
- */
-#include "../../pngpriv.h"
-
-#include "sRGB.h"
-
-/* The tables are declared 'const' in pngpriv.h, so this redefines the tables to
- * be used.
- */
-#define png_sRGB_table sRGB_table
-#define png_sRGB_base sRGB_base
-#define png_sRGB_delta sRGB_delta
-
-static png_uint_16 png_sRGB_table[256];
-static png_uint_16 png_sRGB_base[512];
-static png_byte png_sRGB_delta[512];
-
-static const unsigned int max_input = 255*65535;
-
-double
-fsRGB(double l)
-{
- return sRGB_from_linear(l/max_input);
-}
-
-double
-sRGB(unsigned int i)
-{
- return fsRGB(i);
-}
-
-double
-finvsRGB(unsigned int i)
-{
- return 65535 * linear_from_sRGB(i/255.);
-}
-
-png_uint_16
-invsRGB(unsigned int i)
-{
- unsigned int x = nearbyint(finvsRGB(i));
-
- if (x > 65535)
- {
- fprintf(stderr, "invsRGB(%u) overflows to %u\n", i, x);
- exit(1);
- }
-
- return (png_uint_16)x;
-}
-
-int
-main(int argc, char **argv)
-{
- unsigned int i, i16, ibase;
- double min_error = 0;
- double max_error = 0;
- double min_error16 = 0;
- double max_error16 = 0;
- double adjust;
- double adjust_lo = 0.4, adjust_hi = 0.6, adjust_mid = 0.5;
- unsigned int ec_lo = 0, ec_hi = 0, ec_mid = 0;
- unsigned int error_count = 0;
- unsigned int error_count16 = 0;
- int test_only = 0;
-
- if (argc > 1)
- test_only = strcmp("--test", argv[1]) == 0;
-
- /* Initialize the encoding table first. */
- for (i=0; i<256; ++i)
- {
- png_sRGB_table[i] = invsRGB(i);
- }
-
- /* Now work out the decoding tables (this is where the error comes in because
- * there are 512 set points and 512 straight lines between them.)
- */
- for (;;)
- {
- if (ec_lo == 0)
- adjust = adjust_lo;
-
- else if (ec_hi == 0)
- adjust = adjust_hi;
-
- else if (ec_mid == 0)
- adjust = adjust_mid;
-
- else if (ec_mid < ec_hi)
- adjust = (adjust_mid + adjust_hi)/2;
-
- else if (ec_mid < ec_lo)
- adjust = (adjust_mid + adjust_lo)/2;
-
- else
- {
- fprintf(stderr, "not reached: %u .. %u .. %u\n", ec_lo, ec_mid, ec_hi);
- exit(1);
- }
-
- /* Calculate the table using the current 'adjust' */
- for (i=0; i<=511; ++i)
- {
- double lo = 255 * sRGB(i << 15);
- double hi = 255 * sRGB((i+1) << 15);
- unsigned int calc;
-
- calc = nearbyint((lo+adjust) * 256);
- if (calc > 65535)
- {
- fprintf(stderr, "table[%d][0]: overflow %08x (%d)\n", i, calc,
- calc);
- exit(1);
- }
- png_sRGB_base[i] = calc;
-
- calc = nearbyint((hi-lo) * 32);
- if (calc > 255)
- {
- fprintf(stderr, "table[%d][1]: overflow %08x (%d)\n", i, calc,
- calc);
- exit(1);
- }
- png_sRGB_delta[i] = calc;
- }
-
- /* Check the 16-bit linear values alone: */
- error_count16 = 0;
- for (i16=0; i16 <= 65535; ++i16)
- {
- unsigned int i = 255*i16;
- unsigned int iexact = nearbyint(255*sRGB(i));
- unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
-
- if (icalc != iexact)
- ++error_count16;
- }
-
- /* Now try changing the adjustment. */
- if (ec_lo == 0)
- ec_lo = error_count16;
-
- else if (ec_hi == 0)
- ec_hi = error_count16;
-
- else if (ec_mid == 0)
- {
- ec_mid = error_count16;
- printf("/* initial error counts: %u .. %u .. %u */\n", ec_lo, ec_mid,
- ec_hi);
- }
-
- else if (error_count16 < ec_mid)
- {
- printf("/* adjust (mid ): %f: %u -> %u */\n", adjust, ec_mid,
- error_count16);
- ec_mid = error_count16;
- adjust_mid = adjust;
- }
-
- else if (adjust < adjust_mid && error_count16 < ec_lo)
- {
- printf("/* adjust (low ): %f: %u -> %u */\n", adjust, ec_lo,
- error_count16);
- ec_lo = error_count16;
- adjust_lo = adjust;
- }
-
- else if (adjust > adjust_mid && error_count16 < ec_hi)
- {
- printf("/* adjust (high): %f: %u -> %u */\n", adjust, ec_hi,
- error_count16);
- ec_hi = error_count16;
- adjust_hi = adjust;
- }
-
- else
- {
- adjust = adjust_mid;
- printf("/* adjust: %f: %u */\n", adjust, ec_mid);
- break;
- }
- }
-
- /* For each entry in the table try to adjust it to minimize the error count
- * in that entry. Each entry corresponds to 128 input values.
- */
- for (ibase=0; ibase<65536; ibase+=128)
- {
- png_uint_16 base = png_sRGB_base[ibase >> 7], trybase = base, ob=base;
- png_byte delta = png_sRGB_delta[ibase >> 7], trydelta = delta, od=delta;
- unsigned int ecbase = 0, eco;
-
- for (;;)
- {
- png_sRGB_base[ibase >> 7] = trybase;
- png_sRGB_delta[ibase >> 7] = trydelta;
-
- /* Check the 16-bit linear values alone: */
- error_count16 = 0;
- for (i16=ibase; i16 < ibase+128; ++i16)
- {
- unsigned int i = 255*i16;
- unsigned int iexact = nearbyint(255*sRGB(i));
- unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
-
- if (icalc != iexact)
- ++error_count16;
- }
-
- if (error_count16 == 0)
- break;
-
- if (ecbase == 0)
- {
- eco = ecbase = error_count16;
- ++trybase; /* First test */
- }
-
- else if (error_count16 < ecbase)
- {
- if (trybase > base)
- {
- base = trybase;
- ++trybase;
- }
- else if (trybase < base)
- {
- base = trybase;
- --trybase;
- }
- else if (trydelta > delta)
- {
- delta = trydelta;
- ++trydelta;
- }
- else if (trydelta < delta)
- {
- delta = trydelta;
- --trydelta;
- }
- else
- {
- fprintf(stderr, "makesRGB: impossible\n");
- exit(1);
- }
- ecbase = error_count16;
- }
-
- else
- {
- if (trybase > base)
- trybase = base-1;
- else if (trybase < base)
- {
- trybase = base;
- ++trydelta;
- }
- else if (trydelta > delta)
- trydelta = delta-1;
- else if (trydelta < delta)
- break; /* end of tests */
- }
- }
-
- png_sRGB_base[ibase >> 7] = base;
- png_sRGB_delta[ibase >> 7] = delta;
- if (base != ob || delta != od)
- {
- printf("/* table[%u]={%u,%u} -> {%u,%u} %u -> %u errors */\n",
- ibase>>7, ob, od, base, delta, eco, ecbase);
- }
- else if (0)
- printf("/* table[%u]={%u,%u} %u errors */\n", ibase>>7, ob, od,
- ecbase);
- }
-
- /* Only do the full (slow) test at the end: */
- min_error = -.4999;
- max_error = .4999;
- error_count = 0;
-
- for (i=0; i <= max_input; ++i)
- {
- unsigned int iexact = nearbyint(255*sRGB(i));
- unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
-
- if (icalc != iexact)
- {
- double err = 255*sRGB(i) - icalc;
-
- if (err > (max_error+.001) || err < (min_error-.001))
- {
- printf(
- "/* 0x%08x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\n",
- i, iexact, icalc, png_sRGB_base[i>>15],
- png_sRGB_delta[i>>15], err);
- }
-
- ++error_count;
- if (err > max_error)
- max_error = err;
- else if (err < min_error)
- min_error = err;
- }
- }
-
- /* Re-check the 16-bit cases too, including the warning if there is an error
- * bigger than 1.
- */
- error_count16 = 0;
- max_error16 = 0;
- min_error16 = 0;
- for (i16=0; i16 <= 65535; ++i16)
- {
- unsigned int i = 255*i16;
- unsigned int iexact = nearbyint(255*sRGB(i));
- unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
-
- if (icalc != iexact)
- {
- double err = 255*sRGB(i) - icalc;
-
- ++error_count16;
- if (err > max_error16)
- max_error16 = err;
- else if (err < min_error16)
- min_error16 = err;
-
- if (abs(icalc - iexact) > 1)
- printf(
- "/* 0x%04x: exact: %3d, got: %3d [tables: %08x, %08x] (%f) */\n",
- i16, iexact, icalc, png_sRGB_base[i>>15],
- png_sRGB_delta[i>>15], err);
- }
- }
-
- /* Check the round trip for each 8-bit sRGB value. */
- for (i16=0; i16 <= 255; ++i16)
- {
- unsigned int i = 255 * png_sRGB_table[i16];
- unsigned int iexact = nearbyint(255*sRGB(i));
- unsigned int icalc = PNG_sRGB_FROM_LINEAR(i);
-
- if (i16 != iexact)
- {
- fprintf(stderr, "8-bit rounding error: %d -> %d\n", i16, iexact);
- exit(1);
- }
-
- if (icalc != i16)
- {
- double finv = finvsRGB(i16);
-
- printf("/* 8-bit roundtrip error: %d -> %f -> %d(%f) */\n",
- i16, finv, icalc, fsRGB(255*finv));
- }
- }
-
-
- printf("/* error: %g - %g, %u (%g%%) of readings inexact */\n",
- min_error, max_error, error_count, (100.*error_count)/max_input);
- printf("/* 16-bit error: %g - %g, %u (%g%%) of readings inexact */\n",
- min_error16, max_error16, error_count16, (100.*error_count16)/65535);
-
- if (!test_only)
- {
- printf("const png_uint_16 png_sRGB_table[256] =\n{\n ");
- for (i=0; i<255; )
- {
- do
- {
- printf("%d,", png_sRGB_table[i++]);
- }
- while ((i & 0x7) != 0 && i<255);
- if (i<255) printf("\n ");
- }
- printf("%d\n};\n\n", png_sRGB_table[i]);
-
-
- printf("const png_uint_16 png_sRGB_base[512] =\n{\n ");
- for (i=0; i<511; )
- {
- do
- {
- printf("%d,", png_sRGB_base[i++]);
- }
- while ((i & 0x7) != 0 && i<511);
- if (i<511) printf("\n ");
- }
- printf("%d\n};\n\n", png_sRGB_base[i]);
-
- printf("const png_byte png_sRGB_delta[512] =\n{\n ");
- for (i=0; i<511; )
- {
- do
- {
- printf("%d,", png_sRGB_delta[i++]);
- }
- while ((i & 0xf) != 0 && i<511);
- if (i<511) printf("\n ");
- }
- printf("%d\n};\n\n", png_sRGB_delta[i]);
- }
-
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/png-fix-itxt.c b/Build/source/libs/libpng/libpng-src/contrib/tools/png-fix-itxt.c
deleted file mode 100644
index c7654c11363..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/png-fix-itxt.c
+++ /dev/null
@@ -1,164 +0,0 @@
-
-/* png-fix-itxt version 1.0.0
- *
- * Copyright 2015 Glenn Randers-Pehrson
- * Last changed in libpng 1.6.18 [July 23, 2015]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Usage:
- *
- * png-fix-itxt.exe < bad.png > good.png
- *
- * Fixes a PNG file written with libpng-1.6.0 or 1.6.1 that has one or more
- * uncompressed iTXt chunks. Assumes that the actual length is greater
- * than or equal to the value in the length byte, and that the CRC is
- * correct for the actual length. This program hunts for the CRC and
- * adjusts the length byte accordingly. It is not an error to process a
- * PNG file that has no iTXt chunks or one that has valid iTXt chunks;
- * such files will simply be copied.
- *
- * Requires zlib (for crc32 and Z_NULL); build with
- *
- * gcc -O -o png-fix-itxt png-fix-itxt.c -lz
- *
- * If you need to handle iTXt chunks larger than 500000 kbytes you must
- * rebuild png-fix-itxt with a larger values of MAX_LENGTH (or a smaller value
- * if you know you will never encounter such huge iTXt chunks).
- */
-
-#include <stdio.h>
-#include <zlib.h>
-
-#define MAX_LENGTH 500000
-
-/* Read one character (inchar), also return octet (c), break if EOF */
-#define GETBREAK inchar=getchar(); \
- c=(inchar & 0xffU);\
- if (inchar != c) break
-int
-main(void)
-{
- unsigned int i;
- unsigned char buf[MAX_LENGTH];
- unsigned long crc;
- unsigned char c;
- int inchar;
-
-/* Skip 8-byte signature */
- for (i=8; i; i--)
- {
- GETBREAK;
- putchar(c);
- }
-
-if (inchar == c) /* !EOF */
-for (;;)
- {
- /* Read the length */
- unsigned long length; /* must be 32 bits! */
- GETBREAK; buf[0] = c; length = c; length <<= 8;
- GETBREAK; buf[1] = c; length += c; length <<= 8;
- GETBREAK; buf[2] = c; length += c; length <<= 8;
- GETBREAK; buf[3] = c; length += c;
-
- /* Read the chunkname */
- GETBREAK; buf[4] = c;
- GETBREAK; buf[5] = c;
- GETBREAK; buf[6] = c;
- GETBREAK; buf[7] = c;
-
-
- /* The iTXt chunk type expressed as integers is (105, 84, 88, 116) */
- if (buf[4] == 105 && buf[5] == 84 && buf[6] == 88 && buf[7] == 116)
- {
- if (length >= MAX_LENGTH-12)
- break; /* To do: handle this more gracefully */
-
- /* Initialize the CRC */
- crc = crc32(0, Z_NULL, 0);
-
- /* Copy the data bytes */
- for (i=8; i < length + 12; i++)
- {
- GETBREAK; buf[i] = c;
- }
-
- if (inchar != c) /* EOF */
- break;
-
- /* Calculate the CRC */
- crc = crc32(crc, buf+4, (uInt)length+4);
-
- for (;;)
- {
- /* Check the CRC */
- if (((crc >> 24) & 0xffU) == buf[length+8] &&
- ((crc >> 16) & 0xffU) == buf[length+9] &&
- ((crc >> 8) & 0xffU) == buf[length+10] &&
- ((crc ) & 0xffU) == buf[length+11])
- break;
-
- length++;
-
- if (length >= MAX_LENGTH-12)
- break;
-
- GETBREAK;
- buf[length+11] = c;
-
- /* Update the CRC */
- crc = crc32(crc, buf+7+length, 1);
- }
-
- if (inchar != c) /* EOF */
- break;
-
- /* Update length bytes */
- buf[0] = (unsigned char)((length >> 24) & 0xffU);
- buf[1] = (unsigned char)((length >> 16) & 0xffU);
- buf[2] = (unsigned char)((length >> 8) & 0xffU);
- buf[3] = (unsigned char)((length ) & 0xffU);
-
- /* Write the fixed iTXt chunk (length, name, data, crc) */
- for (i=0; i<length+12; i++)
- putchar(buf[i]);
- }
-
- else
- {
- if (inchar != c) /* EOF */
- break;
-
- /* Copy bytes that were already read (length and chunk name) */
- for (i=0; i<8; i++)
- putchar(buf[i]);
-
- /* Copy data bytes and CRC */
- for (i=8; i< length+12; i++)
- {
- GETBREAK;
- putchar(c);
- }
-
- if (inchar != c) /* EOF */
- {
- break;
- }
-
- /* The IEND chunk type expressed as integers is (73, 69, 78, 68) */
- if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
- break;
- }
-
- if (inchar != c) /* EOF */
- break;
-
- if (buf[4] == 73 && buf[5] == 69 && buf[6] == 78 && buf[7] == 68)
- break;
- }
-
- return 0;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c b/Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c
deleted file mode 100644
index 16d4e7f4d1c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c
+++ /dev/null
@@ -1,2453 +0,0 @@
-/* pngcp.c
- *
- * Copyright (c) 2016 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.24 [August 4, 2016]
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * This is an example of copying a PNG without changes using the png_read_png
- * and png_write_png interfaces. A considerable number of options are provided
- * to manipulate the compression of the PNG data and other compressed chunks.
- *
- * For a more extensive example that uses the transforms see
- * contrib/libtests/pngimage.c in the libpng distribution.
- */
-#include "pnglibconf.h" /* To find how libpng was configured. */
-
-#ifdef PNG_PNGCP_TIMING_SUPPORTED
- /* WARNING:
- *
- * This test is here to allow POSIX.1b extensions to be used if enabled in
- * the compile; specifically the code requires_POSIX_C_SOURCE support of
- * 199309L or later to enable clock_gettime use.
- *
- * IF this causes problems THEN compile with a strict ANSI C compiler and let
- * this code turn on the POSIX features that it minimally requires.
- *
- * IF this does not work there is probably a bug in your ANSI C compiler or
- * your POSIX implementation.
- */
-# define _POSIX_C_SOURCE 199309L
-#else /* No timing support required */
-# define _POSIX_SOURCE 1
-#endif
-
-#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
-# include <config.h>
-#endif
-
-#include <stdio.h>
-
-/* Define the following to use this test against your installed libpng, rather
- * than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-#if PNG_LIBPNG_VER < 10700
- /* READ_PNG and WRITE_PNG were not defined, so: */
-# ifdef PNG_INFO_IMAGE_SUPPORTED
-# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-# define PNG_READ_PNG_SUPPORTED
-# endif /* SEQUENTIAL_READ */
-# ifdef PNG_WRITE_SUPPORTED
-# define PNG_WRITE_PNG_SUPPORTED
-# endif /* WRITE */
-# endif /* INFO_IMAGE */
-#endif /* pre 1.7.0 */
-
-#if (defined(PNG_READ_PNG_SUPPORTED)) && (defined(PNG_WRITE_PNG_SUPPORTED))
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <assert.h>
-
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include <zlib.h>
-
-#ifndef PNG_SETJMP_SUPPORTED
-# include <setjmp.h> /* because png.h did *not* include this */
-#endif
-
-#ifdef __cplusplus
-# define voidcast(type, value) static_cast<type>(value)
-#else
-# define voidcast(type, value) (value)
-#endif /* __cplusplus */
-
-#ifdef __GNUC__
- /* Many versions of GCC erroneously report that local variables unmodified
- * within the scope of a setjmp may be clobbered. This hacks round the
- * problem (sometimes) without harming other compilers.
- */
-# define gv volatile
-#else
-# define gv
-#endif
-
-/* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime. It
- * need not be supported even when clock_gettime is available. It returns the
- * 'CPU' time the process has consumed. 'CPU' time is assumed to include time
- * when the CPU is actually blocked by a pending cache fill but not time
- * waiting for page faults. The attempt is to get a measure of the actual time
- * the implementation takes to read a PNG ignoring the potentially very large IO
- * overhead.
- */
-#ifdef PNG_PNGCP_TIMING_SUPPORTED
-# include <time.h> /* clock_gettime and associated definitions */
-# ifndef CLOCK_PROCESS_CPUTIME_ID
- /* Prevent inclusion of the spurious code: */
-# undef PNG_PNGCP_TIMING_SUPPORTED
-# endif
-#endif /* PNGCP_TIMING */
-
-/* So if the timing feature has been activated: */
-
-/* This structure is used to control the test of a single file. */
-typedef enum
-{
- VERBOSE, /* switches on all messages */
- INFORMATION,
- WARNINGS, /* switches on warnings */
- LIBPNG_WARNING,
- APP_WARNING,
- ERRORS, /* just errors */
- APP_FAIL, /* continuable error - no need to longjmp */
- LIBPNG_ERROR, /* this and higher cause a longjmp */
- LIBPNG_BUG, /* erroneous behavior in libpng */
- APP_ERROR, /* such as out-of-memory in a callback */
- QUIET, /* no normal messages */
- USER_ERROR, /* such as file-not-found */
- INTERNAL_ERROR
-} error_level;
-#define LEVEL_MASK 0xf /* where the level is in 'options' */
-
-#define STRICT 0x010 /* Fail on warnings as well as errors */
-#define LOG 0x020 /* Log pass/fail to stdout */
-#define CONTINUE 0x040 /* Continue on APP_FAIL errors */
-#define SIZES 0x080 /* Report input and output sizes */
-#define SEARCH 0x100 /* Search IDAT compression options */
-#define NOWRITE 0x200 /* Do not write an output file */
-#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
-# define IGNORE_INDEX 0x400 /* Ignore out of range palette indices (BAD!) */
-# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
-# define FIX_INDEX 0x800 /* 'Fix' out of range palette indices (OK) */
-# endif /* GET_PALETTE_MAX */
-#endif /* CHECK_FOR_INVALID_INDEX */
-#define OPTION 0x80000000 /* Used for handling options */
-#define LIST 0x80000001 /* Used for handling options */
-
-/* Result masks apply to the result bits in the 'results' field below; these
- * bits are simple 1U<<error_level. A pass requires either nothing worse than
- * warnings (--relaxes) or nothing worse than information (--strict)
- */
-#define RESULT_STRICT(r) (((r) & ~((1U<<WARNINGS)-1)) == 0)
-#define RESULT_RELAXED(r) (((r) & ~((1U<<ERRORS)-1)) == 0)
-
-/* OPTION DEFINITIONS */
-static const char range_lo[] = "low";
-static const char range_hi[] = "high";
-static const char all[] = "all";
-#define RANGE(lo,hi) { range_lo, lo }, { range_hi, hi }
-typedef struct value_list
-{
- const char *name; /* the command line name of the value */
- int value; /* the actual value to use */
-} value_list;
-
-static const value_list
-#ifdef PNG_SW_COMPRESS_png_level
-vl_compression[] =
-{
- /* Overall compression control. The order controls the search order for
- * 'all'. Since the search is for the smallest the order used is low memory
- * then high speed.
- */
- { "low-memory", PNG_COMPRESSION_LOW_MEMORY },
- { "high-speed", PNG_COMPRESSION_HIGH_SPEED },
- { "high-read-speed", PNG_COMPRESSION_HIGH_READ_SPEED },
- { "low", PNG_COMPRESSION_LOW },
- { "medium", PNG_COMPRESSION_MEDIUM },
- { "old", PNG_COMPRESSION_COMPAT },
- { "high", PNG_COMPRESSION_HIGH },
- { all, 0 }
-},
-#endif /* SW_COMPRESS_png_level */
-
-#if defined(PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED) ||\
- defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED)
-vl_strategy[] =
-{
- /* This controls the order of search. */
- { "huffman", Z_HUFFMAN_ONLY },
- { "RLE", Z_RLE },
- { "fixed", Z_FIXED }, /* the remainder do window searches */
- { "filtered", Z_FILTERED },
- { "default", Z_DEFAULT_STRATEGY },
- { all, 0 }
-},
-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
-vl_windowBits_text[] =
-{
- { "default", MAX_WBITS/*from zlib*/ },
- { "minimum", 8 },
- RANGE(8, MAX_WBITS/*from zlib*/),
- { all, 0 }
-},
-#endif /* text compression */
-vl_level[] =
-{
- { "default", Z_DEFAULT_COMPRESSION /* this is -1 */ },
- { "none", Z_NO_COMPRESSION },
- { "speed", Z_BEST_SPEED },
- { "best", Z_BEST_COMPRESSION },
- { "0", Z_NO_COMPRESSION },
- RANGE(1, 9), /* this deliberately excludes '0' */
- { all, 0 }
-},
-vl_memLevel[] =
-{
- { "max", MAX_MEM_LEVEL }, /* zlib maximum */
- { "1", 1 }, /* zlib minimum */
- { "default", 8 }, /* zlib default */
- { "2", 2 },
- { "3", 3 },
- { "4", 4 },
- { "5", 5 }, /* for explicit testing */
- RANGE(6, MAX_MEM_LEVEL/*zlib*/), /* exclude 5 and below: zlib bugs */
- { all, 0 }
-},
-#endif /* WRITE_CUSTOMIZE_*COMPRESSION */
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-vl_filter[] =
-{
- { all, PNG_ALL_FILTERS },
- { "off", PNG_NO_FILTERS },
- { "none", PNG_FILTER_NONE },
- { "sub", PNG_FILTER_SUB },
- { "up", PNG_FILTER_UP },
- { "avg", PNG_FILTER_AVG },
- { "paeth", PNG_FILTER_PAETH }
-},
-#endif /* WRITE_FILTER */
-#ifdef PNG_PNGCP_TIMING_SUPPORTED
-# define PNGCP_TIME_READ 1
-# define PNGCP_TIME_WRITE 2
-vl_time[] =
-{
- { "both", PNGCP_TIME_READ+PNGCP_TIME_WRITE },
- { "off", 0 },
- { "read", PNGCP_TIME_READ },
- { "write", PNGCP_TIME_WRITE }
-},
-#endif /* PNGCP_TIMING */
-vl_IDAT_size[] = /* for png_set_IDAT_size */
-{
- { "default", 0x7FFFFFFF },
- { "minimal", 1 },
- RANGE(1, 0x7FFFFFFF)
-},
-#ifndef PNG_SW_IDAT_size
- /* Pre 1.7 API: */
-# define png_set_IDAT_size(p,v) png_set_compression_buffer_size(p, v)
-#endif /* !SW_IDAT_size */
-#define SL 8 /* stack limit in display, below */
-vl_log_depth[] = { { "on", 1 }, { "off", 0 }, RANGE(0, SL) },
-vl_on_off[] = { { "on", 1 }, { "off", 0 } };
-
-#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
-static value_list
-vl_windowBits_IDAT[] =
-{
- { "default", MAX_WBITS },
- { "small", 9 },
- RANGE(8, MAX_WBITS), /* modified by set_windowBits_hi */
- { all, 0 }
-};
-#endif /* IDAT compression */
-
-typedef struct option
-{
- const char *name; /* name of the option */
- png_uint_32 opt; /* an option, or OPTION or LIST */
- png_byte search; /* Search on --search */
- png_byte value_count; /* length of the list of values: */
- const value_list *values; /* values for OPTION or LIST */
-} option;
-
-static const option options[] =
-{
- /* struct display options, these are set when the command line is read */
-# define S(n,v) { #n, v, 0, 2, vl_on_off },
- S(verbose, VERBOSE)
- S(warnings, WARNINGS)
- S(errors, ERRORS)
- S(quiet, QUIET)
- S(strict, STRICT)
- S(log, LOG)
- S(continue, CONTINUE)
- S(sizes, SIZES)
- S(search, SEARCH)
- S(nowrite, NOWRITE)
-# ifdef IGNORE_INDEX
- S(ignore-palette-index, IGNORE_INDEX)
-# endif /* IGNORE_INDEX */
-# ifdef FIX_INDEX
- S(fix-palette-index, FIX_INDEX)
-# endif /* FIX_INDEX */
-# undef S
-
- /* OPTION settings, these and LIST settings are read on demand */
-# define VLNAME(name) vl_ ## name
-# define VLSIZE(name) voidcast(png_byte,\
- (sizeof VLNAME(name))/(sizeof VLNAME(name)[0]))
-# define VL(oname, name, type, search)\
- { oname, type, search, VLSIZE(name), VLNAME(name) },
-# define VLO(oname, name, search) VL(oname, name, OPTION, search)
-
-# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
-# define VLCIDAT(name) VLO(#name, name, 1/*search*/)
-# ifdef PNG_SW_COMPRESS_level
-# define VLCiCCP(name) VLO("ICC-profile-" #name, name, 0/*search*/)
-# else
-# define VLCiCCP(name)
-# endif
-# else
-# define VLCIDAT(name)
-# define VLCiCCP(name)
-# endif /* WRITE_CUSTOMIZE_COMPRESSION */
-
-# ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
-# define VLCzTXt(name) VLO("text-" #name, name, 0/*search*/)
-# else
-# define VLCzTXt(name)
-# endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
-
-# define VLC(name) VLCIDAT(name) VLCiCCP(name) VLCzTXt(name)
-
-# ifdef PNG_SW_COMPRESS_png_level
- /* The libpng compression level isn't searched because it justs sets the
- * other things that are searched!
- */
- VLO("compression", compression, 0)
- VLO("text-compression", compression, 0)
- VLO("ICC-profile-compression", compression, 0)
-# endif /* SW_COMPRESS_png_level */
- VLC(strategy)
- VLO("windowBits", windowBits_IDAT, 1)
-# ifdef PNG_SW_COMPRESS_windowBits
- VLO("ICC-profile-windowBits", windowBits_text/*sic*/, 0)
-# endif
- VLO("text-windowBits", windowBits_text, 0)
- VLC(level)
- VLC(memLevel)
- VLO("IDAT-size", IDAT_size, 0)
- VLO("log-depth", log_depth, 0)
-
-# undef VLO
-
- /* LIST settings */
-# define VLL(name, search) VL(#name, name, LIST, search)
-#ifdef PNG_WRITE_FILTER_SUPPORTED
- VLL(filter, 0)
-#endif /* WRITE_FILTER */
-#ifdef PNG_PNGCP_TIMING_SUPPORTED
- VLL(time, 0)
-#endif /* PNGCP_TIMING */
-# undef VLL
-# undef VL
-};
-
-#ifdef __cplusplus
- static const size_t option_count((sizeof options)/(sizeof options[0]));
-#else /* !__cplusplus */
-# define option_count ((sizeof options)/(sizeof options[0]))
-#endif /* !__cplusplus */
-
-static const char *
-cts(int ct)
-{
- switch (ct)
- {
- case PNG_COLOR_TYPE_PALETTE: return "P";
- case PNG_COLOR_TYPE_GRAY: return "G";
- case PNG_COLOR_TYPE_GRAY_ALPHA: return "GA";
- case PNG_COLOR_TYPE_RGB: return "RGB";
- case PNG_COLOR_TYPE_RGB_ALPHA: return "RGBA";
- default: return "INVALID";
- }
-}
-
-struct display
-{
- jmp_buf error_return; /* Where to go to on error */
- unsigned int errset; /* error_return is set */
-
- const char *operation; /* What is happening */
- const char *filename; /* The name of the original file */
- const char *output_file; /* The name of the output file */
-
- /* Used on both read and write: */
- FILE *fp;
-
- /* Used on a read, both the original read and when validating a written
- * image.
- */
- png_alloc_size_t read_size;
- png_structp read_pp;
- png_infop ip;
-# if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
- png_textp text_ptr; /* stash of text chunks */
- int num_text;
- int text_stashed;
-# endif /* pre 1.7 */
-
-# ifdef PNG_PNGCP_TIMING_SUPPORTED
- struct timespec read_time;
- struct timespec read_time_total;
- struct timespec write_time;
- struct timespec write_time_total;
-# endif /* PNGCP_TIMING */
-
- /* Used to write a new image (the original info_ptr is used) */
-# define MAX_SIZE ((png_alloc_size_t)(-1))
- png_alloc_size_t write_size;
- png_alloc_size_t best_size;
- png_structp write_pp;
-
- /* Base file information */
- png_alloc_size_t size;
- png_uint_32 w;
- png_uint_32 h;
- int bpp;
- png_byte ct;
- int no_warnings; /* Do not output libpng warnings */
- int min_windowBits; /* The windowBits range is 8..8 */
-
- /* Options handling */
- png_uint_32 results; /* A mask of errors seen */
- png_uint_32 options; /* See display_log below */
- png_byte entry[option_count]; /* The selected entry+1 of an option
- * that appears on the command line, or
- * 0 if it was not given. */
- int value[option_count]; /* Corresponding value */
-
- /* Compression exhaustive testing */
- /* Temporary variables used only while testing a single collection of
- * settings:
- */
- unsigned int csp; /* next stack entry to use */
- unsigned int nsp; /* highest active entry+1 found so far */
-
- /* Values used while iterating through all the combinations of settings for a
- * single file:
- */
- unsigned int tsp; /* nsp from the last run; this is the
- * index+1 of the highest active entry on
- * this run; this entry will be advanced.
- */
- int opt_string_start; /* Position in buffer for the first
- * searched option; non-zero if earlier
- * options were set on the command line.
- */
- struct stack
- {
- png_alloc_size_t best_size; /* Best so far for this option */
- png_alloc_size_t lo_size;
- png_alloc_size_t hi_size;
- int lo, hi; /* For binary chop of a range */
- int best_val; /* Best value found so far */
- int opt_string_end; /* End of the option string in 'curr' */
- png_byte opt; /* The option being tested */
- png_byte entry; /* The next value entry to be tested */
- png_byte end; /* This is the last entry */
- } stack[SL]; /* Stack of entries being tested */
- char curr[32*SL]; /* current options being tested */
- char best[32*SL]; /* best options */
-
- char namebuf[FILENAME_MAX]; /* output file name */
-};
-
-static void
-display_init(struct display *dp)
- /* Call this only once right at the start to initialize the control
- * structure, the (struct buffer) lists are maintained across calls - the
- * memory is not freed.
- */
-{
- memset(dp, 0, sizeof *dp);
- dp->operation = "internal error";
- dp->filename = "command line";
- dp->output_file = "no output file";
- dp->options = WARNINGS; /* default to !verbose, !quiet */
- dp->fp = NULL;
- dp->read_pp = NULL;
- dp->ip = NULL;
- dp->write_pp = NULL;
- dp->min_windowBits = -1; /* this is an OPTIND, so -1 won't match anything */
-# if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
- dp->text_ptr = NULL;
- dp->num_text = 0;
- dp->text_stashed = 0;
-# endif /* pre 1.7 */
-}
-
-static void
-display_clean_read(struct display *dp)
-{
- if (dp->read_pp != NULL)
- png_destroy_read_struct(&dp->read_pp, NULL, NULL);
-
- if (dp->fp != NULL)
- {
- FILE *fp = dp->fp;
- dp->fp = NULL;
- (void)fclose(fp);
- }
-}
-
-static void
-display_clean_write(struct display *dp)
-{
- if (dp->fp != NULL)
- {
- FILE *fp = dp->fp;
- dp->fp = NULL;
- (void)fclose(fp);
- }
-
- if (dp->write_pp != NULL)
- png_destroy_write_struct(&dp->write_pp, dp->tsp > 0 ? NULL : &dp->ip);
-}
-
-static void
-display_clean(struct display *dp)
-{
- display_clean_read(dp);
- display_clean_write(dp);
- dp->output_file = NULL;
-
-# if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
- /* This is actually created and used by the write code, but only
- * once; it has to be retained for subsequent writes of the same file.
- */
- if (dp->text_stashed)
- {
- dp->text_stashed = 0;
- dp->num_text = 0;
- free(dp->text_ptr);
- dp->text_ptr = NULL;
- }
-# endif /* pre 1.7 */
-
- /* leave the filename for error detection */
- dp->results = 0; /* reset for next time */
-}
-
-static void
-display_destroy(struct display *dp)
-{
- /* Release any memory held in the display. */
- display_clean(dp);
-}
-
-static struct display *
-get_dp(png_structp pp)
- /* The display pointer is always stored in the png_struct error pointer */
-{
- struct display *dp = (struct display*)png_get_error_ptr(pp);
-
- if (dp == NULL)
- {
- fprintf(stderr, "pngcp: internal error (no display)\n");
- exit(99); /* prevents a crash */
- }
-
- return dp;
-}
-
-/* error handling */
-#ifdef __GNUC__
-# define VGATTR __attribute__((__format__ (__printf__,3,4)))
- /* Required to quiet GNUC warnings when the compiler sees a stdarg function
- * that calls one of the stdio v APIs.
- */
-#else
-# define VGATTR
-#endif
-static void VGATTR
-display_log(struct display *dp, error_level level, const char *fmt, ...)
- /* 'level' is as above, fmt is a stdio style format string. This routine
- * does not return if level is above LIBPNG_WARNING
- */
-{
- dp->results |= 1U << level;
-
- if (level > (error_level)(dp->options & LEVEL_MASK))
- {
- const char *lp;
- va_list ap;
-
- switch (level)
- {
- case INFORMATION: lp = "information"; break;
- case LIBPNG_WARNING: lp = "warning(libpng)"; break;
- case APP_WARNING: lp = "warning(pngcp)"; break;
- case APP_FAIL: lp = "error(continuable)"; break;
- case LIBPNG_ERROR: lp = "error(libpng)"; break;
- case LIBPNG_BUG: lp = "bug(libpng)"; break;
- case APP_ERROR: lp = "error(pngcp)"; break;
- case USER_ERROR: lp = "error(user)"; break;
-
- case INTERNAL_ERROR: /* anything unexpected is an internal error: */
- case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
- default: lp = "bug(pngcp)"; break;
- }
-
- fprintf(stderr, "%s: %s: %s",
- dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);
-
- fprintf(stderr, ": ");
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- fputc('\n', stderr);
- }
- /* else do not output any message */
-
- /* Errors cause this routine to exit to the fail code */
- if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
- {
- if (dp->errset)
- longjmp(dp->error_return, level);
-
- else
- exit(99);
- }
-}
-
-#if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
-static void
-text_stash(struct display *dp)
-{
- /* libpng 1.6 and earlier fixed a bug whereby text chunks were written
- * multiple times by png_write_png; the issue was that png_write_png passed
- * the same png_info to both png_write_info and png_write_end. Rather than
- * fixing it by recording the information in the png_struct, or by recording
- * where to write the chunks, the fix made was to change the 'compression'
- * field of the chunk to invalid values, rendering the png_info somewhat
- * useless.
- *
- * The only fix for this given that we use the png_info more than once is to
- * make a copy of the text chunks and png_set_text it each time. This adds a
- * text chunks, so they get replicated, but only the new set gets written
- * each time. This uses memory like crazy but there is no way to delete the
- * useless chunks from the png_info.
- *
- * To make this slightly more efficient only the top level structure is
- * copied; since the old strings are actually preserved (in 1.6 and earlier)
- * this happens to work.
- */
- png_textp chunks = NULL;
-
- dp->num_text = png_get_text(dp->write_pp, dp->ip, &chunks, NULL);
-
- if (dp->num_text > 0)
- {
- dp->text_ptr = voidcast(png_textp, malloc(dp->num_text * sizeof *chunks));
-
- if (dp->text_ptr == NULL)
- display_log(dp, APP_ERROR, "text chunks: stash malloc failed");
-
- else
- memcpy(dp->text_ptr, chunks, dp->num_text * sizeof *chunks);
- }
-
- dp->text_stashed = 1; /* regardless of whether there are chunks or not */
-}
-
-#define text_stash(dp) if (!dp->text_stashed) text_stash(dp)
-
-static void
-text_restore(struct display *dp)
-{
- /* libpng makes a copy, so this is fine: */
- if (dp->text_ptr != NULL)
- png_set_text(dp->write_pp, dp->ip, dp->text_ptr, dp->num_text);
-}
-
-#define text_restore(dp) if (dp->text_stashed) text_restore(dp)
-
-#else
-#define text_stash(dp) ((void)0)
-#define text_restore(dp) ((void)0)
-#endif /* pre 1.7 */
-
-/* OPTIONS:
- *
- * The command handles options of the forms:
- *
- * --option
- * Turn an option on (Option)
- * --no-option
- * Turn an option off (Option)
- * --option=value
- * Set an option to a value (Value)
- * --option=val1,val2,val3
- * Set an option to a bitmask constructed from the values (List)
- */
-static png_byte
-option_index(struct display *dp, const char *opt, size_t len)
- /* Return the index (in options[]) of the given option, outputs an error if
- * it does not exist. Takes the name of the option and a length (number of
- * characters in the name).
- */
-{
- png_byte j;
-
- for (j=0; j<option_count; ++j)
- if (strncmp(options[j].name, opt, len) == 0 && options[j].name[len] == 0)
- return j;
-
- /* If the setjmp buffer is set the code is asking for an option index; this
- * is bad. Otherwise this is the command line option parsing.
- */
- display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
- "%.*s: unknown option", (int)/*SAFE*/len, opt);
- abort(); /* NOT REACHED */
-}
-
-/* This works for an option name (no quotes): */
-#define OPTIND(dp, name) option_index(dp, #name, (sizeof #name)-1)
-
-static int
-get_option(struct display *dp, const char *opt, int *value)
-{
- png_byte i = option_index(dp, opt, strlen(opt));
-
- if (dp->entry[i]) /* option was set on command line */
- {
- *value = dp->value[i];
- return 1;
- }
-
- else
- return 0;
-}
-
-static int
-set_opt_string_(struct display *dp, unsigned int sp, png_byte opt,
- const char *entry_name)
- /* Add the appropriate option string to dp->curr. */
-{
- int offset, add;
-
- if (sp > 0)
- offset = dp->stack[sp-1].opt_string_end;
-
- else
- offset = dp->opt_string_start;
-
- if (entry_name == range_lo)
- add = sprintf(dp->curr+offset, " --%s=%d", options[opt].name,
- dp->value[opt]);
-
- else
- add = sprintf(dp->curr+offset, " --%s=%s", options[opt].name, entry_name);
-
- if (add < 0)
- display_log(dp, INTERNAL_ERROR, "sprintf failed");
-
- assert(offset+add < (int)/*SAFE*/sizeof dp->curr);
- return offset+add;
-}
-
-static void
-set_opt_string(struct display *dp, unsigned int sp)
- /* Add the appropriate option string to dp->curr. */
-{
- dp->stack[sp].opt_string_end = set_opt_string_(dp, sp, dp->stack[sp].opt,
- options[dp->stack[sp].opt].values[dp->stack[sp].entry].name);
-}
-
-static void
-record_opt(struct display *dp, png_byte opt, const char *entry_name)
- /* Record this option in dp->curr; called for an option not being searched,
- * the caller passes in the name of the value, or range_lo to use the
- * numerical value.
- */
-{
- unsigned int sp = dp->csp; /* stack entry of next searched option */
-
- if (sp >= dp->tsp)
- {
- /* At top of stack; add the opt string for this entry to the previous
- * searched entry or the start of the dp->curr buffer if there is nothing
- * on the stack yet (sp == 0).
- */
- int offset = set_opt_string_(dp, sp, opt, entry_name);
-
- if (sp > 0)
- dp->stack[sp-1].opt_string_end = offset;
-
- else
- dp->opt_string_start = offset;
- }
-
- /* else do nothing: option already recorded */
-}
-
-static int
-opt_list_end(struct display *dp, png_byte opt, png_byte entry)
-{
- if (options[opt].values[entry].name == range_lo)
- return entry+1U >= options[opt].value_count /* missing range_hi */ ||
- options[opt].values[entry+1U].name != range_hi /* likewise */ ||
- options[opt].values[entry+1U].value <= dp->value[opt] /* range end */;
-
- else
- return entry+1U >= options[opt].value_count /* missing 'all' */ ||
- options[opt].values[entry+1U].name == all /* last entry */;
-}
-
-static void
-push_opt(struct display *dp, unsigned int sp, png_byte opt, int search)
- /* Push a new option onto the stack, initializing the new stack entry
- * appropriately; this does all the work of next_opt (setting end/nsp) for
- * the first entry in the list.
- */
-{
- png_byte entry;
- const char *entry_name;
-
- assert(sp == dp->tsp && sp < SL);
-
- /* The starting entry is entry 0 unless there is a range in which case it is
- * the entry corresponding to range_lo:
- */
- entry = options[opt].value_count;
- assert(entry > 0U);
-
- do
- {
- entry_name = options[opt].values[--entry].name;
- if (entry_name == range_lo)
- break;
- }
- while (entry > 0U);
-
- dp->tsp = sp+1U;
- dp->stack[sp].best_size =
- dp->stack[sp].lo_size =
- dp->stack[sp].hi_size = MAX_SIZE;
-
- if (search && entry_name == range_lo) /* search this range */
- {
- dp->stack[sp].lo = options[opt].values[entry].value;
- /* check for a mal-formed RANGE above: */
- assert(entry+1 < options[opt].value_count &&
- options[opt].values[entry+1].name == range_hi);
- dp->stack[sp].hi = options[opt].values[entry+1].value;
- }
-
- else
- {
- /* next_opt will just iterate over the range. */
- dp->stack[sp].lo = INT_MAX;
- dp->stack[sp].hi = INT_MIN; /* Prevent range chop */
- }
-
- dp->stack[sp].opt = opt;
- dp->stack[sp].entry = entry;
- dp->stack[sp].best_val = dp->value[opt] = options[opt].values[entry].value;
-
- set_opt_string(dp, sp);
-
- /* This works for the search case too; if the range has only one entry 'end'
- * will be marked here.
- */
- if (opt_list_end(dp, opt, entry))
- {
- dp->stack[sp].end = 1;
- /* Skip the warning if pngcp did this itself. See the code in
- * set_windowBits_hi.
- */
- if (opt != dp->min_windowBits)
- display_log(dp, APP_WARNING, "%s: only testing one value",
- options[opt].name);
- }
-
- else
- {
- dp->stack[sp].end = 0;
- dp->nsp = dp->tsp;
- }
-
- /* Do a lazy cache of the text chunks for libpng 1.6 and earlier; this is
- * because they can only be written once(!) so if we are going to re-use the
- * png_info we need a copy.
- */
- text_stash(dp);
-}
-
-static void
-next_opt(struct display *dp, unsigned int sp)
- /* Return the next value for this option. When called 'sp' is expected to be
- * the topmost stack entry - only the topmost entry changes each time round -
- * and there must be a valid entry to return. next_opt will set dp->nsp to
- * sp+1 if more entries are available, otherwise it will not change it and
- * set dp->stack[s].end to true.
- */
-{
- int search = 0;
- png_byte entry, opt;
- const char *entry_name;
-
- /* dp->stack[sp] must be the top stack entry and it must be active: */
- assert(sp+1U == dp->tsp && !dp->stack[sp].end);
-
- opt = dp->stack[sp].opt;
- entry = dp->stack[sp].entry;
- assert(entry+1U < options[opt].value_count);
- entry_name = options[opt].values[entry].name;
- assert(entry_name != NULL);
-
- /* For ranges increment the value but don't change the entry, for all other
- * cases move to the next entry and load its value:
- */
- if (entry_name == range_lo) /* a range */
- {
- /* A range can be iterated over or searched. The default iteration option
- * is indicated by hi < lo on the stack, otherwise the range being search
- * is [lo..hi] (inclusive).
- */
- if (dp->stack[sp].lo > dp->stack[sp].hi)
- dp->value[opt]++;
-
- else
- {
- /* This is the best size found for this option value: */
- png_alloc_size_t best_size = dp->stack[sp].best_size;
- int lo = dp->stack[sp].lo;
- int hi = dp->stack[sp].hi;
- int val = dp->value[opt];
-
- search = 1; /* end is determined here */
- assert(best_size < MAX_SIZE);
-
- if (val == lo)
- {
- /* Finding the best for the low end of the range: */
- dp->stack[sp].lo_size = best_size;
- assert(hi > val);
-
- if (hi == val+1) /* only 2 entries */
- dp->stack[sp].end = 1;
-
- val = hi;
- }
-
- else if (val == hi)
- {
- dp->stack[sp].hi_size = best_size;
- assert(val > lo+1); /* else 'end' set above */
-
- if (val == lo+2) /* only three entries to test */
- dp->stack[sp].end = 1;
-
- val = (lo + val)/2;
- }
-
- else
- {
- png_alloc_size_t lo_size = dp->stack[sp].lo_size;
- png_alloc_size_t hi_size = dp->stack[sp].hi_size;
-
- /* lo and hi should have been tested. */
- assert(lo_size < MAX_SIZE && hi_size < MAX_SIZE);
-
- /* These cases arise with the 'probe' handling below when there is a
- * dip or peak in the size curve.
- */
- if (val < lo) /* probing a new lo */
- {
- /* Swap lo and val: */
- dp->stack[sp].lo = val;
- dp->stack[sp].lo_size = best_size;
- val = lo;
- best_size = lo_size;
- lo = dp->stack[sp].lo;
- lo_size = dp->stack[sp].lo_size;
- }
-
- else if (val > hi) /* probing a new hi */
- {
- /* Swap hi and val: */
- dp->stack[sp].hi = val;
- dp->stack[sp].hi_size = best_size;
- val = hi;
- best_size = hi_size;
- hi = dp->stack[sp].hi;
- hi_size = dp->stack[sp].hi_size;
- }
-
- /* The following should be true or something got messed up above. */
- assert(lo < val && val < hi);
-
- /* If there are only four entries (lo, val, hi plus one more) just
- * test the remaining entry.
- */
- if (hi == lo+3)
- {
- /* Because of the 'probe' code val can either be lo+1 or hi-1; we
- * need to test the other.
- */
- val = lo + ((val == lo+1) ? 2 : 1);
- assert(lo < val && val < hi);
- dp->stack[sp].end = 1;
- }
-
- else
- {
- /* There are at least 2 entries still untested between lo and hi,
- * i.e. hi >= lo+4. 'val' is the midpoint +/- 0.5
- *
- * Separate out the four easy cases when lo..val..hi are
- * monotonically decreased or (more weird) increasing:
- */
- assert(hi > lo+3);
-
- if (lo_size <= best_size && best_size <= hi_size)
- {
- /* Select the low range; testing this first favours the low
- * range over the high range when everything comes out equal.
- * Because of the probing 'val' may be lo+1. In that case end
- * the search and set 'val' to lo+2.
- */
- if (val == lo+1)
- {
- ++val;
- dp->stack[sp].end = 1;
- }
-
- else
- {
- dp->stack[sp].hi = hi = val;
- dp->stack[sp].hi_size = best_size;
- val = (lo + val) / 2;
- }
- }
-
- else if (lo_size >= best_size && best_size >= hi_size)
- {
- /* Monotonically decreasing size; this is the expected case.
- * Select the high end of the range. As above, val may be
- * hi-1.
- */
- if (val == hi-1)
- {
- --val;
- dp->stack[sp].end = 1;
- }
-
- else
- {
- dp->stack[sp].lo = lo = val;
- dp->stack[sp].lo_size = best_size;
- val = (val + hi) / 2;
- }
- }
-
- /* If both those tests failed 'best_size' is either greater than
- * or less than both lo_size and hi_size. There is a peak or dip
- * in the curve of sizes from lo to hi and val is on the peak or
- * dip.
- *
- * Because the ranges being searched as so small (level is 1..9,
- * windowBits 8..15, memLevel 1..9) there will only be at most
- * three untested values between lo..val and val..hi, so solve
- * the problem by probing down from hi or up from lo, whichever
- * is the higher.
- *
- * This is the place where 'val' is set to outside the range
- * lo..hi, described as 'probing', though maybe 'narrowing' would
- * be more accurate.
- */
- else if (lo_size <= hi_size) /* down from hi */
- {
- dp->stack[sp].hi = val;
- dp->stack[sp].hi_size = best_size;
- val = --hi;
- }
-
- else /* up from low */
- {
- dp->stack[sp].lo = val;
- dp->stack[sp].lo_size = best_size;
- val = ++lo;
- }
-
- /* lo and hi are still the true range limits, check for the end
- * condition.
- */
- assert(hi > lo+1);
- if (hi <= lo+2)
- dp->stack[sp].end = 1;
- }
- }
-
- assert(val != dp->stack[sp].best_val); /* should be a new value */
- dp->value[opt] = val;
- dp->stack[sp].best_size = MAX_SIZE;
- }
- }
-
- else
- {
- /* Increment 'entry' */
- dp->value[opt] = options[opt].values[++entry].value;
- dp->stack[sp].entry = entry;
- }
-
- set_opt_string(dp, sp);
-
- if (!search && opt_list_end(dp, opt, entry)) /* end of list */
- dp->stack[sp].end = 1;
-
- else if (!dp->stack[sp].end) /* still active after all these tests */
- dp->nsp = dp->tsp;
-}
-
-static int
-compare_option(const struct display *dp, unsigned int sp)
-{
- int opt = dp->stack[sp].opt;
-
- /* If the best so far is numerically less than the current value the
- * current set of options is invariably worse.
- */
- if (dp->stack[sp].best_val < dp->value[opt])
- return -1;
-
- /* Lists of options are searched out of numerical order (currently only
- * strategy), so only return +1 here when a range is being searched.
- */
- else if (dp->stack[sp].best_val > dp->value[opt])
- {
- if (dp->stack[sp].lo <= dp->stack[sp].hi /*searching*/)
- return 1;
-
- else
- return -1;
- }
-
- else
- return 0; /* match; current value is the best one */
-}
-
-static int
-advance_opt(struct display *dp, png_byte opt, int search)
-{
- unsigned int sp = dp->csp++; /* my stack entry */
-
- assert(sp >= dp->nsp); /* nsp starts off zero */
-
- /* If the entry was active in the previous run dp->stack[sp] is already
- * set up and dp->tsp will be greater than sp, otherwise a new entry
- * needs to be created.
- *
- * dp->nsp is handled this way:
- *
- * 1) When an option is pushed onto the stack dp->nsp and dp->tsp are
- * both set (by push_opt) to the next stack entry *unless* there is
- * only one entry in the new list, in which case dp->stack[sp].end
- * is set.
- *
- * 2) For the top stack entry next_opt is called. The entry must be
- * active (dp->stack[sp].end is not set) and either 'nsp' or 'end'
- * will be updated as appropriate.
- *
- * 3) For lower stack entries nsp is set unless the stack entry is
- * already at the end. This means that when all the higher entries
- * are popped this entry will be too.
- */
- if (sp >= dp->tsp)
- {
- push_opt(dp, sp, opt, search); /* This sets tsp to sp+1 */
- return 1; /* initialized */
- }
-
- else
- {
- int ret = 0; /* unchanged */
-
- /* An option that is already on the stack; update best_size and best_val
- * if appropriate. On the first run there are no previous values and
- * dp->write_size will be MAX_SIZE, however on the first run dp->tsp
- * starts off as 0.
- */
- assert(dp->write_size > 0U && dp->write_size < MAX_SIZE);
-
- if (dp->stack[sp].best_size > dp->write_size ||
- (dp->stack[sp].best_size == dp->write_size &&
- compare_option(dp, sp) > 0))
- {
- dp->stack[sp].best_size = dp->write_size;
- dp->stack[sp].best_val = dp->value[opt];
- }
-
- if (sp+1U >= dp->tsp)
- {
- next_opt(dp, sp);
- ret = 1; /* advanced */
- }
-
- else if (!dp->stack[sp].end) /* Active, not at top of stack */
- dp->nsp = sp+1U;
-
- return ret; /* advanced || unchanged */
- }
-}
-
-static int
-getallopts_(struct display *dp, png_byte opt, int *value, int record)
- /* Like getop but iterate over all the values if the option was set to "all".
- */
-{
- if (dp->entry[opt]) /* option was set on command line */
- {
- /* Simple, single value, entries don't have a stack frame and have a fixed
- * value (it doesn't change once set on the command line). Otherwise the
- * value (entry) selected from the command line is 'all':
- */
- const char *entry_name = options[opt].values[dp->entry[opt]-1].name;
-
- if (entry_name == all)
- (void)advance_opt(dp, opt, 0/*do not search; iterate*/);
-
- else if (record)
- record_opt(dp, opt, entry_name);
-
- *value = dp->value[opt];
- return 1; /* set */
- }
-
- else
- return 0; /* not set */
-}
-
-static int
-getallopts(struct display *dp, const char *opt_str, int *value)
-{
- return getallopts_(dp, option_index(dp, opt_str, strlen(opt_str)), value, 0);
-}
-
-static int
-getsearchopts(struct display *dp, const char *opt_str, int *value)
- /* As above except that if the option was not set try a search */
-{
- png_byte istrat;
- png_byte opt = option_index(dp, opt_str, strlen(opt_str));
- int record = options[opt].search;
- const char *entry_name;
-
- /* If it was set on the command line honour the setting, including 'all'
- * which will override the built in search:
- */
- if (getallopts_(dp, opt, value, record))
- return 1;
-
- else if (!record) /* not a search option */
- return 0; /* unset and not searched */
-
- /* Otherwise decide what to do here. */
- istrat = OPTIND(dp, strategy);
- entry_name = range_lo; /* record the value, not the name */
-
- if (opt == istrat) /* search all strategies */
- (void)advance_opt(dp, opt, 0/*iterate*/), record=0;
-
- else if (opt == OPTIND(dp, level))
- {
- /* Both RLE and HUFFMAN don't benefit from level increases */
- if (dp->value[istrat] == Z_RLE || dp->value[istrat] == Z_HUFFMAN_ONLY)
- dp->value[opt] = 1;
-
- else /* fixed, filtered or default */
- (void)advance_opt(dp, opt, 1/*search*/), record=0;
- }
-
- else if (opt == OPTIND(dp, windowBits))
- {
- /* Changing windowBits for strategies that do not search the window is
- * pointless. Huffman-only does not search, RLE only searches backwards
- * one byte, so given that the maximum string length is 258, a windowBits
- * of 9 is always sufficient.
- */
- if (dp->value[istrat] == Z_HUFFMAN_ONLY)
- dp->value[opt] = 8;
-
- else if (dp->value[istrat] == Z_RLE)
- dp->value[opt] = 9;
-
- else /* fixed, filtered or default */
- (void)advance_opt(dp, opt, 1/*search*/), record=0;
- }
-
- else if (opt == OPTIND(dp, memLevel))
- {
-# if 0
- (void)advance_opt(dp, opt, 0/*all*/), record=0;
-# else
- dp->value[opt] = MAX_MEM_LEVEL;
-# endif
- }
-
- else /* something else */
- assert(0=="reached");
-
- if (record)
- record_opt(dp, opt, entry_name);
-
- /* One of the above searched options: */
- *value = dp->value[opt];
- return 1;
-}
-
-static int
-find_val(struct display *dp, png_byte opt, const char *str, size_t len)
- /* Like option_index but sets (index+i) of the entry in options[opt] that
- * matches str[0..len-1] into dp->entry[opt] as well as returning the actual
- * value.
- */
-{
- int rlo = INT_MAX, rhi = INT_MIN;
- png_byte j, irange = 0;
-
- for (j=1U; j<=options[opt].value_count; ++j)
- {
- if (strncmp(options[opt].values[j-1U].name, str, len) == 0 &&
- options[opt].values[j-1U].name[len] == 0)
- {
- dp->entry[opt] = j;
- return options[opt].values[j-1U].value;
- }
- else if (options[opt].values[j-1U].name == range_lo)
- rlo = options[opt].values[j-1U].value, irange = j;
- else if (options[opt].values[j-1U].name == range_hi)
- rhi = options[opt].values[j-1U].value;
- }
-
- /* No match on the name, but there may be a range. */
- if (irange > 0)
- {
- char *ep = NULL;
- long l = strtol(str, &ep, 0);
-
- if (ep == str+len && l >= rlo && l <= rhi)
- {
- dp->entry[opt] = irange; /* range_lo */
- return (int)/*SAFE*/l;
- }
- }
-
- display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
- "%s: unknown value setting '%.*s'", options[opt].name,
- (int)/*SAFE*/len, str);
- abort(); /* NOT REACHED */
-}
-
-static int
-opt_check(struct display *dp, const char *arg)
-{
- assert(dp->errset == 0);
-
- if (arg != NULL && arg[0] == '-' && arg[1] == '-')
- {
- int i = 0, negate = (strncmp(arg+2, "no-", 3) == 0), val;
- png_byte j;
-
- if (negate)
- arg += 5; /* --no- */
-
- else
- arg += 2; /* -- */
-
- /* Find the length (expect arg\0 or arg=) */
- while (arg[i] != 0 && arg[i] != '=') ++i;
-
- /* So arg[0..i-1] is the argument name, this does not return if this isn't
- * a valid option name.
- */
- j = option_index(dp, arg, i);
-
- /* It matcheth an option; check the remainder. */
- if (arg[i] == 0) /* no specified value, use the default */
- {
- val = options[j].values[negate].value;
- dp->entry[j] = (png_byte)/*SAFE*/(negate + 1U);
- }
-
- else
- {
- const char *list = arg + (i+1);
-
- /* Expect a single value here unless this is a list, in which case
- * multiple values are combined.
- */
- if (options[j].opt != LIST)
- {
- /* find_val sets 'dp->entry[j]' to a non-zero value: */
- val = find_val(dp, j, list, strlen(list));
-
- if (negate)
- {
- if (options[j].opt < OPTION)
- val = !val;
-
- else
- {
- display_log(dp, USER_ERROR,
- "%.*s: option=arg cannot be negated", i, arg);
- abort(); /* NOT REACHED */
- }
- }
- }
-
- else /* multiple options separated by ',' characters */
- {
- /* --no-option negates list values from the default, which should
- * therefore be 'all'. Notice that if the option list is empty in
- * this case nothing will be removed and therefore --no-option= is
- * the same as --option.
- */
- if (negate)
- val = options[j].values[0].value;
-
- else
- val = 0;
-
- while (*list != 0) /* allows option= which sets 0 */
- {
- /* A value is terminated by the end of the list or a ','
- * character.
- */
- int v, iv;
-
- iv = 0; /* an index into 'list' */
- while (list[++iv] != 0 && list[iv] != ',') {}
-
- v = find_val(dp, j, list, iv);
-
- if (negate)
- val &= ~v;
-
- else
- val |= v;
-
- list += iv;
- if (*list != 0)
- ++list; /* skip the ',' */
- }
- }
- }
-
- /* 'val' is the new value, store it for use later and debugging: */
- dp->value[j] = val;
-
- if (options[j].opt < LEVEL_MASK)
- {
- /* The handling for error levels is to set the level. */
- if (val) /* Set this level */
- dp->options = (dp->options & ~LEVEL_MASK) | options[j].opt;
-
- else
- display_log(dp, USER_ERROR,
- "%.*s: messages cannot be turned off individually; set a message level",
- i, arg);
- }
-
- else if (options[j].opt < OPTION)
- {
- if (val)
- dp->options |= options[j].opt;
-
- else
- dp->options &= ~options[j].opt;
- }
-
- return 1; /* this is an option */
- }
-
- else
- return 0; /* not an option */
-}
-
-#ifdef PNG_PNGCP_TIMING_SUPPORTED
-static void
-set_timer(struct display *dp, struct timespec *timer)
-{
- /* Do the timing using clock_gettime and the per-process timer. */
- if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, timer))
- {
- display_log(dp, APP_ERROR,
- "CLOCK_PROCESS_CPUTIME_ID: %s: timing disabled\n", strerror(errno));
- dp->value[OPTIND(dp,time)] = 0; /* i.e. off */
- }
-}
-
-static void
-start_timer(struct display *dp, int what)
-{
- if ((dp->value[OPTIND(dp,time)] & what) != 0)
- set_timer(dp, what == PNGCP_TIME_READ ? &dp->read_time : &dp->write_time);
-}
-
-static void
-end_timer(struct display *dp, int what)
-{
- if ((dp->value[OPTIND(dp,time)] & what) != 0)
- {
- struct timespec t, tmp;
-
- set_timer(dp, &t);
-
- if (what == PNGCP_TIME_READ)
- tmp = dp->read_time;
-
- else
- tmp = dp->write_time;
-
- t.tv_sec -= tmp.tv_sec;
- t.tv_nsec -= tmp.tv_nsec;
-
- if (t.tv_nsec < 0)
- {
- --(t.tv_sec);
- t.tv_nsec += 1000000000L;
- }
-
- if (what == PNGCP_TIME_READ)
- dp->read_time = t, tmp = dp->read_time_total;
-
- else
- dp->write_time = t, tmp = dp->write_time_total;
-
- tmp.tv_sec += t.tv_sec;
- tmp.tv_nsec += t.tv_nsec;
-
- if (tmp.tv_nsec >= 1000000000L)
- {
- ++(tmp.tv_sec);
- tmp.tv_nsec -= 1000000000L;
- }
-
- if (what == PNGCP_TIME_READ)
- dp->read_time_total = tmp;
-
- else
- dp->write_time_total = tmp;
- }
-}
-
-static void
-print_time(const char *what, struct timespec t)
-{
- printf("%s %.2lu.%.9ld", what, (unsigned long)t.tv_sec, t.tv_nsec);
-}
-#else /* !PNGCP_TIMING */
-#define start_timer(dp, what) ((void)0)
-#define end_timer(dp, what) ((void)0)
-#endif /* !PNGCP_TIMING */
-
-/* The following is used in main to verify that the final argument is a
- * directory:
- */
-static int
-checkdir(const char *pathname)
-{
- struct stat buf;
- return stat(pathname, &buf) == 0 && S_ISDIR(buf.st_mode);
-}
-
-/* Work out whether a path is valid (if not a display_log occurs), a directory
- * (1 is returned) or a file *or* non-existent (0 is returned).
- *
- * Used for a write path.
- */
-static int
-isdir(struct display *dp, const char *pathname)
-{
- if (pathname == NULL)
- return 0; /* stdout */
-
- else if (pathname[0] == 0)
- return 1; /* empty string */
-
- else
- {
- struct stat buf;
- int ret = stat(pathname, &buf);
-
- if (ret == 0) /* the entry exists */
- {
- if (S_ISDIR(buf.st_mode))
- return 1;
-
- /* Else expect an object that exists and can be written: */
- if (access(pathname, W_OK) != 0)
- display_log(dp, USER_ERROR, "%s: cannot be written (%s)", pathname,
- strerror(errno));
-
- return 0; /* file (exists, can be written) */
- }
-
- else /* an error */
- {
- /* Non-existence is fine, other errors are not: */
- if (errno != ENOENT)
- display_log(dp, USER_ERROR, "%s: invalid output name (%s)",
- pathname, strerror(errno));
-
- return 0; /* file (does not exist) */
- }
- }
-}
-
-static void
-makename(struct display *dp, const char *dir, const char *infile)
-{
- /* Make a name for an output file (and check it). */
- dp->namebuf[0] = 0;
-
- if (dir == NULL || infile == NULL)
- display_log(dp, INTERNAL_ERROR, "NULL name to makename");
-
- else
- {
- size_t dsize = strlen(dir);
-
- if (dsize <= (sizeof dp->namebuf)-2) /* Allow for name + '/' + '\0' */
- {
- size_t isize = strlen(infile);
- size_t istart = isize-1;
-
- /* This should fail before here: */
- if (infile[istart] == '/')
- display_log(dp, INTERNAL_ERROR, "infile with trailing /");
-
- memcpy(dp->namebuf, dir, dsize);
- if (dsize > 0 && dp->namebuf[dsize-1] != '/')
- dp->namebuf[dsize++] = '/';
-
- /* Find the rightmost non-/ character: */
- while (istart > 0 && infile[istart-1] != '/')
- --istart;
-
- isize -= istart;
- infile += istart;
-
- if (dsize+isize < (sizeof dp->namebuf)) /* dsize + infile + '\0' */
- {
- memcpy(dp->namebuf+dsize, infile, isize+1);
-
- if (isdir(dp, dp->namebuf))
- display_log(dp, USER_ERROR, "%s: output file is a directory",
- dp->namebuf);
- }
-
- else
- {
- dp->namebuf[dsize] = 0; /* allowed for: -2 at start */
- display_log(dp, USER_ERROR, "%s%s: output file name too long",
- dp->namebuf, infile);
- }
- }
-
- else
- display_log(dp, USER_ERROR, "%s: output directory name too long", dir);
- }
-}
-
-/* error handler callbacks for libpng */
-static void PNGCBAPI
-display_warning(png_structp pp, png_const_charp warning)
-{
- struct display *dp = get_dp(pp);
-
- /* This is used to prevent repeated warnings while searching */
- if (!dp->no_warnings)
- display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
-}
-
-static void PNGCBAPI
-display_error(png_structp pp, png_const_charp error)
-{
- struct display *dp = get_dp(pp);
-
- display_log(dp, LIBPNG_ERROR, "%s", error);
-}
-
-static void
-display_start_read(struct display *dp, const char *filename)
-{
- if (filename != NULL)
- {
- dp->filename = filename;
- dp->fp = fopen(filename, "rb");
- }
-
- else
- {
- dp->filename = "<stdin>";
- dp->fp = stdin;
- }
-
- dp->w = dp->h = 0U;
- dp->bpp = 0U;
- dp->size = 0U;
- dp->read_size = 0U;
-
- if (dp->fp == NULL)
- display_log(dp, USER_ERROR, "file open failed (%s)", strerror(errno));
-}
-
-static void PNGCBAPI
-read_function(png_structp pp, png_bytep data, size_t size)
-{
- struct display *dp = get_dp(pp);
-
- if (size == 0U || fread(data, size, 1U, dp->fp) == 1U)
- dp->read_size += size;
-
- else
- {
- if (feof(dp->fp))
- display_log(dp, LIBPNG_ERROR, "PNG file truncated");
- else
- display_log(dp, LIBPNG_ERROR, "PNG file read failed (%s)",
- strerror(errno));
- }
-}
-
-static void
-read_png(struct display *dp, const char *filename)
-{
- display_clean_read(dp); /* safety */
- display_start_read(dp, filename);
-
- dp->read_pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
- display_error, display_warning);
- if (dp->read_pp == NULL)
- display_log(dp, LIBPNG_ERROR, "failed to create read struct");
-
-# ifdef PNG_BENIGN_ERRORS_SUPPORTED
- png_set_benign_errors(dp->read_pp, 1/*allowed*/);
-# endif /* BENIGN_ERRORS */
-
-# ifdef FIX_INDEX
- if ((dp->options & FIX_INDEX) != 0)
- png_set_check_for_invalid_index(dp->read_pp, 1/*on, no warning*/);
-# ifdef IGNORE_INDEX
- else
-# endif /* IGNORE_INDEX */
-# endif /* FIX_INDEX */
-# ifdef IGNORE_INDEX
- if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
- png_set_check_for_invalid_index(dp->read_pp, -1/*off completely*/);
-# endif /* IGNORE_INDEX */
-
- /* The png_read_png API requires us to make the info struct, but it does the
- * call to png_read_info.
- */
- dp->ip = png_create_info_struct(dp->read_pp);
- if (dp->ip == NULL)
- png_error(dp->read_pp, "failed to create info struct");
-
- /* Set the IO handling */
- png_set_read_fn(dp->read_pp, dp, read_function);
-
-# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- png_set_keep_unknown_chunks(dp->read_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
- 0);
-# endif /* HANDLE_AS_UNKNOWN */
-
-# ifdef PNG_SET_USER_LIMITS_SUPPORTED
- /* Remove the user limits, if any */
- png_set_user_limits(dp->read_pp, 0x7fffffff, 0x7fffffff);
-# endif /* SET_USER_LIMITS */
-
- /* Now read the PNG. */
- start_timer(dp, PNGCP_TIME_READ);
- png_read_png(dp->read_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
- end_timer(dp, PNGCP_TIME_READ);
- dp->w = png_get_image_width(dp->read_pp, dp->ip);
- dp->h = png_get_image_height(dp->read_pp, dp->ip);
- dp->ct = png_get_color_type(dp->read_pp, dp->ip);
- dp->bpp = png_get_bit_depth(dp->read_pp, dp->ip) *
- png_get_channels(dp->read_pp, dp->ip);
- {
- /* png_get_rowbytes should never return 0 because the value is set by the
- * first call to png_set_IHDR, which should have happened by now, but just
- * in case:
- */
- png_alloc_size_t rb = png_get_rowbytes(dp->read_pp, dp->ip);
-
- if (rb == 0)
- png_error(dp->read_pp, "invalid row byte count from libpng");
-
- /* The size calc can overflow. */
- if ((MAX_SIZE-dp->h)/rb < dp->h)
- png_error(dp->read_pp, "image too large");
-
- dp->size = rb * dp->h + dp->h/*filter byte*/;
- }
-
-#ifdef FIX_INDEX
- if (dp->ct == PNG_COLOR_TYPE_PALETTE && (dp->options & FIX_INDEX) != 0)
- {
- int max = png_get_palette_max(dp->read_pp, dp->ip);
- png_colorp palette = NULL;
- int num = -1;
-
- if (png_get_PLTE(dp->read_pp, dp->ip, &palette, &num) != PNG_INFO_PLTE
- || max < 0 || num <= 0 || palette == NULL)
- display_log(dp, LIBPNG_ERROR, "invalid png_get_PLTE result");
-
- if (max >= num)
- {
- /* 'Fix' the palette. */
- int i;
- png_color newpal[256];
-
- for (i=0; i<num; ++i)
- newpal[i] = palette[i];
-
- /* Fill in any remainder with a warning color: */
- for (; i<=max; ++i)
- {
- newpal[i].red = 0xbe;
- newpal[i].green = 0xad;
- newpal[i].blue = 0xed;
- }
-
- png_set_PLTE(dp->read_pp, dp->ip, newpal, i);
- }
- }
-#endif /* FIX_INDEX */
-
- display_clean_read(dp);
- dp->operation = "none";
-}
-
-static void
-display_start_write(struct display *dp, const char *filename)
-{
- assert(dp->fp == NULL);
-
- if ((dp->options & NOWRITE) != 0)
- dp->output_file = "<no write>";
-
- else
- {
- if (filename != NULL)
- {
- dp->output_file = filename;
- dp->fp = fopen(filename, "wb");
- }
-
- else
- {
- dp->output_file = "<stdout>";
- dp->fp = stdout;
- }
-
- if (dp->fp == NULL)
- display_log(dp, USER_ERROR, "%s: file open failed (%s)",
- dp->output_file, strerror(errno));
- }
-}
-
-static void PNGCBAPI
-write_function(png_structp pp, png_bytep data, size_t size)
-{
- struct display *dp = get_dp(pp);
-
- /* The write fail is classed as a USER_ERROR, so --quiet does not turn it
- * off, this seems more likely to be correct.
- */
- if (dp->fp == NULL || fwrite(data, size, 1U, dp->fp) == 1U)
- {
- dp->write_size += size;
- if (dp->write_size < size || dp->write_size == MAX_SIZE)
- png_error(pp, "IDAT size overflow");
- }
-
- else
- display_log(dp, USER_ERROR, "%s: PNG file write failed (%s)",
- dp->output_file, strerror(errno));
-}
-
-/* Compression option, 'method' is never set: there is no choice.
- *
- * IMPORTANT: the order of the entries in this macro determines the preference
- * order when two different combos of two of these options produce an IDAT of
- * the same size. The logic here is to put the things that affect the decoding
- * of the PNG image ahead of those that are relevant only to the encoding.
- */
-#define SET_COMPRESSION\
- SET(strategy, strategy);\
- SET(windowBits, window_bits);\
- SET(level, level);\
- SET(memLevel, mem_level);
-
-#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
-static void
-search_compression(struct display *dp)
-{
- /* Like set_compression below but use a more restricted search than 'all' */
- int val;
-
-# define SET(name, func) if (getsearchopts(dp, #name, &val))\
- png_set_compression_ ## func(dp->write_pp, val);
- SET_COMPRESSION
-# undef SET
-}
-
-static void
-set_compression(struct display *dp)
-{
- int val;
-
-# define SET(name, func) if (getallopts(dp, #name, &val))\
- png_set_compression_ ## func(dp->write_pp, val);
- SET_COMPRESSION
-# undef SET
-}
-
-#ifdef PNG_SW_COMPRESS_level /* 1.7.0+ */
-static void
-set_ICC_profile_compression(struct display *dp)
-{
- int val;
-
-# define SET(name, func) if (getallopts(dp, "ICC-profile-" #name, &val))\
- png_set_ICC_profile_compression_ ## func(dp->write_pp, val);
- SET_COMPRESSION
-# undef SET
-}
-#else
-# define set_ICC_profile_compression(dp) ((void)0)
-#endif
-#else
-# define search_compression(dp) ((void)0)
-# define set_compression(dp) ((void)0)
-# define set_ICC_profile_compression(dp) ((void)0)
-#endif /* WRITE_CUSTOMIZE_COMPRESSION */
-
-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
-static void
-set_text_compression(struct display *dp)
-{
- int val;
-
-# define SET(name, func) if (getallopts(dp, "text-" #name, &val))\
- png_set_text_compression_ ## func(dp->write_pp, val);
- SET_COMPRESSION
-# undef SET
-}
-#else
-# define set_text_compression(dp) ((void)0)
-#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
-
-static void
-write_png(struct display *dp, const char *destname)
-{
- display_clean_write(dp); /* safety */
- display_start_write(dp, destname);
-
- dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
- display_error, display_warning);
-
- if (dp->write_pp == NULL)
- display_log(dp, LIBPNG_ERROR, "failed to create write png_struct");
-
-# ifdef PNG_BENIGN_ERRORS_SUPPORTED
- png_set_benign_errors(dp->write_pp, 1/*allowed*/);
-# endif /* BENIGN_ERRORS */
-
- png_set_write_fn(dp->write_pp, dp, write_function, NULL/*flush*/);
-
-#ifdef IGNORE_INDEX
- if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
- png_set_check_for_invalid_index(dp->write_pp, -1/*off completely*/);
-#endif /* IGNORE_INDEX */
-
- /* Restore the text chunks when using libpng 1.6 or less; this is a macro
- * which expands to nothing in 1.7+ In earlier versions it tests
- * dp->text_stashed, which is only set (below) *after* the first write.
- */
- text_restore(dp);
-
-# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- png_set_keep_unknown_chunks(dp->write_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
- 0);
-# endif /* HANDLE_AS_UNKNOWN */
-
-# ifdef PNG_SET_USER_LIMITS_SUPPORTED
- /* Remove the user limits, if any */
- png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
-# endif
-
- /* OPTION HANDLING */
- /* compression outputs, IDAT and zTXt/iTXt: */
- dp->tsp = dp->nsp;
- dp->nsp = dp->csp = 0;
-# ifdef PNG_SW_COMPRESS_png_level
- {
- int val;
-
- /* This sets everything, but then the following options just override
- * the specific settings for ICC profiles and text.
- */
- if (getallopts(dp, "compression", &val))
- png_set_compression(dp->write_pp, val);
-
- if (getallopts(dp, "ICC-profile-compression", &val))
- png_set_ICC_profile_compression(dp->write_pp, val);
-
- if (getallopts(dp, "text-compression", &val))
- png_set_text_compression(dp->write_pp, val);
- }
-# endif /* png_level support */
- if (dp->options & SEARCH)
- search_compression(dp);
- else
- set_compression(dp);
- set_ICC_profile_compression(dp);
- set_text_compression(dp);
-
- {
- int val;
-
- /* The permitted range is 1..0x7FFFFFFF, so the cast is safe */
- if (get_option(dp, "IDAT-size", &val))
- png_set_IDAT_size(dp->write_pp, val);
- }
-
- /* filter handling */
-# ifdef PNG_WRITE_FILTER_SUPPORTED
- {
- int val;
-
- if (get_option(dp, "filter", &val))
- png_set_filter(dp->write_pp, PNG_FILTER_TYPE_BASE, val);
- }
-# endif /* WRITE_FILTER */
-
- /* This just uses the 'read' info_struct directly, it contains the image. */
- dp->write_size = 0U;
- start_timer(dp, PNGCP_TIME_WRITE);
- png_write_png(dp->write_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
- end_timer(dp, PNGCP_TIME_WRITE);
-
- /* Make sure the file was written ok: */
- if (dp->fp != NULL)
- {
- FILE *fp = dp->fp;
- dp->fp = NULL;
- if (fclose(fp))
- display_log(dp, APP_ERROR, "%s: write failed (%s)",
- destname == NULL ? "stdout" : destname, strerror(errno));
- }
-
- /* Clean it on the way out - if control returns to the caller then the
- * written_file contains the required data.
- */
- display_clean_write(dp);
- dp->operation = "none";
-}
-
-static void
-set_windowBits_hi(struct display *dp)
-{
- /* windowBits is in the range 8..15 but zlib maps '8' to '9' so it is only
- * worth using if the data size is 256 byte or less.
- */
- int wb = MAX_WBITS; /* for large images */
- int i = VLSIZE(windowBits_IDAT);
-
- while (wb > 8 && dp->size <= 1U<<(wb-1)) --wb;
-
- while (--i >= 0) if (VLNAME(windowBits_IDAT)[i].name == range_hi) break;
-
- assert(i > 1); /* vl_windowBits_IDAT always has a RANGE() */
- VLNAME(windowBits_IDAT)[i].value = wb;
-
- assert(VLNAME(windowBits_IDAT)[--i].name == range_lo);
- VLNAME(windowBits_IDAT)[i].value = wb > 8 ? 9 : 8;
-
- /* If wb == 8 then any search has been restricted to just one windowBits
- * entry. Record that here to avoid producing a spurious app-level warning
- * above.
- */
- if (wb == 8)
- dp->min_windowBits = OPTIND(dp, windowBits);
-}
-
-static int
-better_options(const struct display *dp)
-{
- /* Are these options better than the best found so far? Normally the
- * options are tested in preference order, best first, however when doing a
- * search operation on a range the range values are tested out of order. In
- * that case preferable options will get tested later.
- *
- * This function looks through the stack from the bottom up looking for an
- * option that does not match the current best value. When it finds one it
- * checks to see if it is more or less desirable and returns true or false
- * as appropriate.
- *
- * Notice that this means that the order options are pushed onto the stack
- * conveys a priority; lower/earlier options are more important than later
- * ones.
- */
- unsigned int sp;
-
- for (sp=0; sp<dp->csp; ++sp)
- {
- int c = compare_option(dp, sp);
-
- if (c < 0)
- return 0; /* worse */
-
- else if (c > 0)
- return 1; /* better */
- }
-
- assert(0 && "unreached");
-}
-
-static void
-print_search_results(struct display *dp)
-{
- assert(dp->filename != NULL);
- printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu with '%s'\n",
- dp->filename, (unsigned long)dp->w, (unsigned long)dp->h, dp->bpp,
- cts(dp->ct), (unsigned long)dp->size, (unsigned long)dp->read_size,
- (unsigned long)dp->best_size, dp->best);
- fflush(stdout);
-}
-
-static void
-log_search(struct display *dp, unsigned int log_depth)
-{
- /* Log, and reset, the search so far: */
- if (dp->nsp/*next entry to change*/ <= log_depth)
- {
- print_search_results(dp);
- /* Start again with this entry: */
- dp->best_size = MAX_SIZE;
- }
-}
-
-static void
-cp_one_file(struct display *dp, const char *filename, const char *destname)
-{
- unsigned int log_depth;
-
- dp->filename = filename;
- dp->operation = "read";
- dp->no_warnings = 0;
-
- /* Read it then write it: */
- if (filename != NULL && access(filename, R_OK) != 0)
- display_log(dp, USER_ERROR, "%s: invalid file name (%s)",
- filename, strerror(errno));
-
- read_png(dp, filename);
-
- /* But 'destname' may be a directory. */
- dp->operation = "write";
-
- /* Limit the upper end of the windowBits range for this file */
- set_windowBits_hi(dp);
-
- /* For logging, depth to log: */
- {
- int val;
-
- if (get_option(dp, "log-depth", &val) && val >= 0)
- log_depth = (unsigned int)/*SAFE*/val;
-
- else
- log_depth = 0U;
- }
-
- if (destname != NULL) /* else stdout */
- {
- if (isdir(dp, destname))
- {
- makename(dp, destname, filename);
- destname = dp->namebuf;
- }
-
- else if (access(destname, W_OK) != 0 && errno != ENOENT)
- display_log(dp, USER_ERROR, "%s: invalid output name (%s)", destname,
- strerror(errno));
- }
-
- dp->nsp = 0;
- dp->curr[0] = 0; /* acts as a flag for the caller */
- dp->opt_string_start = 0;
- dp->best[0] = 0; /* safety */
- dp->best_size = MAX_SIZE;
- write_png(dp, destname);
-
- /* Initialize the 'best' fields: */
- strcpy(dp->best, dp->curr);
- dp->best_size = dp->write_size;
-
- if (dp->nsp > 0) /* iterating over lists */
- {
- char *tmpname, tmpbuf[(sizeof dp->namebuf) + 4];
- assert(dp->curr[0] == ' ' && dp->tsp > 0);
-
- /* Cancel warnings on subsequent writes */
- log_search(dp, log_depth);
- dp->no_warnings = 1;
-
- /* Make a temporary name for the subsequent tests: */
- if (destname != NULL)
- {
- strcpy(tmpbuf, destname);
- strcat(tmpbuf, ".tmp"); /* space for .tmp allocated above */
- tmpname = tmpbuf;
- }
-
- else
- tmpname = NULL; /* stdout */
-
- /* Loop to find the best option. */
- do
- {
- write_png(dp, tmpname);
-
- /* And compare the sizes (the write function makes sure write_size
- * doesn't overflow.)
- */
- assert(dp->csp > 0);
-
- if (dp->write_size < dp->best_size ||
- (dp->write_size == dp->best_size && better_options(dp)))
- {
- if (destname != NULL && rename(tmpname, destname) != 0)
- display_log(dp, APP_ERROR, "rename %s %s failed (%s)", tmpname,
- destname, strerror(errno));
-
- strcpy(dp->best, dp->curr);
- dp->best_size = dp->write_size;
- }
-
- else if (tmpname != NULL && unlink(tmpname) != 0)
- display_log(dp, APP_WARNING, "unlink %s failed (%s)", tmpname,
- strerror(errno));
-
- log_search(dp, log_depth);
- }
- while (dp->nsp > 0);
-
- /* Do this for the 'sizes' option so that it reports the correct size. */
- dp->write_size = dp->best_size;
- }
-}
-
-static int
-cppng(struct display *dp, const char *file, const char *gv dest)
- /* Exists solely to isolate the setjmp clobbers which some versions of GCC
- * erroneously generate.
- */
-{
- int ret = setjmp(dp->error_return);
-
- if (ret == 0)
- {
- dp->errset = 1;
- cp_one_file(dp, file, dest);
- dp->errset = 0;
- return 0;
- }
-
- else
- {
- dp->errset = 0;
-
- if (ret < ERRORS) /* shouldn't longjmp on warnings */
- display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
-
- return ret;
- }
-}
-
-int
-main(int argc, char **argv)
-{
- /* For each file on the command line test it with a range of transforms */
- int option_end;
- struct display d;
-
- display_init(&d);
-
- d.operation = "options";
- for (option_end = 1;
- option_end < argc && opt_check(&d, argv[option_end]);
- ++option_end)
- {
- }
-
- /* Do a quick check on the directory target case; when there are more than
- * two arguments the last one must be a directory.
- */
- if (!(d.options & NOWRITE) && option_end+2 < argc && !checkdir(argv[argc-1]))
- {
- fprintf(stderr,
- "pngcp: %s: directory required with more than two arguments\n",
- argv[argc-1]);
- return 99;
- }
-
- {
- int errors = 0;
- int i = option_end;
-
- /* Do this at least once; if there are no arguments stdin/stdout are used.
- */
- d.operation = "files";
- do
- {
- const char *infile = NULL;
- const char *outfile = NULL;
- int ret;
-
- if (i < argc)
- {
- infile = argv[i++];
- if (!(d.options & NOWRITE) && i < argc)
- outfile = argv[argc-1];
- }
-
- ret = cppng(&d, infile, outfile);
-
- if (ret)
- {
- if (ret > QUIET) /* abort on user or internal error */
- return 99;
-
- /* An error: the output is meaningless */
- }
-
- else if (d.best[0] != 0)
- {
- /* This result may already have been output, in which case best_size
- * has been reset.
- */
- if (d.best_size < MAX_SIZE)
- print_search_results(&d);
- }
-
- else if (d.options & SIZES)
- {
- printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu [0x%lx]\n",
- infile, (unsigned long)d.w, (unsigned long)d.h, d.bpp,
- cts(d.ct), (unsigned long)d.size, (unsigned long)d.read_size,
- (unsigned long)d.write_size, (unsigned long)d.results);
- fflush(stdout);
- }
-
- /* Here on any return, including failures, except user/internal issues
- */
- {
- int pass = (d.options & STRICT) ?
- RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
-
- if (!pass)
- ++errors;
-
- if (d.options & LOG)
- {
- int j;
-
- printf("%s: pngcp", pass ? "PASS" : "FAIL");
-
- for (j=1; j<option_end; ++j)
- printf(" %s", argv[j]);
-
- if (infile != NULL)
- printf(" %s", infile);
-
-# ifdef PNG_PNGCP_TIMING_SUPPORTED
- /* When logging output the files for each file, if enabled. */
- if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
- print_time(" read", d.read_time);
-
- if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
- print_time(" write", d.write_time);
-# endif /* PNGCP_TIMING */
-
- printf("\n");
- fflush(stdout);
- }
- }
-
- display_clean(&d);
- }
- while (i+!(d.options & NOWRITE) < argc);
- /* I.e. for write cases after the first time through the loop require
- * there to be at least two arguments left and for the last one to be a
- * directory (this was checked above).
- */
-
- /* Release allocated memory */
- display_destroy(&d);
-
-# ifdef PNG_PNGCP_TIMING_SUPPORTED
- {
- int output = 0;
-
- if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
- print_time("read", d.read_time_total), output = 1;
-
- if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
- {
- if (output) putchar(' ');
- print_time("write", d.write_time_total);
- output = 1;
- }
-
- if (output) putchar('\n');
- }
-# endif /* PNGCP_TIMING */
-
- return errors != 0;
- }
-}
-#else /* !READ_PNG || !WRITE_PNG */
-int
-main(void)
-{
- fprintf(stderr, "pngcp: no support for png_read/write_image\n");
- return 77;
-}
-#endif /* !READ_PNG || !WRITE_PNG */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c b/Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c
deleted file mode 100644
index 2fa5d13eaf8..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c
+++ /dev/null
@@ -1,4049 +0,0 @@
-/* pngfix.c
- *
- * Last changed in libpng 1.6.31 [July 27, 2017]
- * Copyright (c) 2014-2017 John Cunningham Bowler
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- *
- * Tool to check and fix the zlib inflate 'too far back' problem.
- * See the usage message for more information.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <errno.h>
-#include <assert.h>
-
-#define implies(x,y) assert(!(x) || (y))
-
-#ifdef __GNUC__
- /* This is used to fix the error:
- *
- * pngfix.c:
- * In function 'zlib_advance':
- * pngfix.c:181:13: error: assuming signed overflow does not
- * occur when simplifying conditional to constant [-Werror=strict-overflow]
- */
-# define FIX_GCC volatile
-#else
-# define FIX_GCC
-#endif
-
-#define PROGRAM_NAME "pngfix"
-
-/* Define the following to use this program against your installed libpng,
- * rather than the one being built here:
- */
-#ifdef PNG_FREESTANDING_TESTS
-# include <png.h>
-#else
-# include "../../png.h"
-#endif
-
-#if PNG_LIBPNG_VER < 10603 /* 1.6.3 */
-# error "pngfix will not work with libpng prior to 1.6.3"
-#endif
-
-#ifdef PNG_SETJMP_SUPPORTED
-#include <setjmp.h>
-
-#if defined(PNG_READ_SUPPORTED) && defined(PNG_EASY_ACCESS_SUPPORTED) &&\
- (defined(PNG_READ_DEINTERLACE_SUPPORTED) ||\
- defined(PNG_READ_INTERLACING_SUPPORTED))
-
-/* zlib.h defines the structure z_stream, an instance of which is included
- * in this structure and is required for decompressing the LZ compressed
- * data in PNG files.
- */
-#ifndef ZLIB_CONST
- /* We must ensure that zlib uses 'const' in declarations. */
-# define ZLIB_CONST
-#endif
-#include <zlib.h>
-#ifdef const
- /* zlib.h sometimes #defines const to nothing, undo this. */
-# undef const
-#endif
-
-/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
- * with older builds.
- */
-#if ZLIB_VERNUM < 0x1260
-# define PNGZ_MSG_CAST(s) constcast(char*,s)
-# define PNGZ_INPUT_CAST(b) constcast(png_bytep,b)
-#else
-# define PNGZ_MSG_CAST(s) (s)
-# define PNGZ_INPUT_CAST(b) (b)
-#endif
-
-#ifndef PNG_MAXIMUM_INFLATE_WINDOW
-# error "pngfix not supported in this libpng version"
-#endif
-
-#if ZLIB_VERNUM >= 0x1240
-
-/* Copied from pngpriv.h */
-#ifdef __cplusplus
-# define voidcast(type, value) static_cast<type>(value)
-# define constcast(type, value) const_cast<type>(value)
-# define aligncast(type, value) \
- static_cast<type>(static_cast<void*>(value))
-# define aligncastconst(type, value) \
- static_cast<type>(static_cast<const void*>(value))
-#else
-# define voidcast(type, value) (value)
-# define constcast(type, value) ((type)(value))
-# define aligncast(type, value) ((void*)(value))
-# define aligncastconst(type, value) ((const void*)(value))
-#endif /* __cplusplus */
-
-#if PNG_LIBPNG_VER < 10700
-/* Chunk tags (copied from pngpriv.h) */
-#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
-#define PNG_U32(b1,b2,b3,b4) \
- (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
-
-/* Constants for known chunk types. */
-#define png_IDAT PNG_U32( 73, 68, 65, 84)
-#define png_IEND PNG_U32( 73, 69, 78, 68)
-#define png_IHDR PNG_U32( 73, 72, 68, 82)
-#define png_PLTE PNG_U32( 80, 76, 84, 69)
-#define png_bKGD PNG_U32( 98, 75, 71, 68)
-#define png_cHRM PNG_U32( 99, 72, 82, 77)
-#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
-#define png_gAMA PNG_U32(103, 65, 77, 65)
-#define png_gIFg PNG_U32(103, 73, 70, 103)
-#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */
-#define png_gIFx PNG_U32(103, 73, 70, 120)
-#define png_hIST PNG_U32(104, 73, 83, 84)
-#define png_iCCP PNG_U32(105, 67, 67, 80)
-#define png_iTXt PNG_U32(105, 84, 88, 116)
-#define png_oFFs PNG_U32(111, 70, 70, 115)
-#define png_pCAL PNG_U32(112, 67, 65, 76)
-#define png_pHYs PNG_U32(112, 72, 89, 115)
-#define png_sBIT PNG_U32(115, 66, 73, 84)
-#define png_sCAL PNG_U32(115, 67, 65, 76)
-#define png_sPLT PNG_U32(115, 80, 76, 84)
-#define png_sRGB PNG_U32(115, 82, 71, 66)
-#define png_sTER PNG_U32(115, 84, 69, 82)
-#define png_tEXt PNG_U32(116, 69, 88, 116)
-#define png_tIME PNG_U32(116, 73, 77, 69)
-#define png_tRNS PNG_U32(116, 82, 78, 83)
-#define png_zTXt PNG_U32(122, 84, 88, 116)
-#endif
-
-/* The 8-byte signature as a pair of 32-bit quantities */
-#define sig1 PNG_U32(137, 80, 78, 71)
-#define sig2 PNG_U32( 13, 10, 26, 10)
-
-/* Is the chunk critical? */
-#define CRITICAL(chunk) (((chunk) & PNG_U32(32,0,0,0)) == 0)
-
-/* Is it safe to copy? */
-#define SAFE_TO_COPY(chunk) (((chunk) & PNG_U32(0,0,0,32)) != 0)
-
-/* Fix ups for builds with limited read support */
-#ifndef PNG_ERROR_TEXT_SUPPORTED
-# define png_error(a,b) png_err(a)
-#endif
-
-/********************************* UTILITIES **********************************/
-/* UNREACHED is a value to cause an assert to fail. Because of the way the
- * assert macro is written the string "UNREACHED" is produced in the error
- * message.
- */
-#define UNREACHED 0
-
-/* 80-bit number handling - a PNG image can be up to (2^31-1)x(2^31-1) 8-byte
- * (16-bit RGBA) pixels in size; that's less than 2^65 bytes or 2^68 bits, so
- * arithmetic of 80-bit numbers is sufficient. This representation uses an
- * arbitrary length array of png_uint_16 digits (0..65535). The representation
- * is little endian.
- *
- * The arithmetic functions take zero to two uarb values together with the
- * number of digits in those values and write the result to the given uarb
- * (always the first argument) returning the number of digits in the result.
- * If the result is negative the return value is also negative (this would
- * normally be an error).
- */
-typedef png_uint_16 udigit; /* A 'unum' is an array of these */
-typedef png_uint_16p uarb;
-typedef png_const_uint_16p uarbc;
-
-#define UDIGITS(unum) ((sizeof unum)/(sizeof (udigit))
- /* IMPORTANT: only apply this to an array, applied to a pointer the result
- * will typically be '2', which is not useful.
- */
-
-static int
-uarb_set(uarb result, png_alloc_size_t val)
- /* Set (initialize) 'result' to 'val'. The size required for 'result' must
- * be determined by the caller from a knowledge of the maximum for 'val'.
- */
-{
- int ndigits = 0;
-
- while (val > 0)
- {
- result[ndigits++] = (png_uint_16)(val & 0xffff);
- val >>= 16;
- }
-
- return ndigits;
-}
-
-static int
-uarb_copy(uarb to, uarb from, int idigits)
- /* Copy a uarb, may reduce the digit count */
-{
- int d, odigits;
-
- for (d=odigits=0; d<idigits; ++d)
- if ((to[d] = from[d]) != 0)
- odigits = d+1;
-
- return odigits;
-}
-
-static int
-uarb_inc(uarb num, int in_digits, png_int_32 add)
- /* This is a signed 32-bit add, except that to avoid overflow the value added
- * or subtracted must be no more than 2^31-65536. A negative result
- * indicates a negative number (which is an error below). The size of
- * 'num' should be max(in_digits+1,2) for arbitrary 'add' but can be just
- * in_digits+1 if add is known to be in the range -65535..65535.
- */
-{
- FIX_GCC int out_digits = 0;
-
- while (out_digits < in_digits)
- {
- add += num[out_digits];
- num[out_digits++] = (png_uint_16)(add & 0xffff);
- add >>= 16;
- }
-
- while (add != 0 && add != (-1))
- {
- num[out_digits++] = (png_uint_16)(add & 0xffff);
- add >>= 16;
- }
-
- if (add == 0)
- {
- while (out_digits > 0 && num[out_digits-1] == 0)
- --out_digits;
- return out_digits; /* may be 0 */
- }
-
- else /* negative result */
- {
- while (out_digits > 1 && num[out_digits-1] == 0xffff)
- --out_digits;
-
- return -out_digits;
- }
-}
-
-static int
-uarb_add32(uarb num, int in_digits, png_uint_32 add)
- /* As above but this works with any 32-bit value and only does 'add' */
-{
- if (in_digits > 0)
- {
- in_digits = uarb_inc(num, in_digits, add & 0xffff);
- return uarb_inc(num+1, in_digits-1, add >> 16)+1;
- }
-
- return uarb_set(num, add);
-}
-
-static int
-uarb_mult_digit(uarb acc, int a_digits, uarb num, FIX_GCC int n_digits,
- png_uint_16 val)
- /* Primitive one-digit multiply - 'val' must be 0..65535. Note that this
- * primitive is a multiply and accumulate - the result of *num * val is added
- * to *acc.
- *
- * This is a one-digit multiply, so the product may be up to one digit longer
- * than 'num', however the add to 'acc' means that the caller must ensure
- * that 'acc' is at least one digit longer than this *and* at least one digit
- * longer than the current length of 'acc'. (Or the caller must otherwise
- * ensure 'adigits' is adequate from knowledge of the values.)
- */
-{
- /* The digits in *acc, *num and val are in the range 0..65535, so the
- * result below is at most (65535*65535)+2*65635 = 65535*(65535+2), which is
- * exactly 0xffffffff.
- */
- if (val > 0 && n_digits > 0) /* Else the product is 0 */
- {
- png_uint_32 carry = 0;
- int out_digits = 0;
-
- while (out_digits < n_digits || carry > 0)
- {
- if (out_digits < a_digits)
- carry += acc[out_digits];
-
- if (out_digits < n_digits)
- carry += (png_uint_32)num[out_digits] * val;
-
- acc[out_digits++] = (png_uint_16)(carry & 0xffff);
- carry >>= 16;
- }
-
- /* So carry is 0 and all the input digits have been consumed. This means
- * that it is possible to skip any remaining digits in acc.
- */
- if (out_digits > a_digits)
- return out_digits;
- }
-
- return a_digits;
-}
-
-static int
-uarb_mult32(uarb acc, int a_digits, uarb num, int n_digits, png_uint_32 val)
- /* calculate acc += num * val, 'val' may be any 32-bit value, 'acc' and 'num'
- * may be any value, returns the number of digits in 'acc'.
- */
-{
- if (n_digits > 0 && val > 0)
- {
- a_digits = uarb_mult_digit(acc, a_digits, num, n_digits,
- (png_uint_16)(val & 0xffff));
-
- val >>= 16;
- if (val > 0)
- a_digits = uarb_mult_digit(acc+1, a_digits-1, num, n_digits,
- (png_uint_16)val) + 1;
-
- /* Because n_digits and val are >0 the following must be true: */
- assert(a_digits > 0);
- }
-
- return a_digits;
-}
-
-static int
-uarb_shift(uarb inout, int ndigits, unsigned int right_shift)
- /* Shift inout right by right_shift bits, right_shift must be in the range
- * 1..15
- */
-{
- FIX_GCC int i = ndigits;
- png_uint_16 carry = 0;
-
- assert(right_shift >= 1 && right_shift <= 15);
-
- while (--i >= 0)
- {
- png_uint_16 temp = (png_uint_16)(carry | (inout[i] >> right_shift));
-
- /* Bottom bits to top bits of carry */
- carry = (png_uint_16)((inout[i] << (16-right_shift)) & 0xffff);
-
- inout[i] = temp;
-
- /* The shift may reduce ndigits */
- if (i == ndigits-1 && temp == 0)
- ndigits = i;
- }
-
- return ndigits;
-}
-
-static int
-uarb_cmp(uarb a, int adigits, uarb b, int bdigits)
- /* Return -1/0/+1 according as a<b/a==b/a>b */
-{
- if (adigits < bdigits)
- return -1;
-
- if (adigits > bdigits)
- return 1;
-
- while (adigits-- > 0)
- if (a[adigits] < b[adigits])
- return -1;
-
- else if (a[adigits] > b[adigits])
- return 1;
-
- return 0;
-}
-
-#if 0 /*UNUSED*/
-static int
-uarb_eq32(uarb num, int digits, png_uint_32 val)
- /* Return true if the uarb is equal to 'val' */
-{
- switch (digits)
- {
- case 0: return val == 0;
- case 1: return val == num[0];
- case 2: return (val & 0xffff) == num[0] && (val >> 16) == num[1];
- default: return 0;
- }
-}
-#endif
-
-static void
-uarb_printx(uarb num, int digits, FILE *out)
- /* Print 'num' as a hexadecimal number (easier than decimal!) */
-{
- while (digits > 0)
- if (num[--digits] > 0)
- {
- fprintf(out, "0x%x", num[digits]);
-
- while (digits > 0)
- fprintf(out, "%.4x", num[--digits]);
- }
-
- else if (digits == 0) /* the number is 0 */
- fputs("0x0", out);
-}
-
-static void
-uarb_print(uarb num, int digits, FILE *out)
- /* Prints 'num' as a decimal if it will fit in an unsigned long, else as a
- * hexadecimal number. Notice that the results vary for images over 4GByte
- * in a system dependent way, and the hexadecimal form doesn't work very well
- * in awk script input.
- *
- *
- * TODO: write uarb_div10
- */
-{
- if (digits * sizeof (udigit) > sizeof (unsigned long))
- uarb_printx(num, digits, out);
-
- else
- {
- unsigned long n = 0;
-
- while (digits > 0)
- n = (n << 16) + num[--digits];
-
- fprintf(out, "%lu", n);
- }
-}
-
-/* Generate random bytes. This uses a boring repeatable algorithm and it
- * is implemented here so that it gives the same set of numbers on every
- * architecture. It's a linear congruential generator (Knuth or Sedgewick
- * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
- * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise
- * Generation.)
- *
- * (Copied from contrib/libtests/pngvalid.c)
- */
-static void
-make_random_bytes(png_uint_32* seed, void* pv, size_t size)
-{
- png_uint_32 u0 = seed[0], u1 = seed[1];
- png_bytep bytes = voidcast(png_bytep, pv);
-
- /* There are thirty-three bits; the next bit in the sequence is bit-33 XOR
- * bit-20. The top 1 bit is in u1, the bottom 32 are in u0.
- */
- size_t i;
- for (i=0; i<size; ++i)
- {
- /* First generate 8 new bits then shift them in at the end. */
- png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
- u1 <<= 8;
- u1 |= u0 >> 24;
- u0 <<= 8;
- u0 |= u;
- *bytes++ = (png_byte)u;
- }
-
- seed[0] = u0;
- seed[1] = u1;
-}
-
-/* Clear an object to a random value. */
-static void
-clear(void *pv, size_t size)
-{
- static png_uint_32 clear_seed[2] = { 0x12345678, 0x9abcdef0 };
- make_random_bytes(clear_seed, pv, size);
-}
-
-#define CLEAR(object) clear(&(object), sizeof (object))
-
-/* Copied from unreleased 1.7 code.
- *
- * CRC checking uses a local pre-built implementation of the Ethernet CRC32.
- * This is to avoid a function call to the zlib DLL and to optimize the
- * byte-by-byte case.
- */
-static png_uint_32 crc_table[256] =
-{
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
- 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
- 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
- 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
- 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
- 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
- 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
- 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
- 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
- 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
- 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
- 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
- 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
- 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
- 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
- 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
- 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
- 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
- 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
- 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
- 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
- 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
- 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
- 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
- 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
- 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
- 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
- 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
- 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
- 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
- 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
- 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
- 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
- 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
- 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
- 0x2d02ef8d
-};
-
-/* The CRC calculated here *IS* conditioned, the corresponding value used by
- * zlib and the result value is obtained by XORing with CRC_INIT, which is also
- * the first value that must be passed in (for the first byte) to crc_one_byte.
- */
-#define CRC_INIT 0xffffffff
-
-static png_uint_32
-crc_one_byte(png_uint_32 crc, int b)
-{
- return crc_table[(crc ^ b) & 0xff] ^ (crc >> 8);
-}
-
-static png_uint_32
-crc_init_4(png_uint_32 value)
-{
- /* This is an alternative to the algorithm used in zlib, which requires four
- * separate tables to parallelize the four byte operations, it only works for
- * a CRC of the first four bytes of the stream, but this is what happens in
- * the parser below where length+chunk-name is read and chunk-name used to
- * initialize the CRC. Notice that the calculation here avoids repeated
- * conditioning (xor with 0xffffffff) by storing the conditioned value.
- */
- png_uint_32 crc = crc_table[(~value >> 24)] ^ 0xffffff;
-
- crc = crc_table[(crc ^ (value >> 16)) & 0xff] ^ (crc >> 8);
- crc = crc_table[(crc ^ (value >> 8)) & 0xff] ^ (crc >> 8);
- return crc_table[(crc ^ value) & 0xff] ^ (crc >> 8);
-}
-
-static int
-chunk_type_valid(png_uint_32 c)
- /* Bit whacking approach to chunk name validation that is intended to avoid
- * branches. The cost is that it uses a lot of 32-bit constants, which might
- * be bad on some architectures.
- */
-{
- png_uint_32 t;
-
- /* Remove bit 5 from all but the reserved byte; this means every
- * 8-bit unit must be in the range 65-90 to be valid. So bit 5
- * must be zero, bit 6 must be set and bit 7 zero.
- */
- c &= ~PNG_U32(32,32,0,32);
- t = (c & ~0x1f1f1f1f) ^ 0x40404040;
-
- /* Subtract 65 for each 8-bit quantity, this must not overflow
- * and each byte must then be in the range 0-25.
- */
- c -= PNG_U32(65,65,65,65);
- t |=c ;
-
- /* Subtract 26, handling the overflow which should set the top
- * three bits of each byte.
- */
- c -= PNG_U32(25,25,25,26);
- t |= ~c;
-
- return (t & 0xe0e0e0e0) == 0;
-}
-
-/**************************** CONTROL INFORMATION *****************************/
-
-/* Information about a sequence of IDAT chunks, the chunks have been re-synced
- * using sync_stream below and the new lengths are recorded here. Because the
- * number of chunks is unlimited this is handled using a linked list of these
- * structures.
- */
-struct IDAT_list
-{
- struct IDAT_list *next; /* Linked list */
- unsigned int length; /* Actual length of the array below */
- unsigned int count; /* Number of entries that are valid */
-# define IDAT_INIT_LENGTH 16
- png_uint_32 lengths[IDAT_INIT_LENGTH];
-};
-
-static void
-IDAT_list_init(struct IDAT_list *list)
-{
- CLEAR(*list);
-
- list->next = NULL;
- list->length = IDAT_INIT_LENGTH;
-}
-
-static size_t
-IDAT_list_size(struct IDAT_list *list, unsigned int length)
- /* Return the size in bytes of an IDAT_list of the given length. */
-{
- if (list != NULL)
- length = list->length;
-
- return sizeof *list - sizeof list->lengths +
- length * sizeof list->lengths[0];
-}
-
-static void
-IDAT_list_end(struct IDAT_list *IDAT_list)
-{
- struct IDAT_list *list = IDAT_list->next;
-
- CLEAR(*IDAT_list);
-
- while (list != NULL)
- {
- struct IDAT_list *next = list->next;
-
- clear(list, IDAT_list_size(list, 0));
- free(list);
- list = next;
- }
-}
-
-static struct IDAT_list *
-IDAT_list_extend(struct IDAT_list *tail)
-{
- /* Use the previous cached value if available. */
- struct IDAT_list *next = tail->next;
-
- if (next == NULL)
- {
- /* Insert a new, malloc'ed, block of IDAT information buffers, this
- * one twice as large as the previous one:
- */
- unsigned int length = 2 * tail->length;
-
- if (length < tail->length) /* arithmetic overflow */
- length = tail->length;
-
- next = voidcast(IDAT_list*, malloc(IDAT_list_size(NULL, length)));
- CLEAR(*next);
-
- /* The caller must handle this: */
- if (next == NULL)
- return NULL;
-
- next->next = NULL;
- next->length = length;
- tail->next = next;
- }
-
- return next;
-}
-
-/* GLOBAL CONTROL STRUCTURE */
-struct global
-{
- /* PUBLIC GLOBAL VARIABLES: OWNER INITIALIZE */
- unsigned int errors :1; /* print file errors to stderr */
- unsigned int warnings :1; /* print libpng warnings to stderr */
- unsigned int optimize_zlib :1; /* Run optimization search */
- unsigned int quiet :2; /* don't output summaries */
- unsigned int verbose :3; /* various internal tracking */
- unsigned int skip :3; /* Non-critical chunks to skip */
-# define SKIP_NONE 0
-# define SKIP_BAD_CRC 1 /* Chunks with a bad CRC */
-# define SKIP_UNSAFE 2 /* Chunks not safe to copy */
-# define SKIP_UNUSED 3 /* Chunks not used by libpng */
-# define SKIP_TRANSFORM 4 /* Chunks only used in transforms */
-# define SKIP_COLOR 5 /* Everything but tRNS, sBIT, gAMA and sRGB */
-# define SKIP_ALL 6 /* Everything but tRNS and sBIT */
-
- png_uint_32 idat_max; /* 0 to perform no re-chunking */
-
- int status_code; /* Accumulated status code */
-# define TOO_FAR_BACK 0x01 /* found a too-far-back error */
-# define CRC_ERROR 0x02 /* fixed an invalid CRC */
-# define STREAM_ERROR 0x04 /* damaged PNG stream (may be fixable) */
-# define TRUNCATED 0x08 /* truncated but still readable */
-# define FILE_ERROR 0x10 /* could not read the file */
-# define WRITE_ERROR 0x20 /* write error (this terminates the read) */
-# define INTERNAL_ERROR 0x40 /* internal limits/errors encountered */
-
- /* PUBLIC GLOBAL VARIABLES: USED INTERNALLY BY IDAT READ CODE */
- struct IDAT_list idat_cache; /* Cache of file IDAT information buffers */
- /* The structure is shared across all uses of this global control
- * structure to avoid reallocation between IDAT streams.
- */
-};
-
-static int
-global_end(struct global *global)
-{
-
- int rc;
-
- IDAT_list_end(&global->idat_cache);
- rc = global->status_code;
- CLEAR(*global);
- return rc;
-}
-
-static void
-global_init(struct global *global)
- /* Call this once (and only once) to initialize the control */
-{
- CLEAR(*global);
-
- /* Globals */
- global->errors = 0;
- global->warnings = 0;
- global->quiet = 0;
- global->verbose = 0;
- global->idat_max = 0; /* no re-chunking of IDAT */
- global->optimize_zlib = 0;
- global->skip = SKIP_NONE;
- global->status_code = 0;
-
- IDAT_list_init(&global->idat_cache);
-}
-
-static int
-skip_chunk_type(const struct global *global, png_uint_32 type)
- /* Return true if this chunk is to be skipped according to the --strip
- * option. This code needs to recognize all known ancillary chunks in order
- * to handle the --strip=unsafe option.
- */
-{
- /* Never strip critical chunks: */
- if (CRITICAL(type))
- return 0;
-
- switch (type)
- {
- /* Chunks that are treated as, effectively, critical because they affect
- * correct interpretation of the pixel values:
- */
- case png_tRNS: case png_sBIT:
- return 0;
-
- /* Chunks that specify gamma encoding which should therefore only be
- * removed if the user insists:
- */
- case png_gAMA: case png_sRGB:
- if (global->skip >= SKIP_ALL)
- return 1;
- return 0;
-
- /* Chunks that affect color interpretation - not used by libpng and rarely
- * used by applications, but technically still required for correct
- * interpretation of the image data:
- */
- case png_cHRM: case png_iCCP:
- if (global->skip >= SKIP_COLOR)
- return 1;
- return 0;
-
- /* Other chunks that are used by libpng in image transformations (as
- * opposed to known chunks that have get/set APIs but are not otherwise
- * used.)
- */
- case png_bKGD:
- if (global->skip >= SKIP_TRANSFORM)
- return 1;
- return 0;
-
- /* All other chunks that libpng knows about and affect neither image
- * interpretation nor libpng transforms - chunks that are effectively
- * unused by libpng even though libpng might recognize and store them.
- */
- case png_fRAc: case png_gIFg: case png_gIFt: case png_gIFx: case png_hIST:
- case png_iTXt: case png_oFFs: case png_pCAL: case png_pHYs: case png_sCAL:
- case png_sPLT: case png_sTER: case png_tEXt: case png_tIME: case png_zTXt:
- if (global->skip >= SKIP_UNUSED)
- return 1;
- return 0;
-
- /* Chunks that libpng does not know about (notice that this depends on the
- * list above including all known chunks!) The decision here depends on
- * whether the safe-to-copy bit is set in the chunk type.
- */
- default:
- if (SAFE_TO_COPY(type))
- {
- if (global->skip >= SKIP_UNUSED) /* as above */
- return 1;
- }
-
- else if (global->skip >= SKIP_UNSAFE)
- return 1;
-
- return 0;
- }
-}
-
-/* PER-FILE CONTROL STRUCTURE */
-struct chunk;
-struct IDAT;
-struct file
-{
- /* ANCESTORS */
- struct global *global;
-
- /* PUBLIC PER-FILE VARIABLES: CALLER INITIALIZE */
- const char * file_name;
- const char * out_name; /* Name of output file (if required) */
-
- /* PUBLIC PER-FILE VARIABLES: SET BY PNG READ CODE */
- /* File specific result codes */
- int status_code; /* Set to a bit mask of the following: */
- int read_errno; /* Records a read error errno */
- int write_errno; /* Records a write error errno */
-
- /* IHDR information */
- png_uint_32 width;
- png_uint_32 height;
- png_byte bit_depth;
- png_byte color_type;
- png_byte compression_method;
- png_byte filter_method;
- png_byte interlace_method;
-
- udigit image_bytes[5];
- int image_digits;
-
- /* PROTECTED PER-FILE VARIABLES: USED BY THE READ CODE */
- FILE * file; /* Original PNG file */
- FILE * out; /* If a new one is being written */
- jmp_buf jmpbuf; /* Set while reading a PNG */
-
- /* PROTECTED CHUNK SPECIFIC VARIABLES: USED BY CHUNK CODE */
- /* The following variables are used during reading to record the length, type
- * and data position of the *next* chunk or, right at the start, the
- * signature (in length,type).
- *
- * When a chunk control structure is instantiated these values are copied
- * into the structure and can then be overritten with the data for the next
- * chunk.
- */
- fpos_t data_pos; /* Position of first byte of chunk data */
- png_uint_32 length; /* First word (length or signature start) */
- png_uint_32 type; /* Second word (type or signature end) */
- png_uint_32 crc; /* Running chunk CRC (used by read_chunk) */
-
- /* These counts are maintained by the read and write routines below and are
- * reset by the chunk handling code. They record the total number of bytes
- * read or written for the chunk, including the header (length,type) bytes.
- */
- png_uint_32 read_count; /* Count of bytes read (in the chunk) */
- png_uint_32 write_count; /* Count of bytes written (in the chunk) */
- int state; /* As defined here: */
-# define STATE_SIGNATURE 0 /* The signature is being written */
-# define STATE_CHUNKS 1 /* Non-IDAT chunks are being written */
-# define STATE_IDAT 2 /* An IDAT stream is being written */
-
- /* Two pointers used to enable clean-up in the event of fatal errors and to
- * hold state about the parser process (only one of each at present.)
- */
- struct chunk * chunk;
- struct IDAT * idat;
-
- /* Interface to allocate a new chunk or IDAT control structure. The result
- * is returned by setting one or other of the above variables. Note that the
- * relevant initializer is called by the allocator function. The alloc_ptr
- * is used only by the implementation of the allocate function.
- */
- void * alloc_ptr;
- void (*alloc)(struct file*,int idat);
- /* idat: allocate IDAT not chunk */
-};
-
-/* Valid longjmp (stop) codes are: */
-#define LIBPNG_WARNING_CODE 1 /* generic png_error */
-#define LIBPNG_ERROR_CODE 2 /* generic png_error */
-#define ZLIB_ERROR_CODE 3 /* generic zlib error */
-#define INVALID_ERROR_CODE 4 /* detected an invalid PNG */
-#define READ_ERROR_CODE 5 /* read failed */
-#define WRITE_ERROR_CODE 6 /* error in write */
-#define UNEXPECTED_ERROR_CODE 7 /* unexpected (internal?) error */
-
-static void
-emit_string(const char *str, FILE *out)
- /* Print a string with spaces replaced by '_' and non-printing characters by
- * an octal escape.
- */
-{
- for (; *str; ++str)
- if (isgraph(UCHAR_MAX & *str))
- putc(*str, out);
-
- else if (isspace(UCHAR_MAX & *str))
- putc('_', out);
-
- else
- fprintf(out, "\\%.3o", *str);
-}
-
-static const char *
-strcode(int code)
-{
- switch (code)
- {
- case LIBPNG_WARNING_CODE: return "warning";
- case LIBPNG_ERROR_CODE: return "libpng";
- case ZLIB_ERROR_CODE: return "zlib";
- case INVALID_ERROR_CODE: return "invalid";
- case READ_ERROR_CODE: return "read";
- case WRITE_ERROR_CODE: return "write";
- case UNEXPECTED_ERROR_CODE: return "unexpected";
- default: return "INVALID";
- }
-}
-
-static void
-emit_error(struct file *file, int code, const char *what)
- /* Generic error message routine, takes a 'stop' code but can be used
- * elsewhere. Always outputs a message.
- */
-{
- const char *reason;
- int err = 0;
-
- switch (code)
- {
- case LIBPNG_WARNING_CODE: reason = "libpng warning:"; break;
- case LIBPNG_ERROR_CODE: reason = "libpng error:"; break;
- case ZLIB_ERROR_CODE: reason = "zlib error:"; break;
- case INVALID_ERROR_CODE: reason = "invalid"; break;
- case READ_ERROR_CODE: reason = "read failure:";
- err = file->read_errno;
- break;
- case WRITE_ERROR_CODE: reason = "write error";
- err = file->write_errno;
- break;
- case UNEXPECTED_ERROR_CODE: reason = "unexpected error:";
- err = file->read_errno;
- if (err == 0)
- err = file->write_errno;
- break;
- default: reason = "INVALID (internal error):"; break;
- }
-
- if (err != 0)
- fprintf(stderr, "%s: %s %s [%s]\n", file->file_name, reason, what,
- strerror(err));
-
- else
- fprintf(stderr, "%s: %s %s\n", file->file_name, reason, what);
-}
-
-static void chunk_end(struct chunk **);
-static void IDAT_end(struct IDAT **);
-
-static int
-file_end(struct file *file)
-{
- int rc;
-
- /* If either of the chunk pointers are set end them here, the IDAT structure
- * must be deallocated first as it may deallocate the chunk structure.
- */
- if (file->idat != NULL)
- IDAT_end(&file->idat);
-
- if (file->chunk != NULL)
- chunk_end(&file->chunk);
-
- rc = file->status_code;
-
- if (file->file != NULL)
- (void)fclose(file->file);
-
- if (file->out != NULL)
- {
- /* NOTE: this is bitwise |, all the following functions must execute and
- * must succeed.
- */
- if (ferror(file->out) | fflush(file->out) | fclose(file->out))
- {
- perror(file->out_name);
- emit_error(file, READ_ERROR_CODE, "output write error");
- rc |= WRITE_ERROR;
- }
- }
-
- /* Accumulate the result codes */
- file->global->status_code |= rc;
-
- CLEAR(*file);
-
- return rc; /* status code: non-zero on read or write error */
-}
-
-static int
-file_init(struct file *file, struct global *global, const char *file_name,
- const char *out_name, void *alloc_ptr, void (*alloc)(struct file*,int))
- /* Initialize a file control structure. This will open the given files as
- * well. The status code returned is 0 on success, non zero (using the flags
- * above) on a file open error.
- */
-{
- CLEAR(*file);
- file->global = global;
-
- file->file_name = file_name;
- file->out_name = out_name;
- file->status_code = 0;
- file->read_errno = 0;
- file->write_errno = 0;
-
- file->file = NULL;
- file->out = NULL;
- /* jmpbuf is garbage: must be set by read_png */
-
- file->read_count = 0;
- file->state = STATE_SIGNATURE;
-
- file->chunk = NULL;
- file->idat = NULL;
-
- file->alloc_ptr = alloc_ptr;
- file->alloc = alloc;
-
- /* Open the files: */
- assert(file_name != NULL);
- file->file = fopen(file_name, "rb");
-
- if (file->file == NULL)
- {
- file->read_errno = errno;
- file->status_code |= FILE_ERROR;
- /* Always output: please give a readable file! */
- perror(file_name);
- return FILE_ERROR;
- }
-
- if (out_name != NULL)
- {
- file->out = fopen(out_name, "wb");
-
- if (file->out == NULL)
- {
- file->write_errno = errno;
- file->status_code |= WRITE_ERROR;
- perror(out_name);
- return WRITE_ERROR;
- }
- }
-
- return 0;
-}
-
-static void
-log_error(struct file *file, int code, const char *what)
- /* Like emit_error but checks the global 'errors' flag */
-{
- if (file->global->errors)
- emit_error(file, code, what);
-}
-
-static char
-type_char(png_uint_32 v)
-{
- /* In fact because chunk::chunk_type is validated prior to any call to this
- * function it will always return a-zA-Z, but the extra codes are just there
- * to help in finding internal (programming) errors. Note that the code only
- * ever considers the low 7 bits of the value (so it is not necessary for the
- * type_name function to mask of the byte.)
- */
- if (v & 32)
- return "!abcdefghijklmnopqrstuvwxyz56789"[(v-96)&31];
-
- else
- return "@ABCDEFGHIJKLMNOPQRSTUVWXYZ01234"[(v-64)&31];
-}
-
-static void
-type_name(png_uint_32 type, FILE *out)
-{
- putc(type_char(type >> 24), out);
- putc(type_char(type >> 16), out);
- putc(type_char(type >> 8), out);
- putc(type_char(type ), out);
-}
-
-static void
-type_sep(FILE *out)
-{
- putc(':', out);
- putc(' ', out);
-}
-
-static png_uint_32 current_type(struct file *file, int code);
-
-PNG_NORETURN static void
-stop(struct file *file, int code, const char *what)
- /* Return control when a PNG file cannot be read. This outputs an 'ERR'
- * summary line too.
- */
-{
- log_error(file, code, what);
-
- /* The chunk being read is typically identified by file->chunk or, if this is
- * NULL, by file->type. This may be wrong if libpng reads ahead, but this
- * only happens with IDAT where libpng reads the header then jumps around
- * finding errors in the previous chunks. We know that is happening because
- * we are at the start of the IDAT (i.e. no IDAT data has yet been written.)
- *
- * SUMMARY FORMAT (stop):
- *
- * IDAT ERR status code read-errno write-errno message file
- *
- * 'uncompressed' will be 0 if there was a problem in the IHDR. The errno
- * values are emit_string(strerror(errno)).
- */
- if (file->global->quiet < 2) /* need two quiets to stop this. */
- {
- png_uint_32 type;
-
- if (file->chunk != NULL)
- type = current_type(file, code); /* Gropes in struct chunk and IDAT */
-
- else
- type = file->type;
-
- if (type)
- type_name(type, stdout);
-
- else /* magic: an IDAT header, produces bogons for too many IDATs */
- fputs("HEAD", stdout); /* not a registered chunk! */
-
- printf(" ERR %.2x %s ", file->status_code, strcode(code));
- /* This only works one strerror at a time, because of the way strerror is
- * implemented.
- */
- emit_string(strerror(file->read_errno), stdout);
- putc(' ', stdout);
- emit_string(strerror(file->write_errno), stdout);
- putc(' ', stdout);
- emit_string(what, stdout);
- putc(' ', stdout);
- fputs(file->file_name, stdout);
- putc('\n', stdout);
- }
-
- file->status_code |= FILE_ERROR;
- longjmp(file->jmpbuf, code);
-}
-
-PNG_NORETURN static void
-stop_invalid(struct file *file, const char *what)
-{
- stop(file, INVALID_ERROR_CODE, what);
-}
-
-static void
-type_message(struct file *file, png_uint_32 type, const char *what)
- /* Error message for a chunk; the chunk name comes from 'type' */
-{
- if (file->global->errors)
- {
- fputs(file->file_name, stderr);
- type_sep(stderr);
- type_name(type, stderr);
- type_sep(stderr);
- fputs(what, stderr);
- putc('\n', stderr);
- }
-}
-
-/* Input file positioning - we jump around in the input file while reading
- * stuff, these wrappers deal with the error handling.
- */
-static void
-file_getpos(struct file *file, fpos_t *pos)
-{
- if (fgetpos(file->file, pos))
- {
- /* This is unexpected, so perror it */
- perror(file->file_name);
- stop(file, READ_ERROR_CODE, "fgetpos");
- }
-}
-
-static void
-file_setpos(struct file *file, const fpos_t *pos)
-{
- if (fsetpos(file->file, pos))
- {
- perror(file->file_name);
- stop(file, READ_ERROR_CODE, "fsetpos");
- }
-}
-
-static void
-getpos(struct file *file)
- /* Get the current position and store it in 'data_pos'. The corresponding
- * setpos() function is chunk specific because it uses the copy of the
- * position for the specific chunk.
- */
-{
- file_getpos(file, &file->data_pos);
-}
-
-
-/* Read utility - read a single byte, returns a value in the range 0..255 or EOF
- * on a read error. In the latter case status_code and read_errno are updated
- * appropriately.
- */
-static int
-read_byte(struct file *file)
-{
- int ch = getc(file->file);
-
- if (ch >= 0 && ch <= 255)
- {
- ++(file->read_count);
- return ch;
- }
-
- else if (ch != EOF)
- {
- file->status_code |= INTERNAL_ERROR;
- file->read_errno = ERANGE; /* out of range character */
-
- /* This is very unexpected; an error message is always output: */
- emit_error(file, UNEXPECTED_ERROR_CODE, "file read");
- }
-
-# ifdef EINTR
- else if (errno == EINTR) /* Interrupted, try again */
- {
- errno = 0;
- return read_byte(file);
- }
-# endif
-
- else
- {
- /* An error, it doesn't really matter what the error is but it gets
- * recorded anyway.
- */
- if (ferror(file->file))
- file->read_errno = errno;
-
- else if (feof(file->file))
- file->read_errno = 0; /* I.e. a regular EOF, no error */
-
- else /* unexpected */
- file->read_errno = EDOM;
- }
-
- /* 'TRUNCATED' is used for all cases of failure to read a byte, because of
- * the way libpng works a byte read is never attempted unless the byte is
- * expected to be there, so EOF should not occur.
- */
- file->status_code |= TRUNCATED;
- return EOF;
-}
-
-static png_byte
-reread_byte(struct file *file)
- /* Read a byte when an error is not expected to happen because the byte has
- * been read before without error.
- */
-{
- int ch = getc(file->file);
-
- if (errno != 0)
- file->read_errno = errno;
-
- if (ch < 0 || ch > 255)
- stop(file, UNEXPECTED_ERROR_CODE, "reread");
-
- return (png_byte)ch;
-}
-
-static png_uint_32
-reread_4(struct file *file)
- /* The same but for a four byte quantity */
-{
- png_uint_32 result = 0;
- int i = 0;
-
- while (++i <= 4)
- result = (result << 8) + reread_byte(file);
-
- return result;
-}
-
-static void
-skip_12(struct file *file)
- /* Skip exactly 12 bytes in the input stream - used to skip a CRC and chunk
- * header that has been read before.
- */
-{
- /* Since the chunks were read before this shouldn't fail: */
- if (fseek(file->file, 12, SEEK_CUR) != 0)
- {
- if (errno != 0)
- file->read_errno = errno;
-
- stop(file, UNEXPECTED_ERROR_CODE, "reskip");
- }
-}
-
-static void
-write_byte(struct file *file, int b)
- /* Write one byte to the output - this causes a fatal error if the write
- * fails and the read of this PNG file immediately terminates. Just
- * increments the write count if there is no output file.
- */
-{
- if (file->out != NULL)
- {
- if (putc(b, file->out) != b)
- {
- file->write_errno = errno;
- file->status_code |= WRITE_ERROR;
- stop(file, WRITE_ERROR_CODE, "write byte");
- }
- }
-
- ++(file->write_count);
-}
-
-/* Derivatives of the read/write functions. */
-static unsigned int
-read_4(struct file *file, png_uint_32 *pu)
- /* Read four bytes, returns the number of bytes read successfully and, if all
- * four bytes are read, assigns the result to *pu.
- */
-{
- unsigned int i = 0;
- png_uint_32 val = 0;
-
- do
- {
- int ch = read_byte(file);
-
- if (ch == EOF)
- return i;
-
- val = (val << 8) + ch;
- } while (++i < 4);
-
- *pu = val;
- return i;
-}
-
-/* CRC handling - read but calculate the CRC while doing so. */
-static int
-crc_read_many(struct file *file, png_uint_32 length)
- /* Reads 'length' bytes and updates the CRC, returns true on success, false
- * if the input is truncated.
- */
-{
- if (length > 0)
- {
- png_uint_32 crc = file->crc;
-
- do
- {
- int ch = read_byte(file);
-
- if (ch == EOF)
- return 0; /* Truncated */
-
- crc = crc_one_byte(crc, ch);
- }
- while (--length > 0);
-
- file->crc = crc;
- }
-
- return 1; /* OK */
-}
-
-static int
-calc_image_size(struct file *file)
- /* Fill in the image_bytes field given the IHDR information, calls stop on
- * error.
- */
-{
- png_uint_16 pd = file->bit_depth;
-
- switch (file->color_type)
- {
- default:
- stop_invalid(file, "IHDR: colour type");
-
- invalid_bit_depth:
- stop_invalid(file, "IHDR: bit depth");
-
- case 0: /* g */
- if (pd != 1 && pd != 2 && pd != 4 && pd != 8 && pd != 16)
- goto invalid_bit_depth;
- break;
-
- case 3:
- if (pd != 1 && pd != 2 && pd != 4 && pd != 8)
- goto invalid_bit_depth;
- break;
-
- case 2: /* rgb */
- if (pd != 8 && pd != 16)
- goto invalid_bit_depth;
-
- pd = (png_uint_16)(pd * 3);
- break;
-
- case 4: /* ga */
- if (pd != 8 && pd != 16)
- goto invalid_bit_depth;
-
- pd = (png_uint_16)(pd * 2);
- break;
-
- case 6: /* rgba */
- if (pd != 8 && pd != 16)
- goto invalid_bit_depth;
-
- pd = (png_uint_16)(pd * 4);
- break;
- }
-
- if (file->width < 1 || file->width > 0x7fffffff)
- stop_invalid(file, "IHDR: width");
-
- else if (file->height < 1 || file->height > 0x7fffffff)
- stop_invalid(file, "IHDR: height");
-
- else if (file->compression_method != 0)
- stop_invalid(file, "IHDR: compression method");
-
- else if (file->filter_method != 0)
- stop_invalid(file, "IHDR: filter method");
-
- else switch (file->interlace_method)
- {
- case PNG_INTERLACE_ADAM7:
- /* Interlacing makes the image larger because of the replication of
- * both the filter byte and the padding to a byte boundary.
- */
- {
- int pass;
- int image_digits = 0;
- udigit row_width[2], row_bytes[3];
-
- for (pass=0; pass<=6; ++pass)
- {
- png_uint_32 pw = PNG_PASS_COLS(file->width, pass);
-
- if (pw > 0)
- {
- int digits;
-
- /* calculate 1+((pw*pd+7)>>3) in row_bytes */
- digits = uarb_mult_digit(row_bytes, uarb_set(row_bytes, 7),
- row_width, uarb_set(row_width, pw), pd);
- digits = uarb_shift(row_bytes, digits, 3);
- digits = uarb_inc(row_bytes, digits, 1);
-
- /* Add row_bytes * pass-height to the file image_bytes field
- */
- image_digits = uarb_mult32(file->image_bytes, image_digits,
- row_bytes, digits,
- PNG_PASS_ROWS(file->height, pass));
- }
- }
-
- file->image_digits = image_digits;
- }
- break;
-
- case PNG_INTERLACE_NONE:
- {
- int digits;
- udigit row_width[2], row_bytes[3];
-
- /* As above, but use image_width in place of the pass width: */
- digits = uarb_mult_digit(row_bytes, uarb_set(row_bytes, 7),
- row_width, uarb_set(row_width, file->width), pd);
- digits = uarb_shift(row_bytes, digits, 3);
- digits = uarb_inc(row_bytes, digits, 1);
-
- /* Set row_bytes * image-height to the file image_bytes field */
- file->image_digits = uarb_mult32(file->image_bytes, 0,
- row_bytes, digits, file->height);
- }
- break;
-
- default:
- stop_invalid(file, "IHDR: interlace method");
- }
-
- assert(file->image_digits >= 1 && file->image_digits <= 5);
- return 1;
-}
-
-/* PER-CHUNK CONTROL STRUCTURE
- * This structure is instantiated for each chunk, except for the IDAT chunks
- * where one chunk control structure is used for the whole of a single stream of
- * IDAT chunks (see the IDAT control structure below).
- */
-struct chunk
-{
- /* ANCESTORS */
- struct file * file;
- struct global * global;
-
- /* PUBLIC IDAT INFORMATION: SET BY THE ZLIB CODE */
- udigit uncompressed_bytes[5];
- int uncompressed_digits;
- udigit compressed_bytes[5];
- int compressed_digits;
-
- /* PUBLIC PER-CHUNK INFORMATION: USED BY CHUNK READ CODE */
- /* This information is filled in by chunk_init from the data in the file
- * control structure, but chunk_length may be changed later.
- */
- fpos_t chunk_data_pos; /* Position of first byte of chunk data */
- png_uint_32 chunk_length; /* From header (or modified below) */
- png_uint_32 chunk_type; /* From header */
-
- /* PUBLIC PER-CHUNK INFORMATION: FOR THE CHUNK WRITE CODE */
- png_uint_32 write_crc; /* Output CRC (may differ from read_crc) */
- png_uint_32 rewrite_offset; /* Count of bytes before rewrite. */
- int rewrite_length; /* Number of bytes left to change */
- png_byte rewrite_buffer[2]; /* Buffer of new byte values */
-};
-
-static void
-chunk_message(struct chunk *chunk, const char *message)
-{
- type_message(chunk->file, chunk->chunk_type, message);
-}
-
-static void
-chunk_end(struct chunk **chunk_var)
-{
- struct chunk *chunk = *chunk_var;
-
- *chunk_var = NULL;
- CLEAR(*chunk);
-}
-
-static void
-chunk_init(struct chunk * const chunk, struct file * const file)
- /* When a chunk is initialized the file length/type/pos are copied into the
- * corresponding chunk fields and the new chunk is registered in the file
- * structure. There can only be one chunk at a time.
- *
- * NOTE: this routine must onely be called from the file alloc routine!
- */
-{
- assert(file->chunk == NULL);
-
- CLEAR(*chunk);
-
- chunk->file = file;
- chunk->global = file->global;
-
- chunk->chunk_data_pos = file->data_pos;
- chunk->chunk_length = file->length;
- chunk->chunk_type = file->type;
-
- /* Compresssed/uncompressed size information (from the zlib control structure
- * that is used to check the compressed data in a chunk.)
- */
- chunk->uncompressed_digits = 0;
- chunk->compressed_digits = 0;
-
- file->chunk = chunk;
-}
-
-static png_uint_32
-current_type(struct file *file, int code)
- /* Guess the actual chunk type that causes a stop() */
-{
- /* This may return png_IDAT for errors detected (late) in the header; that
- * includes any inter-chunk consistency check that libpng performs. Assume
- * that if the chunk_type is png_IDAT and the file write count is 8 this is
- * what is happening.
- */
- if (file->chunk != NULL)
- {
- png_uint_32 type = file->chunk->chunk_type;
-
- /* This is probably wrong for the excess IDATs case, because then libpng
- * whines about too many of them (apparently in some cases erroneously)
- * when the header is read.
- */
- if (code <= LIBPNG_ERROR_CODE && type == png_IDAT &&
- file->write_count == 8)
- type = 0; /* magic */
-
- return type;
- }
-
- else
- return file->type;
-}
-
-static void
-setpos(struct chunk *chunk)
- /* Reset the position to 'chunk_data_pos' - the start of the data for this
- * chunk. As a side effect the read_count in the file is reset to 8, just
- * after the length/type header.
- */
-{
- chunk->file->read_count = 8;
- file_setpos(chunk->file, &chunk->chunk_data_pos);
-}
-
-/* Specific chunk handling - called for each chunk header, all special chunk
- * processing is initiated in these functions.
- */
-/* The next functions handle special processing for those chunks with LZ data,
- * the data is identified and checked for validity. If there are problems which
- * cannot be corrected the routines return false, otherwise true (although
- * modification to the zlib header may be required.)
- *
- * The compressed data is in zlib format (RFC1950) and consequently has a
- * minimum length of 7 bytes.
- */
-static int zlib_check(struct file *file, png_uint_32 offset);
-
-static int
-process_zTXt_iCCP(struct file *file)
- /* zTXt and iCCP have exactly the same form - keyword, null, compression
- * method then compressed data.
- */
-{
- struct chunk *chunk = file->chunk;
- png_uint_32 length;
- png_uint_32 index = 0;
-
- assert(chunk != NULL && file->idat == NULL);
- length = chunk->chunk_length;
- setpos(chunk);
-
- while (length >= 9)
- {
- --length;
- ++index;
- if (reread_byte(file) == 0) /* keyword null terminator */
- {
- --length;
- ++index;
- (void)reread_byte(file); /* compression method */
- return zlib_check(file, index);
- }
- }
-
- chunk_message(chunk, "too short");
- return 0; /* skip */
-}
-
-static int
-process_iTXt(struct file *file)
-{
- /* Like zTXt but more fields. */
- struct chunk *chunk = file->chunk;
- png_uint_32 length;
- png_uint_32 index = 0;
-
- assert(chunk != NULL && file->idat == NULL);
- length = chunk->chunk_length;
- setpos(chunk);
-
- while (length >= 5)
- {
- --length;
- ++index;
- if (reread_byte(file) == 0) /* keyword null terminator */
- {
- --length;
- ++index;
- if (reread_byte(file) == 0) /* uncompressed text */
- return 1; /* nothing to check */
-
- --length;
- ++index;
- (void)reread_byte(file); /* compression method */
-
- /* Skip the language tag (null terminated). */
- while (length >= 9)
- {
- --length;
- ++index;
- if (reread_byte(file) == 0) /* terminator */
- {
- /* Skip the translated keyword */
- while (length >= 8)
- {
- --length;
- ++index;
- if (reread_byte(file) == 0) /* terminator */
- return zlib_check(file, index);
- }
- }
- }
-
- /* Ran out of bytes in the compressed case. */
- break;
- }
- }
-
- log_error(file, INVALID_ERROR_CODE, "iTXt chunk length");
-
- return 0; /* skip */
-}
-
-/* IDAT READ/WRITE CONTROL STRUCTURE */
-struct IDAT
-{
- /* ANCESTORS */
- struct file * file;
- struct global * global;
-
- /* PROTECTED IDAT INFORMATION: SET BY THE IDAT READ CODE */
- struct IDAT_list *idat_list_head; /* START of the list of IDAT information */
- struct IDAT_list *idat_list_tail; /* *END* of the list of IDAT information */
-
- /* PROTECTED IDAT INFORMATION: USED BY THE IDAT WRITE CODE */
- struct IDAT_list *idat_cur; /* Current list entry */
- unsigned int idat_count; /* And the *current* index into the list */
- png_uint_32 idat_index; /* Index of *next* input byte to write */
- png_uint_32 idat_length; /* Cache of current chunk length */
-};
-
-/* NOTE: there is currently no IDAT_reset, so a stream cannot contain more than
- * one IDAT sequence (i.e. MNG is not supported).
- */
-
-static void
-IDAT_end(struct IDAT **idat_var)
-{
- struct IDAT *idat = *idat_var;
- struct file *file = idat->file;
-
- *idat_var = NULL;
-
- CLEAR(*idat);
-
- assert(file->chunk != NULL);
- chunk_end(&file->chunk);
-
- /* Regardless of why the IDAT was killed set the state back to CHUNKS (it may
- * already be CHUNKS because the state isn't changed until process_IDAT
- * returns; a stop will cause IDAT_end to be entered in state CHUNKS!)
- */
- file->state = STATE_CHUNKS;
-}
-
-static void
-IDAT_init(struct IDAT * const idat, struct file * const file)
- /* When the chunk is png_IDAT instantiate an IDAT control structure in place
- * of a chunk control structure. The IDAT will instantiate a chunk control
- * structure using the file alloc routine.
- *
- * NOTE: this routine must only be called from the file alloc routine!
- */
-{
- assert(file->chunk == NULL);
- assert(file->idat == NULL);
-
- CLEAR(*idat);
-
- idat->file = file;
- idat->global = file->global;
-
- /* Initialize the tail to the pre-allocated buffer and set the count to 0
- * (empty.)
- */
- idat->global->idat_cache.count = 0;
- idat->idat_list_head = idat->idat_list_tail = &idat->global->idat_cache;
-
- /* Now the chunk. The allocator calls the initializer of the new chunk and
- * stores the result in file->chunk:
- */
- file->alloc(file, 0/*chunk*/);
- assert(file->chunk != NULL);
-
- /* And store this for cleanup (and to check for double alloc or failure to
- * free.)
- */
- file->idat = idat;
-}
-
-static png_uint_32
-rechunk_length(struct IDAT *idat, int start)
- /* Return the length for the next IDAT chunk, taking into account
- * rechunking.
- */
-{
- png_uint_32 len = idat->global->idat_max;
-
- if (len == 0) /* use original chunk lengths */
- {
- const struct IDAT_list *cur;
- unsigned int count;
-
- if (start)
- return idat->idat_length; /* use the cache */
-
- /* Otherwise rechunk_length is called at the end of a chunk for the length
- * of the next one.
- */
- cur = idat->idat_cur;
- count = idat->idat_count;
-
- assert(idat->idat_index == idat->idat_length &&
- idat->idat_length == cur->lengths[count]);
-
- /* Return length of the *next* chunk */
- if (++count < cur->count)
- return cur->lengths[count];
-
- /* End of this list */
- assert(cur != idat->idat_list_tail);
- cur = cur->next;
- assert(cur != NULL && cur->count > 0);
- return cur->lengths[0];
- }
-
- else /* rechunking */
- {
- /* The chunk size is the lesser of file->idat_max and the number
- * of remaining bytes.
- */
- png_uint_32 have = idat->idat_length - idat->idat_index;
-
- if (len > have)
- {
- struct IDAT_list *cur = idat->idat_cur;
- unsigned int j = idat->idat_count+1; /* the next IDAT in the list */
-
- do
- {
- /* Add up the remaining bytes. This can't overflow because the
- * individual lengths are always <= 0x7fffffff, so when we add two
- * of them overflow is not possible.
- */
- assert(cur != NULL);
-
- for (;;)
- {
- /* NOTE: IDAT_list::count here, not IDAT_list::length */
- for (; j < cur->count; ++j)
- {
- have += cur->lengths[j];
- if (len <= have)
- return len;
- }
-
- /* If this was the end return the count of the available bytes */
- if (cur == idat->idat_list_tail)
- return have;
-
- cur = cur->next;
- j = 0;
- }
- }
- while (len > have);
- }
-
- return len;
- }
-}
-
-static int
-process_IDAT(struct file *file)
- /* Process the IDAT stream, this is the more complex than the preceding
- * cases because the compressed data is spread across multiple IDAT chunks
- * (typically). Rechunking of the data is not handled here; all this
- * function does is establish whether the zlib header needs to be modified.
- *
- * Initially the function returns false, indicating that the chunk should not
- * be written. It does this until the last IDAT chunk is passed in, then it
- * checks the zlib data and returns true.
- *
- * It does not return false on a fatal error; it calls stop instead.
- *
- * The caller must have an instantiated (IDAT) control structure and it must
- * have extent over the whole read of the IDAT stream. For a PNG this means
- * the whole PNG read, for MNG it could have lesser extent.
- */
-{
- struct IDAT_list *list;
-
- assert(file->idat != NULL && file->chunk != NULL);
-
- /* We need to first check the entire sequence of IDAT chunks to ensure the
- * stream is in sync. Do this by building a list of all the chunks and
- * recording the length of each because the length may have been fixed up by
- * sync_stream below.
- *
- * At the end of the list of chunks, where the type of the next chunk is not
- * png_IDAT, process the whole stream using the list data to check validity
- * then return control to the start and rewrite everything.
- */
- list = file->idat->idat_list_tail;
-
- if (list->count == list->length)
- {
- list = IDAT_list_extend(list);
-
- if (list == NULL)
- stop(file, READ_ERROR_CODE, "out of memory");
-
- /* Move to the next block */
- list->count = 0;
- file->idat->idat_list_tail = list;
- }
-
- /* And fill in the next IDAT information buffer. */
- list->lengths[(list->count)++] = file->chunk->chunk_length;
-
- /* The type of the next chunk was recorded in the file control structure by
- * the caller, if this is png_IDAT return 'skip' to the caller.
- */
- if (file->type == png_IDAT)
- return 0; /* skip this for the moment */
-
- /* This is the final IDAT chunk, so run the tests to check for the too far
- * back error and possibly optimize the window bits. This means going back
- * to the start of the first chunk data, which is stored in the original
- * chunk allocation.
- */
- setpos(file->chunk);
-
- if (zlib_check(file, 0))
- {
- struct IDAT *idat;
- int cmp;
-
- /* The IDAT stream was successfully uncompressed; see whether it
- * contained the correct number of bytes of image data.
- */
- cmp = uarb_cmp(file->image_bytes, file->image_digits,
- file->chunk->uncompressed_bytes, file->chunk->uncompressed_digits);
-
- if (cmp < 0)
- type_message(file, png_IDAT, "extra uncompressed data");
-
- else if (cmp > 0)
- stop(file, LIBPNG_ERROR_CODE, "IDAT: uncompressed data too small");
-
- /* Return the stream to the start of the first IDAT chunk; the length
- * is set in the write case below but the input chunk variables must be
- * set (once) here:
- */
- setpos(file->chunk);
-
- idat = file->idat;
- idat->idat_cur = idat->idat_list_head;
- idat->idat_length = idat->idat_cur->lengths[0];
- idat->idat_count = 0; /* Count of chunks read in current list */
- idat->idat_index = 0; /* Index into chunk data */
-
- /* Update the chunk length to the correct value for the IDAT chunk: */
- file->chunk->chunk_length = rechunk_length(idat, 1/*start*/);
-
- /* Change the state to writing IDAT chunks */
- file->state = STATE_IDAT;
-
- return 1;
- }
-
- else /* Failure to decompress the IDAT stream; give up. */
- stop(file, ZLIB_ERROR_CODE, "could not uncompress IDAT");
-}
-
-/* ZLIB CONTROL STRUCTURE */
-struct zlib
-{
- /* ANCESTORS */
- struct IDAT * idat; /* NOTE: May be NULL */
- struct chunk * chunk;
- struct file * file;
- struct global *global;
-
- /* GLOBAL ZLIB INFORMATION: SET BY THE CALLER */
- png_uint_32 rewrite_offset;
-
- /* GLOBAL ZLIB INFORMATION: SET BY THE ZLIB READ CODE */
- udigit compressed_bytes[5];
- int compressed_digits;
- udigit uncompressed_bytes[5];
- int uncompressed_digits;
- int file_bits; /* window bits from the file */
- int ok_bits; /* Set <16 on a successful read */
- int cksum; /* Set on a checksum error */
-
- /* PROTECTED ZLIB INFORMATION: USED BY THE ZLIB ROUTINES */
- z_stream z;
- png_uint_32 extra_bytes; /* Count of extra compressed bytes */
- int state;
- int rc; /* Last return code */
- int window_bits; /* 0 if no change */
- png_byte header[2];
-};
-
-static const char *
-zlib_flevel(struct zlib *zlib)
-{
- switch (zlib->header[1] >> 6)
- {
- case 0: return "supfast";
- case 1: return "stdfast";
- case 2: return "default";
- case 3: return "maximum";
- default: assert(UNREACHED);
- }
-
- return "COMPILER BUG";
-}
-
-static const char *
-zlib_rc(struct zlib *zlib)
- /* Return a string for the zlib return code */
-{
- switch (zlib->rc)
- {
- case Z_OK: return "Z_OK";
- case Z_STREAM_END: return "Z_STREAM_END";
- case Z_NEED_DICT: return "Z_NEED_DICT";
- case Z_ERRNO: return "Z_ERRNO";
- case Z_STREAM_ERROR: return "Z_STREAM_ERROR";
- case Z_DATA_ERROR: return "Z_DATA_ERROR";
- case Z_MEM_ERROR: return "Z_MEM_ERROR";
- case Z_BUF_ERROR: return "Z_BUF_ERROR";
- case Z_VERSION_ERROR: return "Z_VERSION_ERROR";
- default: return "Z_*INVALID_RC*";
- }
-}
-
-static void
-zlib_message(struct zlib *zlib, int unexpected)
- /* Output a message given a zlib rc */
-{
- if (zlib->global->errors)
- {
- const char *reason = zlib->z.msg;
-
- if (reason == NULL)
- reason = "[no message]";
-
- fputs(zlib->file->file_name, stderr);
- type_sep(stderr);
- type_name(zlib->chunk->chunk_type, stderr);
- fprintf(stderr, ": %szlib error: %d (%s) (%s)\n",
- unexpected ? "unexpected " : "", zlib->rc, zlib_rc(zlib), reason);
- }
-}
-
-static void
-zlib_end(struct zlib *zlib)
-{
- /* Output the summary line now; this ensures a summary line always gets
- * output regardless of the manner of exit.
- */
- if (!zlib->global->quiet)
- {
- if (zlib->ok_bits < 16) /* stream was read ok */
- {
- const char *reason;
-
- if (zlib->cksum)
- reason = "CHK"; /* checksum error */
-
- else if (zlib->ok_bits > zlib->file_bits)
- reason = "TFB"; /* fixing a too-far-back error */
-
- else if (zlib->ok_bits == zlib->file_bits)
- reason = "OK ";
-
- else
- reason = "OPT"; /* optimizing window bits */
-
- /* SUMMARY FORMAT (for a successful zlib inflate):
- *
- * IDAT reason flevel file-bits ok-bits compressed uncompressed file
- */
- type_name(zlib->chunk->chunk_type, stdout);
- printf(" %s %s %d %d ", reason, zlib_flevel(zlib), zlib->file_bits,
- zlib->ok_bits);
- uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout);
- putc(' ', stdout);
- uarb_print(zlib->uncompressed_bytes, zlib->uncompressed_digits,
- stdout);
- putc(' ', stdout);
- fputs(zlib->file->file_name, stdout);
- putc('\n', stdout);
- }
-
- else
- {
- /* This is a zlib read error; the chunk will be skipped. For an IDAT
- * stream this will also cause a fatal read error (via stop()).
- *
- * SUMMARY FORMAT:
- *
- * IDAT SKP flevel file-bits z-rc compressed message file
- *
- * z-rc is the zlib failure code; message is the error message with
- * spaces replaced by '-'. The compressed byte count indicates where
- * in the zlib stream the error occurred.
- */
- type_name(zlib->chunk->chunk_type, stdout);
- printf(" SKP %s %d %s ", zlib_flevel(zlib), zlib->file_bits,
- zlib_rc(zlib));
- uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout);
- putc(' ', stdout);
- emit_string(zlib->z.msg ? zlib->z.msg : "[no_message]", stdout);
- putc(' ', stdout);
- fputs(zlib->file->file_name, stdout);
- putc('\n', stdout);
- }
- }
-
- if (zlib->state >= 0)
- {
- zlib->rc = inflateEnd(&zlib->z);
-
- if (zlib->rc != Z_OK)
- zlib_message(zlib, 1/*unexpected*/);
- }
-
- CLEAR(*zlib);
-}
-
-static int
-zlib_reset(struct zlib *zlib, int window_bits)
- /* Reinitializes a zlib with a different window_bits */
-{
- assert(zlib->state >= 0); /* initialized by zlib_init */
-
- zlib->z.next_in = Z_NULL;
- zlib->z.avail_in = 0;
- zlib->z.next_out = Z_NULL;
- zlib->z.avail_out = 0;
-
- zlib->window_bits = window_bits;
- zlib->compressed_digits = 0;
- zlib->uncompressed_digits = 0;
-
- zlib->state = 0; /* initialized, once */
- zlib->rc = inflateReset2(&zlib->z, 0);
- if (zlib->rc != Z_OK)
- {
- zlib_message(zlib, 1/*unexpected*/);
- return 0;
- }
-
- return 1;
-}
-
-static int
-zlib_init(struct zlib *zlib, struct IDAT *idat, struct chunk *chunk,
- int window_bits, png_uint_32 offset)
- /* Initialize a zlib_control; the result is true/false */
-{
- CLEAR(*zlib);
-
- zlib->idat = idat;
- zlib->chunk = chunk;
- zlib->file = chunk->file;
- zlib->global = chunk->global;
- zlib->rewrite_offset = offset; /* never changed for this zlib */
-
- /* *_out does not need to be set: */
- zlib->z.next_in = Z_NULL;
- zlib->z.avail_in = 0;
- zlib->z.zalloc = Z_NULL;
- zlib->z.zfree = Z_NULL;
- zlib->z.opaque = Z_NULL;
-
- zlib->state = -1;
- zlib->window_bits = window_bits;
-
- zlib->compressed_digits = 0;
- zlib->uncompressed_digits = 0;
-
- /* These values are sticky across reset (in addition to the stuff in the
- * first block, which is actually constant.)
- */
- zlib->file_bits = 24;
- zlib->ok_bits = 16; /* unset */
- zlib->cksum = 0; /* set when a checksum error is detected */
-
- /* '0' means use the header; inflateInit2 should always succeed because it
- * does nothing apart from allocating the internal zstate.
- */
- zlib->rc = inflateInit2(&zlib->z, 0);
- if (zlib->rc != Z_OK)
- {
- zlib_message(zlib, 1/*unexpected*/);
- return 0;
- }
-
- else
- {
- zlib->state = 0; /* initialized */
- return 1;
- }
-}
-
-static int
-max_window_bits(uarbc size, int ndigits)
- /* Return the zlib stream window bits required for data of the given size. */
-{
- png_uint_16 cb;
-
- if (ndigits > 1)
- return 15;
-
- cb = size[0];
-
- if (cb > 16384) return 15;
- if (cb > 8192) return 14;
- if (cb > 4096) return 13;
- if (cb > 2048) return 12;
- if (cb > 1024) return 11;
- if (cb > 512) return 10;
- if (cb > 256) return 9;
- return 8;
-}
-
-static int
-zlib_advance(struct zlib *zlib, png_uint_32 nbytes)
- /* Read nbytes compressed bytes; the stream will be initialized if required.
- * Bytes are always being reread and errors are fatal. The return code is as
- * follows:
- *
- * -1: saw the "too far back" error
- * 0: ok, keep going
- * 1: saw Z_STREAM_END (zlib->extra_bytes indicates too much data)
- * 2: a zlib error that cannot be corrected (error message already
- * output if required.)
- */
-# define ZLIB_TOO_FAR_BACK (-1)
-# define ZLIB_OK 0
-# define ZLIB_STREAM_END 1
-# define ZLIB_FATAL 2
-{
- int state = zlib->state;
- int endrc = ZLIB_OK;
- png_uint_32 in_bytes = 0;
- struct file *file = zlib->file;
-
- assert(state >= 0);
-
- while (in_bytes < nbytes && endrc == ZLIB_OK)
- {
- png_uint_32 out_bytes;
- int flush;
- png_byte bIn = reread_byte(file);
- png_byte bOut;
-
- switch (state)
- {
- case 0: /* first header byte */
- {
- int file_bits = 8+(bIn >> 4);
- int new_bits = zlib->window_bits;
-
- zlib->file_bits = file_bits;
-
- /* Check against the existing value - it may not need to be
- * changed. Note that a bogus file_bits is allowed through once,
- * to see if it works, but the window_bits value is set to 15,
- * the maximum.
- */
- if (new_bits == 0) /* no change */
- zlib->window_bits = ((file_bits > 15) ? 15 : file_bits);
-
- else if (new_bits != file_bits) /* rewrite required */
- bIn = (png_byte)((bIn & 0xf) + ((new_bits-8) << 4));
- }
-
- zlib->header[0] = bIn;
- zlib->state = state = 1;
- break;
-
- case 1: /* second header byte */
- {
- int b2 = bIn & 0xe0; /* top 3 bits */
-
- /* The checksum calculation, on the first 11 bits: */
- b2 += 0x1f - ((zlib->header[0] << 8) + b2) % 0x1f;
-
- /* Update the checksum byte if required: */
- if (bIn != b2)
- {
- /* If the first byte wasn't changed this indicates an error in
- * the checksum calculation; signal this by setting 'cksum'.
- */
- if (zlib->file_bits == zlib->window_bits)
- zlib->cksum = 1;
-
- bIn = (png_byte)b2;
- }
- }
-
- zlib->header[1] = bIn;
- zlib->state = state = 2;
- break;
-
- default: /* After the header bytes */
- break;
- }
-
- /* For some streams, perhaps only those compressed with 'superfast
- * compression' (which results in a lot of copying) Z_BUF_ERROR can happen
- * immediately after all output has been flushed on the next input byte.
- * This is handled below when Z_BUF_ERROR is detected by adding an output
- * byte.
- */
- zlib->z.next_in = &bIn;
- zlib->z.avail_in = 1;
- zlib->z.next_out = &bOut;
- zlib->z.avail_out = 0; /* Initially */
-
- /* Initially use Z_NO_FLUSH in an attempt to persuade zlib to look at this
- * byte without confusing what is going on with output.
- */
- flush = Z_NO_FLUSH;
- out_bytes = 0;
-
- /* NOTE: expression 3 is only evaluated on 'continue', because of the
- * 'break' at the end of this loop below.
- */
- for (;endrc == ZLIB_OK;
- flush = Z_SYNC_FLUSH,
- zlib->z.next_out = &bOut,
- zlib->z.avail_out = 1,
- ++out_bytes)
- {
- zlib->rc = inflate(&zlib->z, flush);
- out_bytes -= zlib->z.avail_out;
-
- switch (zlib->rc)
- {
- case Z_BUF_ERROR:
- if (zlib->z.avail_out == 0)
- continue; /* Try another output byte. */
-
- if (zlib->z.avail_in == 0)
- break; /* Try another input byte */
-
- /* Both avail_out and avail_in are 1 yet zlib returned a code
- * indicating no progress was possible. This is unexpected.
- */
- zlib_message(zlib, 1/*unexpected*/);
- endrc = ZLIB_FATAL; /* stop processing */
- break;
-
- case Z_OK:
- /* Zlib is supposed to have made progress: */
- assert(zlib->z.avail_out == 0 || zlib->z.avail_in == 0);
- continue;
-
- case Z_STREAM_END:
- /* This is the successful end. */
- zlib->state = 3; /* end of stream */
- endrc = ZLIB_STREAM_END;
- break;
-
- case Z_NEED_DICT:
- zlib_message(zlib, 0/*stream error*/);
- endrc = ZLIB_FATAL;
- break;
-
- case Z_DATA_ERROR:
- /* The too far back error can be corrected, others cannot: */
- if (zlib->z.msg != NULL &&
- strcmp(zlib->z.msg, "invalid distance too far back") == 0)
- {
- endrc = ZLIB_TOO_FAR_BACK;
- break;
- }
- /* FALLTHROUGH */
-
- default:
- zlib_message(zlib, 0/*stream error*/);
- endrc = ZLIB_FATAL;
- break;
- } /* switch (inflate rc) */
-
- /* Control gets here when further output is not possible; endrc may
- * still be ZLIB_OK if more input is required.
- */
- break;
- } /* for (output bytes) */
-
- /* Keep a running count of output byte produced: */
- zlib->uncompressed_digits = uarb_add32(zlib->uncompressed_bytes,
- zlib->uncompressed_digits, out_bytes);
-
- /* Keep going, the loop will terminate when endrc is no longer set to
- * ZLIB_OK or all the input bytes have been consumed; meanwhile keep
- * adding input bytes.
- */
- assert(zlib->z.avail_in == 0 || endrc != ZLIB_OK);
-
- in_bytes += 1 - zlib->z.avail_in;
- } /* while (input bytes) */
-
- assert(in_bytes == nbytes || endrc != ZLIB_OK);
-
- /* Update the running total of input bytes consumed */
- zlib->compressed_digits = uarb_add32(zlib->compressed_bytes,
- zlib->compressed_digits, in_bytes - zlib->z.avail_in);
-
- /* At the end of the stream update the chunk with the accumulated
- * information if it is an improvement:
- */
- if (endrc == ZLIB_STREAM_END && zlib->window_bits < zlib->ok_bits)
- {
- struct chunk *chunk = zlib->chunk;
-
- chunk->uncompressed_digits = uarb_copy(chunk->uncompressed_bytes,
- zlib->uncompressed_bytes, zlib->uncompressed_digits);
- chunk->compressed_digits = uarb_copy(chunk->compressed_bytes,
- zlib->compressed_bytes, zlib->compressed_digits);
- chunk->rewrite_buffer[0] = zlib->header[0];
- chunk->rewrite_buffer[1] = zlib->header[1];
-
- if (zlib->window_bits != zlib->file_bits || zlib->cksum)
- {
- /* A rewrite is required */
- chunk->rewrite_offset = zlib->rewrite_offset;
- chunk->rewrite_length = 2;
- }
-
- else
- {
- chunk->rewrite_offset = 0;
- chunk->rewrite_length = 0;
- }
-
- if (in_bytes < nbytes)
- chunk_message(chunk, "extra compressed data");
-
- zlib->extra_bytes = nbytes - in_bytes;
- zlib->ok_bits = zlib->window_bits;
- }
-
- return endrc;
-}
-
-static int
-zlib_run(struct zlib *zlib)
- /* Like zlib_advance but also handles a stream of IDAT chunks. */
-{
- /* The 'extra_bytes' field is set by zlib_advance if there is extra
- * compressed data in the chunk it handles (if it sees Z_STREAM_END before
- * all the input data has been used.) This function uses the value to update
- * the correct chunk length, so the problem should only ever be detected once
- * for each chunk. zlib_advance outputs the error message, though see the
- * IDAT specific check below.
- */
- zlib->extra_bytes = 0;
-
- if (zlib->idat != NULL)
- {
- struct IDAT_list *list = zlib->idat->idat_list_head;
- struct IDAT_list *last = zlib->idat->idat_list_tail;
- int skip = 0;
-
- /* 'rewrite_offset' is the offset of the LZ data within the chunk, for
- * IDAT it should be 0:
- */
- assert(zlib->rewrite_offset == 0);
-
- /* Process each IDAT_list in turn; the caller has left the stream
- * positioned at the start of the first IDAT chunk data.
- */
- for (;;)
- {
- unsigned int count = list->count;
- unsigned int i;
-
- for (i = 0; i<count; ++i)
- {
- int rc;
-
- if (skip > 0) /* Skip CRC and next IDAT header */
- skip_12(zlib->file);
-
- skip = 12; /* for the next time */
-
- rc = zlib_advance(zlib, list->lengths[i]);
-
- switch (rc)
- {
- case ZLIB_OK: /* keep going */
- break;
-
- case ZLIB_STREAM_END: /* stop */
- /* There may be extra chunks; if there are and one of them is
- * not zero length output the 'extra data' message. Only do
- * this check if errors are being output.
- */
- if (zlib->global->errors && zlib->extra_bytes == 0)
- {
- struct IDAT_list *check = list;
- int j = i+1, jcount = count;
-
- for (;;)
- {
- for (; j<jcount; ++j)
- if (check->lengths[j] > 0)
- {
- chunk_message(zlib->chunk,
- "extra compressed data");
- goto end_check;
- }
-
- if (check == last)
- break;
-
- check = check->next;
- jcount = check->count;
- j = 0;
- }
- }
-
- end_check:
- /* Terminate the list at the current position, reducing the
- * length of the last IDAT too if required.
- */
- list->lengths[i] -= zlib->extra_bytes;
- list->count = i+1;
- zlib->idat->idat_list_tail = list;
- /* FALLTHROUGH */
-
- default:
- return rc;
- }
- }
-
- /* At the end of the compressed data and Z_STREAM_END was not seen. */
- if (list == last)
- return ZLIB_OK;
-
- list = list->next;
- }
- }
-
- else
- {
- struct chunk *chunk = zlib->chunk;
- int rc;
-
- assert(zlib->rewrite_offset < chunk->chunk_length);
-
- rc = zlib_advance(zlib, chunk->chunk_length - zlib->rewrite_offset);
-
- /* The extra bytes in the chunk are handled now by adjusting the chunk
- * length to exclude them; the zlib data is always stored at the end of
- * the PNG chunk (although clearly this is not necessary.) zlib_advance
- * has already output a warning message.
- */
- chunk->chunk_length -= zlib->extra_bytes;
- return rc;
- }
-}
-
-static int /* global function; not a member function */
-zlib_check(struct file *file, png_uint_32 offset)
- /* Check the stream of zlib compressed data in either idat (if given) or (if
- * not) chunk. In fact it is zlib_run that handles the difference in reading
- * a single chunk and a list of IDAT chunks.
- *
- * In either case the input file must be positioned at the first byte of zlib
- * compressed data (the first header byte).
- *
- * The return value is true on success, including the case where the zlib
- * header may need to be rewritten, and false on an unrecoverable error.
- *
- * In the case of IDAT chunks 'offset' should be 0.
- */
-{
- fpos_t start_pos;
- struct zlib zlib;
-
- /* Record the start of the LZ data to allow a re-read. */
- file_getpos(file, &start_pos);
-
- /* First test the existing (file) window bits: */
- if (zlib_init(&zlib, file->idat, file->chunk, 0/*window bits*/, offset))
- {
- int min_bits, max_bits, rc;
-
- /* The first run using the existing window bits. */
- rc = zlib_run(&zlib);
-
- switch (rc)
- {
- case ZLIB_TOO_FAR_BACK:
- /* too far back error */
- file->status_code |= TOO_FAR_BACK;
- min_bits = zlib.window_bits + 1;
- max_bits = 15;
- break;
-
- case ZLIB_STREAM_END:
- if (!zlib.global->optimize_zlib &&
- zlib.window_bits == zlib.file_bits && !zlib.cksum)
- {
- /* The trivial case where the stream is ok and optimization was
- * not requested.
- */
- zlib_end(&zlib);
- return 1;
- }
-
- max_bits = max_window_bits(zlib.uncompressed_bytes,
- zlib.uncompressed_digits);
- if (zlib.ok_bits < max_bits)
- max_bits = zlib.ok_bits;
- min_bits = 8;
-
- /* cksum is set if there is an error in the zlib header checksum
- * calculation in the original file (and this may be the only reason
- * a rewrite is required). We can't rely on the file window bits in
- * this case, so do the optimization anyway.
- */
- if (zlib.cksum)
- chunk_message(zlib.chunk, "zlib checksum");
- break;
-
-
- case ZLIB_OK:
- /* Truncated stream; unrecoverable, gets converted to ZLIB_FATAL */
- zlib.z.msg = PNGZ_MSG_CAST("[truncated]");
- zlib_message(&zlib, 0/*expected*/);
- /* FALLTHROUGH */
-
- default:
- /* Unrecoverable error; skip the chunk; a zlib_message has already
- * been output.
- */
- zlib_end(&zlib);
- return 0;
- }
-
- /* Optimize window bits or fix a too-far-back error. min_bits and
- * max_bits have been set appropriately, ok_bits records the bit value
- * known to work.
- */
- while (min_bits < max_bits || max_bits < zlib.ok_bits/*if 16*/)
- {
- int test_bits = (min_bits + max_bits) >> 1;
-
- if (zlib_reset(&zlib, test_bits))
- {
- file_setpos(file, &start_pos);
- rc = zlib_run(&zlib);
-
- switch (rc)
- {
- case ZLIB_TOO_FAR_BACK:
- min_bits = test_bits+1;
- if (min_bits > max_bits)
- {
- /* This happens when the stream really is damaged and it
- * contains a distance code that addresses bytes before
- * the start of the uncompressed data.
- */
- assert(test_bits == 15);
-
- /* Output the error that wasn't output before: */
- if (zlib.z.msg == NULL)
- zlib.z.msg = PNGZ_MSG_CAST(
- "invalid distance too far back");
- zlib_message(&zlib, 0/*stream error*/);
- zlib_end(&zlib);
- return 0;
- }
- break;
-
- case ZLIB_STREAM_END: /* success */
- max_bits = test_bits;
- break;
-
- default:
- /* A fatal error; this happens if a too-far-back error was
- * hiding a more serious error, zlib_advance has already
- * output a zlib_message.
- */
- zlib_end(&zlib);
- return 0;
- }
- }
-
- else /* inflateReset2 failed */
- {
- zlib_end(&zlib);
- return 0;
- }
- }
-
- /* The loop guarantees this */
- assert(zlib.ok_bits == max_bits);
- zlib_end(&zlib);
- return 1;
- }
-
- else /* zlib initialization failed - skip the chunk */
- {
- zlib_end(&zlib);
- return 0;
- }
-}
-
-/***************************** LIBPNG CALLBACKS *******************************/
-/* The strategy here is to run a regular libpng PNG file read but examine the
- * input data (from the file) before passing it to libpng so as to be aware of
- * the state we expect libpng to be in. Warning and error callbacks are also
- * intercepted so that they can be quieted and interpreted. Interpretation
- * depends on a somewhat risky string match for known error messages; let us
- * hope that this can be fixed in the next version of libpng.
- *
- * The control structure is pointed to by the libpng error pointer. It contains
- * that set of structures which must persist across multiple read callbacks,
- * which is pretty much everything except the 'zlib' control structure.
- *
- * The file structure is instantiated in the caller of the per-file routine, but
- * the per-file routine contains the chunk and IDAT control structures.
- */
-/* The three routines read_chunk, process_chunk and sync_stream can only be
- * called via a call to read_chunk and only exit at a return from process_chunk.
- * These routines could have been written as one confusing large routine,
- * instead this code relies on the compiler to do tail call elimination. The
- * possible calls are as follows:
- *
- * read_chunk
- * -> sync_stream
- * -> process_chunk
- * -> process_chunk
- * -> read_chunk
- * returns
- */
-static void read_chunk(struct file *file);
-static void
-process_chunk(struct file *file, png_uint_32 file_crc, png_uint_32 next_length,
- png_uint_32 next_type)
- /* Called when the chunk data has been read, next_length and next_type
- * will be set for the next chunk (or 0 if this is IEND).
- *
- * When this routine returns, chunk_length and chunk_type will be set for the
- * next chunk to write because if a chunk is skipped this return calls back
- * to read_chunk.
- */
-{
- png_uint_32 type = file->type;
-
- if (file->global->verbose > 1)
- {
- fputs(" ", stderr);
- type_name(file->type, stderr);
- fprintf(stderr, " %lu 0x%.8x 0x%.8x\n", (unsigned long)file->length,
- file->crc ^ 0xffffffff, file_crc);
- }
-
- /* The basic structure seems correct but the CRC may not match, in this
- * case assume that it is simply a bad CRC, either wrongly calculated or
- * because of damaged stream data.
- */
- if ((file->crc ^ 0xffffffff) != file_crc)
- {
- /* The behavior is set by the 'skip' setting; if it is anything other
- * than SKIP_BAD_CRC ignore the bad CRC and return the chunk, with a
- * corrected CRC and possibly processed, to libpng. Otherwise skip the
- * chunk, which will result in a fatal error if the chunk is critical.
- */
- file->status_code |= CRC_ERROR;
-
- /* Ignore the bad CRC */
- if (file->global->skip != SKIP_BAD_CRC)
- type_message(file, type, "bad CRC");
-
- /* This will cause an IEND with a bad CRC to stop */
- else if (CRITICAL(type))
- stop(file, READ_ERROR_CODE, "bad CRC in critical chunk");
-
- else
- {
- type_message(file, type, "skipped: bad CRC");
-
- /* NOTE: this cannot be reached for IEND because it is critical. */
- goto skip_chunk;
- }
- }
-
- /* Check for other 'skip' cases and handle these; these only apply to
- * ancillary chunks (and not tRNS, which should probably have been a critical
- * chunk.)
- */
- if (skip_chunk_type(file->global, type))
- goto skip_chunk;
-
- /* The chunk may still be skipped if problems are detected in the LZ data,
- * however the LZ data check requires a chunk. Handle this by instantiating
- * a chunk unless an IDAT is already instantiated (IDAT control structures
- * instantiate their own chunk.)
- */
- if (type != png_IDAT)
- file->alloc(file, 0/*chunk*/);
-
- else if (file->idat == NULL)
- file->alloc(file, 1/*IDAT*/);
-
- else
- {
- /* The chunk length must be updated for process_IDAT */
- assert(file->chunk != NULL);
- assert(file->chunk->chunk_type == png_IDAT);
- file->chunk->chunk_length = file->length;
- }
-
- /* Record the 'next' information too, now that the original values for
- * this chunk have been copied. Notice that the IDAT chunks only make a
- * copy of the position of the first chunk, this is fine - process_IDAT does
- * not need the position of this chunk.
- */
- file->length = next_length;
- file->type = next_type;
- getpos(file);
-
- /* Do per-type processing, note that if this code does not return from the
- * function the chunk will be skipped. The rewrite is cancelled here so that
- * it can be set in the per-chunk processing.
- */
- file->chunk->rewrite_length = 0;
- file->chunk->rewrite_offset = 0;
- switch (type)
- {
- default:
- return;
-
- case png_IHDR:
- /* Read this now and update the control structure with the information
- * it contains. The header is validated completely to ensure this is a
- * PNG.
- */
- {
- struct chunk *chunk = file->chunk;
-
- if (chunk->chunk_length != 13)
- stop_invalid(file, "IHDR length");
-
- /* Read all the IHDR information and validate it. */
- setpos(chunk);
- file->width = reread_4(file);
- file->height = reread_4(file);
- file->bit_depth = reread_byte(file);
- file->color_type = reread_byte(file);
- file->compression_method = reread_byte(file);
- file->filter_method = reread_byte(file);
- file->interlace_method = reread_byte(file);
-
- /* This validates all the fields, and calls stop_invalid if
- * there is a problem.
- */
- calc_image_size(file);
- }
- return;
-
- /* Ancillary chunks that require further processing: */
- case png_zTXt: case png_iCCP:
- if (process_zTXt_iCCP(file))
- return;
- chunk_end(&file->chunk);
- file_setpos(file, &file->data_pos);
- break;
-
- case png_iTXt:
- if (process_iTXt(file))
- return;
- chunk_end(&file->chunk);
- file_setpos(file, &file->data_pos);
- break;
-
- case png_IDAT:
- if (process_IDAT(file))
- return;
- /* First pass: */
- assert(next_type == png_IDAT);
- break;
- }
-
- /* Control reaches this point if the chunk must be skipped. For chunks other
- * than IDAT this means that the zlib compressed data is fatally damanged and
- * the chunk will not be passed to libpng. For IDAT it means that the end of
- * the IDAT stream has not yet been reached and we must handle the next
- * (IDAT) chunk. If the LZ data in an IDAT stream cannot be read 'stop' must
- * be used to halt parsing of the PNG.
- */
- read_chunk(file);
- return;
-
- /* This is the generic code to skip the current chunk; simply jump to the
- * next one.
- */
-skip_chunk:
- file->length = next_length;
- file->type = next_type;
- getpos(file);
- read_chunk(file);
-}
-
-static png_uint_32
-get32(png_bytep buffer, int offset)
- /* Read a 32-bit value from an 8-byte circular buffer (used only below).
- */
-{
- return
- (buffer[ offset & 7] << 24) +
- (buffer[(offset+1) & 7] << 16) +
- (buffer[(offset+2) & 7] << 8) +
- (buffer[(offset+3) & 7] );
-}
-
-static void
-sync_stream(struct file *file)
- /* The stream seems to be messed up, attempt to resync from the current chunk
- * header. Executes stop on a fatal error, otherwise calls process_chunk.
- */
-{
- png_uint_32 file_crc;
-
- file->status_code |= STREAM_ERROR;
-
- if (file->global->verbose)
- {
- fputs(" SYNC ", stderr);
- type_name(file->type, stderr);
- putc('\n', stderr);
- }
-
- /* Return to the start of the chunk data */
- file_setpos(file, &file->data_pos);
- file->read_count = 8;
-
- if (read_4(file, &file_crc) == 4) /* else completely truncated */
- {
- /* Ignore the recorded chunk length, proceed through the data looking for
- * a leading sequence of bytes that match the CRC in the following four
- * bytes. Each time a match is found check the next 8 bytes for a valid
- * length, chunk-type pair.
- */
- png_uint_32 length;
- png_uint_32 type = file->type;
- png_uint_32 crc = crc_init_4(type);
- png_byte buffer[8];
- unsigned int nread = 0, nused = 0;
-
- for (length=0; length <= 0x7fffffff; ++length)
- {
- int ch;
-
- if ((crc ^ 0xffffffff) == file_crc)
- {
- /* A match on the CRC; for IEND this is sufficient, but for anything
- * else expect a following chunk header.
- */
- if (type == png_IEND)
- {
- file->length = length;
- process_chunk(file, file_crc, 0, 0);
- return;
- }
-
- else
- {
- /* Need 8 bytes */
- while (nread < 8+nused)
- {
- ch = read_byte(file);
- if (ch == EOF)
- goto truncated;
- buffer[(nread++) & 7] = (png_byte)ch;
- }
-
- /* Prevent overflow */
- nread -= nused & ~7;
- nused -= nused & ~7; /* or, nused &= 7 ;-) */
-
- /* Examine the 8 bytes for a valid chunk header. */
- {
- png_uint_32 next_length = get32(buffer, nused);
-
- if (next_length < 0x7fffffff)
- {
- png_uint_32 next_type = get32(buffer, nused+4);
-
- if (chunk_type_valid(next_type))
- {
- file->read_count -= 8;
- process_chunk(file, file_crc, next_length, next_type);
- return;
- }
- }
-
- /* Not valid, keep going. */
- }
- }
- }
-
- /* This catches up with the circular buffer which gets filled above
- * while checking a chunk header. This code is slightly tricky - if
- * the chunk_type is IEND the buffer will never be used, if it is not
- * the code will always read ahead exactly 8 bytes and pass this on to
- * process_chunk. So the invariant that IEND leaves the file position
- * after the IEND CRC and other chunk leave it after the *next* chunk
- * header is not broken.
- */
- if (nread <= nused)
- {
- ch = read_byte(file);
-
- if (ch == EOF)
- goto truncated;
- }
-
- else
- ch = buffer[(++nused) & 7];
-
- crc = crc_one_byte(crc, file_crc >> 24);
- file_crc = (file_crc << 8) + ch;
- }
-
- /* Control gets to here if when 0x7fffffff bytes (plus 8) have been read,
- * ok, treat this as a damaged stream too:
- */
- }
-
-truncated:
- stop(file, READ_ERROR_CODE, "damaged PNG stream");
-}
-
-static void
-read_chunk(struct file *file)
- /* On entry file::data_pos must be set to the position of the first byte
- * of the chunk data *and* the input file must be at this position. This
- * routine (via process_chunk) instantiates a chunk or IDAT control structure
- * based on file::length and file::type and also resets these fields and
- * file::data_pos for the chunk after this one. For an IDAT chunk the whole
- * stream of IDATs will be read, until something other than an IDAT is
- * encountered, and the file fields will be set for the chunk after the end
- * of the stream of IDATs.
- *
- * For IEND the file::type field will be set to 0, and nothing beyond the end
- * of the IEND chunk will have been read.
- */
-{
- png_uint_32 length = file->length;
- png_uint_32 type = file->type;
-
- /* After IEND file::type is set to 0, if libpng attempts to read
- * more data at this point this is a bug in libpng.
- */
- if (type == 0)
- stop(file, UNEXPECTED_ERROR_CODE, "read beyond IEND");
-
- if (file->global->verbose > 2)
- {
- fputs(" ", stderr);
- type_name(type, stderr);
- fprintf(stderr, " %lu\n", (unsigned long)length);
- }
-
- /* Start the read_crc calculation with the chunk type, then read to the end
- * of the chunk data (without processing it in any way) to check that it is
- * all there and calculate the CRC.
- */
- file->crc = crc_init_4(type);
- if (crc_read_many(file, length)) /* else it was truncated */
- {
- png_uint_32 file_crc; /* CRC read from file */
- unsigned int nread = read_4(file, &file_crc);
-
- if (nread == 4)
- {
- if (type != png_IEND) /* do not read beyond IEND */
- {
- png_uint_32 next_length;
-
- nread += read_4(file, &next_length);
- if (nread == 8 && next_length <= 0x7fffffff)
- {
- png_uint_32 next_type;
-
- nread += read_4(file, &next_type);
-
- if (nread == 12 && chunk_type_valid(next_type))
- {
- /* Adjust the read count back to the correct value for this
- * chunk.
- */
- file->read_count -= 8;
- process_chunk(file, file_crc, next_length, next_type);
- return;
- }
- }
- }
-
- else /* IEND */
- {
- process_chunk(file, file_crc, 0, 0);
- return;
- }
- }
- }
-
- /* Control gets to here if the stream seems invalid or damaged in some
- * way. Either there was a problem reading all the expected data (this
- * chunk's data, its CRC and the length and type of the next chunk) or the
- * next chunk length/type are invalid. Notice that the cases that end up
- * here all correspond to cases that would otherwise terminate the read of
- * the PNG file.
- */
- sync_stream(file);
-}
-
-/* This returns a file* from a png_struct in an implementation specific way. */
-static struct file *get_control(png_const_structrp png_ptr);
-
-static void PNGCBAPI
-error_handler(png_structp png_ptr, png_const_charp message)
-{
- stop(get_control(png_ptr), LIBPNG_ERROR_CODE, message);
-}
-
-static void PNGCBAPI
-warning_handler(png_structp png_ptr, png_const_charp message)
-{
- struct file *file = get_control(png_ptr);
-
- if (file->global->warnings)
- emit_error(file, LIBPNG_WARNING_CODE, message);
-}
-
-/* Read callback - this is where the work gets done to check the stream before
- * passing it to libpng
- */
-static void PNGCBAPI
-read_callback(png_structp png_ptr, png_bytep buffer, size_t count)
- /* Return 'count' bytes to libpng in 'buffer' */
-{
- struct file *file = get_control(png_ptr);
- png_uint_32 type, length; /* For the chunk be *WRITTEN* */
- struct chunk *chunk;
-
- /* libpng should always ask for at least one byte */
- if (count == 0)
- stop(file, UNEXPECTED_ERROR_CODE, "read callback for 0 bytes");
-
- /* The callback always reads ahead by 8 bytes - the signature or chunk header
- * - these bytes are stored in chunk_length and chunk_type. This block is
- * executed once for the signature and once for the first chunk right at the
- * start.
- */
- if (file->read_count < 8)
- {
- assert(file->read_count == 0);
- assert((file->status_code & TRUNCATED) == 0);
-
- (void)read_4(file, &file->length);
-
- if (file->read_count == 4)
- (void)read_4(file, &file->type);
-
- if (file->read_count < 8)
- {
- assert((file->status_code & TRUNCATED) != 0);
- stop(file, READ_ERROR_CODE, "not a PNG (too short)");
- }
-
- if (file->state == STATE_SIGNATURE)
- {
- if (file->length != sig1 || file->type != sig2)
- stop(file, LIBPNG_ERROR_CODE, "not a PNG (signature)");
-
- /* Else write it (this is the initialization of write_count, prior to
- * this it contains CLEAR garbage.)
- */
- file->write_count = 0;
- }
-
- else
- {
- assert(file->state == STATE_CHUNKS);
-
- /* The first chunk must be a well formed IHDR (this could be relaxed to
- * use the checks in process_chunk, but that seems unnecessary.)
- */
- if (file->length != 13 || file->type != png_IHDR)
- stop(file, LIBPNG_ERROR_CODE, "not a PNG (IHDR)");
-
- /* The position of the data must be stored too */
- getpos(file);
- }
- }
-
- /* Retrieve previous state (because the read callbacks are made pretty much
- * byte-by-byte in the sequential reader prior to 1.7).
- */
- chunk = file->chunk;
-
- if (chunk != NULL)
- {
- length = chunk->chunk_length;
- type = chunk->chunk_type;
- }
-
- else
- {
- /* This is the signature case; for IDAT and other chunks these values will
- * be overwritten when read_chunk is called below.
- */
- length = file->length;
- type = file->type;
- }
-
- do
- {
- png_uint_32 b;
-
- /* Complete the read of a chunk; as a side effect this also instantiates
- * a chunk control structure and sets the file length/type/data_pos fields
- * for the *NEXT* chunk header.
- *
- * NOTE: at an IDAT any following IDAT chunks will also be read and the
- * next_ fields will refer to the chunk after the last IDAT.
- *
- * NOTE: read_chunk only returns when it has read a chunk that must now be
- * written.
- */
- if (file->state != STATE_SIGNATURE && chunk == NULL)
- {
- assert(file->read_count == 8);
- assert(file->idat == NULL);
- read_chunk(file);
- chunk = file->chunk;
- assert(chunk != NULL);
-
- /* Do the initialization that was not done before. */
- length = chunk->chunk_length;
- type = chunk->chunk_type;
-
- /* And start writing the new chunk. */
- file->write_count = 0;
- }
-
- /* The chunk_ fields describe a chunk that must be written, or hold the
- * signature. Write the header first. In the signature case this
- * rewrites the signature.
- */
- switch (file->write_count)
- {
- case 0: b = length >> 24; break;
- case 1: b = length >> 16; break;
- case 2: b = length >> 8; break;
- case 3: b = length ; break;
-
- case 4: b = type >> 24; break;
- case 5: b = type >> 16; break;
- case 6: b = type >> 8; break;
- case 7: b = type ; break;
-
- case 8:
- /* The header has been written. If this is really the signature
- * that's all that is required and we can go to normal chunk
- * processing.
- */
- if (file->state == STATE_SIGNATURE)
- {
- /* The signature has been written, the tail call to read_callback
- * below (it's just a goto to the start with a decent compiler)
- * will read the IHDR header ahead and validate it.
- */
- assert(length == sig1 && type == sig2);
- file->read_count = 0; /* Forces a header read */
- file->state = STATE_CHUNKS; /* IHDR: checked above */
- read_callback(png_ptr, buffer, count);
- return;
- }
-
- else
- {
- assert(chunk != NULL);
-
- /* Set up for write, notice that repositioning the input stream
- * is only necessary if something is to be read from it. Also
- * notice that for the IDAT stream this must only happen once -
- * on the first IDAT - to get back to the start of the list and
- * this is done inside process_IDAT:
- */
- chunk->write_crc = crc_init_4(type);
- if (file->state != STATE_IDAT && length > 0)
- setpos(chunk);
- }
- /* FALLTHROUGH */
-
- default:
- assert(chunk != NULL);
-
- /* NOTE: the arithmetic below overflows and gives a large positive
- * png_uint_32 value until the whole chunk data has been written.
- */
- switch (file->write_count - length)
- {
- /* Write the chunk data, normally this just comes from
- * the file. The only exception is for that part of a
- * chunk which is zlib data and which must be rewritten,
- * and IDAT chunks which can be completely
- * reconstructed.
- */
- default:
- if (file->state == STATE_IDAT)
- {
- struct IDAT *idat = file->idat;
-
- assert(idat != NULL);
-
- /* Read an IDAT byte from the input stream of IDAT chunks.
- * Because the IDAT stream can be re-chunked this stream is
- * held in the struct IDAT members. The chunk members, in
- * particular chunk_length (and therefore the length local)
- * refer to the output chunk.
- */
- while (idat->idat_index >= idat->idat_length)
- {
- /* Advance one chunk */
- struct IDAT_list *cur = idat->idat_cur;
-
- assert(idat->idat_index == idat->idat_length);
- assert(cur != NULL && cur->count > 0);
-
- /* NOTE: IDAT_list::count here, not IDAT_list::length */
- if (++(idat->idat_count) >= cur->count)
- {
- assert(idat->idat_count == cur->count);
-
- /* Move on to the next IDAT_list: */
- cur = cur->next;
-
- /* This is an internal error - read beyond the end of
- * the pre-calculated stream.
- */
- if (cur == NULL || cur->count == 0)
- stop(file, UNEXPECTED_ERROR_CODE,
- "read beyond end of IDAT");
-
- idat->idat_count = 0;
- idat->idat_cur = cur;
- }
-
- idat->idat_index = 0;
- /* Zero length IDAT chunks are permitted, so the length
- * here may be 0.
- */
- idat->idat_length = cur->lengths[idat->idat_count];
-
- /* And skip 12 bytes to the next chunk data */
- skip_12(file);
- }
-
- /* The index is always that of the next byte, the rest of
- * the information is always the current IDAT chunk and the
- * current list.
- */
- ++(idat->idat_index);
- }
-
- /* Read the byte from the stream. */
- b = reread_byte(file);
-
- /* If the byte must be rewritten handle that here */
- if (chunk->rewrite_length > 0)
- {
- if (chunk->rewrite_offset > 0)
- --(chunk->rewrite_offset);
-
- else
- {
- b = chunk->rewrite_buffer[0];
- memmove(chunk->rewrite_buffer, chunk->rewrite_buffer+1,
- (sizeof chunk->rewrite_buffer)-
- (sizeof chunk->rewrite_buffer[0]));
-
- --(chunk->rewrite_length);
- }
- }
-
- chunk->write_crc = crc_one_byte(chunk->write_crc, b);
- break;
-
- /* The CRC is written at:
- *
- * chunk_write == chunk_length+8..chunk_length+11
- *
- * so 8 to 11. The CRC is not (yet) conditioned.
- */
- case 8: b = chunk->write_crc >> 24; goto write_crc;
- case 9: b = chunk->write_crc >> 16; goto write_crc;
- case 10: b = chunk->write_crc >> 8; goto write_crc;
- case 11:
- /* This must happen before the chunk_end below: */
- b = chunk->write_crc;
-
- if (file->global->verbose > 2)
- {
- fputs(" ", stderr);
- type_name(type, stderr);
- fprintf(stderr, " %lu 0x%.8x\n", (unsigned long)length,
- chunk->write_crc ^ 0xffffffff);
- }
-
- /* The IDAT stream is written without a call to read_chunk
- * until the end is reached. rechunk_length() calculates the
- * length of the output chunks. Control gets to this point at
- * the end of an *output* chunk - the length calculated by
- * rechunk_length. If this corresponds to the end of the
- * input stream stop writing IDAT chunks, otherwise continue.
- */
- if (file->state == STATE_IDAT &&
- (file->idat->idat_index < file->idat->idat_length ||
- 1+file->idat->idat_count < file->idat->idat_cur->count ||
- file->idat->idat_cur != file->idat->idat_list_tail))
- {
- /* Write another IDAT chunk. Call rechunk_length to
- * calculate the length required.
- */
- length = chunk->chunk_length =
- rechunk_length(file->idat, 0/*end*/);
- assert(type == png_IDAT);
- file->write_count = 0; /* for the new chunk */
- --(file->write_count); /* fake out the increment below */
- }
-
- else
- {
- /* Entered at the end of a non-IDAT chunk and at the end of
- * the IDAT stream. The rewrite should have been cleared.
- */
- if (chunk->rewrite_length > 0 || chunk->rewrite_offset > 0)
- stop(file, UNEXPECTED_ERROR_CODE, "pending rewrite");
-
- /* This is the last byte so reset chunk_read for the next
- * chunk and move the input file to the position after the
- * *next* chunk header if required.
- */
- file->read_count = 8;
- file_setpos(file, &file->data_pos);
-
- if (file->idat == NULL)
- chunk_end(&file->chunk);
-
- else
- IDAT_end(&file->idat);
- }
-
- write_crc:
- b ^= 0xff; /* conditioning */
- break;
- }
- break;
- }
-
- /* Write one byte */
- b &= 0xff;
- *buffer++ = (png_byte)b;
- --count;
- write_byte(file, (png_byte)b); /* increments chunk_write */
- }
- while (count > 0);
-}
-
-/* Bundle the file and an uninitialized chunk and IDAT control structure
- * together to allow implementation of the chunk/IDAT allocate routine.
- */
-struct control
-{
- struct file file;
- struct chunk chunk;
- struct IDAT idat;
-};
-
-static int
-control_end(struct control *control)
-{
- return file_end(&control->file);
-}
-
-static struct file *
-get_control(png_const_structrp png_ptr)
-{
- /* This just returns the (file*). The chunk and idat control structures
- * don't always exist.
- */
- struct control *control = voidcast(struct control*,
- png_get_error_ptr(png_ptr));
- return &control->file;
-}
-
-static void
-allocate(struct file *file, int allocate_idat)
-{
- struct control *control = voidcast(struct control*, file->alloc_ptr);
-
- if (allocate_idat)
- {
- assert(file->idat == NULL);
- IDAT_init(&control->idat, file);
- }
-
- else /* chunk */
- {
- assert(file->chunk == NULL);
- chunk_init(&control->chunk, file);
- }
-}
-
-static int
-control_init(struct control *control, struct global *global,
- const char *file_name, const char *out_name)
- /* This wraps file_init(&control::file) and simply returns the result from
- * file_init.
- */
-{
- return file_init(&control->file, global, file_name, out_name, control,
- allocate);
-}
-
-static int
-read_png(struct control *control)
- /* Read a PNG, return 0 on success else an error (status) code; a bit mask as
- * defined for file::status_code as above.
- */
-{
- png_structp png_ptr;
- png_infop info_ptr = NULL;
- volatile int rc;
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, control,
- error_handler, warning_handler);
-
- if (png_ptr == NULL)
- {
- /* This is not really expected. */
- log_error(&control->file, LIBPNG_ERROR_CODE, "OOM allocating png_struct");
- control->file.status_code |= INTERNAL_ERROR;
- return LIBPNG_ERROR_CODE;
- }
-
- rc = setjmp(control->file.jmpbuf);
- if (rc == 0)
- {
-# ifdef PNG_SET_USER_LIMITS_SUPPORTED
- /* Remove any limits on the size of PNG files that can be read,
- * without this we may reject files based on built-in safety
- * limits.
- */
- png_set_user_limits(png_ptr, 0x7fffffff, 0x7fffffff);
- png_set_chunk_cache_max(png_ptr, 0);
- png_set_chunk_malloc_max(png_ptr, 0);
-# endif
-
- png_set_read_fn(png_ptr, control, read_callback);
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- png_error(png_ptr, "OOM allocating info structure");
-
- if (control->file.global->verbose)
- fprintf(stderr, " INFO\n");
-
- png_read_info(png_ptr, info_ptr);
-
- {
- png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
- int passes = png_set_interlace_handling(png_ptr);
- int pass;
-
- png_start_read_image(png_ptr);
-
- for (pass = 0; pass < passes; ++pass)
- {
- png_uint_32 y = height;
-
- /* NOTE: this skips asking libpng to return either version of
- * the image row, but libpng still reads the rows.
- */
- while (y-- > 0)
- png_read_row(png_ptr, NULL, NULL);
- }
- }
-
- if (control->file.global->verbose)
- fprintf(stderr, " END\n");
-
- /* Make sure to read to the end of the file: */
- png_read_end(png_ptr, info_ptr);
- }
-
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return rc;
-}
-
-static int
-one_file(struct global *global, const char *file_name, const char *out_name)
-{
- int rc;
- struct control control;
-
- if (global->verbose)
- fprintf(stderr, "FILE %s -> %s\n", file_name,
- out_name ? out_name : "<none>");
-
- /* Although control_init can return a failure code the structure is always
- * initialized, so control_end can be used to accumulate any status codes.
- */
- rc = control_init(&control, global, file_name, out_name);
-
- if (rc == 0)
- rc = read_png(&control);
-
- rc |= control_end(&control);
-
- return rc;
-}
-
-static void
-usage(const char *prog)
-{
- /* ANSI C-90 limits strings to 509 characters, so use a string array: */
- size_t i;
- static const char *usage_string[] = {
-" Tests, optimizes and optionally fixes the zlib header in PNG files.",
-" Optionally, when fixing, strips ancillary chunks from the file.",
-0,
-"OPTIONS",
-" OPERATION",
-" By default files are just checked for readability with a summary of the",
-" of zlib issues founds for each compressed chunk and the IDAT stream in",
-" the file.",
-" --optimize (-o):",
-" Find the smallest deflate window size for the compressed data.",
-" --strip=[none|crc|unsafe|unused|transform|color|all]:",
-" none (default): Retain all chunks.",
-" crc: Remove chunks with a bad CRC.",
-" unsafe: Remove chunks that may be unsafe to retain if the image data",
-" is modified. This is set automatically if --max is given but",
-" may be cancelled by a later --strip=none.",
-" unused: Remove chunks not used by libpng when decoding an image.",
-" This retains any chunks that might be used by libpng image",
-" transformations.",
-" transform: unused+bKGD.",
-" color: transform+iCCP and cHRM.",
-" all: color+gAMA and sRGB.",
-" Only ancillary chunks are ever removed. In addition the tRNS and sBIT",
-" chunks are never removed as they affect exact interpretation of the",
-" image pixel values. The following known chunks are treated specially",
-" by the above options:",
-" gAMA, sRGB [all]: These specify the gamma encoding used for the pixel",
-" values.",
-" cHRM, iCCP [color]: These specify how colors are encoded. iCCP also",
-" specifies the exact encoding of a pixel value; however, in",
-" practice most programs will ignore it.",
-" bKGD [transform]: This is used by libpng transforms."
-" --max=<number>:",
-" Use IDAT chunks sized <number>. If no number is given the IDAT",
-" chunks will be the maximum size permitted; 2^31-1 bytes. If the option",
-" is omitted the original chunk sizes will not be changed. When the",
-" option is given --strip=unsafe is set automatically. This may be",
-" cancelled if you know that all unknown unsafe-to-copy chunks really are",
-" safe to copy across an IDAT size change. This is true of all chunks",
-" that have ever been formally proposed as PNG extensions.",
-" MESSAGES",
-" By default the program only outputs summaries for each file.",
-" --quiet (-q):",
-" Do not output the summaries except for files that cannot be read. With",
-" two --quiets these are not output either.",
-" --errors (-e):",
-" Output errors from libpng and the program (except too-far-back).",
-" --warnings (-w):",
-" Output warnings from libpng.",
-" OUTPUT",
-" By default nothing is written.",
-" --out=<file>:",
-" Write the optimized/corrected version of the next PNG to <file>. This",
-" overrides the following two options",
-" --suffix=<suffix>:",
-" Set --out=<name><suffix> for all following files unless overridden on",
-" a per-file basis by explicit --out.",
-" --prefix=<prefix>:",
-" Set --out=<prefix><name> for all the following files unless overridden",
-" on a per-file basis by explicit --out.",
-" These two options can be used together to produce a suffix and prefix.",
-" INTERNAL OPTIONS",
-#if 0 /*NYI*/
-#ifdef PNG_MAXIMUM_INFLATE_WINDOW
-" --test:",
-" Test the PNG_MAXIMUM_INFLATE_WINDOW option. Setting this disables",
-" output as this would produce a broken file.",
-#endif
-#endif
-0,
-"EXIT CODES",
-" *** SUBJECT TO CHANGE ***",
-" The program exit code is value in the range 0..127 holding a bit mask of",
-" the following codes. Notice that the results for each file are combined",
-" together - check one file at a time to get a meaningful error code!",
-" 0x01: The zlib too-far-back error existed in at least one chunk.",
-" 0x02: At least one chunk had a CRC error.",
-" 0x04: A chunk length was incorrect.",
-" 0x08: The file was truncated.",
-" Errors less than 16 are potentially recoverable, for a single file if the",
-" exit code is less than 16 the file could be read (with corrections if a",
-" non-zero code is returned).",
-" 0x10: The file could not be read, even with corrections.",
-" 0x20: The output file could not be written.",
-" 0x40: An unexpected, potentially internal, error occurred.",
-" If the command line arguments are incorrect the program exits with exit",
-" 255. Some older operating systems only support 7-bit exit codes, on those",
-" systems it is suggested that this program is first tested by supplying",
-" invalid arguments.",
-0,
-"DESCRIPTION",
-" " PROGRAM_NAME ":",
-" checks each PNG file on the command line for errors. By default errors are",
-" not output and the program just returns an exit code and prints a summary.",
-" With the --quiet (-q) option the summaries are suppressed too and the",
-" program only outputs unexpected errors (internal errors and file open",
-" errors).",
-" Various known problems in PNG files are fixed while the file is being read",
-" The exit code says what problems were fixed. In particular the zlib error:",
-0,
-" \"invalid distance too far back\"",
-0,
-" caused by an incorrect optimization of a zlib stream is fixed in any",
-" compressed chunk in which it is encountered. An integrity problem of the",
-" PNG stream caused by a bug in libpng which wrote an incorrect chunk length",
-" is also fixed. Chunk CRC errors are automatically fixed up.",
-0,
-" Setting one of the \"OUTPUT\" options causes the possibly modified file to",
-" be written to a new file.",
-0,
-" Notice that some PNG files with the zlib optimization problem can still be",
-" read by libpng under some circumstances. This program will still detect",
-" and, if requested, correct the error.",
-0,
-" The program will reliably process all files on the command line unless",
-" either an invalid argument causes the usage message (this message) to be",
-" produced or the program crashes.",
-0,
-" The summary lines describe issues encountered with the zlib compressed",
-" stream of a chunk. They have the following format, which is SUBJECT TO",
-" CHANGE in the future:",
-0,
-" chunk reason comp-level p1 p2 p3 p4 file",
-0,
-" p1 through p4 vary according to the 'reason'. There are always 8 space",
-" separated fields. Reasons specific formats are:",
-0,
-" chunk ERR status code read-errno write-errno message file",
-" chunk SKP comp-level file-bits zlib-rc compressed message file",
-" chunk ??? comp-level file-bits ok-bits compressed uncompress file",
-0,
-" The various fields are",
-0,
-"$1 chunk: The chunk type of a chunk in the file or 'HEAD' if a problem",
-" is reported by libpng at the start of the IDAT stream.",
-"$2 reason: One of:",
-" CHK: A zlib header checksum was detected and fixed.",
-" TFB: The zlib too far back error was detected and fixed.",
-" OK : No errors were detected in the zlib stream and optimization",
-" was not requested, or was not possible.",
-" OPT: The zlib stream window bits value could be improved (and was).",
-" SKP: The chunk was skipped because of a zlib issue (zlib-rc) with",
-" explanation 'message'",
-" ERR: The read of the file was aborted. The parameters explain why.",
-"$3 status: For 'ERR' the accumulated status code from 'EXIT CODES' above.",
-" This is printed as a 2 digit hexadecimal value",
-" comp-level: The recorded compression level (FLEVEL) of a zlib stream",
-" expressed as a string {supfast,stdfast,default,maximum}",
-"$4 code: The file exit code; where stop was called, as a fairly terse",
-" string {warning,libpng,zlib,invalid,read,write,unexpected}.",
-" file-bits: The zlib window bits recorded in the file.",
-"$5 read-errno: A system errno value from a read translated by strerror(3).",
-" zlib-rc: A zlib return code as a string (see zlib.h).",
-" ok-bits: The smallest zlib window bits value that works.",
-"$6 write-errno:A system errno value from a write translated by strerror(3).",
-" compressed: The count of compressed bytes in the zlib stream, when the",
-" reason is 'SKP'; this is a count of the bytes read from the",
-" stream when the fatal error was encountered.",
-"$7 message: An error message (spaces replaced by _, as in all parameters),",
-" uncompress: The count of bytes from uncompressing the zlib stream; this",
-" may not be the same as the number of bytes in the image.",
-"$8 file: The name of the file (this may contain spaces).",
-};
-
- fprintf(stderr, "Usage: %s {[options] png-file}\n", prog);
-
- for (i=0; i < (sizeof usage_string)/(sizeof usage_string[0]); ++i)
- {
- if (usage_string[i] != 0)
- fputs(usage_string[i], stderr);
-
- fputc('\n', stderr);
- }
-
- exit(255);
-}
-
-int
-main(int argc, const char **argv)
-{
- char temp_name[FILENAME_MAX+1];
- const char * prog = *argv;
- const char * outfile = NULL;
- const char * suffix = NULL;
- const char * prefix = NULL;
- int done = 0; /* if at least one file is processed */
- struct global global;
-
- global_init(&global);
-
- while (--argc > 0)
- {
- ++argv;
-
- if (strcmp(*argv, "--debug") == 0)
- {
- /* To help debugging problems: */
- global.errors = global.warnings = 1;
- global.quiet = 0;
- global.verbose = 7;
- }
-
- else if (strncmp(*argv, "--max=", 6) == 0)
- {
- global.idat_max = (png_uint_32)atol(6+*argv);
-
- if (global.skip < SKIP_UNSAFE)
- global.skip = SKIP_UNSAFE;
- }
-
- else if (strcmp(*argv, "--max") == 0)
- {
- global.idat_max = 0x7fffffff;
-
- if (global.skip < SKIP_UNSAFE)
- global.skip = SKIP_UNSAFE;
- }
-
- else if (strcmp(*argv, "--optimize") == 0 || strcmp(*argv, "-o") == 0)
- global.optimize_zlib = 1;
-
- else if (strncmp(*argv, "--out=", 6) == 0)
- outfile = 6+*argv;
-
- else if (strncmp(*argv, "--suffix=", 9) == 0)
- suffix = 9+*argv;
-
- else if (strncmp(*argv, "--prefix=", 9) == 0)
- prefix = 9+*argv;
-
- else if (strcmp(*argv, "--strip=none") == 0)
- global.skip = SKIP_NONE;
-
- else if (strcmp(*argv, "--strip=crc") == 0)
- global.skip = SKIP_BAD_CRC;
-
- else if (strcmp(*argv, "--strip=unsafe") == 0)
- global.skip = SKIP_UNSAFE;
-
- else if (strcmp(*argv, "--strip=unused") == 0)
- global.skip = SKIP_UNUSED;
-
- else if (strcmp(*argv, "--strip=transform") == 0)
- global.skip = SKIP_TRANSFORM;
-
- else if (strcmp(*argv, "--strip=color") == 0)
- global.skip = SKIP_COLOR;
-
- else if (strcmp(*argv, "--strip=all") == 0)
- global.skip = SKIP_ALL;
-
- else if (strcmp(*argv, "--errors") == 0 || strcmp(*argv, "-e") == 0)
- global.errors = 1;
-
- else if (strcmp(*argv, "--warnings") == 0 || strcmp(*argv, "-w") == 0)
- global.warnings = 1;
-
- else if (strcmp(*argv, "--quiet") == 0 || strcmp(*argv, "-q") == 0)
- {
- if (global.quiet)
- global.quiet = 2;
-
- else
- global.quiet = 1;
- }
-
- else if (strcmp(*argv, "--verbose") == 0 || strcmp(*argv, "-v") == 0)
- ++global.verbose;
-
-#if 0
- /* NYI */
-# ifdef PNG_MAXIMUM_INFLATE_WINDOW
- else if (strcmp(*argv, "--test") == 0)
- ++set_option;
-# endif
-#endif
-
- else if ((*argv)[0] == '-')
- usage(prog);
-
- else
- {
- size_t outlen = strlen(*argv);
-
- if (outfile == NULL) /* else this takes precedence */
- {
- /* Consider the prefix/suffix options */
- if (prefix != NULL)
- {
- size_t prefixlen = strlen(prefix);
-
- if (prefixlen+outlen > FILENAME_MAX)
- {
- fprintf(stderr, "%s: output file name too long: %s%s%s\n",
- prog, prefix, *argv, suffix ? suffix : "");
- global.status_code |= WRITE_ERROR;
- continue;
- }
-
- memcpy(temp_name, prefix, prefixlen);
- memcpy(temp_name+prefixlen, *argv, outlen);
- outlen += prefixlen;
- outfile = temp_name;
- }
-
- else if (suffix != NULL)
- memcpy(temp_name, *argv, outlen);
-
- temp_name[outlen] = 0;
-
- if (suffix != NULL)
- {
- size_t suffixlen = strlen(suffix);
-
- if (outlen+suffixlen > FILENAME_MAX)
- {
- fprintf(stderr, "%s: output file name too long: %s%s\n",
- prog, *argv, suffix);
- global.status_code |= WRITE_ERROR;
- continue;
- }
-
- memcpy(temp_name+outlen, suffix, suffixlen);
- outlen += suffixlen;
- temp_name[outlen] = 0;
- outfile = temp_name;
- }
- }
-
- (void)one_file(&global, *argv, outfile);
- ++done;
- outfile = NULL;
- }
- }
-
- if (!done)
- usage(prog);
-
- return global_end(&global);
-}
-
-#else /* ZLIB_VERNUM < 0x1240 */
-int
-main(void)
-{
- fprintf(stderr,
- "pngfix needs libpng with a zlib >=1.2.4 (not 0x%x)\n",
- ZLIB_VERNUM);
- return 77;
-}
-#endif /* ZLIB_VERNUM */
-
-#else /* No read support */
-
-int
-main(void)
-{
- fprintf(stderr, "pngfix does not work without read deinterlace support\n");
- return 77;
-}
-#endif /* PNG_READ_SUPPORTED && PNG_EASY_ACCESS_SUPPORTED */
-#else /* No setjmp support */
-int
-main(void)
-{
- fprintf(stderr, "pngfix does not work without setjmp support\n");
- return 77;
-}
-#endif /* PNG_SETJMP_SUPPORTED */
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/reindent b/Build/source/libs/libpng/libpng-src/contrib/tools/reindent
deleted file mode 100644
index f4df309b668..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/reindent
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-# reindent a libpng C source
-
-# COPYRIGHT: Written by Glenn Randers-Pehrson, 2016.
-# To the extent possible under law, the author has waived all copyright and
-# related or neighboring rights to this work. This work is published from:
-# United States.
-
-# Usage:
-# reindent inputtabsize outputtabsize inputcontinuestring outputcontinuestring
-#
-# Assumes that continued lines begin with indentation plus one space, and
-# that continued comments begin with indentation plus " *".
-#
-# eg, to change libpng coding style from 3-space indentation with 4-space
-# continuations to 4-space indentation with 2-space continuations:
-#
-# reindent 3 4 "\t " " " < example.c > example.c_4_2
-# and to restore the file back to libpng coding style
-# reindent 4 3 " " " " < example.c_4_2 > example.c_3_4
-
-unexpand --first-only --t $1 | \
- sed -e "/^ *$3[^\*]/{s/$3/$4/}" | \
- expand -t $2
diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/sRGB.h b/Build/source/libs/libpng/libpng-src/contrib/tools/sRGB.h
deleted file mode 100644
index d1ece51291d..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/tools/sRGB.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- * sRGB.h
- *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- *
- * COPYRIGHT: Written by John Cunningham Bowler, 2013.
- * To the extent possible under law, the author has waived all copyright and
- * related or neighboring rights to this work. This work is published from:
- * United States.
- *
- * Utility file; not actually a header, this contains definitions of sRGB
- * calculation functions for inclusion in those test programs that need them.
- *
- * All routines take and return a floating point value in the range
- * 0 to 1.0, doing a calculation according to the sRGB specification
- * (in fact the source of the numbers is the wikipedia article at
- * https://en.wikipedia.org/wiki/SRGB).
- */
-static double
-sRGB_from_linear(double l)
-{
- if (l <= 0.0031308)
- l *= 12.92;
-
- else
- l = 1.055 * pow(l, 1/2.4) - 0.055;
-
- return l;
-}
-
-static double
-linear_from_sRGB(double s)
-{
- if (s <= 0.04045)
- return s / 12.92;
-
- else
- return pow((s+0.055)/1.055, 2.4);
-}
-
-static double
-YfromRGB(double r, double g, double b)
-{
- /* Use the sRGB (rounded) coefficients for Rlinear, Glinear, Blinear to get
- * the CIE Y value (also linear).
- */
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
-}
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.c b/Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.c
deleted file mode 100644
index cf943f32a6c..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*-------------------------------------
- * PNGFILE.C -- Image File Functions
- *-------------------------------------
- *
- * Copyright 2000,2017 Willem van Schaik.
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-#include <windows.h>
-#include <commdlg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <zlib.h>
-
-#include "png.h"
-#include "pngfile.h"
-#include "cexcept.h"
-
-define_exception_type(const char *);
-extern struct exception_context the_exception_context[1];
-struct exception_context the_exception_context[1];
-png_const_charp msg;
-
-static OPENFILENAME ofn;
-
-static png_structp png_ptr = NULL;
-static png_infop info_ptr = NULL;
-
-
-/* cexcept interface */
-
-static void
-png_cexcept_error(png_structp png_ptr, png_const_charp msg)
-{
- if(png_ptr)
- ;
-#ifdef PNG_CONSOLE_IO_SUPPORTED
- fprintf(stderr, "libpng error: %s\n", msg);
-#endif
- {
- Throw msg;
- }
-}
-
-/* Windows open-file functions */
-
-void PngFileInitialize (HWND hwnd)
-{
- static TCHAR szFilter[] = TEXT ("PNG Files (*.PNG)\0*.png\0")
- TEXT ("All Files (*.*)\0*.*\0\0");
-
- ofn.lStructSize = sizeof (OPENFILENAME);
- ofn.hwndOwner = hwnd;
- ofn.hInstance = NULL;
- ofn.lpstrFilter = szFilter;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.nFilterIndex = 0;
- ofn.lpstrFile = NULL; /* Set in Open and Close functions */
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFileTitle = NULL; /* Set in Open and Close functions */
- ofn.nMaxFileTitle = MAX_PATH;
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = NULL;
- ofn.Flags = 0; /* Set in Open and Close functions */
- ofn.nFileOffset = 0;
- ofn.nFileExtension = 0;
- ofn.lpstrDefExt = TEXT ("png");
- ofn.lCustData = 0;
- ofn.lpfnHook = NULL;
- ofn.lpTemplateName = NULL;
-}
-
-BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
-{
- ofn.hwndOwner = hwnd;
- ofn.lpstrFile = pstrFileName;
- ofn.lpstrFileTitle = pstrTitleName;
- ofn.Flags = OFN_HIDEREADONLY;
-
- return GetOpenFileName (&ofn);
-}
-
-BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
-{
- ofn.hwndOwner = hwnd;
- ofn.lpstrFile = pstrFileName;
- ofn.lpstrFileTitle = pstrTitleName;
- ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
-
- return GetSaveFileName (&ofn);
-}
-
-/* PNG image handler functions */
-
-BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,
- int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor)
-{
- static FILE *pfFile;
- png_byte pbSig[8];
- int iBitDepth;
- int iColorType;
- double dGamma;
- png_color_16 *pBackground;
- png_uint_32 ulChannels;
- png_uint_32 ulRowBytes;
- png_byte *pbImageData = *ppbImageData;
- static png_byte **ppbRowPointers = NULL;
- int i;
-
- /* open the PNG input file */
-
- if (!pstrFileName)
- {
- *ppbImageData = pbImageData = NULL;
- return FALSE;
- }
-
- if (!(pfFile = fopen(pstrFileName, "rb")))
- {
- *ppbImageData = pbImageData = NULL;
- return FALSE;
- }
-
- /* first check the eight byte PNG signature */
-
- fread(pbSig, 1, 8, pfFile);
- if (png_sig_cmp(pbSig, 0, 8))
- {
- *ppbImageData = pbImageData = NULL;
- return FALSE;
- }
-
- /* create the two png(-info) structures */
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
- (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
- if (!png_ptr)
- {
- *ppbImageData = pbImageData = NULL;
- return FALSE;
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- *ppbImageData = pbImageData = NULL;
- return FALSE;
- }
-
- Try
- {
-
- /* initialize the png structure */
-
-#ifdef PNG_STDIO_SUPPORTED
- png_init_io(png_ptr, pfFile);
-#else
- png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data);
-#endif
-
- png_set_sig_bytes(png_ptr, 8);
-
- /* read all PNG info up to image data */
-
- png_read_info(png_ptr, info_ptr);
-
- /* get width, height, bit-depth and color-type */
-
- png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,
- &iColorType, NULL, NULL, NULL);
-
- /* expand images of all color-type and bit-depth to 3x8-bit RGB */
- /* let the library process alpha, transparency, background, etc. */
-
-#ifdef PNG_READ_16_TO_8_SUPPORTED
- if (iBitDepth == 16)
-# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
- png_set_scale_16(png_ptr);
-# else
- png_set_strip_16(png_ptr);
-# endif
-#endif
- if (iColorType == PNG_COLOR_TYPE_PALETTE)
- png_set_expand(png_ptr);
- if (iBitDepth < 8)
- png_set_expand(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand(png_ptr);
- if (iColorType == PNG_COLOR_TYPE_GRAY ||
- iColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
-
- /* set the background color to draw transparent and alpha images over */
- if (png_get_bKGD(png_ptr, info_ptr, &pBackground))
- {
- png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
- pBkgColor->red = (byte) pBackground->red;
- pBkgColor->green = (byte) pBackground->green;
- pBkgColor->blue = (byte) pBackground->blue;
- }
- else
- {
- pBkgColor = NULL;
- }
-
- /* if required set gamma conversion */
- if (png_get_gAMA(png_ptr, info_ptr, &dGamma))
- png_set_gamma(png_ptr, (double) 2.2, dGamma);
-
- /* after the transformations are registered, update info_ptr data */
-
- png_read_update_info(png_ptr, info_ptr);
-
- /* get again width, height and the new bit-depth and color-type */
-
- png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,
- &iColorType, NULL, NULL, NULL);
-
-
- /* row_bytes is the width x number of channels */
-
- ulRowBytes = png_get_rowbytes(png_ptr, info_ptr);
- ulChannels = png_get_channels(png_ptr, info_ptr);
-
- *piChannels = ulChannels;
-
- /* now we can allocate memory to store the image */
-
- if (pbImageData)
- {
- free (pbImageData);
- pbImageData = NULL;
- }
- if ((*piHeight) > ((size_t)(-1))/ulRowBytes) {
- {
- png_error(png_ptr, "Visual PNG: image is too big");
- }
- if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight)
- * sizeof(png_byte))) == NULL)
- {
- png_error(png_ptr, "Visual PNG: out of memory");
- }
- *ppbImageData = pbImageData;
-
- /* and allocate memory for an array of row-pointers */
-
- if ((ppbRowPointers = (png_bytepp) malloc((*piHeight)
- * sizeof(png_bytep))) == NULL)
- {
- png_error(png_ptr, "Visual PNG: out of memory");
- }
-
- /* set the individual row-pointers to point at the correct offsets */
-
- for (i = 0; i < (*piHeight); i++)
- ppbRowPointers[i] = pbImageData + i * ulRowBytes;
-
- /* now we can go ahead and just read the whole image */
-
- png_read_image(png_ptr, ppbRowPointers);
-
- /* read the additional chunks in the PNG file (not really needed) */
-
- png_read_end(png_ptr, NULL);
-
- /* and we're done */
-
- free (ppbRowPointers);
- ppbRowPointers = NULL;
-
- /* yepp, done */
- }
-
- Catch (msg)
- {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-
- *ppbImageData = pbImageData = NULL;
-
- if(ppbRowPointers)
- free (ppbRowPointers);
-
- fclose(pfFile);
-
- return FALSE;
- }
-
- fclose (pfFile);
-
- return TRUE;
-}
-
-
-BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,
- int iWidth, int iHeight, png_color bkgColor)
-{
- const int ciBitDepth = 8;
- const int ciChannels = 3;
-
- static FILE *pfFile;
- png_uint_32 ulRowBytes;
- static png_byte **ppbRowPointers = NULL;
- int i;
-
- /* open the PNG output file */
-
- if (!pstrFileName)
- return FALSE;
-
- if (!(pfFile = fopen(pstrFileName, "wb")))
- return FALSE;
-
- /* prepare the standard PNG structures */
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
- (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
- if (!png_ptr)
- {
- fclose(pfFile);
- return FALSE;
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- fclose(pfFile);
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
- return FALSE;
- }
-
- Try
- {
- /* initialize the png structure */
-
-#ifdef PNG_STDIO_SUPPORTED
- png_init_io(png_ptr, pfFile);
-#else
- png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush);
-#endif
-
- /* we're going to write a very simple 3x8-bit RGB image */
-
- png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth,
- PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
- PNG_FILTER_TYPE_BASE);
-
- /* write the file header information */
-
- png_write_info(png_ptr, info_ptr);
-
- /* swap the BGR pixels in the DiData structure to RGB */
-
- png_set_bgr(png_ptr);
-
- /* row_bytes is the width x number of channels */
-
- ulRowBytes = iWidth * ciChannels;
-
- /* we can allocate memory for an array of row-pointers */
-
- if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL)
- Throw "Visualpng: Out of memory";
-
- /* set the individual row-pointers to point at the correct offsets */
-
- for (i = 0; i < iHeight; i++)
- ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2);
-
- /* write out the entire image data in one call */
-
- png_write_image (png_ptr, ppbRowPointers);
-
- /* write the additional chunks to the PNG file (not really needed) */
-
- png_write_end(png_ptr, info_ptr);
-
- /* and we're done */
-
- free (ppbRowPointers);
- ppbRowPointers = NULL;
-
- /* clean up after the write, and free any memory allocated */
-
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-
- /* yepp, done */
- }
-
- Catch (msg)
- {
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-
- if(ppbRowPointers)
- free (ppbRowPointers);
-
- fclose(pfFile);
-
- return FALSE;
- }
-
- fclose (pfFile);
-
- return TRUE;
-}
-
-#ifndef PNG_STDIO_SUPPORTED
-
-static void
-png_read_data(png_structp png_ptr, png_bytep data, size_t length)
-{
- size_t check;
-
- /* fread() returns 0 on error, so it is OK to store this in a size_t
- * instead of an int, which is what fread() actually returns.
- */
- check = fread(data, 1, length, (FILE *)png_ptr->io_ptr);
-
- if (check != length)
- {
- png_error(png_ptr, "Read Error");
- }
-}
-
-static void
-png_write_data(png_structp png_ptr, png_bytep data, size_t length)
-{
- png_uint_32 check;
-
- check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
- if (check != length)
- {
- png_error(png_ptr, "Write Error");
- }
-}
-
-static void
-png_flush(png_structp png_ptr)
-{
- FILE *io_ptr;
- io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
- if (io_ptr != NULL)
- fflush(io_ptr);
-}
-
-#endif
-
-/*-----------------
- * end of source
- *-----------------
- */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.h b/Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.h
deleted file mode 100644
index 1b7b9be3c34..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/PngFile.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*------------------------------------------*/
-/* PNGFILE.H -- Header File for pngfile.c*/
-/*------------------------------------------*/
-
-/* Copyright 2000, Willem van Schaik.*/
-
-/* This code is released under the libpng license.*/
-/* For conditions of distribution and use, see the disclaimer*/
-/* and license in png.h*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <windows.h>
-
-void PngFileInitialize (HWND hwnd) ;
-BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;
-BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;
-
-BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,
- int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor);
-BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,
- int iWidth, int iHeight, png_color BkgColor);
-
-#ifndef PNG_STDIO_SUPPORTED
-static void png_read_data(png_structp png_ptr, png_bytep data, size_t length);
-static void png_write_data(png_structp png_ptr, png_bytep data, size_t length);
-static void png_flush(png_structp png_ptr);
-#endif
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/README.txt b/Build/source/libs/libpng/libpng-src/contrib/visupng/README.txt
deleted file mode 100644
index 72c5cba1790..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/README.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-Microsoft Developer Studio Build File, Format Version 6.00 for VisualPng
-------------------------------------------------------------------------
-
-Copyright 2000, Willem van Schaik.
-
-This code is released under the libpng license.
-For conditions of distribution and use, see the disclaimer
-and license in png.h
-
-As a PNG .dll demo VisualPng is finished. More features would only hinder
-the program's objective. However, further extensions (like support for other
-graphics formats) are in development. To get these, or for pre-compiled
-binaries, go to "http://www.schaik.com/png/visualpng.html".
-
-------------------------------------------------------------------------
-
-Assumes that
-
- libpng DLLs and LIBs are in ..\..\projects\msvc\win32\libpng
- zlib DLLs and LIBs are in ..\..\projects\msvc\win32\zlib
- libpng header files are in ..\..\..\libpng
- zlib header files are in ..\..\..\zlib
- the pngsuite images are in ..\pngsuite
-
-To build:
-
-1) On the main menu Select "Build|Set Active configuration".
- Choose the configuration that corresponds to the library you want to test.
- This library must have been built using the libpng MS project located in
- the "..\..\mscv" subdirectory.
-
-2) Select "Build|Clean"
-
-3) Select "Build|Rebuild All"
-
-4) After compiling and linking VisualPng will be started to view an image
- from the PngSuite directory. Press Ctrl-N (and Ctrl-V) for other images.
-
-
-To install:
-
-When distributing VisualPng (or a further development) the following options
-are available:
-
-1) Build the program with the configuration "Win32 LIB" and you only need to
- include the executable from the ./lib directory in your distribution.
-
-2) Build the program with the configuration "Win32 DLL" and you need to put
- in your distribution the executable from the ./dll directory and the dll's
- libpng1.dll, zlib.dll and msvcrt.dll. These need to be in the user's PATH.
-
-
-Willem van Schaik
-Calgary, June 6th 2000
-
-P.S. VisualPng was written based on preliminary work of:
-
- - Simon-Pierre Cadieux
- - Glenn Randers-Pehrson
- - Greg Roelofs
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.c b/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.c
deleted file mode 100644
index 6baa3b66309..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/*------------------------------------
- * VisualPng.C -- Shows a PNG image
- *------------------------------------
- *
- * Copyright 2000,2017 Willem van Schaik.
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-/* switches */
-
-/* defines */
-
-#define PROGNAME "VisualPng"
-#define LONGNAME "Win32 Viewer for PNG-files"
-#define VERSION "1.0 of 2000 June 07"
-
-/* constants */
-
-#define MARGIN 8
-
-/* standard includes */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <windows.h>
-#include <zlib.h>
-
-/* application includes */
-
-#include "png.h"
-#include "pngfile.h"
-#include "resource.h"
-
-/* macros */
-
-/* function prototypes */
-
-LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
-BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
-
-BOOL CenterAbout (HWND hwndChild, HWND hwndParent);
-
-BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
- int *pFileIndex);
-
-BOOL SearchPngList (TCHAR *pFileList, int FileCount, int *pFileIndex,
- PTSTR pstrPrevName, PTSTR pstrNextName);
-
-BOOL LoadImageFile(HWND hwnd, PTSTR pstrPathName,
- png_byte **ppbImage, int *pxImgSize, int *pyImgSize, int *piChannels,
- png_color *pBkgColor);
-
-BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
- BYTE **ppDiData, int cxWinSize, int cyWinSize,
- BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
- BOOL bStretched);
-
-BOOL InitBitmap (
- BYTE *pDiData, int cxWinSize, int cyWinSize);
-
-BOOL FillBitmap (
- BYTE *pDiData, int cxWinSize, int cyWinSize,
- BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
- BOOL bStretched);
-
-/* a few global variables */
-
-static char *szProgName = PROGNAME;
-static char *szAppName = LONGNAME;
-static char *szIconName = PROGNAME;
-static char szCmdFileName [MAX_PATH];
-
-/* MAIN routine */
-
-int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
-{
- HACCEL hAccel;
- HWND hwnd;
- MSG msg;
- WNDCLASS wndclass;
- int ixBorders, iyBorders;
-
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon (hInstance, szIconName) ;
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
- wndclass.hbrBackground = NULL; /* (HBRUSH) GetStockObject (GRAY_BRUSH); */
- wndclass.lpszMenuName = szProgName;
- wndclass.lpszClassName = szProgName;
-
- if (!RegisterClass (&wndclass))
- {
- MessageBox (NULL, TEXT ("Error: this program requires Windows NT!"),
- szProgName, MB_ICONERROR);
- return 0;
- }
-
- /* if filename given on commandline, store it */
- if ((szCmdLine != NULL) && (*szCmdLine != '\0'))
- if (szCmdLine[0] == '"')
- strncpy (szCmdFileName, szCmdLine + 1, strlen(szCmdLine) - 2);
- else
- strcpy (szCmdFileName, szCmdLine);
- else
- strcpy (szCmdFileName, "");
-
- /* calculate size of window-borders */
- ixBorders = 2 * (GetSystemMetrics (SM_CXBORDER) +
- GetSystemMetrics (SM_CXDLGFRAME));
- iyBorders = 2 * (GetSystemMetrics (SM_CYBORDER) +
- GetSystemMetrics (SM_CYDLGFRAME)) +
- GetSystemMetrics (SM_CYCAPTION) +
- GetSystemMetrics (SM_CYMENUSIZE) +
- 1; /* WvS: don't ask me why? */
-
- hwnd = CreateWindow (szProgName, szAppName,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- 512 + 2 * MARGIN + ixBorders, 384 + 2 * MARGIN + iyBorders,
-/* CW_USEDEFAULT, CW_USEDEFAULT, */
- NULL, NULL, hInstance, NULL);
-
- ShowWindow (hwnd, iCmdShow);
- UpdateWindow (hwnd);
-
- hAccel = LoadAccelerators (hInstance, szProgName);
-
- while (GetMessage (&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator (hwnd, hAccel, &msg))
- {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
- }
- return msg.wParam;
-}
-
-LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
- LPARAM lParam)
-{
- static HINSTANCE hInstance ;
- static HDC hdc;
- static PAINTSTRUCT ps;
- static HMENU hMenu;
-
- static BITMAPFILEHEADER *pbmfh;
- static BITMAPINFOHEADER *pbmih;
- static BYTE *pbImage;
- static int cxWinSize, cyWinSize;
- static int cxImgSize, cyImgSize;
- static int cImgChannels;
- static png_color bkgColor = {127, 127, 127};
-
- static BOOL bStretched = TRUE;
-
- static BYTE *pDib = NULL;
- static BYTE *pDiData = NULL;
-
- static TCHAR szImgPathName [MAX_PATH];
- static TCHAR szTitleName [MAX_PATH];
-
- static TCHAR *pPngFileList = NULL;
- static int iPngFileCount;
- static int iPngFileIndex;
-
- BOOL bOk;
-
- switch (message)
- {
- case WM_CREATE:
- hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
- PngFileInitialize (hwnd);
-
- strcpy (szImgPathName, "");
-
- /* in case we process file given on command-line */
-
- if (szCmdFileName[0] != '\0')
- {
- strcpy (szImgPathName, szCmdFileName);
-
- /* read the other png-files in the directory for later */
- /* next/previous commands */
-
- BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
- &iPngFileIndex);
-
- /* load the image from file */
-
- if (!LoadImageFile (hwnd, szImgPathName,
- &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
- return 0;
-
- /* invalidate the client area for later update */
-
- InvalidateRect (hwnd, NULL, TRUE);
-
- /* display the PNG into the DIBitmap */
-
- DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
- pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
- }
-
- return 0;
-
- case WM_SIZE:
- cxWinSize = LOWORD (lParam);
- cyWinSize = HIWORD (lParam);
-
- /* invalidate the client area for later update */
-
- InvalidateRect (hwnd, NULL, TRUE);
-
- /* display the PNG into the DIBitmap */
-
- DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
- pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
-
- return 0;
-
- case WM_INITMENUPOPUP:
- hMenu = GetMenu (hwnd);
-
- if (pbImage)
- EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_ENABLED);
- else
- EnableMenuItem (hMenu, IDM_FILE_SAVE, MF_GRAYED);
-
- return 0;
-
- case WM_COMMAND:
- hMenu = GetMenu (hwnd);
-
- switch (LOWORD (wParam))
- {
- case IDM_FILE_OPEN:
-
- /* show the File Open dialog box */
-
- if (!PngFileOpenDlg (hwnd, szImgPathName, szTitleName))
- return 0;
-
- /* read the other png-files in the directory for later */
- /* next/previous commands */
-
- BuildPngList (szImgPathName, &pPngFileList, &iPngFileCount,
- &iPngFileIndex);
-
- /* load the image from file */
-
- if (!LoadImageFile (hwnd, szImgPathName,
- &pbImage, &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
- return 0;
-
- /* invalidate the client area for later update */
-
- InvalidateRect (hwnd, NULL, TRUE);
-
- /* display the PNG into the DIBitmap */
-
- DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
- pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
-
- return 0;
-
- case IDM_FILE_SAVE:
-
- /* show the File Save dialog box */
-
- if (!PngFileSaveDlg (hwnd, szImgPathName, szTitleName))
- return 0;
-
- /* save the PNG to a disk file */
-
- SetCursor (LoadCursor (NULL, IDC_WAIT));
- ShowCursor (TRUE);
-
- bOk = PngSaveImage (szImgPathName, pDiData, cxWinSize, cyWinSize,
- bkgColor);
-
- ShowCursor (FALSE);
- SetCursor (LoadCursor (NULL, IDC_ARROW));
-
- if (!bOk)
- MessageBox (hwnd, TEXT ("Error in saving the PNG image"),
- szProgName, MB_ICONEXCLAMATION | MB_OK);
- return 0;
-
- case IDM_FILE_NEXT:
-
- /* read next entry in the directory */
-
- if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
- NULL, szImgPathName))
- {
- if (strcmp (szImgPathName, "") == 0)
- return 0;
-
- /* load the image from file */
-
- if (!LoadImageFile (hwnd, szImgPathName, &pbImage,
- &cxImgSize, &cyImgSize, &cImgChannels, &bkgColor))
- return 0;
-
- /* invalidate the client area for later update */
-
- InvalidateRect (hwnd, NULL, TRUE);
-
- /* display the PNG into the DIBitmap */
-
- DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
- pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
- }
-
- return 0;
-
- case IDM_FILE_PREVIOUS:
-
- /* read previous entry in the directory */
-
- if (SearchPngList (pPngFileList, iPngFileCount, &iPngFileIndex,
- szImgPathName, NULL))
- {
-
- if (strcmp (szImgPathName, "") == 0)
- return 0;
-
- /* load the image from file */
-
- if (!LoadImageFile (hwnd, szImgPathName, &pbImage, &cxImgSize,
- &cyImgSize, &cImgChannels, &bkgColor))
- return 0;
-
- /* invalidate the client area for later update */
-
- InvalidateRect (hwnd, NULL, TRUE);
-
- /* display the PNG into the DIBitmap */
-
- DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
- pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
- }
-
- return 0;
-
- case IDM_FILE_EXIT:
-
- /* more cleanup needed... */
-
- /* free image buffer */
-
- if (pDib != NULL)
- {
- free (pDib);
- pDib = NULL;
- }
-
- /* free file-list */
-
- if (pPngFileList != NULL)
- {
- free (pPngFileList);
- pPngFileList = NULL;
- }
-
- /* let's go ... */
-
- exit (0);
-
- return 0;
-
- case IDM_OPTIONS_STRETCH:
- bStretched = !bStretched;
- if (bStretched)
- CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_CHECKED);
- else
- CheckMenuItem (hMenu, IDM_OPTIONS_STRETCH, MF_UNCHECKED);
-
- /* invalidate the client area for later update */
-
- InvalidateRect (hwnd, NULL, TRUE);
-
- /* display the PNG into the DIBitmap */
-
- DisplayImage (hwnd, &pDib, &pDiData, cxWinSize, cyWinSize,
- pbImage, cxImgSize, cyImgSize, cImgChannels, bStretched);
-
- return 0;
-
- case IDM_HELP_ABOUT:
- DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ;
- return 0;
-
- } /* end switch */
-
- break;
-
- case WM_PAINT:
- hdc = BeginPaint (hwnd, &ps);
-
- if (pDib)
- SetDIBitsToDevice (hdc, 0, 0, cxWinSize, cyWinSize, 0, 0,
- 0, cyWinSize, pDiData, (BITMAPINFO *) pDib, DIB_RGB_COLORS);
-
- EndPaint (hwnd, &ps);
- return 0;
-
- case WM_DESTROY:
- if (pbmfh)
- {
- free (pbmfh);
- pbmfh = NULL;
- }
-
- PostQuitMessage (0);
- return 0;
- }
-
- return DefWindowProc (hwnd, message, wParam, lParam);
-}
-
-BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
- switch (message)
- {
- case WM_INITDIALOG :
- ShowWindow (hDlg, SW_HIDE);
- CenterAbout (hDlg, GetWindow (hDlg, GW_OWNER));
- ShowWindow (hDlg, SW_SHOW);
- return TRUE ;
-
- case WM_COMMAND :
- switch (LOWORD (wParam))
- {
- case IDOK :
- case IDCANCEL :
- EndDialog (hDlg, 0) ;
- return TRUE ;
- }
- break ;
- }
- return FALSE ;
-}
-
-/*---------------
- * CenterAbout
- *---------------
- */
-BOOL CenterAbout (HWND hwndChild, HWND hwndParent)
-{
- RECT rChild, rParent, rWorkArea;
- int wChild, hChild, wParent, hParent;
- int xNew, yNew;
- BOOL bResult;
-
- /* Get the Height and Width of the child window */
- GetWindowRect (hwndChild, &rChild);
- wChild = rChild.right - rChild.left;
- hChild = rChild.bottom - rChild.top;
-
- /* Get the Height and Width of the parent window */
- GetWindowRect (hwndParent, &rParent);
- wParent = rParent.right - rParent.left;
- hParent = rParent.bottom - rParent.top;
-
- /* Get the limits of the 'workarea' */
- bResult = SystemParametersInfo(
- SPI_GETWORKAREA, /* system parameter to query or set */
- sizeof(RECT),
- &rWorkArea,
- 0);
- if (!bResult) {
- rWorkArea.left = rWorkArea.top = 0;
- rWorkArea.right = GetSystemMetrics(SM_CXSCREEN);
- rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN);
- }
-
- /* Calculate new X position, then adjust for workarea */
- xNew = rParent.left + ((wParent - wChild) /2);
- if (xNew < rWorkArea.left) {
- xNew = rWorkArea.left;
- } else if ((xNew+wChild) > rWorkArea.right) {
- xNew = rWorkArea.right - wChild;
- }
-
- /* Calculate new Y position, then adjust for workarea */
- yNew = rParent.top + ((hParent - hChild) /2);
- if (yNew < rWorkArea.top) {
- yNew = rWorkArea.top;
- } else if ((yNew+hChild) > rWorkArea.bottom) {
- yNew = rWorkArea.bottom - hChild;
- }
-
- /* Set it, and return */
- return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE |
- SWP_NOZORDER);
-}
-
-/*----------------
- * BuildPngList
- *----------------
- */
-BOOL BuildPngList (PTSTR pstrPathName, TCHAR **ppFileList, int *pFileCount,
- int *pFileIndex)
-{
- static TCHAR szImgPathName [MAX_PATH];
- static TCHAR szImgFileName [MAX_PATH];
- static TCHAR szImgFindName [MAX_PATH];
-
- WIN32_FIND_DATA finddata;
- HANDLE hFind;
-
- static TCHAR szTmp [MAX_PATH];
- BOOL bOk;
- int i, ii;
- int j, jj;
-
- /* free previous file-list */
-
- if (*ppFileList != NULL)
- {
- free (*ppFileList);
- *ppFileList = NULL;
- }
-
- /* extract foldername, filename and search-name */
-
- strcpy (szImgPathName, pstrPathName);
- strcpy (szImgFileName, strrchr (pstrPathName, '\\') + 1);
-
- strcpy (szImgFindName, szImgPathName);
- *(strrchr (szImgFindName, '\\') + 1) = '\0';
- strcat (szImgFindName, "*.png");
-
- /* first cycle: count number of files in directory for memory allocation */
-
- *pFileCount = 0;
-
- hFind = FindFirstFile(szImgFindName, &finddata);
- bOk = (hFind != (HANDLE) -1);
-
- while (bOk)
- {
- *pFileCount += 1;
- bOk = FindNextFile(hFind, &finddata);
- }
- FindClose(hFind);
-
- /* allocation memory for file-list */
-
- *ppFileList = (TCHAR *) malloc (*pFileCount * MAX_PATH);
-
- /* second cycle: read directory and store filenames in file-list */
-
- hFind = FindFirstFile(szImgFindName, &finddata);
- bOk = (hFind != (HANDLE) -1);
-
- i = 0;
- ii = 0;
- while (bOk)
- {
- strcpy (*ppFileList + ii, szImgPathName);
- strcpy (strrchr(*ppFileList + ii, '\\') + 1, finddata.cFileName);
-
- if (strcmp(pstrPathName, *ppFileList + ii) == 0)
- *pFileIndex = i;
-
- ii += MAX_PATH;
- i++;
-
- bOk = FindNextFile(hFind, &finddata);
- }
- FindClose(hFind);
-
- /* finally we must sort the file-list */
-
- for (i = 0; i < *pFileCount - 1; i++)
- {
- ii = i * MAX_PATH;
- for (j = i+1; j < *pFileCount; j++)
- {
- jj = j * MAX_PATH;
- if (strcmp (*ppFileList + ii, *ppFileList + jj) > 0)
- {
- strcpy (szTmp, *ppFileList + jj);
- strcpy (*ppFileList + jj, *ppFileList + ii);
- strcpy (*ppFileList + ii, szTmp);
-
- /* check if this was the current image that we moved */
-
- if (*pFileIndex == i)
- *pFileIndex = j;
- else
- if (*pFileIndex == j)
- *pFileIndex = i;
- }
- }
- }
-
- return TRUE;
-}
-
-/*----------------
- * SearchPngList
- *----------------
- */
-
-BOOL SearchPngList (
- TCHAR *pFileList, int FileCount, int *pFileIndex,
- PTSTR pstrPrevName, PTSTR pstrNextName)
-{
- if (FileCount > 0)
- {
- /* get previous entry */
-
- if (pstrPrevName != NULL)
- {
- if (*pFileIndex > 0)
- *pFileIndex -= 1;
- else
- *pFileIndex = FileCount - 1;
-
- strcpy (pstrPrevName, pFileList + (*pFileIndex * MAX_PATH));
- }
-
- /* get next entry */
-
- if (pstrNextName != NULL)
- {
- if (*pFileIndex < FileCount - 1)
- *pFileIndex += 1;
- else
- *pFileIndex = 0;
-
- strcpy (pstrNextName, pFileList + (*pFileIndex * MAX_PATH));
- }
-
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/*-----------------
- * LoadImageFile
- *-----------------
- */
-
-BOOL LoadImageFile (HWND hwnd, PTSTR pstrPathName,
- png_byte **ppbImage, int *pxImgSize, int *pyImgSize,
- int *piChannels, png_color *pBkgColor)
-{
- static TCHAR szTmp [MAX_PATH];
-
- /* if there's an existing PNG, free the memory */
-
- if (*ppbImage)
- {
- free (*ppbImage);
- *ppbImage = NULL;
- }
-
- /* Load the entire PNG into memory */
-
- SetCursor (LoadCursor (NULL, IDC_WAIT));
- ShowCursor (TRUE);
-
- PngLoadImage (pstrPathName, ppbImage, pxImgSize, pyImgSize, piChannels,
- pBkgColor);
-
- ShowCursor (FALSE);
- SetCursor (LoadCursor (NULL, IDC_ARROW));
-
- if (*ppbImage != NULL)
- {
- sprintf (szTmp, "VisualPng - %s", strrchr(pstrPathName, '\\') + 1);
- SetWindowText (hwnd, szTmp);
- }
- else
- {
- MessageBox (hwnd, TEXT ("Error in loading the PNG image"),
- szProgName, MB_ICONEXCLAMATION | MB_OK);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*----------------
- * DisplayImage
- *----------------
- */
-BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
- BYTE **ppDiData, int cxWinSize, int cyWinSize,
- BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
- BOOL bStretched)
-{
- BYTE *pDib = *ppDib;
- BYTE *pDiData = *ppDiData;
- /* BITMAPFILEHEADER *pbmfh; */
- BITMAPINFOHEADER *pbmih;
- WORD wDIRowBytes;
- png_color bkgBlack = {0, 0, 0};
- png_color bkgGray = {127, 127, 127};
- png_color bkgWhite = {255, 255, 255};
-
- /* allocate memory for the Device Independent bitmap */
-
- wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2;
-
- if (pDib)
- {
- free (pDib);
- pDib = NULL;
- }
-
- if (cyWinSize > ((size_t)(-1))/wDIRowBytes) {
- {
- MessageBox (hwnd, TEXT ("Visual PNG: image is too big");
- }
- if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) +
- wDIRowBytes * cyWinSize)))
- {
- MessageBox (hwnd, TEXT ("Error in displaying the PNG image"),
- szProgName, MB_ICONEXCLAMATION | MB_OK);
- *ppDib = pDib = NULL;
- return FALSE;
- }
- *ppDib = pDib;
- memset (pDib, 0, sizeof(BITMAPINFOHEADER));
-
- /* initialize the dib-structure */
-
- pbmih = (BITMAPINFOHEADER *) pDib;
- pbmih->biSize = sizeof(BITMAPINFOHEADER);
- pbmih->biWidth = cxWinSize;
- pbmih->biHeight = -((long) cyWinSize);
- pbmih->biPlanes = 1;
- pbmih->biBitCount = 24;
- pbmih->biCompression = 0;
- pDiData = pDib + sizeof(BITMAPINFOHEADER);
- *ppDiData = pDiData;
-
- /* first fill bitmap with gray and image border */
-
- InitBitmap (pDiData, cxWinSize, cyWinSize);
-
- /* then fill bitmap with image */
-
- if (pbImage)
- {
- FillBitmap (
- pDiData, cxWinSize, cyWinSize,
- pbImage, cxImgSize, cyImgSize, cImgChannels,
- bStretched);
- }
-
- return TRUE;
-}
-
-/*--------------
- * InitBitmap
- *--------------
- */
-BOOL InitBitmap (BYTE *pDiData, int cxWinSize, int cyWinSize)
-{
- BYTE *dst;
- int x, y, col;
-
- /* initialize the background with gray */
-
- dst = pDiData;
- for (y = 0; y < cyWinSize; y++)
- {
- col = 0;
- for (x = 0; x < cxWinSize; x++)
- {
- /* fill with GRAY */
- *dst++ = 127;
- *dst++ = 127;
- *dst++ = 127;
- col += 3;
- }
- /* rows start on 4 byte boundaries */
- while ((col % 4) != 0)
- {
- dst++;
- col++;
- }
- }
-
- return TRUE;
-}
-
-/*--------------
- * FillBitmap
- *--------------
- */
-BOOL FillBitmap (
- BYTE *pDiData, int cxWinSize, int cyWinSize,
- BYTE *pbImage, int cxImgSize, int cyImgSize, int cImgChannels,
- BOOL bStretched)
-{
- BYTE *pStretchedImage;
- BYTE *pImg;
- BYTE *src, *dst;
- BYTE r, g, b, a;
- const int cDIChannels = 3;
- WORD wImgRowBytes;
- WORD wDIRowBytes;
- int cxNewSize, cyNewSize;
- int cxImgPos, cyImgPos;
- int xImg, yImg;
- int xWin, yWin;
- int xOld, yOld;
- int xNew, yNew;
-
- if (bStretched)
- {
- cxNewSize = cxWinSize - 2 * MARGIN;
- cyNewSize = cyWinSize - 2 * MARGIN;
-
- /* stretch the image to it's window determined size */
-
- /* the following two are mathematically the same, but the first
- * has side-effects because of rounding
- */
-/* if ((cyNewSize / cxNewSize) > (cyImgSize / cxImgSize)) */
- if ((cyNewSize * cxImgSize) > (cyImgSize * cxNewSize))
- {
- cyNewSize = cxNewSize * cyImgSize / cxImgSize;
- cxImgPos = MARGIN;
- cyImgPos = (cyWinSize - cyNewSize) / 2;
- }
- else
- {
- cxNewSize = cyNewSize * cxImgSize / cyImgSize;
- cyImgPos = MARGIN;
- cxImgPos = (cxWinSize - cxNewSize) / 2;
- }
-
- if (cyNewSize > ((size_t)(-1))/(cImgChannels * cxNewSize)) {
- {
- MessageBox (hwnd, TEXT ("Visual PNG: stretched image is too big");
- }
- pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize);
- pImg = pStretchedImage;
-
- for (yNew = 0; yNew < cyNewSize; yNew++)
- {
- yOld = yNew * cyImgSize / cyNewSize;
- for (xNew = 0; xNew < cxNewSize; xNew++)
- {
- xOld = xNew * cxImgSize / cxNewSize;
-
- r = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 0);
- g = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 1);
- b = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld) + 2);
- *pImg++ = r;
- *pImg++ = g;
- *pImg++ = b;
- if (cImgChannels == 4)
- {
- a = *(pbImage + cImgChannels * ((yOld * cxImgSize) + xOld)
- + 3);
- *pImg++ = a;
- }
- }
- }
-
- /* calculate row-bytes */
-
- wImgRowBytes = cImgChannels * cxNewSize;
- wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
-
- /* copy image to screen */
-
- for (yImg = 0, yWin = cyImgPos; yImg < cyNewSize; yImg++, yWin++)
- {
- if (yWin >= cyWinSize - cyImgPos)
- break;
- src = pStretchedImage + yImg * wImgRowBytes;
- dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
-
- for (xImg = 0, xWin = cxImgPos; xImg < cxNewSize; xImg++, xWin++)
- {
- if (xWin >= cxWinSize - cxImgPos)
- break;
- r = *src++;
- g = *src++;
- b = *src++;
- *dst++ = b; /* note the reverse order */
- *dst++ = g;
- *dst++ = r;
- if (cImgChannels == 4)
- {
- a = *src++;
- }
- }
- }
-
- /* free memory */
-
- if (pStretchedImage != NULL)
- {
- free (pStretchedImage);
- pStretchedImage = NULL;
- }
-
- }
-
- /* process the image not-stretched */
-
- else
- {
- /* calculate the central position */
-
- cxImgPos = (cxWinSize - cxImgSize) / 2;
- cyImgPos = (cyWinSize - cyImgSize) / 2;
-
- /* check for image larger than window */
-
- if (cxImgPos < MARGIN)
- cxImgPos = MARGIN;
- if (cyImgPos < MARGIN)
- cyImgPos = MARGIN;
-
- /* calculate both row-bytes */
-
- wImgRowBytes = cImgChannels * cxImgSize;
- wDIRowBytes = (WORD) ((cDIChannels * cxWinSize + 3L) >> 2) << 2;
-
- /* copy image to screen */
-
- for (yImg = 0, yWin = cyImgPos; yImg < cyImgSize; yImg++, yWin++)
- {
- if (yWin >= cyWinSize - MARGIN)
- break;
- src = pbImage + yImg * wImgRowBytes;
- dst = pDiData + yWin * wDIRowBytes + cxImgPos * cDIChannels;
-
- for (xImg = 0, xWin = cxImgPos; xImg < cxImgSize; xImg++, xWin++)
- {
- if (xWin >= cxWinSize - MARGIN)
- break;
- r = *src++;
- g = *src++;
- b = *src++;
- *dst++ = b; /* note the reverse order */
- *dst++ = g;
- *dst++ = r;
- if (cImgChannels == 4)
- {
- a = *src++;
- }
- }
- }
- }
-
- return TRUE;
-}
-
-/*-----------------
- * end of source
- *-----------------
- */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsp b/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsp
deleted file mode 100644
index 741ef6ce76f..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsp
+++ /dev/null
@@ -1,147 +0,0 @@
-# Microsoft Developer Studio Project File - Name="VisualPng" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Application" 0x0101
-
-CFG=VisualPng - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "VisualPng.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "VisualPng.mak" CFG="VisualPng - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "VisualPng - Win32 Release" (based on "Win32 (x86) Application")
-!MESSAGE "VisualPng - Win32 Debug" (based on "Win32 (x86) Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "VisualPng - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_NO_STDIO" /FD /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MD /W3 /O2 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /D "PNG_NO_STDIO" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
-# ADD LINK32 ..\..\projects\visualc6\Win32_LIB_Release\libpng.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_Release\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
-# Begin Special Build Tool
-OutDir=.\Release
-SOURCE="$(InputPath)"
-PostBuild_Cmds=$(outdir)\VisualPng.exe ..\..\contrib\pngsuite\basn6a16.png
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "VisualPng - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Ignore_Export_Lib 0
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "PNG_NO_STDIO" /FD /GZ /c
-# SUBTRACT BASE CPP /YX
-# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "_DEBUG" /D "PNG_NO_STDIO" /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 ..\..\projects\visualc6\Win32_LIB_Release\libpng.lib ..\..\..\zlib\projects\visualc6\Win32_LIB_Release\zlib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /pdbtype:sept
-# Begin Special Build Tool
-OutDir=.\Debug
-SOURCE="$(InputPath)"
-PostBuild_Cmds=$(outdir)\VisualPng.exe ..\..\contrib\pngsuite\basn6a16.png
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "VisualPng - Win32 Release"
-# Name "VisualPng - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\PngFile.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\VisualPng.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\cexcept.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\PngFile.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\resource.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# Begin Source File
-
-SOURCE=.\VisualPng.ico
-# End Source File
-# Begin Source File
-
-SOURCE=.\VisualPng.rc
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsw b/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsw
deleted file mode 100644
index a30e1cc1cdb..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "VisualPng"=.\VisualPng.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.ico b/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.ico
deleted file mode 100644
index 68aa3719fb5..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.ico
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.png b/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.png
deleted file mode 100644
index c6aa80a9bfa..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.png
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.rc b/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.rc
deleted file mode 100644
index 6e0623a73cf..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/VisualPng.rc
+++ /dev/null
@@ -1,152 +0,0 @@
-//Microsoft Developer Studio generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE DISCARDABLE
-BEGIN
- "resource.h\0"
-END
-
-2 TEXTINCLUDE DISCARDABLE
-BEGIN
- "#include ""afxres.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE DISCARDABLE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Menu
-//
-
-VISUALPNG MENU DISCARDABLE
-BEGIN
- POPUP "&File"
- BEGIN
- MENUITEM "&Open Image...\tCtrl+O", IDM_FILE_OPEN
- MENUITEM "Save &As...", IDM_FILE_SAVE
- MENUITEM SEPARATOR
- MENUITEM "&Next Image\tCtrl+N", IDM_FILE_NEXT
- MENUITEM "Pre&vious Image\tCtrl+V", IDM_FILE_PREVIOUS
- MENUITEM SEPARATOR
- MENUITEM "E&xit\tAlt+X", IDM_FILE_EXIT
- END
- POPUP "&Options"
- BEGIN
- MENUITEM "&Stretch", IDM_OPTIONS_STRETCH, CHECKED
- END
- POPUP "&Help"
- BEGIN
- MENUITEM "&About", IDM_HELP_ABOUT
- END
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Accelerator
-//
-
-VISUALPNG ACCELERATORS DISCARDABLE
-BEGIN
- "N", IDM_FILE_NEXT, VIRTKEY, CONTROL, NOINVERT
- "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
- "P", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT
- "V", IDM_FILE_PREVIOUS, VIRTKEY, CONTROL, NOINVERT
- "X", IDM_FILE_EXIT, VIRTKEY, ALT, NOINVERT
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-VISUALPNG ICON DISCARDABLE "VisualPng.ico"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-ABOUTBOX DIALOG DISCARDABLE 0, 0, 186, 94
-STYLE DS_MODALFRAME | WS_POPUP
-FONT 8, "MS Sans Serif"
-BEGIN
- DEFPUSHBUTTON "OK",IDOK,68,67,50,14
- CTEXT "VisualPng 1.0 - June 2000",IDC_STATIC,49,14,88,8
- LTEXT "a PNG image viewer",IDC_STATIC,60,30,66,8
- LTEXT "(c) Willem van Schaik, 2000",IDC_STATIC,48,52,90,8
- LTEXT "to demonstrate the use of libpng in Visual C",
- IDC_STATIC,25,38,136,8
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE
-BEGIN
- "ABOUTBOX", DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 179
- TOPMARGIN, 7
- BOTTOMMARGIN, 87
- END
-END
-#endif // APSTUDIO_INVOKED
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/cexcept.h b/Build/source/libs/libpng/libpng-src/contrib/visupng/cexcept.h
deleted file mode 100644
index 5f45d769758..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/cexcept.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*===
-cexcept.h 2.0.1 (2008-Jul-19-Sat)
-http://www.nicemice.net/cexcept/
-Adam M. Costello
-http://www.nicemice.net/amc/
-
-An interface for exception-handling in ANSI C (C89 and subsequent ISO
-standards), developed jointly with Cosmin Truta.
-
- Copyright (c) 2000-2008 Adam M. Costello and Cosmin Truta.
- This software may be modified only if its author and version
- information is updated accurately, and may be redistributed
- only if accompanied by this unaltered notice. Subject to those
- restrictions, permission is granted to anyone to do anything
- with this software. The copyright holders make no guarantees
- regarding this software, and are not responsible for any damage
- resulting from its use.
-
-The cexcept interface is not compatible with and cannot interact
-with system exceptions (like division by zero or memory segmentation
-violation), compiler-generated exceptions (like C++ exceptions), or
-other exception-handling interfaces.
-
-When using this interface across multiple .c files, do not include
-this header file directly. Instead, create a wrapper header file that
-includes this header file and then invokes the define_exception_type
-macro (see below). The .c files should then include that header file.
-
-The interface consists of one type, one well-known name, and six macros.
-
-
-define_exception_type(type_name);
-
- This macro is used like an external declaration. It specifies
- the type of object that gets copied from the exception thrower to
- the exception catcher. The type_name can be any type that can be
- assigned to, that is, a non-constant arithmetic type, struct, union,
- or pointer. Examples:
-
- define_exception_type(int);
-
- enum exception { out_of_memory, bad_arguments, disk_full };
- define_exception_type(enum exception);
-
- struct exception { int code; const char *msg; };
- define_exception_type(struct exception);
-
- Because throwing an exception causes the object to be copied (not
- just once, but twice), programmers may wish to consider size when
- choosing the exception type.
-
-
-struct exception_context;
-
- This type may be used after the define_exception_type() macro has
- been invoked. A struct exception_context must be known to both
- the thrower and the catcher. It is expected that there be one
- context for each thread that uses exceptions. It would certainly
- be dangerous for multiple threads to access the same context.
- One thread can use multiple contexts, but that is likely to be
- confusing and not typically useful. The application can allocate
- this structure in any way it pleases--automatic, static, or dynamic.
- The application programmer should pretend not to know the structure
- members, which are subject to change.
-
-
-struct exception_context *the_exception_context;
-
- The Try/Catch and Throw statements (described below) implicitly
- refer to a context, using the name the_exception_context. It is
- the application's responsibility to make sure that this name yields
- the address of a mutable (non-constant) struct exception_context
- wherever those statements are used. Subject to that constraint, the
- application may declare a variable of this name anywhere it likes
- (inside a function, in a parameter list, or externally), and may
- use whatever storage class specifiers (static, extern, etc) or type
- qualifiers (const, volatile, etc) it likes. Examples:
-
- static struct exception_context
- * const the_exception_context = &foo;
-
- { struct exception_context *the_exception_context = bar; ... }
-
- int blah(struct exception_context *the_exception_context, ...);
-
- extern struct exception_context the_exception_context[1];
-
- The last example illustrates a trick that avoids creating a pointer
- object separate from the structure object.
-
- The name could even be a macro, for example:
-
- struct exception_context ec_array[numthreads];
- #define the_exception_context (ec_array + thread_id)
-
- Be aware that the_exception_context is used several times by the
- Try/Catch/Throw macros, so it shouldn't be expensive or have side
- effects. The expansion must be a drop-in replacement for an
- identifier, so it's safest to put parentheses around it.
-
-
-void init_exception_context(struct exception_context *ec);
-
- For context structures allocated statically (by an external
- definition or using the "static" keyword), the implicit
- initialization to all zeros is sufficient, but contexts allocated
- by other means must be initialized using this macro before they
- are used by a Try/Catch statement. It does no harm to initialize
- a context more than once (by using this macro on a statically
- allocated context, or using this macro twice on the same context),
- but a context must not be re-initialized after it has been used by a
- Try/Catch statement.
-
-
-Try statement
-Catch (expression) statement
-
- The Try/Catch/Throw macros are capitalized in order to avoid
- confusion with the C++ keywords, which have subtly different
- semantics.
-
- A Try/Catch statement has a syntax similar to an if/else statement,
- except that the parenthesized expression goes after the second
- keyword rather than the first. As with if/else, there are two
- clauses, each of which may be a simple statement ending with a
- semicolon or a brace-enclosed compound statement. But whereas
- the else clause is optional, the Catch clause is required. The
- expression must be a modifiable lvalue (something capable of being
- assigned to) of the same type (disregarding type qualifiers) that
- was passed to define_exception_type().
-
- If a Throw that uses the same exception context as the Try/Catch is
- executed within the Try clause (typically within a function called
- by the Try clause), and the exception is not caught by a nested
- Try/Catch statement, then a copy of the exception will be assigned
- to the expression, and control will jump to the Catch clause. If no
- such Throw is executed, then the assignment is not performed, and
- the Catch clause is not executed.
-
- The expression is not evaluated unless and until the exception is
- caught, which is significant if it has side effects, for example:
-
- Try foo();
- Catch (p[++i].e) { ... }
-
- IMPORTANT: Jumping into or out of a Try clause (for example via
- return, break, continue, goto, longjmp) is forbidden--the compiler
- will not complain, but bad things will happen at run-time. Jumping
- into or out of a Catch clause is okay, and so is jumping around
- inside a Try clause. In many cases where one is tempted to return
- from a Try clause, it will suffice to use Throw, and then return
- from the Catch clause. Another option is to set a flag variable and
- use goto to jump to the end of the Try clause, then check the flag
- after the Try/Catch statement.
-
- IMPORTANT: The values of any non-volatile automatic variables
- changed within the Try clause are undefined after an exception is
- caught. Therefore, variables modified inside the Try block whose
- values are needed later outside the Try block must either use static
- storage or be declared with the "volatile" type qualifier.
-
-
-Throw expression;
-
- A Throw statement is very much like a return statement, except that
- the expression is required. Whereas return jumps back to the place
- where the current function was called, Throw jumps back to the Catch
- clause of the innermost enclosing Try clause. The expression must
- be compatible with the type passed to define_exception_type(). The
- exception must be caught, otherwise the program may crash.
-
- Slight limitation: If the expression is a comma-expression, it must
- be enclosed in parentheses.
-
-
-Try statement
-Catch_anonymous statement
-
- When the value of the exception is not needed, a Try/Catch statement
- can use Catch_anonymous instead of Catch (expression).
-
-
-Everything below this point is for the benefit of the compiler. The
-application programmer should pretend not to know any of it, because it
-is subject to change.
-
-===*/
-
-
-#ifndef CEXCEPT_H
-#define CEXCEPT_H
-
-
-#include <setjmp.h>
-
-#define define_exception_type(etype) \
-struct exception_context { \
- jmp_buf *penv; \
- int caught; \
- volatile struct { etype etmp; } v; \
-}
-
-/* etmp must be volatile because the application might use automatic */
-/* storage for the_exception_context, and etmp is modified between */
-/* the calls to setjmp() and longjmp(). A wrapper struct is used to */
-/* avoid warnings about a duplicate volatile qualifier in case etype */
-/* already includes it. */
-
-#define init_exception_context(ec) ((void)((ec)->penv = 0))
-
-#define Try \
- { \
- jmp_buf *exception__prev, exception__env; \
- exception__prev = the_exception_context->penv; \
- the_exception_context->penv = &exception__env; \
- if (setjmp(exception__env) == 0) { \
- do
-
-#define exception__catch(action) \
- while (the_exception_context->caught = 0, \
- the_exception_context->caught); \
- } \
- else { \
- the_exception_context->caught = 1; \
- } \
- the_exception_context->penv = exception__prev; \
- } \
- if (!the_exception_context->caught || action) { } \
- else
-
-#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0))
-#define Catch_anonymous exception__catch(0)
-
-/* Try ends with do, and Catch begins with while(0) and ends with */
-/* else, to ensure that Try/Catch syntax is similar to if/else */
-/* syntax. */
-/* */
-/* The 0 in while(0) is expressed as x=0,x in order to appease */
-/* compilers that warn about constant expressions inside while(). */
-/* Most compilers should still recognize that the condition is always */
-/* false and avoid generating code for it. */
-
-#define Throw \
- for (;; longjmp(*the_exception_context->penv, 1)) \
- the_exception_context->v.etmp =
-
-
-#endif /* CEXCEPT_H */
diff --git a/Build/source/libs/libpng/libpng-src/contrib/visupng/resource.h b/Build/source/libs/libpng/libpng-src/contrib/visupng/resource.h
deleted file mode 100644
index b62176d1dca..00000000000
--- a/Build/source/libs/libpng/libpng-src/contrib/visupng/resource.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by VisualPng.rc
-//
-#define IDM_FILE_OPEN 40001
-#define IDM_FILE_SAVE 40002
-#define IDM_FILE_NEXT 40003
-#define IDM_FILE_PREVIOUS 40004
-#define IDM_FILE_EXIT 40005
-#define IDM_OPTIONS_BACKGROUND 40006
-#define IDM_OPTIONS_STRETCH 40007
-#define IDM_HELP_ABOUT 40008
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 113
-#define _APS_NEXT_COMMAND_VALUE 40009
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif