From cc722130e0b5937a52d7f0bf2c16e1d22b8566d6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 14 Jul 2018 15:52:37 -0700 Subject: [PATCH 01/10] Third-Party: Update libpng --- src/third-party/libpng/ANNOUNCE | 59 +- src/third-party/libpng/CHANGES | 931 ++++++- src/third-party/libpng/CMakeLists.txt | 817 +++++- src/third-party/libpng/INSTALL | 178 +- src/third-party/libpng/LICENSE | 84 +- src/third-party/libpng/Makefile.am | 53 +- src/third-party/libpng/Makefile.in | 285 +- src/third-party/libpng/README | 21 +- src/third-party/libpng/TODO | 7 +- src/third-party/libpng/arm/arm_init.c | 5 +- src/third-party/libpng/arm/filter_neon.S | 6 +- .../libpng/arm/filter_neon_intrinsics.c | 18 +- src/third-party/libpng/autogen.sh | 7 +- src/third-party/libpng/config.h.in | 21 + src/third-party/libpng/configure | 342 ++- src/third-party/libpng/configure.ac | 219 +- src/third-party/libpng/contrib/README.txt | 3 +- .../libpng/contrib/arm-neon/README | 2 +- .../libpng/contrib/arm-neon/android-ndk.c | 2 +- .../libpng/contrib/arm-neon/linux-auxv.c | 2 +- .../libpng/contrib/arm-neon/linux.c | 16 +- .../libpng/contrib/conftest/pngcp.dfa | 57 + .../libpng/contrib/examples/README.txt | 2 +- .../libpng/contrib/examples/iccfrompng.c | 5 + .../libpng/contrib/examples/pngpixel.c | 5 +- .../libpng/contrib/examples/pngtopng.c | 26 +- .../libpng/contrib/examples/simpleover.c | 648 +++++ .../libpng/contrib/gregbook/README | 6 +- .../libpng/contrib/gregbook/readpng.c | 8 +- .../libpng/contrib/gregbook/readpng2.c | 56 +- .../libpng/contrib/gregbook/readppm.c | 13 +- .../libpng/contrib/gregbook/rpng-win.c | 11 +- .../libpng/contrib/gregbook/rpng-x.c | 3 +- .../libpng/contrib/gregbook/rpng2-win.c | 14 +- .../libpng/contrib/gregbook/rpng2-x.c | 20 +- .../libpng/contrib/gregbook/wpng.c | 16 +- .../libpng/contrib/gregbook/writepng.c | 2 +- .../libpng/contrib/libtests/fakepng.c | 10 +- .../libpng/contrib/libtests/makepng.c | 539 +++- .../libpng/contrib/libtests/pngimage.c | 114 +- .../libpng/contrib/libtests/pngstest-errors.h | 165 ++ .../libpng/contrib/libtests/pngstest.c | 371 +-- .../libpng/contrib/libtests/pngunknown.c | 89 +- .../libpng/contrib/libtests/pngvalid.c | 2328 +++++++++++----- .../libpng/contrib/libtests/readpng.c | 13 +- .../libpng/contrib/libtests/tarith.c | 28 +- .../libpng/contrib/libtests/timepng.c | 497 +++- .../libpng/contrib/mips-msa/README | 83 + .../libpng/contrib/mips-msa/linux.c | 64 + .../libpng/contrib/oss-fuzz/Dockerfile | 24 + .../libpng/contrib/oss-fuzz/README.txt | 37 + .../libpng/contrib/oss-fuzz/build.sh | 50 + .../contrib/oss-fuzz/libpng_read_fuzzer.cc | 180 ++ .../oss-fuzz/libpng_read_fuzzer.options | 2 + src/third-party/libpng/contrib/oss-fuzz/newcc | 190 ++ .../libpng/contrib/oss-fuzz/png.dict | 39 + .../libpng/contrib/pngminus/README | 2 +- .../libpng/contrib/pngminus/png2pnm.c | 32 +- .../libpng/contrib/pngminus/pnm2png.c | 61 +- .../libpng/contrib/pngsuite/README | 6 +- .../libpng/contrib/powerpc-vsx/README | 81 + .../libpng/contrib/powerpc-vsx/linux.c | 57 + .../libpng/contrib/powerpc-vsx/linux_aux.c | 36 + .../contrib/testpngs/crashers/bad_iCCP.png | Bin 0 -> 321 bytes .../contrib/testpngs/crashers/badadler.png | Bin 0 -> 67 bytes .../contrib/testpngs/crashers/badcrc.png | Bin 0 -> 67 bytes .../crashers/empty_ancillary_chunks.png | Bin 0 -> 730 bytes .../contrib/testpngs/crashers/huge_IDAT.png | Bin 0 -> 79 bytes .../testpngs/crashers/huge_bKGD_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_cHRM_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_eXIf_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_gAMA_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_hIST_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_iCCP_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_iTXt_chunk.png | Bin 0 -> 57 bytes .../crashers/huge_juNK_unsafe_to_copy.png | Bin 0 -> 57 bytes .../crashers/huge_juNk_safe_to_copy.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_pCAL_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_pHYs_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_sCAL_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_sPLT_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_sRGB_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_sTER_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_tEXt_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_tIME_chunk.png | Bin 0 -> 57 bytes .../testpngs/crashers/huge_zTXt_chunk.png | Bin 0 -> 57 bytes .../contrib/testpngs/gray-1-1.8-tRNS.png | Bin 0 -> 325 bytes .../libpng/contrib/testpngs/gray-1-1.8.png | Bin 0 -> 311 bytes .../contrib/testpngs/gray-1-linear-tRNS.png | Bin 0 -> 325 bytes .../libpng/contrib/testpngs/gray-1-linear.png | Bin 0 -> 311 bytes .../contrib/testpngs/gray-1-sRGB-tRNS.png | Bin 0 -> 278 bytes .../libpng/contrib/testpngs/gray-1-sRGB.png | Bin 0 -> 264 bytes .../libpng/contrib/testpngs/gray-1-tRNS.png | Bin 0 -> 265 bytes .../libpng/contrib/testpngs/gray-1.png | Bin 0 -> 251 bytes .../contrib/testpngs/gray-16-1.8-tRNS.png | Bin 0 -> 744 bytes .../libpng/contrib/testpngs/gray-16-1.8.png | Bin 0 -> 744 bytes .../contrib/testpngs/gray-16-linear-tRNS.png | Bin 0 -> 744 bytes .../contrib/testpngs/gray-16-linear.png | Bin 0 -> 744 bytes .../contrib/testpngs/gray-16-sRGB-tRNS.png | Bin 0 -> 697 bytes .../libpng/contrib/testpngs/gray-16-sRGB.png | Bin 0 -> 697 bytes .../libpng/contrib/testpngs/gray-16-tRNS.png | Bin 0 -> 684 bytes .../libpng/contrib/testpngs/gray-16.png | Bin 0 -> 684 bytes .../contrib/testpngs/gray-2-1.8-tRNS.png | Bin 0 -> 325 bytes .../libpng/contrib/testpngs/gray-2-1.8.png | Bin 0 -> 311 bytes .../contrib/testpngs/gray-2-linear-tRNS.png | Bin 0 -> 325 bytes .../libpng/contrib/testpngs/gray-2-linear.png | Bin 0 -> 311 bytes .../contrib/testpngs/gray-2-sRGB-tRNS.png | Bin 0 -> 278 bytes .../libpng/contrib/testpngs/gray-2-sRGB.png | Bin 0 -> 264 bytes .../libpng/contrib/testpngs/gray-2-tRNS.png | Bin 0 -> 265 bytes .../libpng/contrib/testpngs/gray-2.png | Bin 0 -> 251 bytes .../contrib/testpngs/gray-4-1.8-tRNS.png | Bin 0 -> 327 bytes .../libpng/contrib/testpngs/gray-4-1.8.png | Bin 0 -> 313 bytes .../contrib/testpngs/gray-4-linear-tRNS.png | Bin 0 -> 327 bytes .../libpng/contrib/testpngs/gray-4-linear.png | Bin 0 -> 313 bytes .../contrib/testpngs/gray-4-sRGB-tRNS.png | Bin 0 -> 280 bytes .../libpng/contrib/testpngs/gray-4-sRGB.png | Bin 0 -> 266 bytes .../libpng/contrib/testpngs/gray-4-tRNS.png | Bin 0 -> 267 bytes .../libpng/contrib/testpngs/gray-4.png | Bin 0 -> 253 bytes .../contrib/testpngs/gray-8-1.8-tRNS.png | Bin 0 -> 327 bytes .../libpng/contrib/testpngs/gray-8-1.8.png | Bin 0 -> 313 bytes .../contrib/testpngs/gray-8-linear-tRNS.png | Bin 0 -> 327 bytes .../libpng/contrib/testpngs/gray-8-linear.png | Bin 0 -> 313 bytes .../contrib/testpngs/gray-8-sRGB-tRNS.png | Bin 0 -> 280 bytes .../libpng/contrib/testpngs/gray-8-sRGB.png | Bin 0 -> 266 bytes .../libpng/contrib/testpngs/gray-8-tRNS.png | Bin 0 -> 267 bytes .../libpng/contrib/testpngs/gray-8.png | Bin 0 -> 253 bytes .../contrib/testpngs/gray-alpha-16-1.8.png | Bin 0 -> 919 bytes .../contrib/testpngs/gray-alpha-16-linear.png | Bin 0 -> 919 bytes .../contrib/testpngs/gray-alpha-16-sRGB.png | Bin 0 -> 872 bytes .../libpng/contrib/testpngs/gray-alpha-16.png | Bin 0 -> 859 bytes .../contrib/testpngs/gray-alpha-8-1.8.png | Bin 0 -> 744 bytes .../contrib/testpngs/gray-alpha-8-linear.png | Bin 0 -> 744 bytes .../contrib/testpngs/gray-alpha-8-sRGB.png | Bin 0 -> 697 bytes .../libpng/contrib/testpngs/gray-alpha-8.png | Bin 0 -> 684 bytes .../libpng/contrib/testpngs/makepngs.sh | 94 + .../contrib/testpngs/palette-1-1.8-tRNS.png | Bin 0 -> 342 bytes .../libpng/contrib/testpngs/palette-1-1.8.png | Bin 0 -> 329 bytes .../testpngs/palette-1-linear-tRNS.png | Bin 0 -> 342 bytes .../contrib/testpngs/palette-1-linear.png | Bin 0 -> 329 bytes .../contrib/testpngs/palette-1-sRGB-tRNS.png | Bin 0 -> 295 bytes .../contrib/testpngs/palette-1-sRGB.png | Bin 0 -> 282 bytes .../contrib/testpngs/palette-1-tRNS.png | Bin 0 -> 282 bytes .../libpng/contrib/testpngs/palette-1.png | Bin 0 -> 269 bytes .../contrib/testpngs/palette-2-1.8-tRNS.png | Bin 0 -> 350 bytes .../libpng/contrib/testpngs/palette-2-1.8.png | Bin 0 -> 335 bytes .../testpngs/palette-2-linear-tRNS.png | Bin 0 -> 350 bytes .../contrib/testpngs/palette-2-linear.png | Bin 0 -> 335 bytes .../contrib/testpngs/palette-2-sRGB-tRNS.png | Bin 0 -> 303 bytes .../contrib/testpngs/palette-2-sRGB.png | Bin 0 -> 288 bytes .../contrib/testpngs/palette-2-tRNS.png | Bin 0 -> 290 bytes .../libpng/contrib/testpngs/palette-2.png | Bin 0 -> 275 bytes .../contrib/testpngs/palette-4-1.8-tRNS.png | Bin 0 -> 400 bytes .../libpng/contrib/testpngs/palette-4-1.8.png | Bin 0 -> 373 bytes .../testpngs/palette-4-linear-tRNS.png | Bin 0 -> 400 bytes .../contrib/testpngs/palette-4-linear.png | Bin 0 -> 373 bytes .../contrib/testpngs/palette-4-sRGB-tRNS.png | Bin 0 -> 353 bytes .../contrib/testpngs/palette-4-sRGB.png | Bin 0 -> 326 bytes .../contrib/testpngs/palette-4-tRNS.png | Bin 0 -> 340 bytes .../libpng/contrib/testpngs/palette-4.png | Bin 0 -> 313 bytes .../contrib/testpngs/palette-8-1.8-tRNS.png | Bin 0 -> 1360 bytes .../libpng/contrib/testpngs/palette-8-1.8.png | Bin 0 -> 1093 bytes .../testpngs/palette-8-linear-tRNS.png | Bin 0 -> 1360 bytes .../contrib/testpngs/palette-8-linear.png | Bin 0 -> 1093 bytes .../contrib/testpngs/palette-8-sRGB-tRNS.png | Bin 0 -> 1313 bytes .../contrib/testpngs/palette-8-sRGB.png | Bin 0 -> 1046 bytes .../contrib/testpngs/palette-8-tRNS.png | Bin 0 -> 1300 bytes .../libpng/contrib/testpngs/palette-8.png | Bin 0 -> 1033 bytes .../contrib/testpngs/rgb-16-1.8-tRNS.png | Bin 0 -> 1211 bytes .../libpng/contrib/testpngs/rgb-16-1.8.png | Bin 0 -> 1211 bytes .../contrib/testpngs/rgb-16-linear-tRNS.png | Bin 0 -> 1211 bytes .../libpng/contrib/testpngs/rgb-16-linear.png | Bin 0 -> 1211 bytes .../contrib/testpngs/rgb-16-sRGB-tRNS.png | Bin 0 -> 1164 bytes .../libpng/contrib/testpngs/rgb-16-sRGB.png | Bin 0 -> 1164 bytes .../libpng/contrib/testpngs/rgb-16-tRNS.png | Bin 0 -> 1151 bytes .../libpng/contrib/testpngs/rgb-16.png | Bin 0 -> 1151 bytes .../contrib/testpngs/rgb-8-1.8-tRNS.png | Bin 0 -> 837 bytes .../libpng/contrib/testpngs/rgb-8-1.8.png | Bin 0 -> 819 bytes .../contrib/testpngs/rgb-8-linear-tRNS.png | Bin 0 -> 837 bytes .../libpng/contrib/testpngs/rgb-8-linear.png | Bin 0 -> 819 bytes .../contrib/testpngs/rgb-8-sRGB-tRNS.png | Bin 0 -> 790 bytes .../libpng/contrib/testpngs/rgb-8-sRGB.png | Bin 0 -> 772 bytes .../libpng/contrib/testpngs/rgb-8-tRNS.png | Bin 0 -> 777 bytes .../libpng/contrib/testpngs/rgb-8.png | Bin 0 -> 759 bytes .../contrib/testpngs/rgb-alpha-16-1.8.png | Bin 0 -> 1437 bytes .../contrib/testpngs/rgb-alpha-16-linear.png | Bin 0 -> 1437 bytes .../contrib/testpngs/rgb-alpha-16-sRGB.png | Bin 0 -> 1390 bytes .../libpng/contrib/testpngs/rgb-alpha-16.png | Bin 0 -> 1377 bytes .../contrib/testpngs/rgb-alpha-8-1.8.png | Bin 0 -> 919 bytes .../contrib/testpngs/rgb-alpha-8-linear.png | Bin 0 -> 919 bytes .../contrib/testpngs/rgb-alpha-8-sRGB.png | Bin 0 -> 872 bytes .../libpng/contrib/testpngs/rgb-alpha-8.png | Bin 0 -> 859 bytes .../libpng/contrib/tools/README.txt | 3 +- src/third-party/libpng/contrib/tools/chkfmt | 7 + src/third-party/libpng/contrib/tools/genpng.c | 881 ++++++ .../libpng/contrib/tools/png-fix-itxt.c | 69 +- src/third-party/libpng/contrib/tools/pngcp.c | 2453 +++++++++++++++++ src/third-party/libpng/contrib/tools/pngfix.c | 90 +- src/third-party/libpng/contrib/tools/reindent | 25 + src/third-party/libpng/contrib/tools/sRGB.h | 2 +- .../libpng/contrib/visupng/PngFile.c | 10 +- .../libpng/contrib/visupng/VisualPng.c | 10 +- src/third-party/libpng/example.c | 69 +- .../libpng/intel/filter_sse2_intrinsics.c | 406 +++ src/third-party/libpng/intel/intel_init.c | 53 + src/third-party/libpng/libpng-manual.txt | 529 ++-- src/third-party/libpng/libpng.3 | 903 +++--- src/third-party/libpng/libpng.pc.in | 1 + src/third-party/libpng/libpngpf.3 | 8 +- src/third-party/libpng/ltmain.sh | 0 .../libpng/mips/filter_msa_intrinsics.c | 807 ++++++ src/third-party/libpng/mips/mips_init.c | 129 + src/third-party/libpng/png.5 | 10 +- src/third-party/libpng/png.c | 790 +++--- src/third-party/libpng/png.h | 918 +++--- src/third-party/libpng/pngconf.h | 72 +- src/third-party/libpng/pngdebug.h | 2 +- src/third-party/libpng/pngerror.c | 80 +- src/third-party/libpng/pngget.c | 101 +- src/third-party/libpng/pnginfo.h | 12 +- src/third-party/libpng/pngmem.c | 25 +- src/third-party/libpng/pngpread.c | 152 +- src/third-party/libpng/pngpriv.h | 480 +++- src/third-party/libpng/pngread.c | 505 ++-- src/third-party/libpng/pngrio.c | 8 +- src/third-party/libpng/pngrtran.c | 151 +- src/third-party/libpng/pngrutil.c | 927 ++++--- src/third-party/libpng/pngset.c | 372 ++- src/third-party/libpng/pngstruct.h | 39 +- src/third-party/libpng/pngtest.c | 639 +++-- src/third-party/libpng/pngtest.png | Bin 8695 -> 8759 bytes src/third-party/libpng/pngtrans.c | 57 +- src/third-party/libpng/pngwio.c | 8 +- src/third-party/libpng/pngwrite.c | 909 +++--- src/third-party/libpng/pngwtran.c | 22 +- src/third-party/libpng/pngwutil.c | 1203 ++++---- .../libpng/powerpc/filter_vsx_intrinsics.c | 767 ++++++ src/third-party/libpng/powerpc/powerpc_init.c | 125 + .../libpng/projects/owatcom/pngconfig.mak | 2 +- .../libpng/projects/vstudio/WARNING | 27 - .../projects/vstudio/libpng/libpng.vcxproj | 24 +- .../vstudio/pnglibconf/pnglibconf.vcxproj | 2 +- .../vstudio/pngstest/pngstest.vcxproj | 24 +- .../projects/vstudio/pngtest/pngtest.vcxproj | 24 +- .../vstudio/pngunknown/pngunknown.vcxproj | 24 +- .../vstudio/pngvalid/pngvalid.vcxproj | 24 +- .../libpng/projects/vstudio/readme.txt | 46 +- .../libpng/projects/vstudio/zlib.props | 15 +- .../libpng/projects/vstudio/zlib/zlib.vcxproj | 18 +- src/third-party/libpng/scripts/README.txt | 12 +- src/third-party/libpng/scripts/def.c | 2 +- .../libpng/scripts/genchk.cmake.in | 37 + .../libpng/scripts/genout.cmake.in | 93 + .../libpng/scripts/gensrc.cmake.in | 138 + .../libpng/scripts/libpng-config-head.in | 2 +- src/third-party/libpng/scripts/libpng.pc.in | 2 +- src/third-party/libpng/scripts/makefile.cegcc | 2 +- src/third-party/libpng/scripts/makefile.linux | 4 +- .../libpng/scripts/makefile.linux-opt | 265 ++ src/third-party/libpng/scripts/makefile.msys | 2 +- .../libpng/scripts/makefile.ne12bsd | 2 +- .../libpng/scripts/makefile.netbsd | 2 +- .../libpng/scripts/makefile.openbsd | 2 +- src/third-party/libpng/scripts/makefile.sco | 2 +- .../libpng/scripts/makefile.solaris-x86 | 2 +- src/third-party/libpng/scripts/pnglibconf.dfa | 68 +- .../libpng/scripts/pnglibconf.h.prebuilt | 20 +- src/third-party/libpng/scripts/symbols.def | 7 +- src/third-party/libpng/scripts/test.cmake.in | 31 + src/third-party/libpng/tests/pngimage-full | 2 +- src/third-party/libpng/tests/pngimage-quick | 2 +- src/third-party/libpng/tests/pngstest | 53 +- src/third-party/libpng/tests/pngstest-0g01 | 2 - src/third-party/libpng/tests/pngstest-0g02 | 2 - src/third-party/libpng/tests/pngstest-0g04 | 2 - src/third-party/libpng/tests/pngstest-0g08 | 2 - src/third-party/libpng/tests/pngstest-0g16 | 2 - src/third-party/libpng/tests/pngstest-1.8 | 2 + .../libpng/tests/pngstest-1.8-alpha | 2 + src/third-party/libpng/tests/pngstest-2c08 | 2 - src/third-party/libpng/tests/pngstest-2c16 | 2 - src/third-party/libpng/tests/pngstest-3p01 | 2 - src/third-party/libpng/tests/pngstest-3p02 | 2 - src/third-party/libpng/tests/pngstest-3p04 | 2 - src/third-party/libpng/tests/pngstest-3p08 | 2 - src/third-party/libpng/tests/pngstest-4a08 | 2 - src/third-party/libpng/tests/pngstest-4a16 | 2 - src/third-party/libpng/tests/pngstest-6a08 | 2 - src/third-party/libpng/tests/pngstest-6a16 | 2 - src/third-party/libpng/tests/pngstest-error | 14 - src/third-party/libpng/tests/pngstest-linear | 2 + .../libpng/tests/pngstest-linear-alpha | 2 + src/third-party/libpng/tests/pngstest-none | 2 + .../libpng/tests/pngstest-none-alpha | 2 + src/third-party/libpng/tests/pngstest-sRGB | 2 + .../libpng/tests/pngstest-sRGB-alpha | 2 + src/third-party/libpng/tests/pngtest-badpngs | 13 + src/third-party/libpng/tests/pngunknown-IDAT | 2 +- .../libpng/tests/pngunknown-discard | 2 +- .../libpng/tests/pngunknown-if-safe | 2 +- src/third-party/libpng/tests/pngunknown-sAPI | 2 +- src/third-party/libpng/tests/pngunknown-sTER | 2 +- src/third-party/libpng/tests/pngunknown-save | 2 +- src/third-party/libpng/tests/pngunknown-vpAg | 2 +- .../libpng/tests/pngvalid-gamma-16-to-8 | 2 +- .../libpng/tests/pngvalid-gamma-alpha-mode | 2 +- .../libpng/tests/pngvalid-gamma-background | 2 +- .../tests/pngvalid-gamma-expand16-alpha-mode | 2 +- .../tests/pngvalid-gamma-expand16-background | 2 +- .../tests/pngvalid-gamma-expand16-transform | 2 +- .../libpng/tests/pngvalid-gamma-sbit | 2 +- .../libpng/tests/pngvalid-gamma-threshold | 2 +- .../libpng/tests/pngvalid-gamma-transform | 2 +- .../tests/pngvalid-progressive-interlace-size | 2 - .../pngvalid-progressive-interlace-standard | 2 +- .../pngvalid-progressive-interlace-transform | 2 - .../libpng/tests/pngvalid-progressive-size | 2 + .../tests/pngvalid-progressive-standard | 2 +- .../libpng/tests/pngvalid-standard | 2 +- .../libpng/tests/pngvalid-transform | 2 + 319 files changed, 19032 insertions(+), 6060 deletions(-) create mode 100644 src/third-party/libpng/contrib/conftest/pngcp.dfa create mode 100644 src/third-party/libpng/contrib/examples/simpleover.c create mode 100644 src/third-party/libpng/contrib/libtests/pngstest-errors.h create mode 100644 src/third-party/libpng/contrib/mips-msa/README create mode 100644 src/third-party/libpng/contrib/mips-msa/linux.c create mode 100644 src/third-party/libpng/contrib/oss-fuzz/Dockerfile create mode 100644 src/third-party/libpng/contrib/oss-fuzz/README.txt create mode 100755 src/third-party/libpng/contrib/oss-fuzz/build.sh create mode 100644 src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc create mode 100644 src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.options create mode 100644 src/third-party/libpng/contrib/oss-fuzz/newcc create mode 100644 src/third-party/libpng/contrib/oss-fuzz/png.dict create mode 100644 src/third-party/libpng/contrib/powerpc-vsx/README create mode 100644 src/third-party/libpng/contrib/powerpc-vsx/linux.c create mode 100644 src/third-party/libpng/contrib/powerpc-vsx/linux_aux.c create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/bad_iCCP.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/badadler.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/badcrc.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/empty_ancillary_chunks.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_IDAT.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_bKGD_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_cHRM_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_eXIf_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_gAMA_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_hIST_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_iCCP_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_iTXt_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_pCAL_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_pHYs_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_sCAL_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_sPLT_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_sRGB_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_sTER_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_tEXt_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_tIME_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/crashers/huge_zTXt_chunk.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-1.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-16.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-2.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-4.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-16-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-16-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-16-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-16.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-8-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-8-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-8-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/gray-alpha-8.png create mode 100755 src/third-party/libpng/contrib/testpngs/makepngs.sh create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-1.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-2.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-4.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/palette-8.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-16.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8-1.8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8-linear-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8-sRGB-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8-tRNS.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-8.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-16-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-16-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-16-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-16.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-8-1.8.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-8-linear.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-8-sRGB.png create mode 100644 src/third-party/libpng/contrib/testpngs/rgb-alpha-8.png create mode 100644 src/third-party/libpng/contrib/tools/genpng.c create mode 100644 src/third-party/libpng/contrib/tools/pngcp.c create mode 100755 src/third-party/libpng/contrib/tools/reindent create mode 100644 src/third-party/libpng/intel/filter_sse2_intrinsics.c create mode 100644 src/third-party/libpng/intel/intel_init.c mode change 100644 => 100755 src/third-party/libpng/ltmain.sh create mode 100644 src/third-party/libpng/mips/filter_msa_intrinsics.c create mode 100644 src/third-party/libpng/mips/mips_init.c create mode 100644 src/third-party/libpng/powerpc/filter_vsx_intrinsics.c create mode 100644 src/third-party/libpng/powerpc/powerpc_init.c delete mode 100644 src/third-party/libpng/projects/vstudio/WARNING create mode 100644 src/third-party/libpng/scripts/genchk.cmake.in create mode 100644 src/third-party/libpng/scripts/genout.cmake.in create mode 100644 src/third-party/libpng/scripts/gensrc.cmake.in create mode 100644 src/third-party/libpng/scripts/makefile.linux-opt create mode 100644 src/third-party/libpng/scripts/test.cmake.in delete mode 100755 src/third-party/libpng/tests/pngstest-0g01 delete mode 100755 src/third-party/libpng/tests/pngstest-0g02 delete mode 100755 src/third-party/libpng/tests/pngstest-0g04 delete mode 100755 src/third-party/libpng/tests/pngstest-0g08 delete mode 100755 src/third-party/libpng/tests/pngstest-0g16 create mode 100755 src/third-party/libpng/tests/pngstest-1.8 create mode 100755 src/third-party/libpng/tests/pngstest-1.8-alpha delete mode 100755 src/third-party/libpng/tests/pngstest-2c08 delete mode 100755 src/third-party/libpng/tests/pngstest-2c16 delete mode 100755 src/third-party/libpng/tests/pngstest-3p01 delete mode 100755 src/third-party/libpng/tests/pngstest-3p02 delete mode 100755 src/third-party/libpng/tests/pngstest-3p04 delete mode 100755 src/third-party/libpng/tests/pngstest-3p08 delete mode 100755 src/third-party/libpng/tests/pngstest-4a08 delete mode 100755 src/third-party/libpng/tests/pngstest-4a16 delete mode 100755 src/third-party/libpng/tests/pngstest-6a08 delete mode 100755 src/third-party/libpng/tests/pngstest-6a16 delete mode 100755 src/third-party/libpng/tests/pngstest-error create mode 100755 src/third-party/libpng/tests/pngstest-linear create mode 100755 src/third-party/libpng/tests/pngstest-linear-alpha create mode 100755 src/third-party/libpng/tests/pngstest-none create mode 100755 src/third-party/libpng/tests/pngstest-none-alpha create mode 100755 src/third-party/libpng/tests/pngstest-sRGB create mode 100755 src/third-party/libpng/tests/pngstest-sRGB-alpha create mode 100755 src/third-party/libpng/tests/pngtest-badpngs delete mode 100755 src/third-party/libpng/tests/pngvalid-progressive-interlace-size delete mode 100755 src/third-party/libpng/tests/pngvalid-progressive-interlace-transform create mode 100755 src/third-party/libpng/tests/pngvalid-progressive-size create mode 100755 src/third-party/libpng/tests/pngvalid-transform diff --git a/src/third-party/libpng/ANNOUNCE b/src/third-party/libpng/ANNOUNCE index 131e0aa36..0f66c0d1d 100644 --- a/src/third-party/libpng/ANNOUNCE +++ b/src/third-party/libpng/ANNOUNCE @@ -1,4 +1,4 @@ -Libpng 1.6.17 - March 26, 2015 +Libpng 1.6.34 - September 29, 2017 This is a public release of libpng, intended for use in production codes. @@ -7,61 +7,24 @@ Files available for download: Source files with LF line endings (for Unix/Linux) and with a "configure" script - libpng-1.6.17.tar.xz (LZMA-compressed, recommended) - libpng-1.6.17.tar.gz + libpng-1.6.34.tar.xz (LZMA-compressed, recommended) + libpng-1.6.34.tar.gz Source files with CRLF line endings (for Windows), without the "configure" script - lpng1617.7z (LZMA-compressed, recommended) - lpng1617.zip + lpng1634.7z (LZMA-compressed, recommended) + lpng1634.zip Other information: - libpng-1.6.17-README.txt - libpng-1.6.17-LICENSE.txt - libpng-1.6.17-*.asc (armored detached GPG signatures) + libpng-1.6.34-README.txt + libpng-1.6.34-LICENSE.txt + libpng-1.6.34-*.asc (armored detached GPG signatures) -Changes since the last public release (1.6.16): - - Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h - Corrected the width limit calculation in png_check_IHDR(). - Removed user limits from pngfix. Also pass NULL pointers to - png_read_row to skip the unnecessary row de-interlace stuff. - Added testing of png_set_packing() to pngvalid.c - Regenerated configure scripts in the *.tar distributions with libtool-2.4.4 - Implement previously untested cases of libpng transforms in pngvalid.c - Fixed byte order in 2-byte filler, in png_do_read_filler(). - Made the check for out-of-range values in png_set_tRNS() detect - values that are exactly 2^bit_depth, and work on 16-bit platforms. - Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47. - Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and - pngset.c to avoid warnings about dead code. - Do not build png_product2() when it is unused. - Display user limits in the output from pngtest. - Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column - and 1-million-row default limits in pnglibconf.dfa, that can be reset - by the user at build time or run time. This provides a more robust - defense against DOS and as-yet undiscovered overflows. - Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default. - Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins). - Rebuilt configure scripts with automake-1.15 and libtool-2.4.6 - Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block - of png.h. - Avoid runtime checks when converting integer to png_byte with - Visual Studio (Sergey Kosarevsky) - Removed some comments that the configure script did not handle - properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt. - Free the unknown_chunks structure even when it contains no data. - Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF - for consistency, and remove some useless tests (Alexey Petruchik). - Remove pnglibconf.h, pnglibconf.c, pnglibconf.pre, pnglibconf.dfn, - and pnglibconf.out instead of pnglibconf.* in "make clean" (Cosmin). - Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha - value was wrong. It's not clear if this affected the final stored - value; in the obvious code path the upper and lower 8-bits of the - alpha value were identical and the alpha was truncated to 8-bits - rather than dividing by 257 (John Bowler). +Changes since the last public release (1.6.33): + Removed contrib/pngsuite/i*.png; some of these were incorrect and caused + test failures. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/src/third-party/libpng/CHANGES b/src/third-party/libpng/CHANGES index 1be09e938..4b8211891 100644 --- a/src/third-party/libpng/CHANGES +++ b/src/third-party/libpng/CHANGES @@ -1,11 +1,14 @@ - +#if 0 CHANGES - changes for libpng -Version 0.2 +version 0.1 [March 29, 1995] + initial work-in-progress release + +version 0.2 [April 1, 1995] added reader into png.h fixed small problems in stub file -Version 0.3 +version 0.3 [April 8, 1995] added pull reader split up pngwrite.c to several files added pnglib.txt @@ -14,9 +17,9 @@ Version 0.3 fixed some bugs in writer interfaced with zlib 0.5 added K&R support - added check for 64 KB blocks for 16-bit machines + added check for 64 KB blocks for 16 bit machines -Version 0.4 +version 0.4 [April 26, 1995] cleaned up code and commented code simplified time handling into png_time created png_color_16 and png_color_8 to handle color needs @@ -27,28 +30,29 @@ Version 0.4 cleaned up zTXt reader and writer (using zlib's Reset functions) split transformations into pngrtran.c and pngwtran.c -Version 0.5 +version 0.5 [April 30, 1995] interfaced with zlib 0.8 fixed many reading and writing bugs saved using 3 spaces instead of tabs -Version 0.6 +version 0.6 [May 1, 1995] + first beta release added png_large_malloc() and png_large_free() added png_size_t cleaned up some compiler warnings added png_start_read_image() -Version 0.7 +version 0.7 [June 24, 1995] cleaned up lots of bugs finished dithering and other stuff added test program changed name from pnglib to libpng -Version 0.71 [June, 1995] +version 0.71 [June 26, 1995] changed pngtest.png for zlib 0.93 fixed error in libpng.txt and example.c -Version 0.8 +version 0.8 [August 20, 1995] cleaned up some bugs added png_set_filler() split up pngstub.c into pngmem.c, pngio.c, and pngerror.c @@ -91,7 +95,7 @@ Version 0.88 [January, 1996] cleaned up documentation added callbacks for read/write and warning/error functions -Version 0.89 [July, 1996] +Version 0.89 [June 5, 1996] Added new initialization API to make libpng work better with shared libs we now have png_create_read_struct(), png_create_write_struct(), png_create_info_struct(), png_destroy_read_struct(), and @@ -118,6 +122,9 @@ Version 0.89 [July, 1996] New pngtest image also has interlacing and zTXt Updated documentation to reflect new API +Version 0.89c [June 17, 1996] + Bug fixes. + Version 0.90 [January, 1997] Made CRC errors/warnings on critical and ancillary chunks configurable libpng will use the zlib CRC routines by (compile-time) default @@ -158,7 +165,7 @@ Version 0.95 [March, 1997] Added new pCAL chunk read/write support Added experimental filter selection weighting (Greg Roelofs) Removed old png_set_rgbx() and png_set_xrgb() functions that have been - obsolete for about 2 years now (use png_set_filler() instead) + obsolete for about 2 years now (use png_set_filler() instead) Added macros to read 16- and 32-bit ints directly from buffer, to be used only on those systems that support it (namely PowerPC and 680x0) With some testing, this may become the default for MACOS/PPC systems. @@ -440,7 +447,7 @@ Version 1.0.3 [January 14, 1999] Version 1.0.3a [August 12, 1999] Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning - if an attempt is made to read an interlaced image when it's not supported. + if an attempt is made to read an interlaced image when it's not supported. Added check if png_ptr->trans is defined before freeing it in pngread.c Modified the Y2K statement to include versions back to version 0.71 Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c @@ -448,7 +455,7 @@ Version 1.0.3a [August 12, 1999] Replaced leading blanks with tab characters in makefile.hux Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents. Changed (float)red and (float)green to (double)red, (double)green - in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. + in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. Fixed a bug in pngconf.h that omitted when PNG_DEBUG==0 (K Bracey). Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt). Updated documentation to refer to the PNG-1.2 specification. @@ -491,7 +498,7 @@ Version 1.0.3d [September 4, 1999] Added new png_expand functions to scripts/pngdef.pas and pngos2.def Added a demo read_user_transform_fn that examines the row filters in pngtest.c -Version 1.0.4 [September 24, 1999] +Version 1.0.4 [September 24, 1999, not distributed publicly] Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h Made several minor corrections to pngtest.c @@ -518,6 +525,7 @@ Version 1.0.4c [October 1, 1999] Added a "png_check_version" function in png.c and pngtest.c that will generate a helpful compiler error if an old png.h is found in the search path. Changed type of png_user_transform_depth|channels from int to png_byte. + Added "Libpng is OSI Certified Open Source Software" statement to png.h Version 1.0.4d [October 6, 1999] Changed 0.45 to 0.45455 in png_set_sRGB() @@ -585,7 +593,7 @@ Version 1.0.5e [November 30, 1999] with trailing compressed parts easier in the future, and added new functions png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP, png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). - NOTE: Applications that write text chunks MUST define png_text->lang + NOTE: Applications that write text chunks MUST define png_text->lang before calling png_set_text(). It must be set to NULL if you want to write tEXt or zTXt chunks. If you want your application to be able to run with older versions of libpng, use @@ -825,7 +833,7 @@ Version 1.0.7beta11 [May 7, 2000] Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes which are no longer used. Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is - defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED + defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXt_SUPPORTED is defined. Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory overrun when old applications fill the info_ptr->text structure directly. @@ -904,7 +912,7 @@ Version 1.0.7 [July 1, 2000] Version 1.0.8beta1 [July 8, 2000] Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks. Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and - pngwutil.c. + pngwutil.c. Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h. Removed unused "#include " from png.c Added WindowsCE support. @@ -912,12 +920,12 @@ Version 1.0.8beta1 [July 8, 2000] Version 1.0.8beta2 [July 10, 2000] Added project files to the wince directory and made further revisions - of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. + of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. Version 1.0.8beta3 [July 11, 2000] Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS() - for indexed-color input files to avoid potential double-freeing trans array - under some unusual conditions; problem was introduced in version 1.0.6f. + for indexed-color input files to avoid potential double-freeing trans array + under some unusual conditions; problem was introduced in version 1.0.6f. Further revisions to pngtest.c and files in the wince subdirectory. Version 1.0.8beta4 [July 14, 2000] @@ -1089,16 +1097,16 @@ Version 1.2.0beta3 [May 17, 2001] Version 1.2.0beta4 [June 23, 2001] Check for missing profile length field in iCCP chunk and free chunk_data - in case of truncated iCCP chunk. + in case of truncated iCCP chunk. Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc Bumped dll-number from 2 to 3 in makefile.cygwin Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly - if user attempts to run it on an 8-bit display. + if user attempts to run it on an 8-bit display. Updated contrib/gregbook Use png_malloc instead of png_zalloc to allocate palette in pngset.c Updated makefile.ibmc Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes - of png_write_oFFS width and height from png_uint_32 to png_int_32. + of png_write_oFFS width and height from png_uint_32 to png_int_32. Updated example.c Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c @@ -1106,9 +1114,9 @@ Version 1.2.0beta5 [August 8, 2001] Revised contrib/gregbook Revised makefile.gcmmx Revised pnggccrd.c to conditionally compile some thread-unsafe code only - when PNG_THREAD_UNSAFE_OK is defined. + when PNG_THREAD_UNSAFE_OK is defined. Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with - value exceeding 2^bit_depth-1 + value exceeding 2^bit_depth-1 Revised makefile.sgi and makefile.sggcc Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c Removed restriction that do_invert_mono only operate on 1-bit opaque files @@ -1449,8 +1457,9 @@ Version 1.2.6beta4 [July 28, 2004] Use png_malloc instead of png_zalloc to allocate the pallete. Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] - Fixed buffer overflow vulnerability in png_handle_tRNS() - Fixed integer arithmetic overflow vulnerability in png_read_png(). + Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS(). + Fixed NULL dereference vulnerability (CVE-2004-0598) in png_handle_iCCP(). + Fixed integer overflow vulnerability (CVE-2004-0599) in png_read_png(). Fixed some harmless bugs in png_handle_sBIT, etc, that would cause duplicate chunk types to go undetected. Fixed some timestamps in the -config version @@ -1493,7 +1502,7 @@ Version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004] Version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004] Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED - section of png.h where they were inadvertently placed in version rc3. + section of png.h where they were inadvertently placed in version rc3. Version 1.2.6 and 1.0.16 [August 15, 2004] Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1. @@ -2325,7 +2334,7 @@ Version 1.4.0beta63 [June 15, 2009] Version 1.4.0beta64 [June 24, 2009] Eliminated PNG_LEGACY_SUPPORTED code. Moved the various unknown chunk macro definitions outside of the - PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks. + PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks. Version 1.4.0beta65 [June 26, 2009] Added a reference to the libpng license in each file. @@ -3747,8 +3756,9 @@ Version 1.5.7beta04 [November 17, 2011] Version 1.5.7beta05 [November 25, 2011] Removed "zTXt" from warning in generic chunk decompression function. - Validate time settings passed to pngset() and png_convert_to_rfc1123() - (Frank Busse). + Validate time settings passed to png_set_tIME() and png_convert_to_rfc1123() + (Frank Busse). Note: This prevented CVE-2015-7981 from affecting + libpng-1.5.7 and later. Added MINGW support to CMakeLists.txt Reject invalid compression flag or method when reading the iTXt chunk. Backed out 'simplified' API changes. The API seems too complex and there @@ -3794,12 +3804,13 @@ Version 1.6.0beta01 [December 15, 2011] (the other two required headers aren't used). Non-ANSI systems that don't have stddef.h or limits.h will have to provide an appropriate fake containing the relevant types and #defines. - The use of FAR/far has been eliminated and the definition of png_alloc_size_t - is now controlled by a flag so that 'small size_t' systems can select it - if necessary. Libpng 1.6 may not currently work on such systems -- it - seems likely that it will ask 'malloc' for more than 65535 bytes with any - image that has a sufficiently large row size (rather than simply failing - to read such images). + Dropped support for 16-bit platforms. The use of FAR/far has been eliminated + and the definition of png_alloc_size_t is now controlled by a flag so + that 'small size_t' systems can select it if necessary. Libpng 1.6 may + not currently work on such systems -- it seems likely that it will + ask 'malloc' for more than 65535 bytes with any image that has a + sufficiently large row size (rather than simply failing to read such + images). New tools directory containing tools used to generate libpng code. Fixed race conditions in parallel make builds. With higher degrees of parallelism during 'make' the use of the same temporary file names such @@ -4411,7 +4422,7 @@ Version 1.6.1beta02 [February 19, 2013] Version 1.6.1beta03 [February 22, 2013] Fixed ALIGNED_MEMORY support. - Allow run-time ARM NEON checking to be disabled. A new configure option: + Added a new configure option: --enable-arm-neon=always will stop the run-time checks. New checks within arm/arm_init.c will cause the code not to be compiled unless __ARM_NEON__ is set. This should make it fail safe (if someone asks @@ -4430,10 +4441,10 @@ Version 1.6.1beta05 [March 1, 2013] Version 1.6.1beta06 [March 4, 2013] Better documentation of unknown handling API interactions. Corrected Android builds and corrected libpng.vers with symbol - prefixing. This adds an API to set optimization options externally, + prefixing. It also makes those tests compile and link on Android. + Added an API png_set_option() to set optimization options externally, providing an alternative and general solution for the non-portable - run-time tests used by the ARM Neon code. It also makes those tests - compile and link on Android. + run-time tests used by the ARM Neon code, using the PNG_ARM_NEON option. The order of settings vs options in pnglibconf.h is reversed to allow settings to depend on options and options can now set (or override) the defaults for settings. @@ -4525,13 +4536,14 @@ Version 1.6.3beta03 [April 30, 2013] Expanded manual paragraph about writing private chunks, particularly the need to call png_set_keep_unknown_chunks() when writing them. Avoid dereferencing NULL pointer possibly returned from - png_create_write_struct() (Andrew Church). + png_create_write_struct() (Andrew Church). Version 1.6.3beta05 [May 9, 2013] Calculate our own zlib windowBits when decoding rather than trusting the CMF bytes in the PNG datastream. Added an option to force maximum window size for inflating, which was - the behavior of libpng15 and earlier. + the behavior of libpng15 and earlier, via a new PNG_MAXIMUM_INFLATE_WINDOW + option for png_set_options(). Added png-fix-itxt and png-fix-too-far-back to the built programs and removed warnings from the source code and timepng that are revealed as a result. @@ -5051,7 +5063,8 @@ Version 1.6.15beta04 [November 4, 2014] Version 1.6.15beta05 [November 5, 2014] Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in example.c, pngtest.c, and applications in the contrib directory. - Avoid out-of-bounds memory access in png_user_version_check(). + Fixed an out-of-range read in png_user_version_check() (Bug report from + Qixue Xiao, CVE-2015-8540). Simplified and future-proofed png_user_version_check(). Fixed GCC unsigned int->float warnings. Various versions of GCC seem to generate warnings when an unsigned value is implicitly @@ -5134,14 +5147,16 @@ Version 1.6.17beta01 [January 29, 2015] Added testing of png_set_packing() to pngvalid.c Regenerated configure scripts in the *.tar distributions with libtool-2.4.4 Implement previously untested cases of libpng transforms in pngvalid.c - Fixed byte order in 2-byte filler, in png_do_read_filler(). + Fixed byte order in png_do_read_filler() with 16-bit input. Previously + the high and low bytes of the filler, from png_set_filler() or from + png_set_add_alpha(), were read in the wrong order. Made the check for out-of-range values in png_set_tRNS() detect values that are exactly 2^bit_depth, and work on 16-bit platforms. Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47. Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and pngset.c to avoid warnings about dead code. Added "& 0xff" to many instances of expressions that are typecast - to (png_byte), to avoid Coverity gripes. + to (png_byte), to avoid Coverity warnings. Version 1.6.17beta02 [February 7, 2015] Work around one more Coverity-scan dead-code warning. @@ -5205,6 +5220,827 @@ Version 1.6.17rc06 [March 23, 2015] Version 1.6.17 [March 26, 2015] No changes. +Version 1.6.18beta01 [April 1, 2015] + Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros. They + have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves + bug report by Andrew Church). + Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c. This + fixes some arithmetic errors that caused some tests to fail on + some 32-bit platforms (Bug reports by Peter Breitenlohner [i686] + and Petr Gajdos [i586]). + +Version 1.6.18beta02 [April 26, 2015] + Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler + (Bug report by Viktor Szakats). + +Version 1.6.18beta03 [May 6, 2015] + Replaced "unexpected" with an integer (0xabadca11) in pngset.c + where a long was expected, to avoid a compiler warning when PNG_DEBUG > 1. + Added contrib/examples/simpleover.c, to demonstrate how to handle + alpha compositing of multiple images, using the "simplified API" + and an example PNG generation tool, contrib/examples/genpng.c + (John Bowler). + +Version 1.6.18beta04 [May 20, 2015] + PNG_RELEASE_BUILD replaces tests where the code depended on the build base + type and can be defined on the command line, allowing testing in beta + builds (John Bowler). + Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds. + Avoid a harmless potential integer overflow in png_XYZ_from_xy() (Bug + report from Christopher Ferris). + +Version 1.6.18beta05 [May 31, 2015] + Backport filter selection code from libpng-1.7.0beta51, to combine + sub_row, up_row, avg_row, and paeth_row into try_row and tst_row. + Changed png_voidcast(), etc., to voidcast(), etc., in contrib/tools/pngfix.c + to avoid confusion with the libpng private macros. + Fixed old cut&paste bug in the weighted filter selection code in + pngwutil.c, introduced in libpng-0.95, March 1997. + +Version 1.6.18beta06 [June 1, 2015] + Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the + compiled library size. It never worked properly and as far as we can + tell, no one uses it. The png_set_filter_heuristics() and + png_set_filter_heuristics_fixed() APIs are retained but deprecated + and do nothing. + +Version 1.6.18beta07 [June 6, 2015] + Removed non-working progressive reader 'skip' function. This + function has apparently never been used. It was implemented + to support back-door modification of png_struct in libpng-1.4.x + but (because it does nothing and cannot do anything) was apparently + never tested (John Bowler). + Fixed cexcept.h in which GCC 5 now reports that one of the auto + variables in the Try macro needs to be volatile to prevent value + being lost over the setjmp (John Bowler). + Fixed NO_WRITE_FILTER and -Wconversion build breaks (John Bowler). + Fix g++ build breaks (John Bowler). + Quieted some Coverity issues in pngfix.c, png-fix-itxt.c, pngvalid.c, + pngstest.c, and pngimage.c. Most seem harmless, but png-fix-itxt + would only work with iTXt chunks with length 255 or less. + Added #ifdef's to contrib/examples programs so people don't try + to compile them without the minimum required support enabled + (suggested by Flavio Medeiros). + +Version 1.6.18beta08 [June 30, 2015] + Eliminated the final two Coverity defects (insecure temporary file + handling in contrib/libtests/pngstest.c; possible overflow of + unsigned char in contrib/tools/png-fix-itxt.c). To use the "secure" + file handling, define PNG_USE_MKSTEMP, otherwise "tmpfile()" will + be used. + Removed some unused WEIGHTED_FILTER macros from png.h and pngstruct.h + +Version 1.6.18beta09 [July 5, 2015] + Removed some useless typecasts from contrib/tools/png-fix-itxt.c + Fixed a new signed-unsigned comparison in pngrtran.c (Max Stepin). + Replaced arbitrary use of 'extern' with #define PNG_LINKAGE_*. To + preserve API compatibility, the new defines all default to "extern" + (requested by Jan Nijtmans). + +Version 1.6.18rc01 [July 9, 2015] + Belatedly added Mans Rullgard and James Yu to the list of Contributing + Authors. + +Version 1.6.18rc02 [July 12, 2015] + Restored unused FILTER_HEURISTIC macros removed at libpng-1.6.18beta08 + to png.h to avoid compatibility warnings. + +Version 1.6.18rc03 [July 15, 2015] + Minor changes to the man page + +Version 1.6.18 [July 23, 2015] + No changes. + +Version 1.6.19beta01 [July 30, 2015] + Updated obsolete information about the simplified API macros in the + manual pages (Bug report by Arc Riley). + Avoid potentially dereferencing NULL info_ptr in png_info_init_3(). + Rearranged png.h to put the major sections in the same order as + in libpng17. + Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and + PNG_WEIGHT_FACTOR macros. + Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler + (Bug report by Viktor Szakats). Several warnings remain and are + unavoidable, where we test for overflow. + Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c + Fixed uninitialized variable in contrib/gregbook/rpng2-x.c + +Version 1.6.19beta02 [August 19, 2015] + Moved config.h.in~ from the "libpng_autotools_files" list to the + "libpng_autotools_extra" list in autogen.sh because it was causing a + false positive for missing files (bug report by Robert C. Seacord). + Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c + to suppress clang warnings (Bug report by Viktor Szakats). + Fixed some bad links in the man page. + Changed "n bit" to "n-bit" in comments. + Added signed/unsigned 16-bit safety net. This removes the dubious + 0x8000 flag definitions on 16-bit systems. They aren't supported + yet the defs *probably* work, however it seems much safer to do this + and be advised if anyone, contrary to advice, is building libpng 1.6 + on a 16-bit system. It also adds back various switch default clauses + for GCC; GCC errors out if they are not present (with an appropriately + high level of warnings). + Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert + Seacord). + Fixed the recently reported 1's complement security issue by replacing + the value that is illegal in the PNG spec, in both signed and unsigned + values, with 0. Illegal unsigned values (anything greater than or equal + to 0x80000000) can still pass through, but since these are not illegal + in ANSI-C (unlike 0x80000000 in the signed case) the checking that + occurs later can catch them (John Bowler). + +Version 1.6.19beta03 [September 26, 2015] + Fixed png_save_int_32 when int is not 2's complement (John Bowler). + Updated libpng16 with all the recent test changes from libpng17, + including changes to pngvalid.c to ensure that the original, + distributed, version of contrib/visupng/cexcept.h can be used + (John Bowler). + pngvalid contains the correction to the use of SAVE/STORE_ + UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More + tests contain the --strict option to detect warnings and the + pngvalid-standard test has been corrected so that it does not + turn on progressive-read. There is a separate test which does + that. (John Bowler) + Also made some signed/unsigned fixes. + Make pngstest error limits version specific. Splitting the machine + generated error structs out to a file allows the values to be updated + without changing pngstest.c itself. Since libpng 1.6 and 1.7 have + slightly different error limits this simplifies maintenance. The + makepngs.sh script has also been updated to more accurately reflect + current problems in libpng 1.7 (John Bowler). + Incorporated new test PNG files into make check. tests/pngstest-* + are changed so that the new test files are divided into 8 groups by + gamma and alpha channel. These tests have considerably better code + and pixel-value coverage than contrib/pngsuite; however,coverage is + still incomplete (John Bowler). + Removed the '--strict' in 1.6 because of the double-gamma-correction + warning, updated pngstest-errors.h for the errors detected with the + new contrib/testspngs PNG test files (John Bowler). + +Version 1.6.19beta04 [October 15, 2015] + Worked around rgb-to-gray issues in libpng 1.6. The previous + attempts to ignore the errors in the code aren't quite enough to + deal with the 'channel selection' encoding added to libpng 1.7; abort. + pngvalid.c is changed to drop this encoding in prior versions. + Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a + macro, therefore the argument list cannot contain preprocessing + directives. Make sure pow is a function where this happens. This is + a minimal safe fix, the issue only arises in non-performance-critical + code (bug report by Curtis Leach, fix by John Bowler). + Added sPLT support to pngtest.c + +Version 1.6.19rc01 [October 23, 2015] + No changes. + +Version 1.6.19rc02 [October 31, 2015] + Prevent setting or writing over-length PLTE chunk (Cosmin Truta). + Silently truncate over-length PLTE chunk while reading. + Libpng incorrectly calculated the output rowbytes when the application + decreased either the number of channels or the bit depth (or both) in + a user transform. This was safe; libpng overallocated buffer space + (potentially by quite a lot; up to 4 times the amount required) but, + from 1.5.4 on, resulted in a png_error (John Bowler). + +Version 1.6.19rc03 [November 3, 2015] + Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed(). + Clarified COPYRIGHT information to state explicitly that versions + are derived from previous versions. + Removed much of the long list of previous versions from png.h and + libpng.3. + +Version 1.6.19rc04 [November 5, 2015] + Fixed new bug with CRC error after reading an over-length palette + (bug report by Cosmin Truta) (CVE-2015-8126). + +Version 1.6.19 [November 12, 2015] + Cleaned up coding style in png_handle_PLTE(). + +Version 1.6.20beta01 [November 20, 2015] + Avoid potential pointer overflow/underflow in png_handle_sPLT() and + png_handle_pCAL() (Bug report by John Regehr). + +Version 1.6.20beta02 [November 23, 2015] + Fixed incorrect implementation of png_set_PLTE() that uses png_ptr + not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126 + vulnerability. Fixes CVE-2015-8472. + +Version 1.6.20beta03 [November 24, 2015] + Backported tests from libpng-1.7.0beta69. + +Version 1.6.20rc01 [November 26, 2015] + Fixed an error in handling of bad zlib CMINFO field in pngfix, found by + American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't + immediately fault a bad CMINFO field; instead a 'too far back' error + happens later (at least some times). pngfix failed to limit CMINFO to + the allowed values but then assumed that window_bits was in range, + triggering an assert. The bug is mostly harmless; the PNG file cannot + be fixed. + +Version 1.6.20rc02 [November 29, 2015] + In libpng 1.6 zlib initialization was changed to use the window size + in the zlib stream, not a fixed value. This causes some invalid images, + where CINFO is too large, to display 'correctly' if the rest of the + data is valid. This provides a workaround for zlib versions where the + error arises (ones that support the API change to use the window size + in the stream). + +Version 1.6.20 [December 3, 2015] + No changes. + +Version 1.6.21beta01 [December 11, 2015] + Fixed syntax "$(command)" in tests/pngstest that some shells other than + bash could not parse (Bug report by Nelson Beebe). Use `command` instead. + +Version 1.6.21beta02 [December 14, 2015] + Moved png_check_keyword() from pngwutil.c to pngset.c + Removed LE/BE dependencies in pngvalid, to 'fix' the current problem + in the BigEndian tests by not testing it, making the BE code the same + as the LE version. + Fixes to pngvalid for various reduced build configurations (eliminate unused + statics) and a fix for the case in rgb_to_gray when the digitize option + reduces graylo to 0, producing a large error. + +Version 1.6.21beta03 [December 18, 2015] + Widened the 'limit' check on the internally calculated error limits in + the 'DIGITIZE' case (the code used prior to 1.7 for rgb_to_gray error + checks) and changed the check to only operate in non-release builds + (base build type not RC or RELEASE.) + Fixed undefined behavior in pngvalid.c, undefined because + (png_byte) << shift is undefined if it changes the signed bit + (because png_byte is promoted to int). The libpng exported functions + png_get_uint_32 and png_get_uint_16 handle this. (Bug reported by + David Drysdale as a result of reports from UBSAN in clang 3.8). + This changes pngvalid to use BE random numbers; this used to produce + errors but these should not be fixed as a result of the previous changes. + +Version 1.6.21rc01 [January 4, 2016] + In projects/vstudio, combined readme.txt and WARNING into README.txt + +Version 1.6.21rc02 [January 7, 2016] + Relocated assert() in contrib/tools/pngfix.c, bug found by American + Fuzzy Lop, reported by Brian Carpenter. + Marked 'limit' UNUSED in transform_range_check(). This only affects + release builds. + +Version 1.6.21 [January 15, 2016] + Worked around a false-positive Coverity issue in pngvalid.c. + +Version 1.6.22beta01 [January 23, 2016] + Changed PNG_USE_MKSTEMP to __COVERITY__ to select alternate + "tmpfile()" implementation in contrib/libtests/pngstest.c + Fixed NO_STDIO build of pngunknown.c to skip calling png_init_io() + if there is no stdio.h support. + Added a png_image_write_to_memory() API and a number of assist macros + to allow an application that uses the simplified API write to bypass + stdio and write directly to memory. + Added some warnings (png.h) and some check code to detect *possible* + overflow in the ROW_STRIDE and simplified image SIZE macros. This + disallows image width/height/format that *might* overflow. This is + a quiet API change that limits in-memory image size (uncompressed) to + less than 4GByte and image row size (stride) to less than 2GByte. + Revised workaround for false-positive Coverity issue in pngvalid.c. + +Version 1.6.22beta02 [February 8, 2016] + Only use exit(77) in configure builds. + Corrected error in PNG_IMAGE_PNG_SIZE_MAX. This new macro underreported + the palette size because it failed to take into account that the memory + palette has to be expanded to full RGB when it is written to PNG. + Updated CMakeLists.txt, added supporting scripts/gen*.cmake.in + and test.cmake.in (Roger Leigh). + Relaxed limit checks on gamma values in pngrtran.c. As suggested in + the comments gamma values outside the range currently permitted + by png_set_alpha_mode are useful for HDR data encoding. These values + are already permitted by png_set_gamma so it is reasonable caution to + extend the png_set_alpha_mode range as HDR imaging systems are starting + to emerge. + +Version 1.6.22beta03 [March 9, 2016] + Added a common-law trademark notice and export control information + to the LICENSE file, png.h, and the man page. + Restored "& 0xff" in png_save_uint_16() and png_save_uint_32() that + were accidentally removed from libpng-1.6.17. + Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h + (Robert C. Seacord). + Removed dubious "#if INT_MAX" test from png.h that was added to + libpng-1.6.19beta02 (John Bowler). + Add ${INCLUDES} in scripts/genout.cmake.in (Bug report by Nixon Kwok). + Updated LICENSE to say files in the contrib directory are not + necessarily under the libpng license, and that some makefiles have + other copyright owners. + Added INTEL-SSE2 support (Mike Klein and Matt Sarett, Google, Inc.). + Made contrib/libtests/timepng more robust. The code no longer gives + up/fails on invalid PNG data, it just skips it (with error messages). + The code no longer fails on PNG files with data beyond IEND. Options + exist to use png_read_png (reading the whole image, not by row) and, in + that case, to apply any of the supported transforms. This makes for + more realistic testing; the decoded data actually gets used in a + meaningful fashion (John Bowler). + Fixed some misleading indentation (Krishnaraj Bhat). + +Version 1.6.22beta04 [April 5, 2016] + Force GCC compilation to C89 if needed (Dagobert Michelsen). + SSE filter speed improvements for bpp=3: + memcpy-free implementations of load3() / store3(). + call load3() only when needed at the end of a scanline. + +Version 1.6.22beta05 [April 27, 2016] + Added PNG_FAST_FILTERS macro (defined as + PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_UP). + Various fixes for contrib/libtests/timepng.c + Moved INTEL-SSE code from pngpriv.h into contrib/intel/intel_sse.patch. + Fixed typo (missing underscore) in #define PNG_READ_16_TO_8_SUPPORTED + (Bug report by Y.Ohashik). + +Version 1.6.22beta06 [May 5, 2016] + Rebased contrib/intel_sse.patch. + Quieted two Coverity issues in contrib/libtests/timepng.c. + Fixed issues with scripts/genout.cmake.in (David Capello, Nixon Kwok): + Added support to use multiple directories in ZLIBINCDIR variable, + Fixed CMAKE_C_FLAGS with multiple values when genout is compiled on MSVC, + Fixed pnglibconf.c compilation on OS X including the sysroot path. + +Version 1.6.22rc01 [May 14, 2016] + No changes. + +Version 1.6.22rc02 [May 16, 2016] + Removed contrib/timepng from default build; it does not build on platforms + that don't supply clock_gettime(). + +Version 1.6.22rc03 [May 17, 2016] + Restored contrib/timepng to default build but check for the presence + of clock_gettime() in configure.ac and Makefile.am. + +Version 1.6.22 [May 26, 2016] + No changes. + +Version 1.6.23beta01 [May 29, 2016] + Stop a potential memory leak in png_set_tRNS() (Bug report by Ted Ying). + Fixed the progressive reader to handle empty first IDAT chunk properly + (patch by Timothy Nikkel). This bug was introduced in libpng-1.6.0 and + only affected the libpng16 branch. + Added tests in pngvalid.c to check zero-length IDAT chunks in various + positions. Fixed the sequential reader to handle these more robustly + (John Bowler). + +Version 1.6.23rc01 [June 2, 2016] + Corrected progressive read input buffer in pngvalid.c. The previous version + the code invariably passed just one byte at a time to libpng. The intent + was to pass a random number of bytes in the range 0..511. + Moved sse2 prototype from pngpriv.h to contrib/intel/intel_sse.patch. + Added missing ")" in pngerror.c (Matt Sarrett). + +Version 1.6.23rc02 [June 4, 2016] + Fixed undefined behavior in png_push_save_buffer(). Do not call + memcpy() with a null source, even if count is zero (Leon Scroggins III). + +Version 1.6.23 [June 9, 2016] + Fixed bad link to RFC2083 in png.5 (Nikola Forro). + +Version 1.6.24beta01 [June 11, 2016] + Avoid potential overflow of the PNG_IMAGE_SIZE macro. This macro + is not used within libpng, but is used in some of the examples. + +Version 1.6.24beta02 [June 23, 2016] + Correct filter heuristic overflow handling. This was broken when the + write filter code was moved out-of-line; if there is a single filter and + the heuristic sum overflows the calculation of the filtered line is not + completed. In versions prior to 1.6 the code was duplicated in-line + and the check not performed, so the filter operation completed; however, + in the multi-filter case where the sum is performed the 'none' filter would + be selected if all the sums overflowed, even if it wasn't in the filter + list. The fix to the first problem is simply to provide PNG_SIZE_MAX as + the current lmins sum value; this means the sum can never exceed it and + overflows silently. A reasonable compiler that does choose to inline + the code will simply eliminate the sum check. + The fix to the second problem is to use high precision arithmetic (this is + implemented in 1.7), however a simple safe fix here is to chose the lowest + numbered filter in the list from png_set_filter (this only works if the + first problem is also fixed) (John Bowler). + Use a more efficient absolute value calculation on SSE2 (Matthieu Darbois). + Fixed the case where PNG_IMAGE_BUFFER_SIZE can overflow in the application + as a result of the application using an increased 'row_stride'; previously + png_image_finish_read only checked for overflow on the base calculation of + components. (I.e. it checked for overflow of a 32-bit number on the total + number of pixel components in the output format, not the possibly padded row + length and not the number of bytes, which for linear formats is twice the + number of components.) + MSVC does not like '-(unsigned)', so replaced it with 0U-(unsigned) + MSVC does not like (uInt) = -(unsigned) (i.e. as an initializer), unless + the conversion is explicitly invoked by a cast. + Put the SKIP definition in the correct place. It needs to come after the + png.h include (see all the other .c files in contrib/libtests) because it + depends on PNG_LIBPNG_VER. + Removed the three compile warning options from the individual project + files into the zlib.props globals. It increases the warning level from 4 + to All and adds a list of the warnings that need to be turned off. This is + semi-documentary; the intent is to tell libpng users which warnings have + been examined and judged non-fixable at present. The warning about + structure padding is fixable, but it would be a signficant change (moving + structure members around). + +Version 1.6.24beta03 [July 4, 2016] + Optimized absolute value calculation in filter selection, similar to + code in the PAETH decoder in pngrutil.c. Build with PNG_USE_ABS to + use this. + Added pngcp to the build together with a pngcp.dfa configuration test. + Added high resolution timing to pngcp. + Added "Common linking failures" section to INSTALL. + Relocated misplaced #endif in png.c sRGB profile checking. + Fixed two Coverity issues in pngcp.c. + +Version 1.6.24beta04 [July 8, 2016] + Avoid filter-selection heuristic sum calculations in cases where only one + filter is a candidate for selection. This trades off code size (added + private png_setup_*_row_only() functions) for speed. + +Version 1.6.24beta05 [July 13, 2016] + Fixed some indentation to comply with our coding style. + Added contrib/tools/reindent. + +Version 1.6.24beta06 [July 18, 2016] + Fixed more indentation to comply with our coding style. + Eliminated unnecessary tests of boolean png_isaligned() vs 0. + +Version 1.6.24rc01 [July 25, 2016] + No changes. + +Version 1.6.24rc02 [August 1, 2016] + Conditionally compile SSE2 headers in contrib/intel/intel_sse.patch + Conditionally compile png_decompress_chunk(). + +Version 1.6.24rc03 [August 2, 2016] + Conditionally compile ARM_NEON headers in pngpriv.h + Updated contrib/intel/intel_sse.patch + +Version 1.6.24[August 4, 2016] + No changes. + +Version 1.6.25beta01 [August 12, 2016] + Reject oversized iCCP profile immediately. + Cleaned up PNG_DEBUG compile of pngtest.c. + Conditionally compile png_inflate(). + +Version 1.6.25beta02 [August 18, 2016] + Don't install pngcp; it conflicts with pngcp in the pngtools package. + Minor editing of INSTALL, (whitespace, added copyright line) + +Version 1.6.25rc01 [August 24, 2016] + No changes. + +Version 1.6.25rc02 [August 29, 2016] + Added MIPS support (Mandar Sahastrabuddhe ). + Only the UP filter is currently implemented. + +Version 1.6.25rc03 [August 29, 2016] + Rebased contrib/intel/intel_sse.patch after the MIPS implementation. + +Version 1.6.25rc04 [August 30, 2016] + Added MIPS support for SUB, AVG, and PAETH filters (Mandar Sahastrabuddhe). + +Version 1.6.25rc05 [August 30, 2016] + Rebased contrib/intel/intel_sse.patch after the MIPS implementation update.. + +Version 1.6.25 [September 1, 2016] + No changes. + +Version 1.6.26beta01 [September 26, 2016] + Fixed handling zero length IDAT in pngfix (bug report by Agostino Sarubbo, + bugfix by John Bowler). + Do not issue a png_error() on read in png_set_pCAL() because png_handle_pCAL + has allocated memory that libpng needs to free. + Conditionally compile png_set_benign_errors() in pngread.c and pngtest.c + Issue a png_benign_error instead of a png_error on ADLER32 mismatch + while decoding compressed data chunks. + Changed PNG_ZLIB_VERNUM to ZLIB_VERNUM in pngpriv.h, pngstruct.h, and + pngrutil.c. + If CRC handling of critical chunks has been set to PNG_CRC_QUIET_USE, + ignore the ADLER32 checksum in the IDAT chunk as well as the chunk CRCs. + Issue png_benign_error() on ADLER32 checksum mismatch instead of png_error(). + Add tests/badcrc.png and tests/badadler.png to tests/pngtest. + Merged pngtest.c with libpng-1.7.0beta84/pngtest.c + +Version 1.6.26beta02 [October 1, 2016] + Updated the documentation about CRC and ADLER32 handling. + Quieted 117 warnings from clang-3.8 in pngtrans.c, pngread.c, + pngwrite.c, pngunknown.c, and pngvalid.c. + Quieted 58 (out of 144) -Wconversion compiler warnings by changing + flag definitions in pngpriv.h from 0xnnnn to 0xnnnnU and trivial changes + in png.c, pngread.c, and pngwutil.c. + +Version 1.6.26beta03 [October 2, 2016] + Removed contrib/libtests/*.orig and *.rej that slipped into the tarballs. + Quieted the 86 remaining -Wconversion compiler warnings by + revising the png_isaligned() macro and trivial changes in png.c, + pngerror.c, pngget.c, pngmem.c, pngset.c, pngrtran.c, pngrutil.c, + pngwtran.c, pngwrite.c, and pngwutil.c. + +Version 1.6.26beta04 [October 3, 2016] + Quieted (bogus?) clang warnings about "absolute value has no effect" + when PNG_USE_ABS is defined. + Fixed offsets in contrib/intel/intel_sse.patch + +Version 1.6.26beta05 [October 6, 2016] + Changed integer constant 4294967294 to unsigned 4294967294U in pngconf.h + to avoid a signed/unsigned compare in the preprocessor. + +Version 1.6.26beta06 [October 7, 2016] + Use zlib-1.2.8.1 inflateValidate() instead of inflateReset2() to + optionally avoid ADLER32 evaluation. + +Version 1.6.26rc01 [October 12, 2016] + No changes. + +Version 1.6.26 [October 20, 2016] + Cosmetic change, "ptr != 0" to "ptr != NULL" in png.c and pngrutil.c + Despammed email addresses (replaced "@" with " at "). + +Version 1.6.27beta01 [November 2, 2016] + Restrict the new ADLER32-skipping to IDAT chunks. It broke iCCP chunk + handling: an erroneous iCCP chunk would throw a png_error and reject the + entire PNG image instead of rejecting just the iCCP chunk with a warning, + if built with zlib-1.2.8.1. + +Version 1.6.27rc01 [December 27, 2016] + Control ADLER32 checking with new PNG_IGNORE_ADLER32 option. Fixes + an endless loop when handling erroneous ADLER32 checksums; bug + introduced in libpng-1.6.26. + Removed the use of a macro containing the pre-processor 'defined' + operator. It is unclear whether this is valid; a macro that + "generates" 'defined' is not permitted, but the use of the word + "generates" within the C90 standard seems to imply more than simple + substitution of an expression itself containing a well-formed defined + operation. + Added ARM support to CMakeLists.txt (Andreas Franek). + +Version 1.6.27 [December 29, 2016] + Fixed a potential null pointer dereference in png_set_text_2() (bug report + and patch by Patrick Keshishian, CVE-2016-10087). + +Version 1.6.28rc01 [January 3, 2017] + Fixed arm/aarch64 detection in CMakeLists.txt (Gianfranco Costamagna). + Added option to Cmake build allowing a custom location of zlib to be + specified in a scenario where libpng is being built as a subproject + alongside zlib by another project (Sam Serrels). + Changed png_ptr->options from a png_byte to png_uint_32, to accomodate + up to 16 options. + +Version 1.6.28rc02 [January 4, 2017] + Added "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna). + Moved SSE2 optimization code into the main libpng source directory. + Configure libpng with "configure --enable-intel-sse" or compile + libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it. + +Version 1.6.28rc03 [January 4, 2017] + Backed out the SSE optimization and last CMakeLists.txt to allow time for QA. + +Version 1.6.28 [January 5, 2017] + No changes. + +Version 1.6.29beta01 [January 12, 2017] + Readded "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna). + Moved SSE2 optimization code into the main libpng source directory. + Configure libpng with "configure --enable-intel-sse" or compile + libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it. + Simplified conditional compilation in pngvalid.c, for AIX (Michael Felt). + +Version 1.6.29beta02 [February 22, 2017] + Avoid conditional directives that break statements in pngrutil.c (Romero + Malaquias) + The contrib/examples/pngtopng.c recovery code was in the wrong "if" + branches; the comments were correct. + Added code for PowerPC VSX optimisation (Vadim Barkov). + +Version 1.6.29beta03 [March 1, 2017] + Avoid potential overflow of shift operations in png_do_expand() (Aaron Boxer). + Change test ZLIB_VERNUM >= 0x1281 to ZLIB_VERNUM >= 0x1290 in pngrutil.c + because Solaris 11 distributes zlib-1.2.8.f that is older than 1.2.8.1, + as suggested in zlib FAQ, item 24. + Suppress clang warnings about implicit sign changes in png.c + +Version 1.6.29 [March 16, 2017] + No changes. + +Version 1.6.30beta01 [April 1, 2017] + Added missing "$(CPPFLAGS)" to the compile line for c.pic.o in + makefile.linux and makefile.solaris-x86 (Cosmin). + Revised documentation of png_get_error_ptr() in the libpng manual. + Silence clang -Wcomma and const drop warnings (Viktor Szakats). + Update Sourceforge URLs in documentation (https instead of http). + +Version 1.6.30beta02 [April 22, 2017] + Document need to check for integer overflow when allocating a pixel + buffer for multiple rows in contrib/gregbook, contrib/pngminus, + example.c, and in the manual (suggested by Jaeseung Choi). This + is similar to the bug reported against pngquant in CVE-2016-5735. + Removed reference to the obsolete PNG_SAFE_LIMITS macro in the documentation. + +Version 1.6.30beta03 [May 22, 2017] + Check for integer overflow in contrib/visupng and contrib/tools/genpng. + Do not double evaluate CMAKE_SYSTEM_PROCESSOR in CMakeLists.txt. + Test CMAKE_HOST_WIN32 instead of WIN32 in CMakeLists.txt. + Fix some URL in documentation. + +Version 1.6.30beta04 [June 7, 2017] + Avoid writing an empty IDAT when the last IDAT exactly fills the + compression buffer (bug report by Brian Baird). This bug was + introduced in libpng-1.6.0. + +Version 1.6.30rc01 [June 14, 2017] + No changes. + +Version 1.6.30rc02 [June 25, 2017] + Update copyright year in pnglibconf.h, make ltmain.sh executable. + Add a reference to the libpng.download site in README. + +Version 1.6.30 [June 28, 2017] + No changes. + +Version 1.6.31beta01 [July 5, 2017] + Guard the definition of _POSIX_SOURCE in pngpriv.h (AIX already defines it; + bug report by Michael Felt). + Revised pngpriv.h to work around failure to compile arm/filter_neon.S + ("typedef" directive is unrecognized by the assembler). The problem + was introduced in libpng-1.6.30beta01. + Added "Requires: zlib" to libpng.pc.in (Pieter Neerincx). + Added special case for FreeBSD in arm/filter_neon.S (Maya Rashish). + +Version 1.6.31beta02 [July 8, 2017] + Added instructions for disabling hardware optimizations in INSTALL. + Added "--enable-hardware-optimizations" configuration flag to enable + or disable all hardware optimizations with one flag. + +Version 1.6.31beta03 [July 9, 2017] + Updated CMakeLists.txt to add INTEL_SSE and MIPS_MSA platforms. + Changed "int" to "png_size_t" in intel/filter_sse2.c to prevent + possible integer overflow (Bug report by John Bowler). + Quieted "declaration after statement" warnings in intel/filter_sse2.c. + Added scripts/makefile-linux-opt, which has hardware optimizations enabled. + +Version 1.6.31beta04 [July 11, 2017] + Removed one of the GCC-7.1.0 'strict-overflow' warnings that result when + integers appear on both sides of a compare. Worked around the others by + forcing the strict-overflow setting in the relevant functions to a level + where they are not reported (John Bowler). + Changed "FALL THROUGH" comments to "FALLTHROUGH" because GCC doesn't like + the space. + Worked around some C-style casts from (void*) because g++ 5.4.0 objects + to them. + Increased the buffer size for 'sprint' to pass the gcc 7.1.0 'sprint + overflow' check that is on by default with -Wall -Wextra. + +Version 1.6.31beta05 [July 13, 2017] + Added eXIf chunk support. + +Version 1.6.31beta06 [July 17, 2017] + Added a minimal eXIf chunk (with Orientation and FocalLengthIn35mmFilm + tags) to pngtest.png. + +Version 1.6.31beta07 [July 18, 2017] + Revised the eXIf chunk in pngtest.png to fix "Bad IFD1 Directory" warning. + +Version 1.6.31rc01 [July 19, 2017] + No changes. + +Version 1.6.31rc02 [July 25, 2017] + Fixed typo in example.c (png_free_image should be png_image_free) (Bug + report by John Smith) + +Version 1.6.31 [July 27, 2017] + No changes. + +Version 1.6.32beta01 [July 31, 2017] + Avoid possible NULL dereference in png_handle_eXIf when benign_errors + are allowed. Avoid leaking the input buffer "eXIf_buf". + Eliminated png_ptr->num_exif member from pngstruct.h and added num_exif + to arguments for png_get_eXIf() and png_set_eXIf(). + Added calls to png_handle_eXIf(() in pngread.c and png_write_eXIf() in + pngwrite.c, and made various other fixes to png_write_eXIf(). + Changed name of png_get_eXIF and png_set_eXIf() to png_get_eXIf_1() and + png_set_eXIf_1(), respectively, to avoid breaking API compatibility + with libpng-1.6.31. + +Version 1.6.32beta02 [August 1, 2017] + Updated contrib/libtests/pngunknown.c with eXIf chunk. + +Version 1.6.32beta03 [August 2, 2017] + Initialized btoa[] in pngstest.c + Stop memory leak when returning from png_handle_eXIf() with an error + (Bug report from the OSS-fuzz project). + +Version 1.6.32beta04 [August 2, 2017] + Replaced local eXIf_buf with info_ptr-eXIf_buf in png_handle_eXIf(). + Update libpng.3 and libpng-manual.txt about eXIf functions. + +Version 1.6.32beta05 [August 2, 2017] + Restored png_get_eXIf() and png_set_eXIf() to maintain API compatability. + +Version 1.6.32beta06 [August 2, 2017] + Removed png_get_eXIf_1() and png_set_eXIf_1(). + +Version 1.6.32beta07 [August 3, 2017] + Check length of all chunks except IDAT against user limit to fix an + OSS-fuzz issue (Fixes CVE-2017-12652). + +Version 1.6.32beta08 [August 3, 2017] + Check length of IDAT against maximum possible IDAT size, accounting + for height, rowbytes, interlacing and zlib/deflate overhead. + Restored png_get_eXIf_1() and png_set_eXIf_1(), because strlen(eXIf_buf) + does not work (the eXIf chunk data can contain zeroes). + +Version 1.6.32beta09 [August 3, 2017] + Require cmake-2.8.8 in CMakeLists.txt. Revised symlink creation, + no longer using deprecated cmake LOCATION feature (Clifford Yapp). + Fixed five-byte error in the calculation of IDAT maximum possible size. + +Version 1.6.32beta10 [August 5, 2017] + Moved chunk-length check into a png_check_chunk_length() private + function (Suggested by Max Stepin). + Moved bad pngs from tests to contrib/libtests/crashers + Moved testing of bad pngs into a separate tests/pngtest-badpngs script + Added the --xfail (expected FAIL) option to pngtest.c. It writes XFAIL + in the output but PASS for the libpng test. + Require cmake-3.0.2 in CMakeLists.txt (Clifford Yapp). + Fix "const" declaration info_ptr argument to png_get_eXIf_1() and the + num_exif argument to png_get_eXIf_1() (Github Issue 171). + +Version 1.6.32beta11 [August 7, 2017] + Added "eXIf" to "chunks_to_ignore[]" in png_set_keep_unknown_chunks(). + Added huge_IDAT.png and empty_ancillary_chunks.png to testpngs/crashers. + Make pngtest --strict, --relax, --xfail options imply -m (multiple). + Removed unused chunk_name parameter from png_check_chunk_length(). + Relocated setting free_me for eXIf data, to stop an OSS-fuzz leak. + Initialize profile_header[] in png_handle_iCCP() to fix OSS-fuzz issue. + Initialize png_ptr->row_buf[0] to 255 in png_read_row() to fix OSS-fuzz UMR. + Attempt to fix a UMR in png_set_text_2() to fix OSS-fuzz issue. + Increase minimum zlib stream from 9 to 14 in png_handle_iCCP(), to account + for the minimum 'deflate' stream, and relocate the test to a point + after the keyword has been read. + Check that the eXIf chunk has at least 2 bytes and begins with "II" or "MM". + +Version 1.6.32rc01 [August 18, 2017] + Added a set of "huge_xxxx_chunk.png" files to contrib/testpngs/crashers, + one for each known chunk type, with length = 2GB-1. + Check for 0 return from png_get_rowbytes() and added some (size_t) typecasts + in contrib/pngminus/*.c to stop some Coverity issues (162705, 162706, + and 162707). + Renamed chunks in contrib/testpngs/crashers to avoid having files whose + names differ only in case; this causes problems with some platforms + (github issue #172). + +Version 1.6.32rc02 [August 22, 2017] + Added contrib/oss-fuzz directory which contains files used by the oss-fuzz + project (https://github.com/google/oss-fuzz/tree/master/projects/libpng). + +Version 1.6.32 [August 24, 2017] + No changes. + +Version 1.6.33beta01 [August 28, 2017] + Added PNGMINUS_UNUSED macro to contrib/pngminus/p*.c and added missing + parenthesis in contrib/pngminus/pnm2png.c (bug report by Christian Hesse). + Fixed off-by-one error in png_do_check_palette_indexes() (Bug report + by Mick P., Source Forge Issue #269). + +Version 1.6.33beta02 [September 3, 2017] + Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc + to fix shortlived oss-fuzz issue 3234. + Compute a larger limit on IDAT because some applications write a deflate + buffer for each row (Bug report by Andrew Church). + Use current date (DATE) instead of release-date (RDATE) in last + changed date of contrib/oss-fuzz files. + Enabled ARM support in CMakeLists.txt (Bernd Kuhls). + +Version 1.6.33beta03 [September 14, 2017] + Fixed incorrect typecast of some arguments to png_malloc() and + png_calloc() that were png_uint_32 instead of png_alloc_size_t + (Bug report by "irwir" in Github libpng issue #175). + Use pnglibconf.h.prebuilt when building for ANDROID with cmake (Github + issue 162, by rcdailey). + +Version 1.6.33rc01 [September 20, 2017] + Initialize memory allocated by png_inflate to zero, using memset, to + stop an oss-fuzz "use of uninitialized value" detection in png_set_text_2() + due to truncated iTXt or zTXt chunk. + Initialize memory allocated by png_read_buffer to zero, using memset, to + stop an oss-fuzz "use of uninitialized value" detection in + png_icc_check_tag_table() due to truncated iCCP chunk. + Removed a redundant test (suggested by "irwir" in Github issue #180). + +Version 1.6.33rc02 [September 23, 2017] + Added an interlaced version of each file in contrib/pngsuite. + Relocate new memset() call in pngrutil.c. + Removed more redundant tests (suggested by "irwir" in Github issue #180). + Add support for loading images with associated alpha in the Simplified + API (Samuel Williams). + +Version 1.6.33 [September 28, 2017] + Revert contrib/oss-fuzz/libpng_read_fuzzer.cc to libpng-1.6.32 state. + Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc + Add end_info structure and png_read_end() to the libpng fuzzer. + +Version 1.6.34 [September 29, 2017] + Removed contrib/pngsuite/i*.png; some of these were incorrect and caused + test failures. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement @@ -5212,3 +6048,4 @@ to subscribe) or to glennrp at users.sourceforge.net Glenn R-P +#endif diff --git a/src/third-party/libpng/CMakeLists.txt b/src/third-party/libpng/CMakeLists.txt index f062a23a1..3b8d786cb 100644 --- a/src/third-party/libpng/CMakeLists.txt +++ b/src/third-party/libpng/CMakeLists.txt @@ -1,28 +1,57 @@ # CMakeLists.txt -# Copyright (C) 2007-2015 Glenn Randers-Pehrson +# Copyright (C) 2007,2009-2017 Glenn Randers-Pehrson +# Written by Christian Ehrlicher, 2007 +# Revised by Roger Lowman, 2009-2010 +# Revised by Clifford Yapp, 2011-2012 +# Revised by Roger Leigh, 2016 +# Revised by Andreas Franek, 2016 # This code is released under the libpng license. # For conditions of distribution and use, see the disclaimer # and license in png.h -cmake_minimum_required(VERSION 2.4.4) -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) +cmake_minimum_required(VERSION 3.0.2) +cmake_policy(VERSION 3.0.2) + +# Set MacOSX @rpath usage globally. +if (POLICY CMP0020) + cmake_policy(SET CMP0020 NEW) +endif(POLICY CMP0020) +if (POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) +endif(POLICY CMP0042) +# Use new variable expansion policy. +if (POLICY CMP0053) + cmake_policy(SET CMP0053 NEW) +endif(POLICY CMP0053) +if (POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif(POLICY CMP0054) set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo") -project(libpng C) +project(libpng ASM C) enable_testing() set(PNGLIB_MAJOR 1) set(PNGLIB_MINOR 6) -set(PNGLIB_RELEASE 17) +set(PNGLIB_RELEASE 34) set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR}) set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE}) +include(GNUInstallDirs) + # needed packages -find_package(ZLIB REQUIRED) -include_directories(${ZLIB_INCLUDE_DIR}) + +#Allow users to specify location of Zlib, +# Useful if zlib is being built alongside this as a sub-project +option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" OFF) + +IF(NOT PNG_BUILD_ZLIB) + find_package(ZLIB REQUIRED) + include_directories(${ZLIB_INCLUDE_DIR}) +ENDIF(NOT PNG_BUILD_ZLIB) if(NOT WIN32) find_library(M_LIBRARY @@ -47,32 +76,391 @@ option(PNG_FRAMEWORK "Build OS X framework" OFF) option(PNG_DEBUG "Build with debug output" OFF) option(PNGARG "Disable ANSI-C prototypes" OFF) +option(PNG_HARDWARE_OPTIMIZATIONS "Enable Hardware Optimizations" ON) + + +set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names") +set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings") + +if(PNG_HARDWARE_OPTIMIZATIONS) +# set definitions and sources for arm +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") + set(PNG_ARM_NEON_POSSIBLE_VALUES check on off) + set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations: + check: (default) use internal checking code; + off: disable the optimizations; + on: turn on unconditionally.") + set_property(CACHE PNG_ARM_NEON PROPERTY STRINGS + ${PNG_ARM_NEON_POSSIBLE_VALUES}) + list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index) + if(index EQUAL -1) + message(FATAL_ERROR + " PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]") + elseif(NOT ${PNG_ARM_NEON} STREQUAL "off") + set(libpng_arm_sources + arm/arm_init.c + arm/filter_neon.S + arm/filter_neon_intrinsics.c) + + if(${PNG_ARM_NEON} STREQUAL "on") + add_definitions(-DPNG_ARM_NEON_OPT=2) + elseif(${PNG_ARM_NEON} STREQUAL "check") + add_definitions(-DPNG_ARM_NEON_CHECK_SUPPORTED) + endif() + else() + add_definitions(-DPNG_ARM_NEON_OPT=0) + endif() +endif() + +# set definitions and sources for powerpc +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*" ) + set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off) + set(PNG_POWERPC_VSX "on" CACHE STRING "Enable POWERPC VSX optimizations: + off: disable the optimizations.") + set_property(CACHE PNG_POWERPC_VSX PROPERTY STRINGS + ${PNG_POWERPC_VSX_POSSIBLE_VALUES}) + list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index) + if(index EQUAL -1) + message(FATAL_ERROR + " PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]") + elseif(NOT ${PNG_POWERPC_VSX} STREQUAL "off") + set(libpng_powerpc_sources + powerpc/powerpc_init.c + powerpc/filter_vsx_intrinsics.c) + if(${PNG_POWERPC_VSX} STREQUAL "on") + add_definitions(-DPNG_POWERPC_VSX_OPT=2) + endif() + else() + add_definitions(-DPNG_POWERPC_VSX_OPT=0) + endif() +endif() + +# set definitions and sources for intel +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*" ) + set(PNG_INTEL_SSE_POSSIBLE_VALUES on off) + set(PNG_INTEL_SSE "on" CACHE STRING "Enable INTEL_SSE optimizations: + off: disable the optimizations") + set_property(CACHE PNG_INTEL_SSE PROPERTY STRINGS + ${PNG_INTEL_SSE_POSSIBLE_VALUES}) + list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index) + if(index EQUAL -1) + message(FATAL_ERROR + " PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]") + elseif(NOT ${PNG_INTEL_SSE} STREQUAL "off") + set(libpng_intel_sources + intel/intel_init.c + intel/filter_sse2_intrinsics.c) + if(${PNG_INTEL_SSE} STREQUAL "on") + add_definitions(-DPNG_INTEL_SSE_OPT=1) + endif() + else() + add_definitions(-DPNG_INTEL_SSE_OPT=0) + endif() +endif() + +# set definitions and sources for MIPS +if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*" ) + set(PNG_MIPS_MSA_POSSIBLE_VALUES on off) + set(PNG_MIPS_MSA "on" CACHE STRING "Enable MIPS_MSA optimizations: + off: disable the optimizations") + set_property(CACHE PNG_MIPS_MSA PROPERTY STRINGS + ${PNG_MIPS_MSA_POSSIBLE_VALUES}) + list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index) + if(index EQUAL -1) + message(FATAL_ERROR + " PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]") + elseif(NOT ${PNG_MIPS_MSA} STREQUAL "off") + set(libpng_mips_sources + mips/mips_init.c + mips/filter_msa_intrinsics.c) + if(${PNG_MIPS_MSA} STREQUAL "on") + add_definitions(-DPNG_MIPS_MSA_OPT=2) + endif() + else() + add_definitions(-DPNG_MIPS_MSA_OPT=0) + endif() +endif() +endif(PNG_HARDWARE_OPTIMIZATIONS) + # SET LIBNAME set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR}) # to distinguish between debug and release lib set(CMAKE_DEBUG_POSTFIX "d") -# Use the prebuilt pnglibconf.h file from the scripts folder -# TODO: fix this by building with awk; without this no cmake build can be -# configured directly (to do so indirectly use your local awk to build a -# pnglibconf.h in the build directory.) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt - ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h) +include(CheckCSourceCompiles) +option(ld-version-script "Enable linker version script" ON) +if(ld-version-script AND NOT APPLE) + # Check if LD supports linker scripts. + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" "VERS_1 { + global: sym; + local: *; +}; + +VERS_2 { + global: sym2; + main; +} VERS_1; +") + set(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'") + check_c_source_compiles("void sym(void) {} +void sym2(void) {} +int main(void) {return 0;} +" HAVE_LD_VERSION_SCRIPT) + if(NOT HAVE_LD_VERSION_SCRIPT) + set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE} "-Wl,-M -Wl,${CMAKE_CURRENT_BINARY_DIR}/conftest.map") + check_c_source_compiles("void sym(void) {} +void sym2(void) {} +int main(void) {return 0;} +" HAVE_SOLARIS_LD_VERSION_SCRIPT) + endif() + set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE}) + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map") +endif() + +# Find symbol prefix. Likely obsolete and unnecessary with recent +# toolchains (it's not done in many other projects). +function(symbol_prefix) + set(SYMBOL_PREFIX) + + execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E" "-" + INPUT_FILE /dev/null + OUTPUT_VARIABLE OUT + RESULT_VARIABLE STATUS) + + if(CPP_FAIL) + message(WARNING "Failed to run the C preprocessor") + endif() + + string(REPLACE "\n" ";" OUT "${OUT}") + foreach(line ${OUT}) + string(REGEX MATCH "^PREFIX=" found_match "${line}") + if(found_match) + STRING(REGEX REPLACE "^PREFIX=(.*\)" "\\1" prefix "${line}") + string(REGEX MATCH "__USER_LABEL_PREFIX__" found_match "${prefix}") + if(found_match) + STRING(REGEX REPLACE "(.*)__USER_LABEL_PREFIX__(.*)" "\\1\\2" prefix "${prefix}") + endif() + set(SYMBOL_PREFIX "${prefix}") + endif() + endforeach() + + message(STATUS "Symbol prefix: ${SYMBOL_PREFIX}") + set(SYMBOL_PREFIX "${SYMBOL_PREFIX}" PARENT_SCOPE) +endfunction() + +if(UNIX) + symbol_prefix() +endif() + +find_program(AWK NAMES gawk awk) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +if(NOT AWK OR ANDROID) + # No awk available to generate sources; use pre-built pnglibconf.h + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt + ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h) + add_custom_target(genfiles) # Dummy +else() + include(CMakeParseArguments) + # Generate .chk from .out with awk + # generate_chk(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]]) + function(generate_chk) + set(options) + set(oneValueArgs INPUT OUTPUT) + set(multiValueArgs DEPENDS) + cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if (NOT _GC_INPUT) + message(FATAL_ERROR "Invalid arguments. generate_out requires input.") + endif() + if (NOT _GC_OUTPUT) + message(FATAL_ERROR "Invalid arguments. generate_out requires output.") + endif() + + add_custom_command(OUTPUT "${_GC_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + "-DINPUT=${_GC_INPUT}" + "-DOUTPUT=${_GC_OUTPUT}" + -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake" + DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endfunction() + + # Generate .out from .c with awk + # generate_out(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]]) + function(generate_out) + set(options) + set(oneValueArgs INPUT OUTPUT) + set(multiValueArgs DEPENDS) + cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if (NOT _GO_INPUT) + message(FATAL_ERROR "Invalid arguments. generate_out requires input.") + endif() + if (NOT _GO_OUTPUT) + message(FATAL_ERROR "Invalid arguments. generate_out requires output.") + endif() + + add_custom_command(OUTPUT "${_GO_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + "-DINPUT=${_GO_INPUT}" + "-DOUTPUT=${_GO_OUTPUT}" + -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake" + DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endfunction() + + # Generate specific source file with awk + # generate_source(OUTPUT outputfile [DEPENDS dep1 [dep2...]]) + function(generate_source) + set(options) + set(oneValueArgs OUTPUT) + set(multiValueArgs DEPENDS) + cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if (NOT _GSO_OUTPUT) + message(FATAL_ERROR "Invalid arguments. generate_source requires output.") + endif() + + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}" + COMMAND "${CMAKE_COMMAND}" + "-DOUTPUT=${_GSO_OUTPUT}" + -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake" + DEPENDS ${_GSO_DEPENDS} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endfunction() + + # Copy file + function(generate_copy source destination) + add_custom_command(OUTPUT "${destination}" + COMMAND "${CMAKE_COMMAND}" -E remove "${destination}" + COMMAND "${CMAKE_COMMAND}" -E copy "${source}" + "${destination}" + DEPENDS "${source}") + endfunction() + + # Generate scripts/pnglibconf.h + generate_source(OUTPUT "scripts/pnglibconf.c" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk" + "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h") + + # Generate pnglibconf.c + generate_source(OUTPUT "pnglibconf.c" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk" + "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h") + + if(PNG_PREFIX) + set(PNGLIBCONF_H_EXTRA_DEPENDS + "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/macro.lst") + set(PNGPREFIX_H_EXTRA_DEPENDS + "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out") + endif() + + generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out") + + # Generate pnglibconf.h + generate_source(OUTPUT "pnglibconf.h" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" + ${PNGLIBCONF_H_EXTRA_DEPENDS}) + + generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h") + + generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" + "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" + "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out") + + # Generate pngprefix.h + generate_source(OUTPUT "pngprefix.h" + DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS}) + + generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h") + + generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" + "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt") + + generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" + "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" + "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h") + + generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def") + + add_custom_target(symbol-check DEPENDS + "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk") + + generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" + "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym") + generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" + "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers") + + add_custom_target(genvers DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers") + add_custom_target(gensym DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym") + + add_custom_target("genprebuilt" + COMMAND "${CMAKE_COMMAND}" + "-DOUTPUT=scripts/pnglibconf.h.prebuilt" + -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + + # A single target handles generation of all generated files. If + # they are dependend upon separately by multiple targets, this + # confuses parallel make (it would require a separate top-level + # target for each file to track the dependencies properly). + add_custom_target(genfiles DEPENDS + "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym" + "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers" + "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" + "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" + "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" + "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h" + "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" + "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c" + "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" + "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" + "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" + "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" + "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out") +endif(NOT AWK OR ANDROID) + # OUR SOURCES set(libpng_public_hdrs png.h pngconf.h - ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h + "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" ) -set(libpng_sources - ${libpng_public_hdrs} +set(libpng_private_hdrs + pngpriv.h pngdebug.h pnginfo.h - pngpriv.h pngstruct.h +) +if(AWK AND NOT ANDROID) + list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h") +endif() +set(libpng_sources + ${libpng_public_hdrs} + ${libpng_private_hdrs} png.c pngerror.c pngget.c @@ -88,6 +476,10 @@ set(libpng_sources pngwrite.c pngwtran.c pngwutil.c + ${libpng_arm_sources} + ${libpng_intel_sources} + ${libpng_mips_sources} + ${libpng_powerpc_sources} ) set(pngtest_sources pngtest.c @@ -98,7 +490,18 @@ set(pngvalid_sources set(pngstest_sources contrib/libtests/pngstest.c ) -# SOME NEEDED DEFINITIONS +set(pngunknown_sources + contrib/libtests/pngunknown.c +) +set(pngimage_sources + contrib/libtests/pngimage.c +) +set(pngfix_sources + contrib/tools/pngfix.c +) +set(png_fix_itxt_sources + contrib/tools/png-fix-itxt.c +) if(MSVC) add_definitions(-D_CRT_SECURE_NO_DEPRECATE) @@ -114,33 +517,59 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIR}) unset(PNG_LIB_TARGETS) if(PNG_SHARED) - add_library(${PNG_LIB_NAME} SHARED ${libpng_sources}) - set(PNG_LIB_TARGETS ${PNG_LIB_NAME}) + add_library(png SHARED ${libpng_sources}) + set(PNG_LIB_TARGETS png) + set_target_properties(png PROPERTIES OUTPUT_NAME ${PNG_LIB_NAME}) + add_dependencies(png genfiles) if(MSVC) # msvc does not append 'lib' - do it here to have consistent name - set_target_properties(${PNG_LIB_NAME} PROPERTIES PREFIX "lib") - set_target_properties(${PNG_LIB_NAME} PROPERTIES IMPORT_PREFIX "lib") + set_target_properties(png PROPERTIES PREFIX "lib") + set_target_properties(png PROPERTIES IMPORT_PREFIX "lib") + endif() + target_link_libraries(png ${ZLIB_LIBRARY} ${M_LIBRARY}) + + if(UNIX AND AWK) + if(HAVE_LD_VERSION_SCRIPT) + set_target_properties(png PROPERTIES LINK_FLAGS + "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'") + elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT) + set_target_properties(png PROPERTIES LINK_FLAGS + "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'") + endif() endif() - target_link_libraries(${PNG_LIB_NAME} ${ZLIB_LIBRARY} ${M_LIBRARY}) endif() if(PNG_STATIC) # does not work without changing name - set(PNG_LIB_NAME_STATIC ${PNG_LIB_NAME}_static) - add_library(${PNG_LIB_NAME_STATIC} STATIC ${libpng_sources}) - list(APPEND PNG_LIB_TARGETS ${PNG_LIB_NAME_STATIC}) + set(PNG_LIB_NAME_STATIC png_static) + add_library(png_static STATIC ${libpng_sources}) + add_dependencies(png_static genfiles) + # MSVC doesn't use a different file extension for shared vs. static + # libs. We are able to change OUTPUT_NAME to remove the _static + # for all other platforms. + if(NOT MSVC) + set_target_properties(png_static PROPERTIES + OUTPUT_NAME "${PNG_LIB_NAME}" + CLEAN_DIRECT_OUTPUT 1) + else() + set_target_properties(png_static PROPERTIES + OUTPUT_NAME "${PNG_LIB_NAME}_static" + CLEAN_DIRECT_OUTPUT 1) + endif() + list(APPEND PNG_LIB_TARGETS png_static) if(MSVC) # msvc does not append 'lib' - do it here to have consistent name - set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES PREFIX "lib") + set_target_properties(png_static PROPERTIES PREFIX "lib") endif() - target_link_libraries(${PNG_LIB_NAME_STATIC} ${ZLIB_LIBRARY} ${M_LIBRARY}) + target_link_libraries(png_static ${ZLIB_LIBRARY} ${M_LIBRARY}) endif() if(PNG_FRAMEWORK) - set(PNG_LIB_NAME_FRAMEWORK ${PNG_LIB_NAME}_framework) - add_library(${PNG_LIB_NAME_FRAMEWORK} SHARED ${libpng_sources}) - list(APPEND PNG_LIB_TARGETS ${PNG_LIB_NAME_FRAMEWORK}) - set_target_properties(${PNG_LIB_NAME_FRAMEWORK} PROPERTIES + set(PNG_LIB_NAME_FRAMEWORK png_framework) + add_library(png_framework SHARED ${libpng_sources}) + add_dependencies(png_framework genfiles) + list(APPEND PNG_LIB_TARGETS png_framework) + set_target_properties(png_framework PROPERTIES FRAMEWORK TRUE FRAMEWORK_VERSION ${PNGLIB_VERSION} MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PNGLIB_MAJOR}.${PNGLIB_MINOR} @@ -149,7 +578,7 @@ if(PNG_FRAMEWORK) XCODE_ATTRIBUTE_INSTALL_PATH "@rpath" PUBLIC_HEADER "${libpng_public_hdrs}" OUTPUT_NAME png) - target_link_libraries(${PNG_LIB_NAME_FRAMEWORK} ${ZLIB_LIBRARY} ${M_LIBRARY}) + target_link_libraries(png_framework ${ZLIB_LIBRARY} ${M_LIBRARY}) endif() if(NOT PNG_LIB_TARGETS) @@ -160,79 +589,233 @@ if(NOT PNG_LIB_TARGETS) endif() if(PNG_SHARED AND WIN32) - set_target_properties(${PNG_LIB_NAME} PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL) + set_target_properties(png PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL) endif() +function(png_add_test) + set(options) + set(oneValueArgs NAME COMMAND) + set(multiValueArgs OPTIONS FILES) + cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (NOT _PAT_NAME) + message(FATAL_ERROR "Invalid arguments. png_add_test requires name.") + endif() + if (NOT _PAT_COMMAND) + message(FATAL_ERROR "Invalid arguments. png_add_test requires command.") + endif() + + set(TEST_OPTIONS "${_PAT_OPTIONS}") + set(TEST_FILES "${_PAT_FILES}") + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/test.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" @ONLY) + if(CMAKE_MAJOR_VERSION GREATER 2) # have generator expressions + add_test(NAME "${_PAT_NAME}" + COMMAND "${CMAKE_COMMAND}" + "-DLIBPNG=$" + "-DTEST_COMMAND=$" + -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake") + else() # old 2.x add_test; limited and won't work well on Windows + # Note LIBPNG is a dummy value as there are no generator expressions + add_test("${_PAT_NAME}" "${CMAKE_COMMAND}" + "-DLIBPNG=${CMAKE_CURRENT_BINARY_DIR}/libpng.so" + "-DTEST_COMMAND=./${_PAT_COMMAND}" + -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake") + endif() +endfunction() + if(PNG_TESTS AND PNG_SHARED) - # does not work with msvc due to png_lib_ver issue + # Find test PNG files by globbing, but sort lists to ensure + # consistency between different filesystems. + file(GLOB PNGSUITE_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/*.png") + list(SORT PNGSUITE_PNGS) + file(GLOB TEST_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/*.png") + list(SORT TEST_PNGS) + + set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png") + add_executable(pngtest ${pngtest_sources}) - target_link_libraries(pngtest ${PNG_LIB_NAME}) - add_test(pngtest ./pngtest ${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png) - # + target_link_libraries(pngtest png) + + png_add_test(NAME pngtest COMMAND pngtest FILES "${PNGTEST_PNG}") + add_executable(pngvalid ${pngvalid_sources}) - target_link_libraries(pngvalid ${PNG_LIB_NAME}) - add_test(pngvalid ./pngvalid) + target_link_libraries(pngvalid png) + + png_add_test(NAME pngvalid-gamma-16-to-8 + COMMAND pngvalid OPTIONS --gamma-16-to-8) + png_add_test(NAME pngvalid-gamma-alpha-mode + COMMAND pngvalid OPTIONS --gamma-alpha-mode) + png_add_test(NAME pngvalid-gamma-background + COMMAND pngvalid OPTIONS --gamma-background) + png_add_test(NAME pngvalid-gamma-expand16-alpha-mode + COMMAND pngvalid OPTIONS --gamma-alpha-mode --expand16) + png_add_test(NAME pngvalid-gamma-expand16-background + COMMAND pngvalid OPTIONS --gamma-background --expand16) + png_add_test(NAME pngvalid-gamma-expand16-transform + COMMAND pngvalid OPTIONS --gamma-transform --expand16) + png_add_test(NAME pngvalid-gamma-sbit + COMMAND pngvalid OPTIONS --gamma-sbit) + png_add_test(NAME pngvalid-gamma-threshold + COMMAND pngvalid OPTIONS --gamma-threshold) + png_add_test(NAME pngvalid-gamma-transform + COMMAND pngvalid OPTIONS --gamma-transform) + png_add_test(NAME pngvalid-progressive-interlace-standard + COMMAND pngvalid OPTIONS --standard --progressive-read --interlace) + png_add_test(NAME pngvalid-progressive-size + COMMAND pngvalid OPTIONS --size --progressive-read) + png_add_test(NAME pngvalid-progressive-standard + COMMAND pngvalid OPTIONS --standard --progressive-read) + png_add_test(NAME pngvalid-standard + COMMAND pngvalid OPTIONS --standard) + png_add_test(NAME pngvalid-transform + COMMAND pngvalid OPTIONS --transform) + add_executable(pngstest ${pngstest_sources}) - target_link_libraries(pngstest ${PNG_LIB_NAME}) - add_test(pngstest ./pngstest - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g01.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g02.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g04.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g16.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn2c08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn2c16.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p01.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p02.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p04.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn4a08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn4a16.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn6a08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn6a16.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g01.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g02.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g04.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn2c16.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn3p08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbgn2c16.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbgn3p08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbrn2c08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbwn0g16.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbwn3p08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbyn3p08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n0g08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n2c08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n3p08.png - ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp1n3p08.png - ) + target_link_libraries(pngstest png) + + foreach(gamma_type 1.8 linear none sRGB) + foreach(alpha_type none alpha) + set(PNGSTEST_FILES) + foreach(test_png ${TEST_PNGS}) + string(REGEX MATCH ".*-linear[-.].*" TEST_PNG_LINEAR "${test_png}") + string(REGEX MATCH ".*-sRGB[-.].*" TEST_PNG_SRGB "${test_png}") + string(REGEX MATCH ".*-1.8[-.].*" TEST_PNG_G18 "${test_png}") + string(REGEX MATCH ".*-alpha-.*" TEST_PNG_ALPHA "${test_png}") + + set(TEST_PNG_VALID TRUE) + + if(TEST_PNG_ALPHA) + if (NOT "${alpha_type}" STREQUAL "alpha") + set(TEST_PNG_VALID FALSE) + endif() + else() + if ("${alpha_type}" STREQUAL "alpha") + set(TEST_PNG_VALID FALSE) + endif() + endif() + + if(TEST_PNG_LINEAR) + if(NOT "${gamma_type}" STREQUAL "linear") + set(TEST_PNG_VALID FALSE) + endif() + elseif(TEST_PNG_SRGB) + if(NOT "${gamma_type}" STREQUAL "sRGB") + set(TEST_PNG_VALID FALSE) + endif() + elseif(TEST_PNG_G18) + if(NOT "${gamma_type}" STREQUAL "1.8") + set(TEST_PNG_VALID FALSE) + endif() + else() + if(NOT "${gamma_type}" STREQUAL "none") + set(TEST_PNG_VALID FALSE) + endif() + endif() + + if(TEST_PNG_VALID) + list(APPEND PNGSTEST_FILES "${test_png}") + endif() + endforeach() + # Should already be sorted, but sort anyway to be certain. + list(SORT PNGSTEST_FILES) + png_add_test(NAME pngstest-${gamma_type}-${alpha_type} + COMMAND pngstest + OPTIONS --tmpfile "${gamma_type}-${alpha_type}-" --log + FILES ${PNGSTEST_FILES}) + endforeach() + endforeach() + + add_executable(pngunknown ${pngunknown_sources}) + target_link_libraries(pngunknown png) + + png_add_test(NAME pngunknown-discard COMMAND pngunknown OPTIONS --strict default=discard FILES "${PNGTEST_PNG}") + png_add_test(NAME pngunknown-IDAT COMMAND pngunknown OPTIONS --strict default=discard IDAT=save FILES "${PNGTEST_PNG}") + png_add_test(NAME pngunknown-if-safe COMMAND pngunknown OPTIONS --strict default=if-safe FILES "${PNGTEST_PNG}") + png_add_test(NAME pngunknown-sAPI COMMAND pngunknown OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save FILES "${PNGTEST_PNG}") + png_add_test(NAME pngunknown-save COMMAND pngunknown OPTIONS --strict default=save FILES "${PNGTEST_PNG}") + png_add_test(NAME pngunknown-sTER COMMAND pngunknown OPTIONS --strict sTER=if-safe FILES "${PNGTEST_PNG}") + png_add_test(NAME pngunknown-vpAg COMMAND pngunknown OPTIONS --strict vpAg=if-safe FILES "${PNGTEST_PNG}") + + add_executable(pngimage ${pngimage_sources}) + target_link_libraries(pngimage png) + + png_add_test(NAME pngimage-quick COMMAND pngimage OPTIONS --list-combos --log FILES ${PNGSUITE_PNGS}) + png_add_test(NAME pngimage-full COMMAND pngimage OPTIONS --exhaustive --list-combos --log FILES ${PNGSUITE_PNGS}) endif() -# Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set -IF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) - SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib") -ENDIF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) +if(PNG_SHARED) + add_executable(pngfix ${pngfix_sources}) + target_link_libraries(pngfix png) + set(PNG_BIN_TARGETS pngfix) + + add_executable(png-fix-itxt ${png_fix_itxt_sources}) + target_link_libraries(png-fix-itxt ${ZLIB_LIBRARY} ${M_LIBRARY}) + list(APPEND PNG_BIN_TARGETS png-fix-itxt) +endif() # Set a variable with CMake code which: # Creates a symlink from src to dest (if possible) or alternatively # copies if different. -macro(CREATE_SYMLINK SRC_FILE DEST_FILE) - FILE(REMOVE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}) - if(WIN32 AND NOT CYGWIN AND NOT MSYS) - ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE} - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SRC_FILE}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SRC_FILE}" ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE} - DEPENDS ${PNG_LIB_TARGETS} - ) - ADD_CUSTOM_TARGET(${DEST_FILE}_COPY ALL DEPENDS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}) - else(WIN32 AND NOT CYGWIN AND NOT MSYS) - get_filename_component(LINK_TARGET "${SRC_FILE}" NAME) - execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - endif(WIN32 AND NOT CYGWIN AND NOT MSYS) -endmacro() +include(CMakeParseArguments) + +function(CREATE_SYMLINK DEST_FILE) + + cmake_parse_arguments(S "" "FILE;TARGET" "" ${ARGN}) + + if(NOT S_TARGET AND NOT S_FILE) + message(FATAL_ERROR "Specify either a TARGET or a FILE for CREATE_SYMLINK to link to.") + endif(NOT S_TARGET AND NOT S_FILE) + + if(S_TARGET AND S_FILE) + message(FATAL_ERROR "CREATE_SYMLINK called with both source file ${S_FILE} and build target ${S_TARGET} arguments - can only handle 1 type per call.") + endif(S_TARGET AND S_FILE) + + if(S_FILE) + # If we don't need to symlink something that's coming from a build target, + # we can go ahead and symlink/copy at configure time. + + if(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS) + execute_process( + COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${S_FILE} ${DEST_FILE} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + else(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS) + execute_process( + COMMAND ${CMAKE_COMMAND} -E create_symlink ${S_FILE} ${DEST_FILE} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ) + endif(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS) + endif(S_FILE) + + if(S_TARGET) + # We need to use generator expressions, which can be a bit tricky, so for + # simplicity make the symlink a POST_BUILD step and use the TARGET + # signature of add_custom_command. + + if(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS) + add_custom_command(TARGET ${S_TARGET} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_if_different $ $/${DEST_FILE} + ) + else(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS) + add_custom_command(TARGET ${S_TARGET} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E create_symlink $ $/${DEST_FILE} + ) + endif(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS) + + endif(S_TARGET) + +endfunction() + +# Create source generation scripts. +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genout.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/gensrc.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake @ONLY) + # libpng is a library so default to 'lib' if(NOT DEFINED CMAKE_INSTALL_LIBDIR) @@ -251,31 +834,21 @@ if(NOT WIN32 OR CYGWIN OR MINGW) set(LIBS "-lz -lm") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY) - CREATE_SYMLINK(${PNGLIB_NAME}.pc libpng.pc) + CREATE_SYMLINK(libpng.pc FILE ${PNGLIB_NAME}.pc) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY) - CREATE_SYMLINK(${PNGLIB_NAME}-config libpng-config) + CREATE_SYMLINK(libpng-config FILE ${PNGLIB_NAME}-config) endif(NOT WIN32 OR CYGWIN OR MINGW) # SET UP LINKS if(PNG_SHARED) - set_target_properties(${PNG_LIB_NAME} PROPERTIES -# VERSION 16.${PNGLIB_RELEASE}.1.6.17 + set_target_properties(png PROPERTIES +# VERSION 16.${PNGLIB_RELEASE}.1.6.34 VERSION 16.${PNGLIB_RELEASE}.0 SOVERSION 16 CLEAN_DIRECT_OUTPUT 1) endif() -if(PNG_STATIC) - # MSVC doesn't use a different file extension for shared vs. static - # libs. We are able to change OUTPUT_NAME to remove the _static - # for all other platforms. - if(NOT MSVC) - set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES - OUTPUT_NAME ${PNG_LIB_NAME} - CLEAN_DIRECT_OUTPUT 1) - endif() -endif() # If CMake > 2.4.x, we set a variable used below to export # targets to an export file. @@ -298,26 +871,20 @@ if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) if(PNG_SHARED) # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin if(CYGWIN OR MINGW) - get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME} LOCATION_${CMAKE_BUILD_TYPE}) - CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} - DESTINATION ${CMAKE_INSTALL_LIBDIR}) + CREATE_SYMLINK(libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} TARGET png) + install(FILES $/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif(CYGWIN OR MINGW) if(NOT WIN32) - get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME} LOCATION_${CMAKE_BUILD_TYPE}) - CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_SHARED_LIBRARY_SUFFIX}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_SHARED_LIBRARY_SUFFIX} - DESTINATION ${CMAKE_INSTALL_LIBDIR}) + CREATE_SYMLINK(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png) + install(FILES $/libpng${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif(NOT WIN32) endif(PNG_SHARED) if(PNG_STATIC) if(NOT WIN32 OR CYGWIN OR MINGW) - get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME_STATIC} LOCATION_${CMAKE_BUILD_TYPE}) - CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_STATIC_LIBRARY_SUFFIX}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_STATIC_LIBRARY_SUFFIX} - DESTINATION ${CMAKE_INSTALL_LIBDIR}) + CREATE_SYMLINK( libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static) + install(FILES $/libpng${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif(NOT WIN32 OR CYGWIN OR MINGW) endif() endif() @@ -334,6 +901,11 @@ if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL ) endif(NOT WIN32 OR CYGWIN OR MINGW) endif() +if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL ) + install(TARGETS ${PNG_BIN_TARGETS} + RUNTIME DESTINATION bin) +endif() + if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) # Install man pages if(NOT PNG_MAN_DIR) @@ -342,7 +914,7 @@ if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) install(FILES libpng.3 libpngpf.3 DESTINATION ${PNG_MAN_DIR}/man3) install(FILES png.5 DESTINATION ${PNG_MAN_DIR}/man5) # Install pkg-config files - if(NOT WIN32 OR CYGWIN OR MINGW) + if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config @@ -351,7 +923,7 @@ if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config DESTINATION bin) - endif(NOT WIN32 OR CYGWIN OR MINGW) + endif(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW) endif() # On versions of CMake that support it, create an export file CMake @@ -371,4 +943,3 @@ endif() # to create msvc import lib for mingw compiled shared lib # pexports libpng.dll > libpng.def # lib /def:libpng.def /machine:x86 - diff --git a/src/third-party/libpng/INSTALL b/src/third-party/libpng/INSTALL index a294ffe63..e8edb7240 100644 --- a/src/third-party/libpng/INSTALL +++ b/src/third-party/libpng/INSTALL @@ -1,24 +1,26 @@ -Installing libpng + Installing libpng Contents - I. Simple installation - II. Rebuilding the configure scripts - III. Using scripts/makefile* - IV. Using cmake - V. Directory structure - VI. Building with project files - VII. Building with makefiles -VIII. Configuring libpng for 16-bit platforms - IX. Configuring for DOS - X. Configuring for Medium Model - XI. Prepending a prefix to exported symbols - XII. Configuring for compiler xxx: -XIII. Removing unwanted object code - XIV. Changes to the build and configuration of libpng in libpng-1.5.x - XV. Setjmp/longjmp issues - XVI. Other sources of information about libpng + I. Simple installation + II. Rebuilding the configure scripts + III. Using scripts/makefile* + IV. Using cmake + V. Directory structure + VI. Building with project files + VII. Building with makefiles + VIII. Configuring libpng for 16-bit platforms + IX. Configuring for DOS + X. Configuring for Medium Model + XI. Prepending a prefix to exported symbols + XII. Configuring for compiler xxx: + XIII. Removing unwanted object code + XIV. Enabling or disabling hardware optimizations + XV. Changes to the build and configuration of libpng in libpng-1.5.x + XVI. Setjmp/longjmp issues + XVII. Common linking failures + XVIII. Other sources of information about libpng I. Simple installation @@ -47,7 +49,9 @@ If configure does not work on your system, or if you have a need to change configure.ac or Makefile.am, and you have a reasonably up-to-date set of tools, running ./autogen.sh in a git clone before running ./configure may fix the problem. To be really sure that you -aren't using any of the included pre-built scripts, you can do this: +aren't using any of the included pre-built scripts, especially if you +are building from a tar distribution instead of a git distribution, +do this: ./configure --enable-maintainer-mode make maintainer-clean @@ -75,8 +79,8 @@ Or you can use one of the "projects" in the "projects" directory. Before installing libpng, you must first install zlib, if it is not already on your system. zlib can usually be found -wherever you got libpng; otherwise go to http://zlib.net. You can place -zlib in in the same directory as libpng or in another directory. +wherever you got libpng; otherwise go to https://zlib.net/. You can +place zlib in the same directory as libpng or in another directory. If your system already has a preinstalled zlib you will still need to have access to the zlib.h and zconf.h include files that @@ -87,22 +91,24 @@ standard library search path, put ZLIBLIB, ZLIBINC, CPPFLAGS, LDFLAGS, and LD_LIBRARY_PATH in your environment before running "make test" or "make distcheck": -ZLIBLIB=/path/to/lib export ZLIBLIB -ZLIBINC=/path/to/include export ZLIBINC -CPPFLAGS="-I$ZLIBINC" export CPPFLAGS -LDFLAGS="-L$ZLIBLIB" export LDFLAGS -LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH + ZLIBLIB=/path/to/lib export ZLIBLIB + ZLIBINC=/path/to/include export ZLIBINC + CPPFLAGS="-I$ZLIBINC" export CPPFLAGS + LDFLAGS="-L$ZLIBLIB" export LDFLAGS + LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH If you are using one of the makefile scripts, put ZLIBLIB and ZLIBINC -in your environment and type "make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test". +in your environment and type + + make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test IV. Using cmake If you want to use "cmake" (see www.cmake.org), type - cmake . -DCMAKE_INSTALL_PREFIX=/path - make - make install + cmake . -DCMAKE_INSTALL_PREFIX=/path + make + make install As when using the simple configure method described above, "/path" points to the installation directory where you want to put the libpng "lib", "include", @@ -116,8 +122,8 @@ or "zlib128") so that you have directories called "zlib" and "libpng". Your directory structure should look like this: - .. (the parent directory) - libpng (this directory) + .. (the parent directory) + libpng (this directory) INSTALL (this file) README *.h, *.c => libpng source files @@ -160,10 +166,15 @@ VII. Building with makefiles Copy the file (or files) that you need from the scripts directory into this directory, for example - MSDOS example: copy scripts\makefile.msc makefile - copy scripts\pnglibconf.h.prebuilt pnglibconf.h - UNIX example: cp scripts/makefile.std makefile - cp scripts/pnglibconf.h.prebuilt pnglibconf.h +MSDOS example: + + copy scripts\makefile.msc makefile + copy scripts\pnglibconf.h.prebuilt pnglibconf.h + +UNIX example: + + cp scripts/makefile.std makefile + cp scripts/pnglibconf.h.prebuilt pnglibconf.h Read the makefile to see if you need to change any source or target directories to match your preferences. @@ -239,7 +250,7 @@ libpng are compiled. All the defines end in _SUPPORTED. If you are never going to use a capability, you can change the #define to #undef before recompiling libpng and save yourself code and data space, or you can turn off individual capabilities with defines that begin with -PNG_NO_. +"PNG_NO_". In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead. @@ -271,7 +282,57 @@ library to fail if they call functions not available in your library. The size of the library itself should not be an issue, because only those sections that are actually used will be loaded into memory. -XIV. Changes to the build and configuration of libpng in libpng-1.5.x +XIV. Enabling or disabling hardware optimizations + +Certain hardware capabilites, such as the Intel SSE instructions, +are normally detected at run time. Enable them with configure options +such as one of + + --enable-arm-neon=yes + --enable-mips-msa=yes + --enable-intel-sse=yes + --enable-powerpc-vsx=yes + +or enable them all at once with + + --enable-hardware-optimizations=yes + +or, if you are not using "configure", you can use one +or more of + + CPPFLAGS += "-DPNG_ARM_NEON" + CPPFLAGS += "-DPNG_MIPS_MSA" + CPPFLAGS += "-DPNG_INTEL_SSE" + CPPFLAGS += "-DPNG_POWERPC_VSX" + +See for example scripts/makefile.linux-opt + +If you wish to avoid using them, +you can disable them via the configure option + + --disable-hardware-optimizations + +to disable them all, or + + --enable-intel-sse=no + +to disable a particular one, +or via compiler-command options such as + + CPPFLAGS += "-DPNG_ARM_NEON_OPT=0, -DPNG_MIPS_MSA_OPT=0, + -DPNG_INTEL_SSE_OPT=0, -DPNG_POWERPC_VSX_OPT=0" + +If you are using cmake, hardware optimizations are "on" +by default. To disable them, use + + cmake . -DPNG_ARM_NEON=no -DPNG_INTEL_SSE=no \ + -DPNG_MIPS_MSA=no -DPNG_POWERPC_VSX=no + +or disable them all at once with + + cmake . -DPNG_HARDWARE_OPTIMIZATIONS=no + +XV. Changes to the build and configuration of libpng in libpng-1.5.x Details of internal changes to the library code can be found in the CHANGES file and in the GIT repository logs. These will be of no concern to the vast @@ -307,7 +368,7 @@ only png_longjmp_ptr, which must match the C longjmp function.) The new approach is documented in pngconf.h Despite these changes, libpng 1.5.0 only supports the native C function -calling standard on those platforms tested so far (__cdecl on Microsoft +calling standard on those platforms tested so far ("__cdecl" on Microsoft Windows). This is because the support requirements for alternative calling conventions seem to no longer exist. Developers who find it necessary to set PNG_API_RULE to 1 should advise the mailing list @@ -362,7 +423,7 @@ $PREFIX/include directory). Do not edit pnglibconf.h after you have built libpng, because than the settings would not accurately reflect the settings that were used to build libpng. -XV. Setjmp/longjmp issues +XVI. Setjmp/longjmp issues Libpng uses setjmp()/longjmp() for error handling. Unfortunately setjmp() is known to be not thread-safe on some platforms and we don't know of @@ -371,7 +432,7 @@ your application is going to be using multiple threads, you should configure libpng with PNG_NO_SETJMP in your pngusr.dfa file, with -DPNG_NO_SETJMP on your compile line, or with - #undef PNG_SETJMP_SUPPORTED + #undef PNG_SETJMP_SUPPORTED in your pnglibconf.h or pngusr.h. @@ -380,28 +441,25 @@ This requires setjmp/longjmp, so you must either build the library with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined. -XVI. Other sources of information about libpng: +XVII. Common linking failures + +If your application fails to find libpng or zlib entries while linking: + + Be sure "-lz" appears after "-lpng" on your linking command. + + Be sure you have built libpng, zlib, and your application for the + same platform (e.g., 32-bit or 64-bit). + + If you are using the vstudio project, observe the WARNING in + project/vstudio/README.txt. + +XVIII. Other sources of information about libpng: Further information can be found in the README and libpng-manual.txt files, in the individual makefiles, in png.h, and the manual pages libpng.3 and png.5. -Using the ./configure script -- 16 December 2002. -================================================= - -The ./configure script should work compatibly with what scripts/makefile.* -did, however there are some options you might need to add to configure -explicitly, which previously was done semi-automatically (if you didn't edit -scripts/makefile.* yourself, that is) - -CFLAGS="-Wall -O -funroll-loops \ --malign-loops=2 -malign-functions=2" ./configure --prefix=/usr/include \ ---with-pkgconfigdir=/usr/lib/pkgconfig --includedir=/usr/include - -You can alternatively specify --includedir=/usr/include, /usr/local/include, -/usr/include/libpng16, or whatever. - -If you find that the configure script is out-of-date or is not supporting -your platform properly, try running autogen.sh to regenerate "configure", -"Makefile.in", and the other configuration files. Then try configure again. - +Copyright (c) 1998-2002,2006-2016 Glenn Randers-Pehrson +This document is released under the libpng license. +For conditions of distribution and use, see the disclaimer +and license in png.h. diff --git a/src/third-party/libpng/LICENSE b/src/third-party/libpng/LICENSE index eb4a9a9da..4cda4fa0a 100644 --- a/src/third-party/libpng/LICENSE +++ b/src/third-party/libpng/LICENSE @@ -10,21 +10,21 @@ this sentence. This code is released under the libpng license. -libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are -Copyright (c) 2004, 2006-2015 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.2.5 -with the following individual added to the list of Contributing Authors - - Cosmin Truta - -libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are -Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.0.6 -with the following individuals added to the list of Contributing Authors +libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are +Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are +derived from libpng-1.0.6, and are distributed according to the same +disclaimer and license as libpng-1.0.6 with the following individuals +added to the list of Contributing Authors: Simon-Pierre Cadieux Eric S. Raymond + Mans Rullgard + Cosmin Truta Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov and with the following additions to the disclaimer: @@ -35,19 +35,25 @@ and with the following additions to the disclaimer: risk of satisfactory quality, performance, accuracy, and effort is with the user. +Some files in the "contrib" directory and some configure-generated +files that are distributed with libpng have other copyright owners and +are released under other open source licenses. + libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are -Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-0.96, -with the following individuals added to the list of Contributing Authors: +Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from +libpng-0.96, and are distributed according to the same disclaimer and +license as libpng-0.96, with the following individuals added to the list +of Contributing Authors: Tom Lane Glenn Randers-Pehrson Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are -Copyright (c) 1996, 1997 Andreas Dilger -Distributed according to the same disclaimer and license as libpng-0.88, -with the following individuals added to the list of Contributing Authors: +Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, +and are distributed according to the same disclaimer and license as +libpng-0.88, with the following individuals added to the list of +Contributing Authors: John Bowler Kevin Bracey @@ -56,8 +62,11 @@ with the following individuals added to the list of Contributing Authors: Greg Roelofs Tom Tanner +Some files in the "scripts" directory have other copyright owners +but are released under this license. + libpng versions 0.5, May 1995, through 0.88, January 1996, are -Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. +Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: @@ -80,13 +89,13 @@ Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: -1. The origin of this source code must not be misrepresented. + 1. The origin of this source code must not be misrepresented. -2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. -3. This Copyright notice may not be removed or altered from any - source or altered source distribution. + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to @@ -94,18 +103,31 @@ supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. +END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. -A "png_get_copyright" function is available, for convenient use in "about" -boxes and the like: +TRADEMARK: - printf("%s",png_get_copyright(NULL)); +The name "libpng" has not been registered by the Copyright owner +as a trademark in any jurisdiction. However, because libpng has +been distributed and maintained world-wide, continually since 1995, +the Copyright owner claims "common-law trademark protection" in any +jurisdiction where common-law trademark is recognized. -Also, the PNG logo (in PNG format, of course) is supplied in the -files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). +OSI CERTIFICATION: -Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a -certification mark of the Open Source Initiative. +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is +a certification mark of the Open Source Initiative. OSI has not addressed +the additional disclaimers inserted at version 1.0.7. + +EXPORT CONTROL: + +The Copyright owner believes that the Export Control Classification +Number (ECCN) for libpng is EAR99, which means not subject to export +controls or International Traffic in Arms Regulations (ITAR) because +it is open source, publicly available software, that does not contain +any encryption software. See the EAR, paragraphs 734.3(b)(3) and +734.7(b). Glenn Randers-Pehrson glennrp at users.sourceforge.net -March 26, 2015 +September 29, 2017 diff --git a/src/third-party/libpng/Makefile.am b/src/third-party/libpng/Makefile.am index ac5f95cf7..08db3e599 100644 --- a/src/third-party/libpng/Makefile.am +++ b/src/third-party/libpng/Makefile.am @@ -1,13 +1,21 @@ -# Makefile.am: -# Source file for Makefile.in (and hence Makefile) +# Makefile.am, the source file for Makefile.in (and hence Makefile), is # +# Copyright (c) 2004-2016 Glenn Randers-Pehrson +# Last changed in libpng 1.6.25 [September 1, 2016] +# +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h PNGLIB_BASENAME= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ ACLOCAL_AMFLAGS = -I scripts # test programs - run on make check, make distcheck -check_PROGRAMS= pngtest pngunknown pngstest pngvalid pngimage +check_PROGRAMS= pngtest pngunknown pngstest pngvalid pngimage pngcp +if HAVE_CLOCK_GETTIME +check_PROGRAMS += timepng +endif # Utilities - installed bin_PROGRAMS= pngfix png-fix-itxt @@ -37,37 +45,38 @@ pngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngimage_SOURCES = contrib/libtests/pngimage.c pngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la +timepng_SOURCES = contrib/libtests/timepng.c +timepng_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la + pngfix_SOURCES = contrib/tools/pngfix.c pngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la png_fix_itxt_SOURCES = contrib/tools/png-fix-itxt.c +pngcp_SOURCES = contrib/tools/pngcp.c +pngcp_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la + # Generally these are single line shell scripts to run a test with a particular # set of parameters: TESTS =\ tests/pngtest\ + tests/pngtest-badpngs\ tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\ tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\ tests/pngvalid-gamma-expand16-background\ tests/pngvalid-gamma-expand16-transform tests/pngvalid-gamma-sbit\ tests/pngvalid-gamma-threshold tests/pngvalid-gamma-transform\ - tests/pngvalid-progressive-interlace-size\ + tests/pngvalid-progressive-size\ tests/pngvalid-progressive-interlace-standard\ - tests/pngvalid-progressive-interlace-transform\ + tests/pngvalid-transform\ tests/pngvalid-progressive-standard tests/pngvalid-standard\ - tests/pngstest-0g01 tests/pngstest-0g02 tests/pngstest-0g04\ - tests/pngstest-0g08 tests/pngstest-0g16 tests/pngstest-2c08\ - tests/pngstest-2c16 tests/pngstest-3p01 tests/pngstest-3p02\ - tests/pngstest-3p04 tests/pngstest-3p08 tests/pngstest-4a08\ - tests/pngstest-4a16 tests/pngstest-6a08 tests/pngstest-6a16\ - tests/pngstest-error tests/pngunknown-IDAT\ + tests/pngstest-1.8 tests/pngstest-1.8-alpha tests/pngstest-linear\ + tests/pngstest-linear-alpha tests/pngstest-none tests/pngstest-none-alpha\ + tests/pngstest-sRGB tests/pngstest-sRGB-alpha tests/pngunknown-IDAT\ tests/pngunknown-discard tests/pngunknown-if-safe tests/pngunknown-sAPI\ tests/pngunknown-sTER tests/pngunknown-save tests/pngunknown-vpAg\ tests/pngimage-quick tests/pngimage-full -# These tests are expected, and required, to fail: -XFAIL_TESTS = tests/pngstest-error - # man pages dist_man_MANS= libpng.3 libpngpf.3 png.5 @@ -89,6 +98,21 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += arm/arm_init.c\ arm/filter_neon.S arm/filter_neon_intrinsics.c endif +if PNG_MIPS_MSA +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += mips/mips_init.c\ + mips/filter_msa_intrinsics.c +endif + +if PNG_INTEL_SSE +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += intel/intel_init.c\ + intel/filter_sse2_intrinsics.c +endif + +if PNG_POWERPC_VSX +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += powerpc/powerpc_init.c\ + powerpc/filter_vsx_intrinsics.c +endif + nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined -export-dynamic \ @@ -225,6 +249,7 @@ contrib/libtests/timepng.o: pnglibconf.h contrib/tools/makesRGB.o: pnglibconf.h contrib/tools/pngfix.o: pnglibconf.h +contrib/tools/pngcp.o: pnglibconf.h # We must use -DPNG_NO_USE_READ_MACROS here even when the library may actually # be built with PNG_USE_READ_MACROS; this prevents the read macros from diff --git a/src/third-party/libpng/Makefile.in b/src/third-party/libpng/Makefile.in index 1563c99e5..b25f3387b 100644 --- a/src/third-party/libpng/Makefile.in +++ b/src/third-party/libpng/Makefile.in @@ -14,9 +14,14 @@ @SET_MAKE@ -# Makefile.am: -# Source file for Makefile.in (and hence Makefile) +# Makefile.am, the source file for Makefile.in (and hence Makefile), is # +# Copyright (c) 2004-2016 Glenn Randers-Pehrson +# Last changed in libpng 1.6.25 [September 1, 2016] +# +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h @@ -96,18 +101,29 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = pngtest$(EXEEXT) pngunknown$(EXEEXT) \ - pngstest$(EXEEXT) pngvalid$(EXEEXT) pngimage$(EXEEXT) + pngstest$(EXEEXT) pngvalid$(EXEEXT) pngimage$(EXEEXT) \ + pngcp$(EXEEXT) $(am__EXEEXT_1) +@HAVE_CLOCK_GETTIME_TRUE@am__append_1 = timepng bin_PROGRAMS = pngfix$(EXEEXT) png-fix-itxt$(EXEEXT) -@PNG_ARM_NEON_TRUE@am__append_1 = arm/arm_init.c\ +@PNG_ARM_NEON_TRUE@am__append_2 = arm/arm_init.c\ @PNG_ARM_NEON_TRUE@ arm/filter_neon.S arm/filter_neon_intrinsics.c +@PNG_MIPS_MSA_TRUE@am__append_3 = mips/mips_init.c\ +@PNG_MIPS_MSA_TRUE@ mips/filter_msa_intrinsics.c + +@PNG_INTEL_SSE_TRUE@am__append_4 = intel/intel_init.c\ +@PNG_INTEL_SSE_TRUE@ intel/filter_sse2_intrinsics.c + +@PNG_POWERPC_VSX_TRUE@am__append_5 = powerpc/powerpc_init.c\ +@PNG_POWERPC_VSX_TRUE@ powerpc/filter_vsx_intrinsics.c + # Versioned symbols and restricted exports -@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_TRUE@am__append_2 = -Wl,-M -Wl,libpng.vers -@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_FALSE@am__append_3 = -Wl,--version-script=libpng.vers +@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_TRUE@am__append_6 = -Wl,-M -Wl,libpng.vers +@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_FALSE@am__append_7 = -Wl,--version-script=libpng.vers # Only restricted exports when possible -@HAVE_LD_VERSION_SCRIPT_FALSE@am__append_4 = -export-symbols libpng.sym -@DO_PNG_PREFIX_TRUE@am__append_5 = -DPNG_PREFIX='@PNG_PREFIX@' +@HAVE_LD_VERSION_SCRIPT_FALSE@am__append_8 = -export-symbols libpng.sym +@DO_PNG_PREFIX_TRUE@am__append_9 = -DPNG_PREFIX='@PNG_PREFIX@' subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/scripts/libtool.m4 \ @@ -164,14 +180,24 @@ am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST = png.c \ pngrtran.c pngrutil.c pngset.c pngtrans.c pngwio.c pngwrite.c \ pngwtran.c pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h \ pngpriv.h pngstruct.h pngusr.dfa arm/arm_init.c \ - arm/filter_neon.S arm/filter_neon_intrinsics.c + arm/filter_neon.S arm/filter_neon_intrinsics.c \ + mips/mips_init.c mips/filter_msa_intrinsics.c \ + intel/intel_init.c intel/filter_sse2_intrinsics.c \ + powerpc/powerpc_init.c powerpc/filter_vsx_intrinsics.c am__dirstamp = $(am__leading_dot)dirstamp @PNG_ARM_NEON_TRUE@am__objects_1 = arm/arm_init.lo arm/filter_neon.lo \ @PNG_ARM_NEON_TRUE@ arm/filter_neon_intrinsics.lo +@PNG_MIPS_MSA_TRUE@am__objects_2 = mips/mips_init.lo \ +@PNG_MIPS_MSA_TRUE@ mips/filter_msa_intrinsics.lo +@PNG_INTEL_SSE_TRUE@am__objects_3 = intel/intel_init.lo \ +@PNG_INTEL_SSE_TRUE@ intel/filter_sse2_intrinsics.lo +@PNG_POWERPC_VSX_TRUE@am__objects_4 = powerpc/powerpc_init.lo \ +@PNG_POWERPC_VSX_TRUE@ powerpc/filter_vsx_intrinsics.lo am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = png.lo pngerror.lo \ pngget.lo pngmem.lo pngpread.lo pngread.lo pngrio.lo \ pngrtran.lo pngrutil.lo pngset.lo pngtrans.lo pngwio.lo \ - pngwrite.lo pngwtran.lo pngwutil.lo $(am__objects_1) + pngwrite.lo pngwtran.lo pngwutil.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = \ $(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) \ @@ -185,10 +211,14 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK = $(LIBTOOL) $(AM_V_lt) \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS) $(LDFLAGS) -o \ $@ +@HAVE_CLOCK_GETTIME_TRUE@am__EXEEXT_1 = timepng$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) am_png_fix_itxt_OBJECTS = contrib/tools/png-fix-itxt.$(OBJEXT) png_fix_itxt_OBJECTS = $(am_png_fix_itxt_OBJECTS) png_fix_itxt_LDADD = $(LDADD) +am_pngcp_OBJECTS = contrib/tools/pngcp.$(OBJEXT) +pngcp_OBJECTS = $(am_pngcp_OBJECTS) +pngcp_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am_pngfix_OBJECTS = contrib/tools/pngfix.$(OBJEXT) pngfix_OBJECTS = $(am_pngfix_OBJECTS) pngfix_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @@ -207,6 +237,9 @@ pngunknown_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am_pngvalid_OBJECTS = contrib/libtests/pngvalid.$(OBJEXT) pngvalid_OBJECTS = $(am_pngvalid_OBJECTS) pngvalid_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la +am_timepng_OBJECTS = contrib/libtests/timepng.$(OBJEXT) +timepng_OBJECTS = $(am_timepng_OBJECTS) +timepng_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la SCRIPTS = $(bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -254,14 +287,14 @@ am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \ $(nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \ - $(png_fix_itxt_SOURCES) $(pngfix_SOURCES) $(pngimage_SOURCES) \ - $(pngstest_SOURCES) $(pngtest_SOURCES) $(pngunknown_SOURCES) \ - $(pngvalid_SOURCES) + $(png_fix_itxt_SOURCES) $(pngcp_SOURCES) $(pngfix_SOURCES) \ + $(pngimage_SOURCES) $(pngstest_SOURCES) $(pngtest_SOURCES) \ + $(pngunknown_SOURCES) $(pngvalid_SOURCES) $(timepng_SOURCES) DIST_SOURCES = \ $(am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST) \ - $(png_fix_itxt_SOURCES) $(pngfix_SOURCES) $(pngimage_SOURCES) \ - $(pngstest_SOURCES) $(pngtest_SOURCES) $(pngunknown_SOURCES) \ - $(pngvalid_SOURCES) + $(png_fix_itxt_SOURCES) $(pngcp_SOURCES) $(pngfix_SOURCES) \ + $(pngimage_SOURCES) $(pngstest_SOURCES) $(pngtest_SOURCES) \ + $(pngunknown_SOURCES) $(pngvalid_SOURCES) $(timepng_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -664,37 +697,36 @@ pngunknown_SOURCES = contrib/libtests/pngunknown.c pngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngimage_SOURCES = contrib/libtests/pngimage.c pngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la +timepng_SOURCES = contrib/libtests/timepng.c +timepng_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngfix_SOURCES = contrib/tools/pngfix.c pngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la png_fix_itxt_SOURCES = contrib/tools/png-fix-itxt.c +pngcp_SOURCES = contrib/tools/pngcp.c +pngcp_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la # Generally these are single line shell scripts to run a test with a particular # set of parameters: TESTS = \ tests/pngtest\ + tests/pngtest-badpngs\ tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\ tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\ tests/pngvalid-gamma-expand16-background\ tests/pngvalid-gamma-expand16-transform tests/pngvalid-gamma-sbit\ tests/pngvalid-gamma-threshold tests/pngvalid-gamma-transform\ - tests/pngvalid-progressive-interlace-size\ + tests/pngvalid-progressive-size\ tests/pngvalid-progressive-interlace-standard\ - tests/pngvalid-progressive-interlace-transform\ + tests/pngvalid-transform\ tests/pngvalid-progressive-standard tests/pngvalid-standard\ - tests/pngstest-0g01 tests/pngstest-0g02 tests/pngstest-0g04\ - tests/pngstest-0g08 tests/pngstest-0g16 tests/pngstest-2c08\ - tests/pngstest-2c16 tests/pngstest-3p01 tests/pngstest-3p02\ - tests/pngstest-3p04 tests/pngstest-3p08 tests/pngstest-4a08\ - tests/pngstest-4a16 tests/pngstest-6a08 tests/pngstest-6a16\ - tests/pngstest-error tests/pngunknown-IDAT\ + tests/pngstest-1.8 tests/pngstest-1.8-alpha tests/pngstest-linear\ + tests/pngstest-linear-alpha tests/pngstest-none tests/pngstest-none-alpha\ + tests/pngstest-sRGB tests/pngstest-sRGB-alpha tests/pngunknown-IDAT\ tests/pngunknown-discard tests/pngunknown-if-safe tests/pngunknown-sAPI\ tests/pngunknown-sTER tests/pngunknown-save tests/pngunknown-vpAg\ tests/pngimage-quick tests/pngimage-full -# These tests are expected, and required, to fail: -XFAIL_TESTS = tests/pngstest-error - # man pages dist_man_MANS = libpng.3 libpngpf.3 png.5 EXTRA_SCRIPTS = libpng-config libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config @@ -707,12 +739,13 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c \ pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c \ pngrutil.c pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c \ pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h \ - pngstruct.h pngusr.dfa $(am__append_1) + pngstruct.h pngusr.dfa $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined \ -export-dynamic -version-number \ @PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0 \ - $(am__append_2) $(am__append_3) $(am__append_4) + $(am__append_6) $(am__append_7) $(am__append_8) @HAVE_LD_VERSION_SCRIPT_FALSE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.sym @HAVE_LD_VERSION_SCRIPT_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.vers pkginclude_HEADERS = png.h pngconf.h @@ -748,7 +781,7 @@ SUFFIXES = .chk .out SYMBOL_CFLAGS = -DPNGLIB_LIBNAME='PNG@PNGLIB_MAJOR@@PNGLIB_MINOR@_0' \ -DPNGLIB_VERSION='@PNGLIB_VERSION@' \ -DSYMBOL_PREFIX='$(SYMBOL_PREFIX)' -DPNG_NO_USE_READ_MACROS \ - -DPNG_BUILDING_SYMBOL_TABLE $(am__append_5) + -DPNG_BUILDING_SYMBOL_TABLE $(am__append_9) # EXT_LIST is a list of the possibly library directory extensions, this exists # because we can't find a good way of discovering the file extensions that are @@ -857,6 +890,35 @@ arm/arm_init.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp) arm/filter_neon.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp) arm/filter_neon_intrinsics.lo: arm/$(am__dirstamp) \ arm/$(DEPDIR)/$(am__dirstamp) +mips/$(am__dirstamp): + @$(MKDIR_P) mips + @: > mips/$(am__dirstamp) +mips/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) mips/$(DEPDIR) + @: > mips/$(DEPDIR)/$(am__dirstamp) +mips/mips_init.lo: mips/$(am__dirstamp) mips/$(DEPDIR)/$(am__dirstamp) +mips/filter_msa_intrinsics.lo: mips/$(am__dirstamp) \ + mips/$(DEPDIR)/$(am__dirstamp) +intel/$(am__dirstamp): + @$(MKDIR_P) intel + @: > intel/$(am__dirstamp) +intel/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) intel/$(DEPDIR) + @: > intel/$(DEPDIR)/$(am__dirstamp) +intel/intel_init.lo: intel/$(am__dirstamp) \ + intel/$(DEPDIR)/$(am__dirstamp) +intel/filter_sse2_intrinsics.lo: intel/$(am__dirstamp) \ + intel/$(DEPDIR)/$(am__dirstamp) +powerpc/$(am__dirstamp): + @$(MKDIR_P) powerpc + @: > powerpc/$(am__dirstamp) +powerpc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) powerpc/$(DEPDIR) + @: > powerpc/$(DEPDIR)/$(am__dirstamp) +powerpc/powerpc_init.lo: powerpc/$(am__dirstamp) \ + powerpc/$(DEPDIR)/$(am__dirstamp) +powerpc/filter_vsx_intrinsics.lo: powerpc/$(am__dirstamp) \ + powerpc/$(DEPDIR)/$(am__dirstamp) libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la: $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) $(EXTRA_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) $(AM_V_CCLD)$(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK) -rpath $(libdir) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD) $(LIBS) @@ -930,6 +992,12 @@ contrib/tools/png-fix-itxt.$(OBJEXT): contrib/tools/$(am__dirstamp) \ png-fix-itxt$(EXEEXT): $(png_fix_itxt_OBJECTS) $(png_fix_itxt_DEPENDENCIES) $(EXTRA_png_fix_itxt_DEPENDENCIES) @rm -f png-fix-itxt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(png_fix_itxt_OBJECTS) $(png_fix_itxt_LDADD) $(LIBS) +contrib/tools/pngcp.$(OBJEXT): contrib/tools/$(am__dirstamp) \ + contrib/tools/$(DEPDIR)/$(am__dirstamp) + +pngcp$(EXEEXT): $(pngcp_OBJECTS) $(pngcp_DEPENDENCIES) $(EXTRA_pngcp_DEPENDENCIES) + @rm -f pngcp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(pngcp_OBJECTS) $(pngcp_LDADD) $(LIBS) contrib/tools/pngfix.$(OBJEXT): contrib/tools/$(am__dirstamp) \ contrib/tools/$(DEPDIR)/$(am__dirstamp) @@ -971,6 +1039,12 @@ contrib/libtests/pngvalid.$(OBJEXT): contrib/libtests/$(am__dirstamp) \ pngvalid$(EXEEXT): $(pngvalid_OBJECTS) $(pngvalid_DEPENDENCIES) $(EXTRA_pngvalid_DEPENDENCIES) @rm -f pngvalid$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngvalid_OBJECTS) $(pngvalid_LDADD) $(LIBS) +contrib/libtests/timepng.$(OBJEXT): contrib/libtests/$(am__dirstamp) \ + contrib/libtests/$(DEPDIR)/$(am__dirstamp) + +timepng$(EXEEXT): $(timepng_OBJECTS) $(timepng_DEPENDENCIES) $(EXTRA_timepng_DEPENDENCIES) + @rm -f timepng$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(timepng_OBJECTS) $(timepng_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ @@ -1013,6 +1087,12 @@ mostlyclean-compile: -rm -f arm/*.lo -rm -f contrib/libtests/*.$(OBJEXT) -rm -f contrib/tools/*.$(OBJEXT) + -rm -f intel/*.$(OBJEXT) + -rm -f intel/*.lo + -rm -f mips/*.$(OBJEXT) + -rm -f mips/*.lo + -rm -f powerpc/*.$(OBJEXT) + -rm -f powerpc/*.lo distclean-compile: -rm -f *.tab.c @@ -1040,8 +1120,16 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngstest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngunknown.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngvalid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/timepng.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/png-fix-itxt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngfix.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/filter_sse2_intrinsics.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/intel_init.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/filter_msa_intrinsics.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/mips_init.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/powerpc_init.Plo@am__quote@ .S.o: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -1097,6 +1185,9 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -rm -rf arm/.libs arm/_libs + -rm -rf intel/.libs intel/_libs + -rm -rf mips/.libs mips/_libs + -rm -rf powerpc/.libs powerpc/_libs distclean-libtool: -rm -f libtool config.lt @@ -1457,6 +1548,13 @@ tests/pngtest.log: tests/pngtest --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/pngtest-badpngs.log: tests/pngtest-badpngs + @p='tests/pngtest-badpngs'; \ + b='tests/pngtest-badpngs'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-16-to-8.log: tests/pngvalid-gamma-16-to-8 @p='tests/pngvalid-gamma-16-to-8'; \ b='tests/pngvalid-gamma-16-to-8'; \ @@ -1520,9 +1618,9 @@ tests/pngvalid-gamma-transform.log: tests/pngvalid-gamma-transform --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngvalid-progressive-interlace-size.log: tests/pngvalid-progressive-interlace-size - @p='tests/pngvalid-progressive-interlace-size'; \ - b='tests/pngvalid-progressive-interlace-size'; \ +tests/pngvalid-progressive-size.log: tests/pngvalid-progressive-size + @p='tests/pngvalid-progressive-size'; \ + b='tests/pngvalid-progressive-size'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ @@ -1534,9 +1632,9 @@ tests/pngvalid-progressive-interlace-standard.log: tests/pngvalid-progressive-in --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngvalid-progressive-interlace-transform.log: tests/pngvalid-progressive-interlace-transform - @p='tests/pngvalid-progressive-interlace-transform'; \ - b='tests/pngvalid-progressive-interlace-transform'; \ +tests/pngvalid-transform.log: tests/pngvalid-transform + @p='tests/pngvalid-transform'; \ + b='tests/pngvalid-transform'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ @@ -1555,114 +1653,58 @@ tests/pngvalid-standard.log: tests/pngvalid-standard --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-0g01.log: tests/pngstest-0g01 - @p='tests/pngstest-0g01'; \ - b='tests/pngstest-0g01'; \ +tests/pngstest-1.8.log: tests/pngstest-1.8 + @p='tests/pngstest-1.8'; \ + b='tests/pngstest-1.8'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-0g02.log: tests/pngstest-0g02 - @p='tests/pngstest-0g02'; \ - b='tests/pngstest-0g02'; \ +tests/pngstest-1.8-alpha.log: tests/pngstest-1.8-alpha + @p='tests/pngstest-1.8-alpha'; \ + b='tests/pngstest-1.8-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-0g04.log: tests/pngstest-0g04 - @p='tests/pngstest-0g04'; \ - b='tests/pngstest-0g04'; \ +tests/pngstest-linear.log: tests/pngstest-linear + @p='tests/pngstest-linear'; \ + b='tests/pngstest-linear'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-0g08.log: tests/pngstest-0g08 - @p='tests/pngstest-0g08'; \ - b='tests/pngstest-0g08'; \ +tests/pngstest-linear-alpha.log: tests/pngstest-linear-alpha + @p='tests/pngstest-linear-alpha'; \ + b='tests/pngstest-linear-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-0g16.log: tests/pngstest-0g16 - @p='tests/pngstest-0g16'; \ - b='tests/pngstest-0g16'; \ +tests/pngstest-none.log: tests/pngstest-none + @p='tests/pngstest-none'; \ + b='tests/pngstest-none'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-2c08.log: tests/pngstest-2c08 - @p='tests/pngstest-2c08'; \ - b='tests/pngstest-2c08'; \ +tests/pngstest-none-alpha.log: tests/pngstest-none-alpha + @p='tests/pngstest-none-alpha'; \ + b='tests/pngstest-none-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-2c16.log: tests/pngstest-2c16 - @p='tests/pngstest-2c16'; \ - b='tests/pngstest-2c16'; \ +tests/pngstest-sRGB.log: tests/pngstest-sRGB + @p='tests/pngstest-sRGB'; \ + b='tests/pngstest-sRGB'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-3p01.log: tests/pngstest-3p01 - @p='tests/pngstest-3p01'; \ - b='tests/pngstest-3p01'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-3p02.log: tests/pngstest-3p02 - @p='tests/pngstest-3p02'; \ - b='tests/pngstest-3p02'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-3p04.log: tests/pngstest-3p04 - @p='tests/pngstest-3p04'; \ - b='tests/pngstest-3p04'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-3p08.log: tests/pngstest-3p08 - @p='tests/pngstest-3p08'; \ - b='tests/pngstest-3p08'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-4a08.log: tests/pngstest-4a08 - @p='tests/pngstest-4a08'; \ - b='tests/pngstest-4a08'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-4a16.log: tests/pngstest-4a16 - @p='tests/pngstest-4a16'; \ - b='tests/pngstest-4a16'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-6a08.log: tests/pngstest-6a08 - @p='tests/pngstest-6a08'; \ - b='tests/pngstest-6a08'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-6a16.log: tests/pngstest-6a16 - @p='tests/pngstest-6a16'; \ - b='tests/pngstest-6a16'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -tests/pngstest-error.log: tests/pngstest-error - @p='tests/pngstest-error'; \ - b='tests/pngstest-error'; \ +tests/pngstest-sRGB-alpha.log: tests/pngstest-sRGB-alpha + @p='tests/pngstest-sRGB-alpha'; \ + b='tests/pngstest-sRGB-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ @@ -1960,6 +2002,12 @@ distclean-generic: -rm -f contrib/libtests/$(am__dirstamp) -rm -f contrib/tools/$(DEPDIR)/$(am__dirstamp) -rm -f contrib/tools/$(am__dirstamp) + -rm -f intel/$(DEPDIR)/$(am__dirstamp) + -rm -f intel/$(am__dirstamp) + -rm -f mips/$(DEPDIR)/$(am__dirstamp) + -rm -f mips/$(am__dirstamp) + -rm -f powerpc/$(DEPDIR)/$(am__dirstamp) + -rm -f powerpc/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -1976,7 +2024,7 @@ clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) + -rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) intel/$(DEPDIR) mips/$(DEPDIR) powerpc/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -2028,7 +2076,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) + -rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) intel/$(DEPDIR) mips/$(DEPDIR) powerpc/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -2152,6 +2200,7 @@ contrib/libtests/timepng.o: pnglibconf.h contrib/tools/makesRGB.o: pnglibconf.h contrib/tools/pngfix.o: pnglibconf.h +contrib/tools/pngcp.o: pnglibconf.h .c.out: rm -f $@ $*.tf[12] diff --git a/src/third-party/libpng/README b/src/third-party/libpng/README index a158ea8a7..0da5a5ef8 100644 --- a/src/third-party/libpng/README +++ b/src/third-party/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.17 - March 26, 2015 (shared library 16.0) +README for libpng version 1.6.34 - September 29, 2017 (shared library 16.0) See the note about version numbers near the top of png.h See INSTALL for instructions on how to install libpng. @@ -23,7 +23,7 @@ earlier versions if you are using a shared library. The type of the png_uint_32, which will affect shared-library applications that use this function. -To avoid problems with changes to the internals of png info_struct, +To avoid problems with changes to the internals of the png info_struct, new APIs have been made available in 0.95 to avoid direct application access to info_ptr. These functions are the png_set_ and png_get_ functions. These functions should be used when @@ -88,11 +88,11 @@ zlib should be available at the same place that libpng is, or at zlib.net. You may also want a copy of the PNG specification. It is available as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find -these at http://www.libpng.org/pub/png/documents/ +these at http://www.libpng.org/pub/png/pngdocs.html . -This code is currently being archived at libpng.sf.net in the -[DOWNLOAD] area, and at ftp://ftp.simplesystems.org. If you can't find it -in any of those places, e-mail me, and I'll help you find it. +This code is currently being archived at libpng.sourceforge.io in the +[DOWNLOAD] area, and at http://libpng.download/src . If you +can't find it in any of those places, e-mail me, and I'll help you find it. I am not a lawyer, but I believe that the Export Control Classification Number (ECCN) for libpng is EAR99, which means not subject to export @@ -134,7 +134,7 @@ and ...". If in doubt, send questions to me. I'll bounce them to others, if necessary. Please do not send suggestions on how to change PNG. We have -been discussing PNG for nineteen years now, and it is official and +been discussing PNG for twenty years now, and it is official and finished. If you have suggestions for libpng, however, I'll gladly listen. Even if your suggestion is not used immediately, it may be used later. @@ -179,18 +179,25 @@ Files in this distribution: pngwtran.c => Write data transformations pngwutil.c => Write utility functions arm => Contains optimized code for the ARM platform + powerpc => Contains optimized code for the PowerPC platform contrib => Contributions + arm-neon => Optimized code for ARM-NEON platform + powerpc-vsx => Optimized code for POWERPC-VSX platform examples => Example programs gregbook => source code for PNG reading and writing, from Greg Roelofs' "PNG: The Definitive Guide", O'Reilly, 1999 libtests => Test programs + mips-msa => Optimized code for MIPS-MSA platform pngminim => Minimal decoder, encoder, and progressive decoder programs demonstrating use of pngusr.dfa pngminus => Simple pnm2png and png2pnm programs pngsuite => Test images + testpngs tools => Various tools visupng => Contains a MSVC workspace for VisualPng + intel => Optimized code for INTEL-SSE2 platform + mips => Optimized code for MIPS platform projects => Contains project files and workspaces for building a DLL owatcom => Contains a WATCOM project for building libpng diff --git a/src/third-party/libpng/TODO b/src/third-party/libpng/TODO index 72633774f..36d6092a2 100644 --- a/src/third-party/libpng/TODO +++ b/src/third-party/libpng/TODO @@ -5,13 +5,14 @@ Final bug fixes. Better C++ wrapper/full C++ implementation? Fix problem with C++ and EXTERN "C". cHRM transformation. -Remove setjmp/longjmp usage in favor of returning error codes. +Remove setjmp/longjmp usage in favor of returning error codes. As a start on + this, minimize the use of png_error(), replacing them with + png_warning(); return(0); or similar. Palette creation. Add "grayscale->palette" transformation and "palette->grayscale" detection. Improved dithering. Multi-lingual error and warning message support. Complete sRGB transformation (presently it simply uses gamma=0.45455). -Make profile checking optional via a png_set_something() call. Man pages for function calls. Better documentation. Better filter selection @@ -23,7 +24,7 @@ Use greater precision when changing to linear gamma for compositing against background and doing rgb-to-gray transformation. Investigate pre-incremented loop counters and other loop constructions. Add interpolated method of handling interlacing. -Switch to the simpler zlib (zlib/libpng) license if legally possible. Extend pngvalid.c to validate more of the libpng transformations. +Refactor preprocessor conditionals to compile entire statements */ diff --git a/src/third-party/libpng/arm/arm_init.c b/src/third-party/libpng/arm/arm_init.c index fb3d50d04..02df812e7 100644 --- a/src/third-party/libpng/arm/arm_init.c +++ b/src/third-party/libpng/arm/arm_init.c @@ -1,9 +1,9 @@ /* arm_init.c - NEON optimised filter functions * - * Copyright (c) 2014 Glenn Randers-Pehrson + * Copyright (c) 2014,2016 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.16 [December 22, 2014] + * 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 @@ -66,6 +66,7 @@ png_init_filter_functions_neon(png_structp pp, unsigned int bpp) * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, * as documented in png.h */ + png_debug(1, "in png_init_filter_functions_neon"); #ifdef PNG_ARM_NEON_API_SUPPORTED switch ((pp->options >> PNG_ARM_NEON) & 3) { diff --git a/src/third-party/libpng/arm/filter_neon.S b/src/third-party/libpng/arm/filter_neon.S index 3b061d6bb..000764cd2 100644 --- a/src/third-party/libpng/arm/filter_neon.S +++ b/src/third-party/libpng/arm/filter_neon.S @@ -1,9 +1,9 @@ /* filter_neon.S - NEON optimised filter functions * - * Copyright (c) 2014 Glenn Randers-Pehrson + * Copyright (c) 2014,2017 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.16 [December 22, 2014] + * Last changed in libpng 1.6.31 [July 27, 2017] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -16,7 +16,7 @@ #define PNG_VERSION_INFO_ONLY #include "../pngpriv.h" -#if defined(__linux__) && defined(__ELF__) +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ #endif diff --git a/src/third-party/libpng/arm/filter_neon_intrinsics.c b/src/third-party/libpng/arm/filter_neon_intrinsics.c index d42c78890..ea7e356bc 100644 --- a/src/third-party/libpng/arm/filter_neon_intrinsics.c +++ b/src/third-party/libpng/arm/filter_neon_intrinsics.c @@ -1,11 +1,11 @@ /* filter_neon_intrinsics.c - NEON optimised filter functions * - * Copyright (c) 2014 Glenn Randers-Pehrson + * Copyright (c) 2014,2016 Glenn Randers-Pehrson * Written by James Yu , October 2013. * Based on filter_neon.S, written by Mans Rullgard, 2011. * - * Last changed in libpng 1.6.16 [December 22, 2014] + * 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 @@ -47,6 +47,8 @@ png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, png_bytep rp_stop = row + row_info->rowbytes; png_const_bytep pp = prev_row; + png_debug(1, "in png_read_filter_row_up_neon"); + for (; rp < rp_stop; rp += 16, pp += 16) { uint8x16_t qrp, qpp; @@ -72,6 +74,8 @@ png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); + png_debug(1, "in png_read_filter_row_sub3_neon"); + for (; rp < rp_stop;) { uint8x8_t vtmp1, vtmp2; @@ -113,6 +117,8 @@ png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); + png_debug(1, "in png_read_filter_row_sub4_neon"); + for (; rp < rp_stop; rp += 16) { uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); @@ -148,6 +154,8 @@ png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, vrpt = png_ptr(uint8x8x2_t,&vtmp); vrp = *vrpt; + png_debug(1, "in png_read_filter_row_avg3_neon"); + for (; rp < rp_stop; pp += 12) { uint8x8_t vtmp1, vtmp2, vtmp3; @@ -207,6 +215,8 @@ png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); + png_debug(1, "in png_read_filter_row_avg4_neon"); + for (; rp < rp_stop; rp += 16, pp += 16) { uint32x2x4_t vtmp; @@ -280,6 +290,8 @@ png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, vrpt = png_ptr(uint8x8x2_t,&vtmp); vrp = *vrpt; + png_debug(1, "in png_read_filter_row_paeth3_neon"); + for (; rp < rp_stop; pp += 12) { uint8x8x2_t *vppt; @@ -339,6 +351,8 @@ png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); + png_debug(1, "in png_read_filter_row_paeth4_neon"); + for (; rp < rp_stop; rp += 16, pp += 16) { uint32x2x4_t vtmp; diff --git a/src/third-party/libpng/autogen.sh b/src/third-party/libpng/autogen.sh index 9af34bde2..91607171b 100755 --- a/src/third-party/libpng/autogen.sh +++ b/src/third-party/libpng/autogen.sh @@ -73,12 +73,13 @@ done # present bad things are happening. # # The autotools generated files: -libpng_autotools_files="Makefile.in aclocal.m4 config.guess config.h.in\ - config.sub configure depcomp install-sh ltmain.sh missing test-driver" +libpng_autotools_files="Makefile.in aclocal.m4 config.guess config.h.in + config.sub configure depcomp install-sh ltmain.sh missing\ + test-driver" # # Files generated by versions of configue >2.68 or automake >1.13 (i.e. later # versions than those required by configure.ac): -libpng_autotools_extra="compile" +libpng_autotools_extra="compile config.h.in~" # # These are separate because 'maintainer-clean' does not remove them. libpng_libtool_files="scripts/libtool.m4 scripts/ltoptions.m4\ diff --git a/src/third-party/libpng/config.h.in b/src/third-party/libpng/config.h.in index 898037ec3..a0ec9bc14 100644 --- a/src/third-party/libpng/config.h.in +++ b/src/third-party/libpng/config.h.in @@ -78,6 +78,27 @@ /* Enable ARM Neon optimizations */ #undef PNG_ARM_NEON_OPT +/* Enable Intel SSE optimizations */ +#undef PNG_INTEL_SSE_OPT + +/* Turn on MIPS MSA optimizations at run-time */ +#undef PNG_MIPS_MSA_API_SUPPORTED + +/* Check for MIPS MSA support at run-time */ +#undef PNG_MIPS_MSA_CHECK_SUPPORTED + +/* Enable MIPS MSA optimizations */ +#undef PNG_MIPS_MSA_OPT + +/* Turn on POWERPC VSX optimizations at run-time */ +#undef PNG_POWERPC_VSX_API_SUPPORTED + +/* Check for POWERPC VSX support at run-time */ +#undef PNG_POWERPC_VSX_CHECK_SUPPORTED + +/* Enable POWERPC VSX optimizations */ +#undef PNG_POWERPC_VSX_OPT + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff --git a/src/third-party/libpng/configure b/src/third-party/libpng/configure index 0bf19ee44..603fd9e0e 100755 --- a/src/third-party/libpng/configure +++ b/src/third-party/libpng/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libpng 1.6.17. +# Generated by GNU Autoconf 2.69 for libpng 1.6.34. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libpng' PACKAGE_TARNAME='libpng' -PACKAGE_VERSION='1.6.17' -PACKAGE_STRING='libpng 1.6.17' +PACKAGE_VERSION='1.6.34' +PACKAGE_STRING='libpng 1.6.34' PACKAGE_BUGREPORT='png-mng-implement@lists.sourceforge.net' PACKAGE_URL='' @@ -635,6 +635,12 @@ ac_includes_default="\ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS +PNG_POWERPC_VSX_FALSE +PNG_POWERPC_VSX_TRUE +PNG_INTEL_SSE_FALSE +PNG_INTEL_SSE_TRUE +PNG_MIPS_MSA_FALSE +PNG_MIPS_MSA_TRUE PNG_ARM_NEON_FALSE PNG_ARM_NEON_TRUE DO_INSTALL_LIBPNG_CONFIG_FALSE @@ -657,6 +663,8 @@ HAVE_LD_VERSION_SCRIPT_FALSE HAVE_LD_VERSION_SCRIPT_TRUE HAVE_SOLARIS_LD_FALSE HAVE_SOLARIS_LD_TRUE +HAVE_CLOCK_GETTIME_FALSE +HAVE_CLOCK_GETTIME_TRUE LIBOBJS POW_LIB PNG_COPTS @@ -805,7 +813,11 @@ with_libpng_prefix enable_unversioned_links enable_unversioned_libpng_pc enable_unversioned_libpng_config +enable_hardware_optimizations enable_arm_neon +enable_mips_msa +enable_intel_sse +enable_powerpc_vsx ' ac_precious_vars='build_alias host_alias @@ -1360,7 +1372,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libpng 1.6.17 to adapt to many kinds of systems. +\`configure' configures libpng 1.6.34 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1430,7 +1442,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libpng 1.6.17:";; + short | recursive ) echo "Configuration of libpng 1.6.34:";; esac cat <<\_ACEOF @@ -1482,6 +1494,8 @@ Optional Features: link to the versioned version. This is done by default - use --disable-unversioned-libpng-config to change this. + --enable-hardware-optimizations + Enable hardware optimizations: =no/off, yes/on: --enable-arm-neon Enable ARM NEON optimizations: =no/off, check, api, yes/on: no/off: disable the optimizations; check: use internal checking code (deprecated and poorly @@ -1489,6 +1503,23 @@ Optional Features: call to png_set_option; yes/on: turn on unconditionally. If not specified: determined by the compiler. + --enable-mips-msa Enable MIPS MSA optimizations: =no/off, check, api, + yes/on: no/off: disable the optimizations; check: + use internal checking code (deprecated and poorly + supported); api: disable by default, enable by a + call to png_set_option; yes/on: turn on + unconditionally. If not specified: determined by the + compiler. + --enable-intel-sse Enable Intel SSE optimizations: =no/off, yes/on: + no/off: disable the optimizations; yes/on: enable + the optimizations. If not specified: determined by + the compiler. + --enable-powerpc-vsx Enable POWERPC VSX optimizations: =no/off, check, + api, yes/on: no/off: disable the optimizations; + check: use internal checking code api: disable by + default, enable by a call to png_set_option yes/on: + turn on unconditionally. If not specified: + determined by the compiler. Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1591,7 +1622,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libpng configure 1.6.17 +libpng configure 1.6.34 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1923,7 +1954,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libpng $as_me 1.6.17, which was +It was created by libpng $as_me 1.6.34, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2794,7 +2825,7 @@ fi # Define the identity of the package. PACKAGE='libpng' - VERSION='1.6.17' + VERSION='1.6.34' cat >>confdefs.h <<_ACEOF @@ -2888,7 +2919,7 @@ END fi # The following line causes --disable-maintainer-mode to be the default to -# configure, this is necessary because libpng distributions cannot rely on the +# configure. This is necessary because libpng distributions cannot rely on the # time stamps of the autotools generated files being correct { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 @@ -2915,10 +2946,10 @@ fi -PNGLIB_VERSION=1.6.17 +PNGLIB_VERSION=1.6.34 PNGLIB_MAJOR=1 PNGLIB_MINOR=6 -PNGLIB_RELEASE=17 +PNGLIB_RELEASE=34 @@ -12597,6 +12628,41 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi +# For GCC 5 the default mode for C is -std=gnu11 instead of -std=gnu89 +# In pngpriv.h we request just the POSIX 1003.1 and C89 APIs by defining _POSIX_SOURCE to 1 +# This is incompatible with the new default mode, so we test for that and force the +# "-std=c89" compiler option: +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we need to force back C standard to C89" >&5 +$as_echo_n "checking if we need to force back C standard to C89... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define _POSIX_SOURCE 1 + #include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + + if test "x$GCC" != "xyes"; then + as_fn_error $? "Forcing back to C89 is required but the flags are only known for GCC" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$CFLAGS -std=c89" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # Checks for header files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } @@ -13073,6 +13139,26 @@ fi done +# Some later POSIX 1003.1 functions are required for test programs, failure here +# is soft (the corresponding test program is not built). +ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" +if test "x$ac_cv_func_clock_gettime" = xyes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not building timepng" >&5 +$as_echo "$as_me: WARNING: not building timepng" >&2;} +fi + + if test "$ac_cv_func_clock_gettime" = "yes"; then + HAVE_CLOCK_GETTIME_TRUE= + HAVE_CLOCK_GETTIME_FALSE='#' +else + HAVE_CLOCK_GETTIME_TRUE='#' + HAVE_CLOCK_GETTIME_FALSE= +fi + + + # Check whether --with-zlib-prefix was given. if test "${with_zlib_prefix+set}" = set; then : withval=$with_zlib_prefix; ZPREFIX=${withval} @@ -13420,6 +13506,64 @@ fi # HOST SPECIFIC OPTIONS # ===================== # +# DEFAULT +# ======= +# +# Check whether --enable-hardware-optimizations was given. +if test "${enable_hardware_optimizations+set}" = set; then : + enableval=$enable_hardware_optimizations; case "$enableval" in + no|off) + # disable hardware optimization on all systems: + enable_arm_neon=no + +$as_echo "#define PNG_ARM_NEON_OPT 0" >>confdefs.h + + enable_mips_msa=no + +$as_echo "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h + + enable_powerpc_vsx=no + +$as_echo "#define PNG_POWERPC_VSX_OPT 0" >>confdefs.h + + enable_intel_sse=no + +$as_echo "#define PNG_INTEL_SSE_OPT 0" >>confdefs.h + + ;; + *) + # allow enabling hardware optimization on any system: + case "$host_cpu" in + arm*|aarch64*) + enable_arm_neon=yes + +$as_echo "#define PNG_ARM_NEON_OPT 0" >>confdefs.h + + ;; + mipsel*|mips64el*) + enable_mips_msa=yes + +$as_echo "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h + + ;; + i?86|x86_64) + enable_intel_sse=yes + +$as_echo "#define PNG_INTEL_SSE_OPT 1" >>confdefs.h + + ;; + powerpc*|ppc64*) + enable_powerpc_vsx=yes + +$as_echo "#define PNG_POWERPC_VSX_OPT 2" >>confdefs.h + + ;; + esac + ;; + esac +fi + + # ARM # === # @@ -13476,6 +13620,162 @@ else fi +# MIPS +# === +# +# MIPS MSA (SIMD) support. + +# Check whether --enable-mips-msa was given. +if test "${enable_mips_msa+set}" = set; then : + enableval=$enable_mips_msa; case "$enableval" in + no|off) + # disable the default enabling on __mips_msa systems: + +$as_echo "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h + + # Prevent inclusion of the assembler files below: + enable_mips_msa=no;; + check) + +$as_echo "#define PNG_MIPS_MSA_CHECK_SUPPORTED /**/" >>confdefs.h +;; + api) + +$as_echo "#define PNG_MIPS_MSA_API_SUPPORTED /**/" >>confdefs.h +;; + yes|on) + +$as_echo "#define PNG_MIPS_MSA_OPT 2" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-mips-msa: please specify 'check' or 'api', if + you want the optimizations unconditionally pass '-mmsa -mfp64' + to the compiler." >&5 +$as_echo "$as_me: WARNING: --enable-mips-msa: please specify 'check' or 'api', if + you want the optimizations unconditionally pass '-mmsa -mfp64' + to the compiler." >&2;};; + *) + as_fn_error $? "--enable-mips-msa=${enable_mips_msa}: invalid value" "$LINENO" 5 + esac +fi + + +# Add MIPS specific files to all builds where the host_cpu is mips ('mips*') or +# where MIPS optimizations were explicitly requested (this allows a fallback if a +# future host CPU does not match 'mips*') + + if test "$enable_mips_msa" != 'no' && + case "$host_cpu" in + mipsel*|mips64el*) :;; + esac; then + PNG_MIPS_MSA_TRUE= + PNG_MIPS_MSA_FALSE='#' +else + PNG_MIPS_MSA_TRUE='#' + PNG_MIPS_MSA_FALSE= +fi + + +# INTEL +# ===== +# +# INTEL SSE (SIMD) support. + +# Check whether --enable-intel-sse was given. +if test "${enable_intel_sse+set}" = set; then : + enableval=$enable_intel_sse; case "$enableval" in + no|off) + # disable the default enabling: + +$as_echo "#define PNG_INTEL_SSE_OPT 0" >>confdefs.h + + # Prevent inclusion of the assembler files below: + enable_intel_sse=no;; + yes|on) + +$as_echo "#define PNG_INTEL_SSE_OPT 1" >>confdefs.h +;; + *) + as_fn_error $? "--enable-intel-sse=${enable_intel_sse}: invalid value" "$LINENO" 5 + esac +fi + + +# Add Intel specific files to all builds where the host_cpu is Intel ('x86*') +# or where Intel optimizations were explicitly requested (this allows a +# fallback if a future host CPU does not match 'x86*') + if test "$enable_intel_sse" != 'no' && + case "$host_cpu" in + i?86|x86_64) :;; + *) test "$enable_intel_sse" != '';; + esac; then + PNG_INTEL_SSE_TRUE= + PNG_INTEL_SSE_FALSE='#' +else + PNG_INTEL_SSE_TRUE='#' + PNG_INTEL_SSE_FALSE= +fi + + +# PowerPC +# === +# +# PowerPC VSX (SIMD) support. + +# Check whether --enable-powerpc-vsx was given. +if test "${enable_powerpc_vsx+set}" = set; then : + enableval=$enable_powerpc_vsx; case "$enableval" in + no|off) + # disable the default enabling on __ppc64__ systems: + +$as_echo "#define PNG_POWERPC_VSX_OPT 0" >>confdefs.h + + # Prevent inclusion of the platform specific files below: + enable_powerpc_vsx=no;; + check) + +$as_echo "#define PNG_POWERPC_VSX_CHECK_SUPPORTED /**/" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-powerpc-vsx Please check contrib/powerpc/README file + for the list of supported OSes." >&5 +$as_echo "$as_me: WARNING: --enable-powerpc-vsx Please check contrib/powerpc/README file + for the list of supported OSes." >&2;};; + api) + +$as_echo "#define PNG_POWERPC_VSX_API_SUPPORTED /**/" >>confdefs.h +;; + yes|on) + +$as_echo "#define PNG_POWERPC_VSX_OPT 2" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-powerpc-vsx: please specify 'check' or 'api', if + you want the optimizations unconditionally pass '-maltivec -mvsx' + or '-mcpu=power8'to the compiler." >&5 +$as_echo "$as_me: WARNING: --enable-powerpc-vsx: please specify 'check' or 'api', if + you want the optimizations unconditionally pass '-maltivec -mvsx' + or '-mcpu=power8'to the compiler." >&2;};; + *) + as_fn_error $? "--enable-powerpc-vsx=${enable_powerpc_vsx}: invalid value" "$LINENO" 5 + esac +fi + + +# Add PowerPC specific files to all builds where the host_cpu is powerpc('powerpc*') or +# where POWERPC optimizations were explicitly requested (this allows a fallback if a +# future host CPU does not match 'powerpc*') + + if test "$enable_powerpc_vsx" != 'no' && + case "$host_cpu" in + powerpc*|ppc64*) :;; + esac; then + PNG_POWERPC_VSX_TRUE= + PNG_POWERPC_VSX_FALSE='#' +else + PNG_POWERPC_VSX_TRUE='#' + PNG_POWERPC_VSX_FALSE= +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: Extra options for compiler: $PNG_COPTS" >&5 $as_echo "$as_me: Extra options for compiler: $PNG_COPTS" >&6;} @@ -13626,6 +13926,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_CLOCK_GETTIME_TRUE}" && test -z "${HAVE_CLOCK_GETTIME_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CLOCK_GETTIME\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_SOLARIS_LD_TRUE}" && test -z "${HAVE_SOLARIS_LD_FALSE}"; then as_fn_error $? "conditional \"HAVE_SOLARIS_LD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -13654,6 +13958,18 @@ if test -z "${PNG_ARM_NEON_TRUE}" && test -z "${PNG_ARM_NEON_FALSE}"; then as_fn_error $? "conditional \"PNG_ARM_NEON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${PNG_MIPS_MSA_TRUE}" && test -z "${PNG_MIPS_MSA_FALSE}"; then + as_fn_error $? "conditional \"PNG_MIPS_MSA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${PNG_INTEL_SSE_TRUE}" && test -z "${PNG_INTEL_SSE_FALSE}"; then + as_fn_error $? "conditional \"PNG_INTEL_SSE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${PNG_POWERPC_VSX_TRUE}" && test -z "${PNG_POWERPC_VSX_FALSE}"; then + as_fn_error $? "conditional \"PNG_POWERPC_VSX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -14051,7 +14367,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libpng $as_me 1.6.17, which was +This file was extended by libpng $as_me 1.6.34, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14117,7 +14433,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libpng config.status 1.6.17 +libpng config.status 1.6.34 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/src/third-party/libpng/configure.ac b/src/third-party/libpng/configure.ac index 1c46ca235..e3cfafd6e 100644 --- a/src/third-party/libpng/configure.ac +++ b/src/third-party/libpng/configure.ac @@ -1,5 +1,12 @@ # configure.ac +# Copyright (c) 2004-2016 Glenn Randers-Pehrson +# Last changed in libpng 1.6.25 [September 1, 2016] + +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h + dnl Process this file with autoconf to produce a configure script. dnl dnl Minor upgrades (compatible ABI): increment the package version @@ -18,7 +25,7 @@ AC_PREREQ([2.68]) dnl Version number stuff here: -AC_INIT([libpng],[1.6.17],[png-mng-implement@lists.sourceforge.net]) +AC_INIT([libpng],[1.6.34],[png-mng-implement@lists.sourceforge.net]) AC_CONFIG_MACRO_DIR([scripts]) # libpng does not follow GNU file name conventions (hence 'foreign') @@ -29,7 +36,7 @@ AC_CONFIG_MACRO_DIR([scripts]) # 1.13 is required for parallel tests AM_INIT_AUTOMAKE([1.13 foreign dist-xz color-tests silent-rules subdir-objects]) # The following line causes --disable-maintainer-mode to be the default to -# configure, this is necessary because libpng distributions cannot rely on the +# configure. This is necessary because libpng distributions cannot rely on the # time stamps of the autotools generated files being correct AM_MAINTAINER_MODE @@ -39,10 +46,10 @@ dnl automake, so the following is not necessary (and is not defined anyway): dnl AM_PREREQ([1.11.2]) dnl stop configure from automagically running automake -PNGLIB_VERSION=1.6.17 +PNGLIB_VERSION=1.6.34 PNGLIB_MAJOR=1 PNGLIB_MINOR=6 -PNGLIB_RELEASE=17 +PNGLIB_RELEASE=34 dnl End of version number stuff @@ -60,7 +67,7 @@ AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET -dnl libtool/libtoolize; version 2.4.2 is the tested version, this or any +dnl libtool/libtoolize; version 2.4.2 is the tested version. This or any dnl compatible later version may be used LT_INIT([win32-dll]) LT_PREREQ([2.4.2]) @@ -107,6 +114,25 @@ AC_ARG_ENABLE(werror, CFLAGS="$sav_CFLAGS" fi],) +# For GCC 5 the default mode for C is -std=gnu11 instead of -std=gnu89 +# In pngpriv.h we request just the POSIX 1003.1 and C89 APIs by defining _POSIX_SOURCE to 1 +# This is incompatible with the new default mode, so we test for that and force the +# "-std=c89" compiler option: +AC_MSG_CHECKING([if we need to force back C standard to C89]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ + [#define _POSIX_SOURCE 1] + [#include ] + ])], + AC_MSG_RESULT(no),[ + if test "x$GCC" != "xyes"; then + AC_MSG_ERROR( + [Forcing back to C89 is required but the flags are only known for GCC]) + fi + AC_MSG_RESULT(yes) + CFLAGS="$CFLAGS -std=c89" +]) + # Checks for header files. AC_HEADER_STDC @@ -120,6 +146,12 @@ AC_C_RESTRICT AC_FUNC_STRTOD AC_CHECK_FUNCS([memset], , AC_MSG_ERROR(memset not found in libc)) AC_CHECK_FUNCS([pow], , AC_CHECK_LIB(m, pow, , AC_MSG_ERROR(cannot find pow)) ) + +# Some later POSIX 1003.1 functions are required for test programs, failure here +# is soft (the corresponding test program is not built). +AC_CHECK_FUNC([clock_gettime],,[AC_MSG_WARN([not building timepng])]) +AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "$ac_cv_func_clock_gettime" = "yes"]) + AC_ARG_WITH(zlib-prefix, AS_HELP_STRING([[[--with-zlib-prefix]]], [prefix that may have been used in installed zlib]), @@ -268,6 +300,55 @@ AM_CONDITIONAL([DO_INSTALL_LIBPNG_CONFIG], # HOST SPECIFIC OPTIONS # ===================== # +# DEFAULT +# ======= +# +AC_ARG_ENABLE([hardware-optimizations], + AS_HELP_STRING([[[--enable-hardware-optimizations]]], + [Enable hardware optimizations: =no/off, yes/on:]), + [case "$enableval" in + no|off) + # disable hardware optimization on all systems: + enable_arm_neon=no + AC_DEFINE([PNG_ARM_NEON_OPT], [0], + [Disable ARM_NEON optimizations]) + enable_mips_msa=no + AC_DEFINE([PNG_MIPS_MSA_OPT], [0], + [Disable MIPS_MSA optimizations]) + enable_powerpc_vsx=no + AC_DEFINE([PNG_POWERPC_VSX_OPT], [0], + [Disable POWERPC VSX optimizations]) + enable_intel_sse=no + AC_DEFINE([PNG_INTEL_SSE_OPT], [0], + [Disable INTEL_SSE optimizations]) + ;; + *) + # allow enabling hardware optimization on any system: + case "$host_cpu" in + arm*|aarch64*) + enable_arm_neon=yes + AC_DEFINE([PNG_ARM_NEON_OPT], [0], + [Enable ARM_NEON optimizations]) + ;; + mipsel*|mips64el*) + enable_mips_msa=yes + AC_DEFINE([PNG_MIPS_MSA_OPT], [0], + [Enable MIPS_MSA optimizations]) + ;; + i?86|x86_64) + enable_intel_sse=yes + AC_DEFINE([PNG_INTEL_SSE_OPT], [1], + [Enable Intel SSE optimizations]) + ;; + powerpc*|ppc64*) + enable_powerpc_vsx=yes + AC_DEFINE([PNG_POWERPC_VSX_OPT], [2], + [Enable POWERPC VSX optimizations]) + ;; + esac + ;; + esac]) + # ARM # === # @@ -314,6 +395,134 @@ AM_CONDITIONAL([PNG_ARM_NEON], *) test "$enable_arm_neon" != '';; esac]) +# MIPS +# === +# +# MIPS MSA (SIMD) support. + +AC_ARG_ENABLE([mips-msa], + AS_HELP_STRING([[[--enable-mips-msa]]], + [Enable MIPS MSA optimizations: =no/off, check, api, yes/on:] + [no/off: disable the optimizations; check: use internal checking code] + [(deprecated and poorly supported); api: disable by default, enable by] + [a call to png_set_option; yes/on: turn on unconditionally.] + [If not specified: determined by the compiler.]), + [case "$enableval" in + no|off) + # disable the default enabling on __mips_msa systems: + AC_DEFINE([PNG_MIPS_MSA_OPT], [0], + [Disable MIPS MSA optimizations]) + # Prevent inclusion of the assembler files below: + enable_mips_msa=no;; + check) + AC_DEFINE([PNG_MIPS_MSA_CHECK_SUPPORTED], [], + [Check for MIPS MSA support at run-time]);; + api) + AC_DEFINE([PNG_MIPS_MSA_API_SUPPORTED], [], + [Turn on MIPS MSA optimizations at run-time]);; + yes|on) + AC_DEFINE([PNG_MIPS_MSA_OPT], [2], + [Enable MIPS MSA optimizations]) + AC_MSG_WARN([--enable-mips-msa: please specify 'check' or 'api', if] + [you want the optimizations unconditionally pass '-mmsa -mfp64'] + [to the compiler.]);; + *) + AC_MSG_ERROR([--enable-mips-msa=${enable_mips_msa}: invalid value]) + esac]) + +# Add MIPS specific files to all builds where the host_cpu is mips ('mips*') or +# where MIPS optimizations were explicitly requested (this allows a fallback if a +# future host CPU does not match 'mips*') + +AM_CONDITIONAL([PNG_MIPS_MSA], + [test "$enable_mips_msa" != 'no' && + case "$host_cpu" in + mipsel*|mips64el*) :;; + esac]) + +# INTEL +# ===== +# +# INTEL SSE (SIMD) support. + +AC_ARG_ENABLE([intel-sse], + AS_HELP_STRING([[[--enable-intel-sse]]], + [Enable Intel SSE optimizations: =no/off, yes/on:] + [no/off: disable the optimizations;] + [yes/on: enable the optimizations.] + [If not specified: determined by the compiler.]), + [case "$enableval" in + no|off) + # disable the default enabling: + AC_DEFINE([PNG_INTEL_SSE_OPT], [0], + [Disable Intel SSE optimizations]) + # Prevent inclusion of the assembler files below: + enable_intel_sse=no;; + yes|on) + AC_DEFINE([PNG_INTEL_SSE_OPT], [1], + [Enable Intel SSE optimizations]);; + *) + AC_MSG_ERROR([--enable-intel-sse=${enable_intel_sse}: invalid value]) + esac]) + +# Add Intel specific files to all builds where the host_cpu is Intel ('x86*') +# or where Intel optimizations were explicitly requested (this allows a +# fallback if a future host CPU does not match 'x86*') +AM_CONDITIONAL([PNG_INTEL_SSE], + [test "$enable_intel_sse" != 'no' && + case "$host_cpu" in + i?86|x86_64) :;; + *) test "$enable_intel_sse" != '';; + esac]) + +# PowerPC +# === +# +# PowerPC VSX (SIMD) support. + +AC_ARG_ENABLE([powerpc-vsx], +AS_HELP_STRING([[[--enable-powerpc-vsx]]], + [Enable POWERPC VSX optimizations: =no/off, check, api, yes/on:] + [no/off: disable the optimizations; check: use internal checking code] + [api: disable by default, enable by a call to png_set_option] + [yes/on: turn on unconditionally.] + [If not specified: determined by the compiler.]), + [case "$enableval" in + no|off) + # disable the default enabling on __ppc64__ systems: + AC_DEFINE([PNG_POWERPC_VSX_OPT], [0], + [Disable POWERPC VSX optimizations]) + # Prevent inclusion of the platform specific files below: + enable_powerpc_vsx=no;; + check) + AC_DEFINE([PNG_POWERPC_VSX_CHECK_SUPPORTED], [], + [Check for POWERPC VSX support at run-time]) + AC_MSG_WARN([--enable-powerpc-vsx Please check contrib/powerpc/README file] + [for the list of supported OSes.]);; + api) + AC_DEFINE([PNG_POWERPC_VSX_API_SUPPORTED], [], + [Turn on POWERPC VSX optimizations at run-time]);; + yes|on) + AC_DEFINE([PNG_POWERPC_VSX_OPT], [2], + [Enable POWERPC VSX optimizations]) + AC_MSG_WARN([--enable-powerpc-vsx: please specify 'check' or 'api', if] + [you want the optimizations unconditionally pass '-maltivec -mvsx'] + [or '-mcpu=power8'to the compiler.]);; + *) + AC_MSG_ERROR([--enable-powerpc-vsx=${enable_powerpc_vsx}: invalid value]) + esac]) + +# Add PowerPC specific files to all builds where the host_cpu is powerpc('powerpc*') or +# where POWERPC optimizations were explicitly requested (this allows a fallback if a +# future host CPU does not match 'powerpc*') + +AM_CONDITIONAL([PNG_POWERPC_VSX], + [test "$enable_powerpc_vsx" != 'no' && + case "$host_cpu" in + powerpc*|ppc64*) :;; + esac]) + + AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]]) # Config files, substituting as above diff --git a/src/third-party/libpng/contrib/README.txt b/src/third-party/libpng/contrib/README.txt index bcd433d35..97963c6d5 100644 --- a/src/third-party/libpng/contrib/README.txt +++ b/src/third-party/libpng/contrib/README.txt @@ -1,4 +1,5 @@ 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. +libpng proper and are not used for building the library, although some are used +for testing the library via "make check". diff --git a/src/third-party/libpng/contrib/arm-neon/README b/src/third-party/libpng/contrib/arm-neon/README index 535c8d3f7..b4248cf28 100644 --- a/src/third-party/libpng/contrib/arm-neon/README +++ b/src/third-party/libpng/contrib/arm-neon/README @@ -1,7 +1,7 @@ OPERATING SYSTEM SPECIFIC ARM NEON DETECTION -------------------------------------------- -Detection of the ability to exexcute ARM NEON on an ARM processor requires +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 diff --git a/src/third-party/libpng/contrib/arm-neon/android-ndk.c b/src/third-party/libpng/contrib/arm-neon/android-ndk.c index 724012348..fb3a4898d 100644 --- a/src/third-party/libpng/contrib/arm-neon/android-ndk.c +++ b/src/third-party/libpng/contrib/arm-neon/android-ndk.c @@ -17,7 +17,7 @@ * * Documentation: * http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html - * http://code.google.com/p/android/issues/detail?id=49065 + * 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 diff --git a/src/third-party/libpng/contrib/arm-neon/linux-auxv.c b/src/third-party/libpng/contrib/arm-neon/linux-auxv.c index 696e297ef..4d26bd3b3 100644 --- a/src/third-party/libpng/contrib/arm-neon/linux-auxv.c +++ b/src/third-party/libpng/contrib/arm-neon/linux-auxv.c @@ -7,7 +7,7 @@ * 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 diff --git a/src/third-party/libpng/contrib/arm-neon/linux.c b/src/third-party/libpng/contrib/arm-neon/linux.c index abae9e33b..a9bc360dd 100644 --- a/src/third-party/libpng/contrib/arm-neon/linux.c +++ b/src/third-party/libpng/contrib/arm-neon/linux.c @@ -1,8 +1,8 @@ /* contrib/arm-neon/linux.c * - * Copyright (c) 2014 Glenn Randers-Pehrson - * Written by John Bowler, 2014. - * Last changed in libpng 1.6.16 [December 22, 2014] + * 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 @@ -62,7 +62,7 @@ png_have_neon(png_structp png_ptr) counter=0; state = Feature; - /* FALL THROUGH */ + /* FALLTHROUGH */ case Feature: /* Match 'FEATURE', ASCII case insensitive. */ @@ -72,10 +72,10 @@ png_have_neon(png_structp png_ptr) state = Colon; break; } - + /* did not match 'feature' */ state = SkipLine; - /* FALL THROUGH */ + /* FALLTHROUGH */ case SkipLine: skipLine: @@ -110,7 +110,7 @@ png_have_neon(png_structp png_ptr) state = Neon; counter = 0; - /* FALL THROUGH */ + /* FALLTHROUGH */ case Neon: /* Look for 'neon' tag */ @@ -122,7 +122,7 @@ png_have_neon(png_structp png_ptr) } state = SkipTag; - /* FALL THROUGH */ + /* FALLTHROUGH */ case SkipTag: /* Skip non-space characters */ diff --git a/src/third-party/libpng/contrib/conftest/pngcp.dfa b/src/third-party/libpng/contrib/conftest/pngcp.dfa new file mode 100644 index 000000000..15a856e2f --- /dev/null +++ b/src/third-party/libpng/contrib/conftest/pngcp.dfa @@ -0,0 +1,57 @@ +# 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 suppport +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 are just required for specific customizations +option WRITE_CUSTOMIZE_ZTXT_COMPRESSION on +option WRITE_CUSTOMIZE_COMPRESSION on diff --git a/src/third-party/libpng/contrib/examples/README.txt b/src/third-party/libpng/contrib/examples/README.txt index 0525c9d36..48dab4f0f 100644 --- a/src/third-party/libpng/contrib/examples/README.txt +++ b/src/third-party/libpng/contrib/examples/README.txt @@ -21,4 +21,4 @@ ORIGINAL AUTHORS of the people below claim any rights with regard to the contents of this directory. - John Bowler + John Bowler diff --git a/src/third-party/libpng/contrib/examples/iccfrompng.c b/src/third-party/libpng/contrib/examples/iccfrompng.c index 386e522a3..603037e70 100644 --- a/src/third-party/libpng/contrib/examples/iccfrompng.c +++ b/src/third-party/libpng/contrib/examples/iccfrompng.c @@ -26,6 +26,10 @@ #include +#if defined(PNG_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) && \ + defined (PNG_iCCP_SUPPORTED) + + static int verbose = 1; static png_byte no_profile[] = "no profile"; @@ -178,3 +182,4 @@ main(int argc, char **argv) /* Exit code is true if any extract succeeds */ return extracted == 0; } +#endif /* READ && STDIO && iCCP */ diff --git a/src/third-party/libpng/contrib/examples/pngpixel.c b/src/third-party/libpng/contrib/examples/pngpixel.c index e0d43e3f0..f762379ed 100644 --- a/src/third-party/libpng/contrib/examples/pngpixel.c +++ b/src/third-party/libpng/contrib/examples/pngpixel.c @@ -27,6 +27,8 @@ */ #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, @@ -85,7 +87,7 @@ print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row, */ case PNG_COLOR_TYPE_PALETTE: { - PNG_CONST unsigned int index = component(row, x, 0, bit_depth, 1); + PNG_CONST int index = component(row, x, 0, bit_depth, 1); png_colorp palette = NULL; int num_palette = 0; @@ -366,3 +368,4 @@ int main(int argc, const char **argv) return result; } +#endif /* READ && SEQUENTIAL_READ */ diff --git a/src/third-party/libpng/contrib/examples/pngtopng.c b/src/third-party/libpng/contrib/examples/pngtopng.c index b1b3be677..904b97238 100644 --- a/src/third-party/libpng/contrib/examples/pngtopng.c +++ b/src/third-party/libpng/contrib/examples/pngtopng.c @@ -1,10 +1,12 @@ /*- pngtopng * - * COPYRIGHT: Written by John Cunningham Bowler, 2011. + * 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. * @@ -20,6 +22,8 @@ * 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) { @@ -57,26 +61,27 @@ int main(int argc, const char **argv) else fprintf(stderr, "pngtopng: write %s: %s\n", argv[2], image.message); - - free(buffer); } else - { fprintf(stderr, "pngtopng: read %s: %s\n", argv[1], image.message); - /* 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); - } + 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 @@ -90,3 +95,4 @@ int main(int argc, const char **argv) return result; } +#endif /* READ && WRITE */ diff --git a/src/third-party/libpng/contrib/examples/simpleover.c b/src/third-party/libpng/contrib/examples/simpleover.c new file mode 100644 index 000000000..59dd31368 --- /dev/null +++ b/src/third-party/libpng/contrib/examples/simpleover.c @@ -0,0 +1,648 @@ +/*- 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 [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 +#include +#include +#include +#include + +/* Normally use 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 : + */ +#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 +#include + +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/src/third-party/libpng/contrib/gregbook/README b/src/third-party/libpng/contrib/gregbook/README index 7b1f6a3ea..90e28f7ce 100644 --- a/src/third-party/libpng/contrib/gregbook/README +++ b/src/third-party/libpng/contrib/gregbook/README @@ -15,7 +15,7 @@ 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@decus.de, for making the necessary changes for OpenVMS and for +zinser at decus.de, for making the necessary changes for OpenVMS and for providing an appropriate build script.) Build instructions can be found below. @@ -55,7 +55,7 @@ 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 -http://pobox.com/~newt/greg_contact.html +https://pobox.com/~newt/greg_contact.html 16 March 2008 @@ -63,7 +63,7 @@ BUILD INSTRUCTIONS - Prerequisites (in order of compilation): - - zlib http://zlib.net/ + - zlib https://zlib.net/ - libpng http://www.libpng.org/pub/png/libpng.html - pngbook http://www.libpng.org/pub/png/book/sources.html diff --git a/src/third-party/libpng/contrib/gregbook/readpng.c b/src/third-party/libpng/contrib/gregbook/readpng.c index 9167403e5..fad9b536a 100644 --- a/src/third-party/libpng/contrib/gregbook/readpng.c +++ b/src/third-party/libpng/contrib/gregbook/readpng.c @@ -4,7 +4,7 @@ --------------------------------------------------------------------------- - Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. + 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 @@ -264,6 +264,12 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) *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; diff --git a/src/third-party/libpng/contrib/gregbook/readpng2.c b/src/third-party/libpng/contrib/gregbook/readpng2.c index 4cf2600a4..5d13e1530 100644 --- a/src/third-party/libpng/contrib/gregbook/readpng2.c +++ b/src/third-party/libpng/contrib/gregbook/readpng2.c @@ -4,7 +4,7 @@ --------------------------------------------------------------------------- - Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. + 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 @@ -51,6 +51,12 @@ 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) + ---------------------------------------------------------------------------*/ @@ -261,36 +267,38 @@ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr) /* 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_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) + 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: */ - png_get_bKGD(png_ptr, info_ptr, &pBackground); + 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; + /* 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; + } } } diff --git a/src/third-party/libpng/contrib/gregbook/readppm.c b/src/third-party/libpng/contrib/gregbook/readppm.c index 7fefc3943..52e702777 100644 --- a/src/third-party/libpng/contrib/gregbook/readppm.c +++ b/src/third-party/libpng/contrib/gregbook/readppm.c @@ -9,7 +9,7 @@ --------------------------------------------------------------------------- - Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. + 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 @@ -154,12 +154,17 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) *pRowbytes = rowbytes = channels*width; *pChannels = channels; - if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { + 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; } - Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height)); - + if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { + return NULL; + } /* now we can go ahead and just read the whole image */ diff --git a/src/third-party/libpng/contrib/gregbook/rpng-win.c b/src/third-party/libpng/contrib/gregbook/rpng-win.c index f53ddc8ec..1a6f87615 100644 --- a/src/third-party/libpng/contrib/gregbook/rpng-win.c +++ b/src/third-party/libpng/contrib/gregbook/rpng-win.c @@ -24,10 +24,11 @@ - 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 Greg Roelofs. All rights reserved. + 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 @@ -182,7 +183,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) #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@realviz.com for supplying the magical + * app. Thanks to David.Geldreich at realviz.com for supplying the magical * incantation. */ AllocConsole(); @@ -496,6 +497,12 @@ static int rpng_win_create_window(HINSTANCE hInst, int showmode) 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))) { diff --git a/src/third-party/libpng/contrib/gregbook/rpng-x.c b/src/third-party/libpng/contrib/gregbook/rpng-x.c index ddd7c58d6..92effaa6d 100644 --- a/src/third-party/libpng/contrib/gregbook/rpng-x.c +++ b/src/third-party/libpng/contrib/gregbook/rpng-x.c @@ -28,10 +28,11 @@ - 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 Greg Roelofs. All rights reserved. + 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 diff --git a/src/third-party/libpng/contrib/gregbook/rpng2-win.c b/src/third-party/libpng/contrib/gregbook/rpng2-win.c index eda176eee..ed6b526ec 100644 --- a/src/third-party/libpng/contrib/gregbook/rpng2-win.c +++ b/src/third-party/libpng/contrib/gregbook/rpng2-win.c @@ -33,12 +33,11 @@ - 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: - (GR-P) + - 2.04: check for integer overflow (Glenn R-P) --------------------------------------------------------------------------- - Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. + 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 @@ -301,7 +300,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) #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@realviz.com for supplying the magical + * app. Thanks to David.Geldreich at realviz.com for supplying the magical * incantation. */ AllocConsole(); @@ -650,6 +649,13 @@ static void rpng2_win_init() 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); diff --git a/src/third-party/libpng/contrib/gregbook/rpng2-x.c b/src/third-party/libpng/contrib/gregbook/rpng2-x.c index cf371014c..af944c0f2 100644 --- a/src/third-party/libpng/contrib/gregbook/rpng2-x.c +++ b/src/third-party/libpng/contrib/gregbook/rpng2-x.c @@ -43,12 +43,12 @@ - 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) - - TO DO: - use nanosleep() instead of usleep(), which is obsolete/deprecated. + - 2.05: Use nanosleep() instead of usleep(), which is deprecated (GR-P). + - 2.06: check for integer overflow (Glenn R-P) --------------------------------------------------------------------------- - Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. + 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 @@ -119,6 +119,7 @@ # undef usleep # define usleep(usec) { \ struct timespec ts; \ + ts.tv_sec = 0; \ ts.tv_nsec = (usec) * 1000; \ nanosleep(&ts, NULL); } # endif @@ -497,12 +498,12 @@ int main(int argc, char **argv) "\t\t transparent images; overrides -bgcolor\n", num_bgpat-1); #ifdef FEATURE_LOOP - fprintf(stderr, + 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, + 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" @@ -781,6 +782,13 @@ static void rpng2_x_init(void) 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); diff --git a/src/third-party/libpng/contrib/gregbook/wpng.c b/src/third-party/libpng/contrib/gregbook/wpng.c index a06e3529e..a8f367fb8 100644 --- a/src/third-party/libpng/contrib/gregbook/wpng.c +++ b/src/third-party/libpng/contrib/gregbook/wpng.c @@ -29,6 +29,7 @@ - 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 @@ -38,7 +39,7 @@ --------------------------------------------------------------------------- - Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. + 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 @@ -702,7 +703,18 @@ int main(int argc, char **argv) if (wpng_info.interlaced) { long i; ulg bytes; - ulg image_bytes = rowbytes * wpng_info.height; /* overflow? */ + 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 *)); diff --git a/src/third-party/libpng/contrib/gregbook/writepng.c b/src/third-party/libpng/contrib/gregbook/writepng.c index c5c953479..055c74374 100644 --- a/src/third-party/libpng/contrib/gregbook/writepng.c +++ b/src/third-party/libpng/contrib/gregbook/writepng.c @@ -4,7 +4,7 @@ --------------------------------------------------------------------------- - Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. + 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 diff --git a/src/third-party/libpng/contrib/libtests/fakepng.c b/src/third-party/libpng/contrib/libtests/fakepng.c index fcc111286..6512c1401 100644 --- a/src/third-party/libpng/contrib/libtests/fakepng.c +++ b/src/third-party/libpng/contrib/libtests/fakepng.c @@ -1,4 +1,12 @@ -/* Fake a PNG - just write it out directly. */ +/* 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 #include /* for crc32 */ diff --git a/src/third-party/libpng/contrib/libtests/makepng.c b/src/third-party/libpng/contrib/libtests/makepng.c index 9f11b2964..9dff04846 100644 --- a/src/third-party/libpng/contrib/libtests/makepng.c +++ b/src/third-party/libpng/contrib/libtests/makepng.c @@ -1,8 +1,9 @@ -/* makepng.c - * - * Copyright (c) 2013 John Cunningham Bowler - * - * Last changed in libpng 1.6.1 [March 28, 2013] +/* 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 @@ -10,8 +11,8 @@ * * Make a test PNG image. The arguments are as follows: * - * makepng [--sRGB|--linear|--1.8] [--color=] color-type bit-depth \ - * [file-name] + * 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 @@ -39,8 +40,8 @@ * 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 the PNG file has - * a tRNS chunk, as follows: + * 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 @@ -53,6 +54,9 @@ * 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: * @@ -60,20 +64,64 @@ * 16 bits: 256x256 * More than 16 bits: 1024x1024 * - * Row filtering is turned off (the 'none' filter is used on every row) and the - * images are not interlaced. + * 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= ... * * 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. * - * 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 --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 _ISOC99_SOURCE /* for strtoull */ +#define IMAGE_LICENSING "Dedicated to the public domain per Creative Commons "\ + "license \"CC0 1.0\"; https://creativecommons.org/publicdomain/zero/1.0/" #include /* for offsetof */ #include @@ -82,6 +130,8 @@ #include #include #include +#include +#include #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) # include @@ -96,6 +146,25 @@ # include "../../png.h" #endif +#include + +/* 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.) */ @@ -107,7 +176,7 @@ typedef struct chunk_insert png_charp parameters[1]; } chunk_insert; -static int +static unsigned int channels_of_type(int color_type) { if (color_type & PNG_COLOR_MASK_PALETTE) @@ -128,14 +197,15 @@ channels_of_type(int color_type) } } -static int +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) +image_size_of_type(int color_type, int bit_depth, unsigned int *colors, + int small) { if (*colors) return 16; @@ -144,7 +214,16 @@ image_size_of_type(int color_type, int bit_depth, unsigned int *colors) { int pixel_depth = pixel_depth_of_type(color_type, bit_depth); - if (pixel_depth < 8) + 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) @@ -217,7 +296,8 @@ generate_palette(png_colorp palette, png_bytep trans, int bit_depth, else { unsigned int size = 1U << (bit_depth/2); /* 2, 4 or 16 */ - unsigned int x, y, ip; + unsigned int x, y; + volatile unsigned int ip = 0; for (x=0; x> 8); *row = (png_byte)value; return; @@ -306,15 +386,148 @@ set_value(png_bytep row, size_t rowbytes, png_uint_32 x, unsigned int bit_depth, } } -static void +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) + unsigned int *colors, int small) { - png_uint_32 size_max = image_size_of_type(color_type, bit_depth, colors)-1; + 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) switch (channels_of_type(color_type)) + 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. @@ -526,6 +739,8 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type, colors[0], channels_of_type(color_type)); exit(1); } + + return filters; } @@ -554,7 +769,7 @@ makepng_error(png_structp png_ptr, png_const_charp message) 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) + 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); @@ -581,6 +796,15 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth, /* 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); @@ -588,11 +812,37 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth, png_error(png_ptr, "OOM allocating info structure"); { - unsigned int size = image_size_of_type(color_type, bit_depth, colors); + const 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) + { + const unsigned int pixel_depth = + pixel_depth_of_type(color_type, bit_depth); + + if (pixel_depth <= 8U) + { + assert(size == (1U<*[string] */ if (endptr != NULL && *endptr == '*') @@ -1062,7 +1333,8 @@ insert_iTXt(png_structp png_ptr, png_infop info_ptr, int nparams, } static void -insert_hIST(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params) +insert_hIST(png_structp png_ptr, png_infop info_ptr, int nparams, + png_charpp params) { int i; png_uint_16 freq[256]; @@ -1089,6 +1361,56 @@ insert_hIST(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp par 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) +{ + const int ct = png_get_color_type(png_ptr, info_ptr); + const int c = (ct & PNG_COLOR_MASK_COLOR ? 3 : 1) + + (ct & PNG_COLOR_MASK_ALPHA ? 1 : 0); + const 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) @@ -1216,6 +1538,11 @@ find_insert(png_const_charp what, png_charp param) 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); @@ -1231,6 +1558,80 @@ find_insert(png_const_charp what, png_charp param) 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. @@ -1280,6 +1681,8 @@ main(int argc, char **argv) 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 */ @@ -1292,6 +1695,18 @@ main(int argc, char **argv) { 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; @@ -1432,9 +1847,10 @@ main(int argc, char **argv) if (color_type == 8 || bit_depth == 32) { - fprintf(stderr, "usage: makepng [--sRGB|--linear|--1.8] " + 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"); + " Make a test PNG file, by default writes to stdout.\n" + " Other options are available, UTSL.\n"); exit(1); } @@ -1453,10 +1869,19 @@ main(int argc, char **argv) } } + /* 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) + if (filters == PNG_ALL_FILTERS && !small/*small provides defaults*/) { if ((color_type & PNG_COLOR_MASK_PALETTE) != 0 || bit_depth < 8) filters = PNG_FILTER_NONE; @@ -1474,9 +1899,39 @@ main(int argc, char **argv) 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); + head_insert, filters, colors, small, tRNS); if (ret != 0 && file_name != NULL) remove(file_name); diff --git a/src/third-party/libpng/contrib/libtests/pngimage.c b/src/third-party/libpng/contrib/libtests/pngimage.c index dccfbce12..9ae402cc4 100644 --- a/src/third-party/libpng/contrib/libtests/pngimage.c +++ b/src/third-party/libpng/contrib/libtests/pngimage.c @@ -1,8 +1,8 @@ /* pngimage.c * - * Copyright (c) 2014 John Cunningham Bowler + * Copyright (c) 2015,2016 John Cunningham Bowler * - * Last changed in libpng 1.6.10 [March 6, 2014] + * 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 @@ -36,7 +36,28 @@ # include /* because png.h did *not* include this */ #endif -#if defined(PNG_INFO_IMAGE_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED) +/* 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 @@ -236,10 +257,12 @@ static struct transform_info */ #endif #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - T(SCALE_16, NONE, X, X, 16, R) + 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 }; @@ -294,7 +317,7 @@ transform_name(int t) t &= -t; /* first set bit */ - for (i=0; iread_ip = NULL; buffer_init(&dp->original_file); -# ifdef PNG_WRITE_SUPPORTED +# ifdef PNG_WRITE_PNG_SUPPORTED dp->write_pp = NULL; buffer_init(&dp->written_file); # endif @@ -592,7 +616,7 @@ display_clean_read(struct display *dp) png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL); } -#ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_PNG_SUPPORTED static void display_clean_write(struct display *dp) { @@ -604,7 +628,7 @@ display_clean_write(struct display *dp) static void display_clean(struct display *dp) { -# ifdef PNG_WRITE_SUPPORTED +# ifdef PNG_WRITE_PNG_SUPPORTED display_clean_write(dp); # endif display_clean_read(dp); @@ -622,7 +646,7 @@ static void display_destroy(struct display *dp) { /* Release any memory held in the display. */ -# ifdef PNG_WRITE_SUPPORTED +# ifdef PNG_WRITE_PNG_SUPPORTED buffer_destroy(&dp->written_file); # endif @@ -690,7 +714,35 @@ display_log(struct display *dp, error_level level, const char *fmt, ...) int tr = dp->transforms; if (is_combo(tr)) - fprintf(stderr, "(0x%x)", 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)); @@ -910,13 +962,13 @@ update_display(struct display *dp) int bd = dp->bit_depth; unsigned int i; - for (i=0; iactive_transforms = active; dp->ignored_transforms = inactive; /* excluding write-only transforms */ - - if (active == 0) - display_log(dp, INTERNAL_ERROR, "bad transform table"); } } @@ -977,7 +1026,7 @@ compare_read(struct display *dp, int applied_transforms) { 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); @@ -1044,6 +1093,7 @@ compare_read(struct display *dp, int applied_transforms) } else +# ifdef PNG_sBIT_SUPPORTED { unsigned long y; int bpp; /* bits-per-pixel then bytes-per-pixel */ @@ -1120,8 +1170,8 @@ compare_read(struct display *dp, int applied_transforms) { int b; - case 16: /* Two bytes per component, bit-endian */ - for (b = (bpp >> 4); b > 0; ) + case 16: /* Two bytes per component, big-endian */ + for (b = (bpp >> 4); b > 0; --b) { unsigned int sig = (unsigned int)(0xffff0000 >> sig_bits[b]); @@ -1205,12 +1255,16 @@ compare_read(struct display *dp, int applied_transforms) } } /* 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_SUPPORTED +#ifdef PNG_WRITE_PNG_SUPPORTED static void buffer_write(struct display *dp, struct buffer *buffer, png_bytep data, png_size_t size) @@ -1309,7 +1363,7 @@ write_png(struct display *dp, png_infop ip, int transforms) */ display_clean_write(dp); } -#endif /* WRITE_SUPPORTED */ +#endif /* WRITE_PNG */ static int skip_transform(struct display *dp, int tr) @@ -1371,7 +1425,7 @@ test_one_file(struct display *dp, const char *filename) return; /* no point testing more */ } -#ifdef PNG_WRITE_SUPPORTED +#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. @@ -1412,7 +1466,7 @@ test_one_file(struct display *dp, const char *filename) * out and read it back in again (without the reversible transforms) * we should get back to the place where we started. */ -#ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_PNG_SUPPORTED if ((current & write_transforms) == current) { /* All transforms reversible: write the PNG with the transformations @@ -1588,6 +1642,12 @@ main(const int argc, const char * const * const argv) 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); @@ -1642,11 +1702,11 @@ main(const int argc, const char * const * const argv) return errors != 0; } } -#else /* !PNG_INFO_IMAGE_SUPPORTED || !PNG_READ_SUPPORTED */ +#else /* !READ_PNG */ int main(void) { fprintf(stderr, "pngimage: no support for png_read/write_image\n"); - return 77; + return SKIP; } #endif diff --git a/src/third-party/libpng/contrib/libtests/pngstest-errors.h b/src/third-party/libpng/contrib/libtests/pngstest-errors.h new file mode 100644 index 000000000..3356f1c46 --- /dev/null +++ b/src/third-party/libpng/contrib/libtests/pngstest-errors.h @@ -0,0 +1,165 @@ +/* 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/src/third-party/libpng/contrib/libtests/pngstest.c b/src/third-party/libpng/contrib/libtests/pngstest.c index d7c1c1e79..ab4508930 100644 --- a/src/third-party/libpng/contrib/libtests/pngstest.c +++ b/src/third-party/libpng/contrib/libtests/pngstest.c @@ -1,9 +1,8 @@ /*- * pngstest.c * - * Copyright (c) 2013-2014 John Cunningham Bowler - * - * Last changed in libpng 1.6.16 [December 22, 2014] + * 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 @@ -35,6 +34,15 @@ # 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" @@ -99,10 +107,18 @@ make_random_bytes(png_uint_32* seed, void* pv, size_t size) 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) { - static png_uint_32 color_seed[2] = { 0x12345678, 0x9abcdef }; make_random_bytes(color_seed, color, sizeof *color); } @@ -307,7 +323,7 @@ compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms) } #endif /* unused */ -#define READ_FILE 1 /* else memory */ +#define USE_FILE 1 /* else memory */ #define USE_STDIO 2 /* else use file name */ #define STRICT 4 /* fail on warnings too */ #define VERBOSE 8 @@ -316,16 +332,19 @@ compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms) #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 & READ_FILE) + if (opts & USE_FILE) printf(" --file"); if (opts & USE_STDIO) printf(" --stdio"); - if (opts & STRICT) - printf(" --strict"); + if (!(opts & STRICT)) + printf(" --nostrict"); if (opts & VERBOSE) printf(" --verbose"); if (opts & KEEP_TMPFILES) @@ -338,6 +357,12 @@ print_opts(png_uint_32 opts) 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 */ @@ -615,7 +640,7 @@ freeimage(Image *image) if (image->tmpfile_name[0] != 0 && (image->opts & KEEP_TMPFILES) == 0) { - remove(image->tmpfile_name); + (void)remove(image->tmpfile_name); image->tmpfile_name[0] = 0; } } @@ -741,8 +766,15 @@ checkopaque(Image *image) return logerror(image, image->file_name, ": opaque not NULL", ""); } - else if (image->image.warning_or_error != 0 && (image->opts & STRICT) != 0) - return logerror(image, image->file_name, " --strict", ""); + /* 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; @@ -1984,156 +2016,7 @@ static void (* const gpc_fn_colormapped[8/*in*/][8/*out*/]) * gpc_error_to_colormap. */ #if PNG_FORMAT_FLAG_COLORMAP == 8 /* extra check also required */ -/* START MACHINE GENERATED */ -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, 18, 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, 4, 13, 0 }, { 0, 14, 13, 0 }, { 0, 19, 0, 0 }, { 0, 0, 0, 0 }, - { 0, 832, 764, 0 }, { 0, 832, 764, 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, 9, 7, 0 }, { 0, 74, 9, 0 }, { 0, 16, 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, 8, 0 }, { 0, 0, 8, 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, 8, 0 }, { 0, 9, 8, 0 }, - { 0, 585, 427, 0 }, { 0, 585, 427, 0 }, { 0, 717, 409, 0 }, { 0, 717, 409, 0 }, - { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 }, - { 0, 13323, 460, 0 }, { 0, 334, 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, 19, 0 }, { 0, 0, 19, 0 }, { 0, 0, 15, 0 }, { 0, 0, 15, 0 } - }, { /* input: sRGB-rgb+alpha */ - { 0, 12, 14, 0 }, { 0, 180, 14, 0 }, { 0, 14, 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, 8, 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, 8, 3, 0 }, { 0, 32, 3, 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, 2, 0 }, { 0, 255, 2, 25 }, { 0, 88, 2, 0 }, { 0, 255, 2, 25 }, - { 0, 1012, 745, 0 }, { 0, 16026, 745, 6425 }, { 0, 1012, 745, 0 }, { 0, 16026, 745, 6425 } - }, { /* input: sRGB-rgb */ - { 0, 0, 19, 0 }, { 0, 0, 19, 0 }, { 0, 0, 25, 0 }, { 0, 0, 25, 0 }, - { 0, 0, 937, 0 }, { 0, 0, 937, 0 }, { 0, 0, 13677, 0 }, { 0, 0, 13677, 0 } - }, { /* input: sRGB-rgb+alpha */ - { 0, 63, 77, 0 }, { 0, 255, 19, 25 }, { 0, 220, 25, 0 }, { 0, 255, 25, 67 }, - { 0, 17534, 18491, 0 }, { 0, 15614, 2824, 6425 }, { 0, 14019, 13677, 0 }, { 0, 48573, 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, 97, 74, 0 }, { 0, 255, 74, 25 }, - { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6552 }, { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6552 } - }, { /* 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, 46509, 24992, 17347 } - } -}; -/* END MACHINE GENERATED */ +# include "pngstest-errors.h" /* machine generated */ #endif /* COLORMAP flag check */ #endif /* flag checks */ @@ -2154,7 +2037,7 @@ typedef struct int in_opaque; /* Value of input alpha that is opaque */ int is_palette; /* Sample values come from the palette */ int accumulate; /* Accumlate component errors (don't log) */ - int output_8bit; /* Output is 8 bit (else 16 bit) */ + int output_8bit; /* Output is 8-bit (else 16-bit) */ void (*in_gp)(Pixel*, png_const_voidp); void (*out_gp)(Pixel*, png_const_voidp); @@ -2727,9 +2610,9 @@ compare_two_images(Image *a, Image *b, int via_linear, const unsigned int b_sample = PNG_IMAGE_SAMPLE_SIZE(formatb); int alpha_added, alpha_removed; int bchannels; - int btoa[4]; 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) @@ -2828,7 +2711,7 @@ compare_two_images(Image *a, Image *b, int via_linear, else if (y >= b->image.colormap_entries) { - if ((a->opts & ACCUMULATE) == 0) + if ((b->opts & ACCUMULATE) == 0) { char pindex[9]; sprintf(pindex, "%lu[%lu]", (unsigned long)y, @@ -2862,22 +2745,27 @@ compare_two_images(Image *a, Image *b, int via_linear, */ 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[9]; - sprintf(pindex, "%d[%lu]", amax, - (unsigned long)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[9]; - sprintf(pindex, "%d[%lu]", bmax, - (unsigned long)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); } } @@ -2997,10 +2885,13 @@ compare_two_images(Image *a, Image *b, int via_linear, { 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; @@ -3016,10 +2907,13 @@ compare_two_images(Image *a, Image *b, int via_linear, { 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; @@ -3157,14 +3051,14 @@ read_file(Image *image, png_uint_32 format, png_const_colorp background) static int read_one_file(Image *image) { - if (!(image->opts & READ_FILE) || (image->opts & USE_STDIO)) + 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 & READ_FILE) + if (image->opts & USE_FILE) image->input_file = f; else /* memory */ @@ -3175,7 +3069,9 @@ read_one_file(Image *image) 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)); @@ -3243,7 +3139,41 @@ write_one_file(Image *output, Image *image, int convert_to_8bit) 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) { @@ -3272,10 +3202,14 @@ write_one_file(Image *output, Image *image, int convert_to_8bit) else return logerror(image, "tmpfile", ": open: ", strerror(errno)); +#else /* SIMPLIFIED_WRITE_STDIO */ + return logerror(image, "tmpfile", ": open: unsupported", ""); +#endif /* SIMPLIFIED_WRITE_STDIO */ } - else + else if (image->opts & USE_FILE) { +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED static int counter = 0; char name[32]; @@ -3295,6 +3229,51 @@ write_one_file(Image *output, Image *image, int convert_to_8bit) 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 @@ -3470,6 +3449,8 @@ test_one_file(const char *file_name, format_list *formats, png_uint_32 opts, 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); @@ -3507,7 +3488,7 @@ test_one_file(const char *file_name, format_list *formats, png_uint_32 opts, int main(int argc, char **argv) { - png_uint_32 opts = FAST_WRITE; + png_uint_32 opts = FAST_WRITE | STRICT; format_list formats; const char *touch = NULL; int log_pass = 0; @@ -3516,11 +3497,17 @@ main(int argc, char **argv) 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= 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 @@ -103,6 +114,7 @@ typedef png_byte *png_const_bytep; #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) @@ -199,6 +211,13 @@ static struct 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, @@ -363,7 +382,7 @@ ancillary(const char *name) return PNG_CHUNK_ANCILLARY(PNG_U32(name[0], name[1], name[2], name[3])); } -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED static int ancillaryb(const png_byte *name) { @@ -467,7 +486,7 @@ get_valid(display *d, png_infop info_ptr) png_textp text; png_uint_32 ntext = png_get_text(d->png_ptr, info_ptr, &text, NULL); - while (ntext-- > 0) switch (text[ntext].compression) + while (ntext > 0) switch (text[--ntext].compression) { case -1: flags |= PNG_INFO_tEXt; @@ -554,7 +573,7 @@ read_callback(png_structp pp, png_unknown_chunkp pc) /* 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_STORE_UNKNOWN_CHUNKS_SUPPORTED +# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED return discard; # else return 1; /*handled; discard*/ @@ -562,7 +581,7 @@ read_callback(png_structp pp, png_unknown_chunkp pc) } #endif /* READ_USER_CHUNKS_SUPPORTED */ -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED static png_uint_32 get_unknown(display *d, png_infop info_ptr, int after_IDAT) { @@ -603,7 +622,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT) ++(d->error_count); break; } - /* FALL THROUGH (safe) */ + /* FALLTHROUGH */ /* (safe) */ case PNG_HANDLE_CHUNK_ALWAYS: break; } @@ -615,7 +634,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT) return flags; } -#else +#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 */ @@ -634,8 +653,8 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT) * a check to ensure the logic is correct. */ # error No store support and no user chunk support, this will not work -# endif -#endif +# endif /* READ_USER_CHUNKS */ +#endif /* SAVE_UNKNOWN_CHUNKS */ static int check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/, @@ -722,11 +741,17 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/, * in this case, so we just check the arguments! This could * be improved in the future by using the read callback. */ - png_byte name[5]; +# 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; + memcpy(name, chunk_info[chunk].name, 5); + png_set_keep_unknown_chunks(d->png_ptr, option, name, 1); + chunk_info[chunk].keep = option; + } continue; } @@ -735,7 +760,12 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/, case 7: /* default */ if (memcmp(argv[i], "default", 7) == 0) { - png_set_keep_unknown_chunks(d->png_ptr, option, NULL, 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; } @@ -745,7 +775,12 @@ check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/, case 3: /* all */ if (memcmp(argv[i], "all", 3) == 0) { - png_set_keep_unknown_chunks(d->png_ptr, option, NULL, -1); +# 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) @@ -985,6 +1020,20 @@ perform_one_test(FILE *fp, int argc, const char **argv, 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 @@ -1049,7 +1098,7 @@ static const char *standard_tests[] = "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", 0, + "sBIT=save", "sRGB=save", "eXIf=save", 0, 0/*end*/ }; @@ -1229,7 +1278,7 @@ main(void) fprintf(stderr, " test ignored: no support to find out about unknown chunks\n"); /* So the test is skipped: */ - return 77; + return SKIP; } #endif /* READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS */ @@ -1240,6 +1289,6 @@ main(void) fprintf(stderr, " test ignored: no support to modify unknown chunk handling\n"); /* So the test is skipped: */ - return 77; + return SKIP; } -#endif /* SET_UNKNOWN_CHUNKS && READ */ +#endif /* SET_UNKNOWN_CHUNKS && READ*/ diff --git a/src/third-party/libpng/contrib/libtests/pngvalid.c b/src/third-party/libpng/contrib/libtests/pngvalid.c index 79de125da..4dc4f8447 100644 --- a/src/third-party/libpng/contrib/libtests/pngvalid.c +++ b/src/third-party/libpng/contrib/libtests/pngvalid.c @@ -1,9 +1,8 @@ /* pngvalid.c - validate libpng by constructing then reading png files. * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 2014-2015 Glenn Randers-Pehrson - * Written by John Cunningham Bowler + * 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 @@ -62,10 +61,10 @@ /* 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 -# define SKIP 0 -#else +#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. @@ -74,7 +73,7 @@ (defined(PNG_FIXED_POINT_SUPPORTED) || defined(PNG_FLOATING_POINT_SUPPORTED)) #if PNG_LIBPNG_VER < 10500 -/* This deliberately lacks the PNG_CONST. */ +/* This deliberately lacks the const. */ typedef png_byte *png_const_bytep; /* This is copied from 1.5.1 png.h: */ @@ -116,11 +115,32 @@ typedef png_byte *png_const_bytep; # 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 /* For floating point constants */ #include /* For malloc */ #include /* For memcpy, memset */ #include /* 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. */ @@ -164,6 +184,24 @@ define_exception_type(struct png_store*); */ #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 @@ -172,7 +210,7 @@ define_exception_type(struct png_store*); * warning messages into buffers that are too small. */ static size_t safecat(char *buffer, size_t bufsize, size_t pos, - PNG_CONST char *cat) + const char *cat) { while (pos < bufsize && cat != NULL && *cat != 0) buffer[pos++] = *cat++; @@ -201,16 +239,16 @@ static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d, } #endif -static PNG_CONST char invalid[] = "invalid"; -static PNG_CONST char sep[] = ": "; +static const char invalid[] = "invalid"; +static const char sep[] = ": "; -static PNG_CONST char *colour_types[8] = +static const char *colour_types[8] = { "grayscale", invalid, "truecolour", "indexed-colour", "grayscale with alpha", invalid, "truecolour with alpha", invalid }; -#ifdef PNG_READ_SUPPORTED +#ifdef PNG_READ_TRANSFORMS_SUPPORTED /* Convert a double precision value to fixed point. */ static png_fixed_point fix(double d) @@ -258,7 +296,8 @@ make_four_random_bytes(png_uint_32* seed, png_bytep bytes) make_random_bytes(seed, bytes, 4); } -#ifdef PNG_READ_SUPPORTED +#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\ + defined PNG_WRITE_FILTER_SUPPORTED static void randomize(void *pv, size_t size) { @@ -266,36 +305,62 @@ randomize(void *pv, size_t size) make_random_bytes(random_seed, pv, size); } -#define RANDOMIZE(this) randomize(&(this), sizeof (this)) +#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) { - unsigned int x; - - RANDOMIZE(x); - - return x % max; /* 0 .. max-1 */ + 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) { - unsigned char x; - - RANDOMIZE(x); - - return x & 1; + return random_byte() & 1; } -#endif -#endif /* PNG_READ_SUPPORTED */ +#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 (0 otherwise.) + * 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) + \ @@ -316,12 +381,16 @@ standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type, png_uint_32 w, png_uint_32 h, int do_interlace) { pos = safecat(buffer, bufsize, pos, colour_types[colour_type]); - if (npalette > 0) + 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"); @@ -378,25 +447,32 @@ standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id) static int next_format(png_bytep colour_type, png_bytep bit_depth, - unsigned int* palette_number, int no_low_depth_gray) + unsigned int* palette_number, int low_depth_gray, int tRNS) { if (*bit_depth == 0) { *colour_type = 0; - if (no_low_depth_gray) - *bit_depth = 8; - else + if (low_depth_gray) *bit_depth = 1; + else + *bit_depth = 8; *palette_number = 0; return 1; } - if (*colour_type == 3) + if (*colour_type < 4/*no alpha channel*/) { - /* Add multiple palettes for colour type 3. */ - if (++*palette_number < PALETTE_COUNT(*bit_depth)) + /* 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; } @@ -500,7 +576,8 @@ sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth, */ static void pixel_copy(png_bytep toBuffer, png_uint_32 toIndex, - png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize) + 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. @@ -510,15 +587,25 @@ pixel_copy(png_bytep toBuffer, png_uint_32 toIndex, if (pixelSize < 8) /* Sub-byte */ { /* Mask to select the location of the copied pixel: */ - unsigned int destMask = ((1U<> 3] & ~destMask; unsigned int sourceByte = fromBuffer[fromIndex >> 3]; /* Don't rely on << or >> supporting '0' here, just in case: */ fromIndex &= 7; - if (fromIndex > 0) sourceByte <<= fromIndex; - if ((toIndex & 7) > 0) sourceByte >>= toIndex & 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)); } @@ -531,7 +618,8 @@ pixel_copy(png_bytep toBuffer, png_uint_32 toIndex, * bytes at the end. */ static void -row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth) +row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth, + int littleendian) { memcpy(toBuffer, fromBuffer, bitWidth >> 3); @@ -541,10 +629,10 @@ row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth) toBuffer += bitWidth >> 3; fromBuffer += bitWidth >> 3; - /* The remaining bits are in the top of the byte, the mask is the bits to - * retain. - */ - mask = 0xff >> (bitWidth & 7); + if (littleendian) + mask = 0xff << (bitWidth & 7); + else + mask = 0xff >> (bitWidth & 7); *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask)); } } @@ -620,6 +708,8 @@ 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) */ png_size_t datacount; /* In this (the last) buffer */ png_store_buffer data; /* Last buffer in file */ @@ -675,6 +765,13 @@ typedef struct png_store 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; @@ -684,6 +781,9 @@ typedef struct png_store png_byte* image; /* Buffer for reading interlaced images */ png_size_t cb_image; /* Size of this buffer */ png_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; @@ -708,7 +808,7 @@ store_pool_mark(png_bytep mark) make_four_random_bytes(store_seed, mark); } -#ifdef PNG_READ_SUPPORTED +#ifdef PNG_READ_TRANSFORMS_SUPPORTED /* Use this for random 32 bit values; this function makes sure the result is * non-zero. */ @@ -770,6 +870,11 @@ store_init(png_store* ps) 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; @@ -792,6 +897,11 @@ 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); @@ -805,9 +915,6 @@ store_storenew(png_store *ps) { png_store_buffer *pb; - if (ps->writepos != STORE_BUFFER_SIZE) - png_error(ps->pwrite, "invalid store call"); - pb = voidcast(png_store_buffer*, malloc(sizeof *pb)); if (pb == NULL) @@ -838,21 +945,52 @@ store_freefile(png_store_file **ppf) } } +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 storeage, 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 = voidcast(png_store_file*, malloc(sizeof *pf)); + 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; @@ -866,7 +1004,7 @@ store_storefile(png_store *ps, png_uint_32 id) /* 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, PNG_CONST char *msg) + size_t pos, const char *msg) { if (pp != NULL && pp == ps->pread) { @@ -984,7 +1122,7 @@ store_warning(png_structp ppIn, png_const_charp message) */ /* Return a single row from the correct image. */ static png_bytep -store_image_row(PNG_CONST png_store* ps, png_const_structp pp, int nImage, +store_image_row(const png_store* ps, png_const_structp pp, int nImage, png_uint_32 y) { png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2; @@ -1088,7 +1226,7 @@ store_ensure_image(png_store *ps, png_const_structp pp, int nImages, #ifdef PNG_READ_SUPPORTED static void -store_image_check(PNG_CONST png_store* ps, png_const_structp pp, int iImage) +store_image_check(const png_store* ps, png_const_structp pp, int iImage) { png_const_bytep image = ps->image; @@ -1103,7 +1241,7 @@ store_image_check(PNG_CONST png_store* ps, png_const_structp pp, int iImage) image += 2; /* skip image first row markers */ - while (rows-- > 0) + for (; rows > 0; --rows) { if (image[-2] != 190 || image[-1] != 239) png_error(pp, "row start overwritten"); @@ -1118,32 +1256,119 @@ store_image_check(PNG_CONST png_store* ps, png_const_structp pp, int iImage) } #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, png_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) { - size_t cb; + if (writepos >= STORE_BUFFER_SIZE) + store_storenew(ps), writepos = 0; - if (ps->writepos >= STORE_BUFFER_SIZE) - store_storenew(ps); + if (chunkpos < 4) + { + png_byte b = *pb++; + --st; + chunklen = (chunklen << 8) + b; + ps->new.buffer[writepos++] = b; + ++chunkpos; + } - cb = st; + else if (chunkpos < 8) + { + png_byte b = *pb++; + --st; + chunktype = (chunktype << 8) + b; + ps->new.buffer[writepos++] = b; - if (cb > STORE_BUFFER_SIZE - ps->writepos) - cb = STORE_BUFFER_SIZE - ps->writepos; + if (++chunkpos == 8) + { + chunklen &= 0xffffffffU; + if (chunklen > 0x7fffffffU) + png_error(pp, "chunk length too great"); - memcpy(ps->new.buffer + ps->writepos, pb, cb); - pb += cb; - st -= cb; - ps->writepos += cb; - } + 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 */ + { + png_size_t cb = st; + + if (cb > STORE_BUFFER_SIZE - writepos) + cb = STORE_BUFFER_SIZE - writepos; + + if (cb > chunklen - chunkpos/* bytes left in chunk*/) + cb = (png_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 @@ -1163,7 +1388,6 @@ store_read_buffer_size(png_store *ps) return ps->current->datacount; } -#ifdef PNG_READ_TRANSFORMS_SUPPORTED /* Return total bytes available for read. */ static size_t store_read_buffer_avail(png_store *ps) @@ -1188,7 +1412,6 @@ store_read_buffer_avail(png_store *ps) return 0; } -#endif static int store_read_buffer_next(png_store *ps) @@ -1240,6 +1463,240 @@ store_read_imp(png_store *ps, png_bytep pb, png_size_t st) } } +static png_size_t +store_read_chunk(png_store *ps, png_bytep pb, const png_size_t max, + const png_size_t min) +{ + png_uint_32 chunklen = ps->chunklen; + png_uint_32 chunktype = ps->chunktype; + png_uint_32 chunkpos = ps->chunkpos; + png_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 += (png_size_t)/*SAFE*/avail; + st -= (png_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 */ + { + png_size_t avail = st; + + if (avail > chunklen - chunkpos) + avail = (png_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, png_size_t st) { @@ -1249,26 +1706,33 @@ store_read(png_structp ppIn, png_bytep pb, png_size_t st) if (ps == NULL || ps->pread != pp) png_error(pp, "bad store read call"); - store_read_imp(ps, pb, st); + store_read_chunk(ps, pb, st, st); } static void store_progressive_read(png_store *ps, png_structp pp, png_infop pi) { - /* Notice that a call to store_read will cause this function to fail because - * readpos will be set. - */ if (ps->pread != pp || ps->current == NULL || ps->next == NULL) png_error(pp, "store state damaged (progressive)"); - do + /* 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) { - if (ps->readpos != 0) - png_error(pp, "store_read called during progressive read"); + static png_uint_32 noise = 2; + png_size_t cb; + png_byte buffer[512]; - png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps)); + /* 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); } - while (store_read_buffer_next(ps)); } #endif /* PNG_READ_SUPPORTED */ @@ -1305,7 +1769,10 @@ store_current_palette(png_store *ps, int *npalette) * 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; @@ -1335,7 +1802,7 @@ typedef struct store_memory * all the memory. */ static void -store_pool_error(png_store *ps, png_const_structp pp, PNG_CONST char *msg) +store_pool_error(png_store *ps, png_const_structp pp, const char *msg) { if (pp != NULL) png_error(pp, msg); @@ -1399,7 +1866,7 @@ store_pool_delete(png_store *ps, store_pool *pool) next->next = NULL; fprintf(stderr, "\t%lu bytes @ %p\n", - (unsigned long)next->size, (PNG_CONST void*)(next+1)); + (unsigned long)next->size, (const void*)(next+1)); /* The NULL means this will always return, even if the memory is * corrupted. */ @@ -1554,8 +2021,7 @@ store_write_reset(png_store *ps) * returned libpng structures as destroyed by store_write_reset above. */ static png_structp -set_store_for_write(png_store *ps, png_infopp ppi, - PNG_CONST char * volatile name) +set_store_for_write(png_store *ps, png_infopp ppi, const char *name) { anon_context(ps); @@ -1637,6 +2103,11 @@ store_read_reset(png_store *ps) 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 @@ -1651,6 +2122,11 @@ store_read_set(png_store *ps, png_uint_32 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; } @@ -1675,7 +2151,7 @@ store_read_set(png_store *ps, png_uint_32 id) */ static png_structp set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id, - PNG_CONST char *name) + const char *name) { /* Set the name for png_error */ safecat(ps->test, sizeof ps->test, 0, name); @@ -1782,6 +2258,7 @@ typedef struct color_encoding } color_encoding; #ifdef PNG_READ_SUPPORTED +#if defined PNG_READ_TRANSFORMS_SUPPORTED && defined PNG_READ_cHRM_SUPPORTED static double chromaticity_x(CIE_color c) { @@ -1795,7 +2272,7 @@ chromaticity_y(CIE_color c) } static CIE_color -white_point(PNG_CONST color_encoding *encoding) +white_point(const color_encoding *encoding) { CIE_color white; @@ -1805,12 +2282,13 @@ white_point(PNG_CONST color_encoding *encoding) return white; } +#endif /* READ_TRANSFORMS && READ_cHRM */ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED static void normalize_color_encoding(color_encoding *encoding) { - PNG_CONST double whiteY = encoding->red.Y + encoding->green.Y + + const double whiteY = encoding->red.Y + encoding->green.Y + encoding->blue.Y; if (whiteY != 1) @@ -1828,9 +2306,10 @@ normalize_color_encoding(color_encoding *encoding) } #endif +#ifdef PNG_READ_TRANSFORMS_SUPPORTED static size_t safecat_color_encoding(char *buffer, size_t bufsize, size_t pos, - PNG_CONST color_encoding *e, double encoding_gamma) + const color_encoding *e, double encoding_gamma) { if (e != 0) { @@ -1867,6 +2346,7 @@ safecat_color_encoding(char *buffer, size_t bufsize, size_t pos, return pos; } +#endif /* READ_TRANSFORMS */ #endif /* PNG_READ_SUPPORTED */ typedef struct png_modifier @@ -1891,9 +2371,9 @@ typedef struct png_modifier unsigned int ngammas; unsigned int ngamma_tests; /* Number of gamma tests to run*/ double current_gamma; /* 0 if not set */ - PNG_CONST color_encoding *encodings; + const color_encoding *encodings; unsigned int nencodings; - PNG_CONST color_encoding *current_encoding; /* If an encoding has been set */ + const color_encoding *current_encoding; /* If an encoding has been set */ unsigned int encoding_counter; /* For iteration */ int encoding_ignored; /* Something overwrote it */ @@ -1904,7 +2384,7 @@ typedef struct png_modifier unsigned int repeat :1; /* Repeat this transform test. */ unsigned int test_uses_encoding :1; - /* Lowest sbit to test (libpng fails for sbit < 8) */ + /* 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 @@ -1924,6 +2404,8 @@ typedef struct png_modifier * 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 */ @@ -1959,6 +2441,7 @@ typedef struct png_modifier /* 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 @@ -1990,6 +2473,16 @@ typedef struct png_modifier 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 @@ -2042,6 +2535,11 @@ modifier_init(png_modifier *pm) 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; @@ -2054,6 +2552,11 @@ modifier_init(png_modifier *pm) 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; @@ -2087,7 +2590,7 @@ static double digitize(double value, int depth, int do_round) * rounding and 'do_round' should be 1, if it is 0 the digitized value will * be truncated. */ - PNG_CONST unsigned int digitization_factor = (1U << depth) -1; + const unsigned int digitization_factor = (1U << depth) -1; /* Limiting the range is done as a convenience to the caller - it's easier to * do it once here than every time at the call site. @@ -2106,7 +2609,7 @@ static double digitize(double value, int depth, int do_round) #endif /* RGB_TO_GRAY */ #ifdef PNG_READ_GAMMA_SUPPORTED -static double abserr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) +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. @@ -2118,7 +2621,7 @@ static double abserr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) return pm->maxabs8; } -static double calcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) +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). @@ -2131,7 +2634,7 @@ static double calcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) return pm->maxcalc8; } -static double pcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) +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. @@ -2154,7 +2657,7 @@ static double pcerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) * The specified parameter does *not* include the base .5 digitization error but * it is added here. */ -static double outerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) +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 @@ -2186,7 +2689,7 @@ static double outerr(PNG_CONST png_modifier *pm, int in_depth, int out_depth) * 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(PNG_CONST png_modifier *pm, int in_depth, int out_depth) +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: @@ -2224,7 +2727,7 @@ static double outlog(PNG_CONST png_modifier *pm, int in_depth, int out_depth) * but in the 8 bit calculation case it's actually quantization to a multiple of * 257! */ -static int output_quantization_factor(PNG_CONST png_modifier *pm, int in_depth, +static int output_quantization_factor(const png_modifier *pm, int in_depth, int out_depth) { if (out_depth == 16 && in_depth != 16 && @@ -2288,7 +2791,7 @@ modification_init(png_modification *pmm) #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED static void -modifier_current_encoding(PNG_CONST png_modifier *pm, color_encoding *ce) +modifier_current_encoding(const png_modifier *pm, color_encoding *ce) { if (pm->current_encoding != 0) *ce = *pm->current_encoding; @@ -2300,9 +2803,10 @@ modifier_current_encoding(PNG_CONST png_modifier *pm, color_encoding *ce) } #endif +#ifdef PNG_READ_TRANSFORMS_SUPPORTED static size_t safecat_current_encoding(char *buffer, size_t bufsize, size_t pos, - PNG_CONST png_modifier *pm) + const png_modifier *pm) { pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding, pm->current_gamma); @@ -2312,6 +2816,7 @@ safecat_current_encoding(char *buffer, size_t bufsize, size_t pos, return pos; } +#endif /* Iterate through the usefully testable color encodings. An encoding is one * of: @@ -2331,7 +2836,7 @@ safecat_current_encoding(char *buffer, size_t bufsize, size_t pos, * caller of modifier_reset must reset it at the start of each run of the test! */ static unsigned int -modifier_total_encodings(PNG_CONST png_modifier *pm) +modifier_total_encodings(const png_modifier *pm) { return 1 + /* (1) nothing */ pm->ngammas + /* (2) gamma values to test */ @@ -2447,29 +2952,18 @@ modifier_set_encoding(png_modifier *pm) * assumption below that the first encoding in the list is the one for sRGB. */ static int -modifier_color_encoding_is_sRGB(PNG_CONST png_modifier *pm) +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(PNG_CONST png_modifier *pm) +modifier_color_encoding_is_set(const png_modifier *pm) { return pm->current_gamma != 0; } -/* Convenience macros. */ -#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d)) -#define CHUNK_IHDR CHUNK(73,72,68,82) -#define CHUNK_PLTE CHUNK(80,76,84,69) -#define CHUNK_IDAT CHUNK(73,68,65,84) -#define CHUNK_IEND CHUNK(73,69,78,68) -#define CHUNK_cHRM CHUNK(99,72,82,77) -#define CHUNK_gAMA CHUNK(103,65,77,65) -#define CHUNK_sBIT CHUNK(115,66,73,84) -#define CHUNK_sRGB CHUNK(115,82,71,66) - /* The guts of modification are performed during a read. */ static void modifier_crc(png_bytep buffer) @@ -2509,7 +3003,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st) { static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; case modifier_start: - store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */ + store_read_chunk(&pm->this, pm->buffer, 8, 8); /* signature. */ pm->buffer_count = 8; pm->buffer_position = 0; @@ -2519,7 +3013,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st) break; case modifier_signature: - store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */ + store_read_chunk(&pm->this, pm->buffer, 13+12, 13+12); /* IHDR */ pm->buffer_count = 13+12; pm->buffer_position = 0; @@ -2560,7 +3054,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st) { if (cb > st) cb = st; pm->flush -= cb; - store_read_imp(&pm->this, pb, cb); + store_read_chunk(&pm->this, pb, cb, cb); pb += cb; st -= cb; if (st == 0) return; @@ -2577,7 +3071,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st) pm->pending_chunk = 0; } else - store_read_imp(&pm->this, pm->buffer, 8); + store_read_chunk(&pm->this, pm->buffer, 8, 8); pm->buffer_count = 8; pm->buffer_position = 0; @@ -2643,8 +3137,8 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st) */ if (len+12 <= sizeof pm->buffer) { - store_read_imp(&pm->this, pm->buffer+pm->buffer_count, - len+12-pm->buffer_count); + png_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. */ @@ -2773,7 +3267,7 @@ modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi) /* Set up a modifier. */ static png_structp set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id, - PNG_CONST char *name) + 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 @@ -2833,7 +3327,7 @@ gama_modification_init(gama_modification *me, png_modifier *pm, double gammad) typedef struct chrm_modification { png_modification this; - PNG_CONST color_encoding *encoding; + const color_encoding *encoding; png_fixed_point wx, wy, rx, ry, gx, gy, bx, by; } chrm_modification; @@ -2857,7 +3351,7 @@ chrm_modify(png_modifier *pm, png_modification *me, int add) static void chrm_modification_init(chrm_modification *me, png_modifier *pm, - PNG_CONST color_encoding *encoding) + const color_encoding *encoding) { CIE_color white = white_point(encoding); @@ -3185,13 +3679,58 @@ init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette, 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 + 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, const png_byte colour_type, + const 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; + const 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: */ @@ -3441,13 +3980,17 @@ transform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX], #ifdef PNG_WRITE_INTERLACING_SUPPORTED # define INTERLACE_LAST PNG_INTERLACE_LAST # define check_interlace_type(type) ((void)(type)) -#else -# define INTERLACE_LAST (PNG_INTERLACE_NONE+1) -# define png_set_interlace_handling(a) (1) - +# 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 PNG_CONST interlace_type) +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 @@ -3457,17 +4000,110 @@ check_interlace_type(int PNG_CONST interlace_type) 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 -/* Make a standardized image given a an image colour type, bit depth and +/* 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< 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); } } @@ -3598,19 +4266,20 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, } static void -make_transform_images(png_store *ps) +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(ps->test, sizeof ps->test, 0, "make standard images"); + 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. + * 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, 0)) + while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1)) { int interlace_type; @@ -3620,59 +4289,13 @@ make_transform_images(png_store *ps) char name[FILE_NAME_SIZE]; standard_name(name, sizeof name, 0, colour_type, bit_depth, - palette_number, interlace_type, 0, 0, 0); - make_transform_image(ps, colour_type, bit_depth, palette_number, + palette_number, interlace_type, 0, 0, do_own_interlace); + make_transform_image(&pm->this, colour_type, bit_depth, palette_number, interlace_type, name); } } } -/* 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) -{ - 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. - */ - xin = PNG_PASS_START_COL(pass); - xstep = 1U<= PNG_FILTER_VALUE_LAST ? PNG_ALL_FILTERS : nfilter); + { + int filters = 8 << random_mod(PNG_FILTER_VALUE_LAST); - if (nfilter-- == 0) - nfilter = PNG_FILTER_VALUE_LAST-1; + 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); @@ -3896,8 +4518,8 @@ make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, } static void -make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo, - int PNG_CONST bdhi) +make_size(png_store* const ps, png_byte const colour_type, int bdlo, + int const bdhi) { for (; bdlo <= bdhi; ++bdlo) { @@ -3920,6 +4542,11 @@ make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo, # 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 @@ -3993,41 +4620,45 @@ sBIT_error_fn(png_structp pp, png_infop pi) png_set_sBIT(pp, pi, &bad); } -static PNG_CONST struct +static const struct { void (*fn)(png_structp, png_infop); - PNG_CONST char *msg; + const char *msg; unsigned int warning :1; /* the error is a warning... */ } error_test[] = { - /* no warnings makes these errors undetectable. */ - { sBIT0_error_fn, "sBIT(0): failed to detect error", 1 }, - { sBIT_error_fn, "sBIT(too big): failed to detect error", 1 }, + /* 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* volatile psIn, png_byte PNG_CONST colour_type, +make_error(png_store* const ps, png_byte const colour_type, png_byte bit_depth, int interlace_type, int test, png_const_charp name) { - png_store * volatile ps = psIn; - context(ps, fault); check_interlace_type(interlace_type); Try { - png_structp pp; png_infop pi; - - pp = set_store_for_write(ps, &pi, name); + const png_structp pp = set_store_for_write(ps, &pi, name); + png_uint_32 w, h; + gnu_volatile(pp) if (pp == NULL) Throw ps; - png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth), - transform_height(pp, colour_type, bit_depth), bit_depth, colour_type, - interlace_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + 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*/); @@ -4039,6 +4670,8 @@ make_error(png_store* volatile psIn, png_byte PNG_CONST colour_type, # 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; @@ -4059,45 +4692,77 @@ make_error(png_store* volatile psIn, png_byte PNG_CONST colour_type, } Catch (fault) - ps = fault; /* expected exit, make sure ps is not clobbered */ + { /* expected exit */ + } #undef exception__prev #undef exception__env /* And clear these flags */ - ps->expect_error = 0; ps->expect_warning = 0; - /* Now write the whole image, just to make sure that the detected, or - * undetected, errro has not created problems inside libpng. - */ - if (png_get_rowbytes(pp, pi) != - transform_rowsize(pp, colour_type, bit_depth)) - png_error(pp, "row size incorrect"); + if (ps->expect_error) + ps->expect_error = 0; else { - png_uint_32 h = transform_height(pp, colour_type, bit_depth); - int npasses = png_set_interlace_handling(pp); - int pass; + /* Now write the whole image, just to make sure that the detected, or + * undetected, errro 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"); - if (npasses != npasses_from_interlace_type(pp, interlace_type)) - png_error(pp, "write: png_set_interlace_handling failed"); - - for (pass=0; 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); + png_write_end(pp, pi); + } /* The following deletes the file that was just written. */ store_write_reset(ps); @@ -4110,8 +4775,8 @@ make_error(png_store* volatile psIn, png_byte PNG_CONST colour_type, } static int -make_errors(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, - int bdlo, int PNG_CONST bdhi) +make_errors(png_modifier* const pm, png_byte const colour_type, + int bdlo, int const bdhi) { for (; bdlo <= bdhi; ++bdlo) { @@ -4124,7 +4789,7 @@ make_errors(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, char name[FILE_NAME_SIZE]; standard_name(name, sizeof name, 0, colour_type, 1<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; @@ -4619,14 +5287,14 @@ standard_info_part1(standard_display *dp, png_structp pp, png_infop pi) case 0: dp->transparent.red = dp->transparent.green = dp->transparent.blue = trans_color->gray; - dp->is_transparent = 1; + 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->is_transparent = 1; + dp->has_tRNS = 1; break; case 3: @@ -4647,8 +5315,19 @@ standard_info_part1(standard_display *dp, png_structp pp, png_infop pi) * turning on interlace handling (if do_interlace is not set.) */ dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type); - if (!dp->do_interlace && dp->npasses != png_set_interlace_handling(pp)) - png_error(pp, "validate: file changed 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. @@ -4730,7 +5409,7 @@ static void PNGCBAPI progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass) { png_const_structp pp = ppIn; - PNG_CONST standard_display *dp = voidcast(standard_display*, + const standard_display *dp = voidcast(standard_display*, png_get_progressive_ptr(pp)); /* When handling interlacing some rows will be absent in each pass, the @@ -4754,7 +5433,7 @@ progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass) if (pass != png_get_current_pass_number(pp)) png_error(pp, "png_get_current_pass_number is broken"); -#endif +#endif /* USER_TRANSFORM_INFO */ y = PNG_ROW_FROM_PASS_ROW(y, pass); } @@ -4765,38 +5444,39 @@ progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass) row = store_image_row(dp->ps, pp, 0, y); -#ifdef PNG_READ_INTERLACING_SUPPORTED /* 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); + deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass, + dp->littleendian); else - row_copy(row, new_row, dp->pixel_size * dp->w); + 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 */ } -#ifdef 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"); -#endif /* PNG_READ_INTERLACING_SUPPORTED */ } static void sequential_row(standard_display *dp, png_structp pp, png_infop pi, - PNG_CONST int iImage, PNG_CONST int iDisplay) + const int iImage, const int iDisplay) { - PNG_CONST int npasses = dp->npasses; - PNG_CONST int do_interlace = dp->do_interlace && + const int npasses = dp->npasses; + const int do_interlace = dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7; - PNG_CONST png_uint_32 height = standard_height(pp, dp->id); - PNG_CONST png_uint_32 width = standard_width(pp, dp->id); - PNG_CONST png_store* ps = dp->ps; + const png_uint_32 height = standard_height(pp, dp->id); + const png_uint_32 width = standard_width(pp, dp->id); + const png_store* ps = dp->ps; int pass; for (pass=0; pass= 0) deinterlace_row(store_image_row(ps, pp, iImage, y), row, - dp->pixel_size, dp->w, pass); + 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->pixel_size, dp->w, pass, dp->littleendian); } } else @@ -4982,14 +5662,6 @@ standard_row_validate(standard_display *dp, png_const_structp pp, * 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 PNG_LIBPNG_VER < 10506 - * The side effect inside the libpng sequential reader is that the 'row' - * array retains the correct values for unwritten pixels within the row - * bytes, while the 'display' array gets bits off the end of the image (in - * the last byte) trashed. Unfortunately in the progressive reader the - * row bytes are always trashed, so we always do a pixel_cmp here even though - * a memcmp of all cbRow bytes will succeed for the sequential reader. -#endif */ if (iImage >= 0 && (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y), @@ -5002,19 +5674,12 @@ standard_row_validate(standard_display *dp, png_const_structp pp, png_error(pp, msg); } -#if PNG_LIBPNG_VER < 10506 - /* In this case use pixel_cmp because we need to compare a partial - * byte at the end of the row if the row is not an exact multiple - * of 8 bits wide. (This is fixed in libpng-1.5.6 and pixel_cmp is - * changed to match!) - */ -#endif 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", + 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); @@ -5059,7 +5724,7 @@ standard_end(png_structp ppIn, png_infop pi) /* A single test run checking the standard image to ensure it is not damaged. */ static void -standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id, +standard_test(png_store* const psIn, png_uint_32 const id, int do_interlace, int use_update_info) { standard_display d; @@ -5147,8 +5812,8 @@ standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id, } static int -test_standard(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, - int bdlo, int PNG_CONST bdhi) +test_standard(png_modifier* const pm, png_byte const colour_type, + int bdlo, int const bdhi) { for (; bdlo <= bdhi; ++bdlo) { @@ -5158,7 +5823,7 @@ test_standard(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, interlace_type < INTERLACE_LAST; ++interlace_type) { standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, - interlace_type, 0, 0, 0), 0/*do_interlace*/, pm->use_update_info); + interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info); if (fail(pm)) return 0; @@ -5193,8 +5858,8 @@ perform_standard_test(png_modifier *pm) /********************************** SIZE TESTS ********************************/ static int -test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, - int bdlo, int PNG_CONST bdhi) +test_size(png_modifier* const pm, png_byte const colour_type, + int bdlo, int const bdhi) { /* Run the tests on each combination. * @@ -5203,8 +5868,10 @@ test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, * width and height. This is a waste of time in practice, hence the * hinc and winc stuff: */ - static PNG_CONST png_byte hinc[] = {1, 3, 11, 1, 5}; - static PNG_CONST png_byte winc[] = {1, 9, 5, 7, 1}; + static const png_byte hinc[] = {1, 3, 11, 1, 5}; + static const png_byte winc[] = {1, 9, 5, 7, 1}; + const int save_bdlo = bdlo; + for (; bdlo <= bdhi; ++bdlo) { png_uint_32 h, w; @@ -5230,22 +5897,6 @@ test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, if (fail(pm)) return 0; -# ifdef PNG_WRITE_INTERLACING_SUPPORTED - 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; - - 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 - /* 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. @@ -5257,7 +5908,45 @@ test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, 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); @@ -5265,6 +5954,18 @@ test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type, 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 */ } } @@ -5375,14 +6076,14 @@ image_pixel_setf(image_pixel *this, unsigned int rMax, unsigned int gMax, 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, - PNG_CONST image_pixel *format /*from pngvalid transform of input*/) + const image_pixel *format /*from pngvalid transform of input*/) { - PNG_CONST png_byte sample_depth = (png_byte)(colour_type == + const png_byte sample_depth = (png_byte)(colour_type == PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth); - PNG_CONST unsigned int max = (1U<swap16); - PNG_CONST int littleendian = (format != 0 && format->littleendian); - PNG_CONST int sig_bits = (format != 0 && format->sig_bits); + const unsigned int max = (1U<swap16); + const int littleendian = (format != 0 && format->littleendian); + const 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 @@ -5400,7 +6101,7 @@ image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type, /* This permits the caller to default to the sample value. */ if (palette != 0) { - PNG_CONST unsigned int i = this->palette_index; + const unsigned int i = this->palette_index; this->red = palette[i].red; this->green = palette[i].green; @@ -5476,6 +6177,9 @@ image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type, 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, @@ -5505,10 +6209,14 @@ image_pixel_convert_PLTE(image_pixel *this) /* 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. Palette images will be converted to alpha (using the above API). + * 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, PNG_CONST standard_display *display) +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); @@ -5517,11 +6225,21 @@ image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display) { if (this->colour_type == PNG_COLOR_TYPE_GRAY) { - if (this->bit_depth < 8) - this->bit_depth = 8; +# 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 @@ -5553,9 +6271,11 @@ image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display) this->alphaf = 0; else this->alphaf = 1; - - this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; } + 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 @@ -5565,18 +6285,19 @@ image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display) 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. */ - PNG_CONST char *name; + const char *name; /* Each transform can be disabled from the command line: */ int enable; /* The global list of transforms; read only. */ - struct image_transform *PNG_CONST list; + struct image_transform *const list; /* The global count of the number of times this transform has been set on an * image. @@ -5589,7 +6310,7 @@ typedef struct image_transform /* The next transform in the list, each transform must call its own next * transform after it has processed the pixel successfully. */ - PNG_CONST struct image_transform *next; + const struct image_transform *next; /* A single transform for the image, expressed as a series of function * callbacks and some space for values. @@ -5597,12 +6318,12 @@ typedef struct image_transform * 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)(PNG_CONST struct image_transform *this, + 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)(PNG_CONST struct image_transform *this, + 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 @@ -5611,8 +6332,8 @@ typedef struct image_transform * in the libpng implementation!) The png_structp is solely to allow error * reporting via png_error and png_warning. */ - void (*mod)(PNG_CONST struct image_transform *this, image_pixel *that, - png_const_structp pp, PNG_CONST struct transform_display *display); + 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 @@ -5620,7 +6341,7 @@ typedef struct image_transform * point running it. */ int (*add)(struct image_transform *this, - PNG_CONST struct image_transform **that, png_byte colour_type, + const struct image_transform **that, png_byte colour_type, png_byte bit_depth); } image_transform; @@ -5630,7 +6351,8 @@ typedef struct transform_display /* Parameters */ png_modifier* pm; - PNG_CONST image_transform* transform_list; + const image_transform* transform_list; + unsigned int max_gamma_8; /* Local variables */ png_byte output_colour_type; @@ -5672,7 +6394,7 @@ transform_set_encoding(transform_display *this) /* Three functions to end the list: */ static void -image_transform_ini_end(PNG_CONST image_transform *this, +image_transform_ini_end(const image_transform *this, transform_display *that) { UNUSED(this) @@ -5680,7 +6402,7 @@ image_transform_ini_end(PNG_CONST image_transform *this, } static void -image_transform_set_end(PNG_CONST image_transform *this, +image_transform_set_end(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { UNUSED(this) @@ -5707,11 +6429,11 @@ sample_scale(double sample_value, unsigned int scale) } static void -image_transform_mod_end(PNG_CONST image_transform *this, image_pixel *that, - png_const_structp pp, PNG_CONST transform_display *display) +image_transform_mod_end(const image_transform *this, image_pixel *that, + png_const_structp pp, const transform_display *display) { - PNG_CONST unsigned int scale = (1U<sample_depth)-1; - PNG_CONST int sig_bits = that->sig_bits; + const unsigned int scale = (1U<sample_depth)-1; + const int sig_bits = that->sig_bits; UNUSED(this) UNUSED(pp) @@ -5802,17 +6524,18 @@ static image_transform image_transform_end = */ static void transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id, - PNG_CONST image_transform *transform_list) + const image_transform *transform_list) { memset(dp, 0, sizeof *dp); /* Standard fields */ - standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/, + 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 */ @@ -5848,8 +6571,9 @@ transform_info_imp(transform_display *dp, png_structp pp, png_infop 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) + 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 @@ -5860,16 +6584,16 @@ transform_info_imp(transform_display *dp, png_structp pp, png_infop pi) { case PNG_COLOR_TYPE_PALETTE: if (dp->output_bit_depth > 8) goto error; - /*FALL THROUGH*/ + /* FALLTHROUGH */ case PNG_COLOR_TYPE_GRAY: if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 || dp->output_bit_depth == 4) break; - /*FALL THROUGH*/ + /* FALLTHROUGH */ default: if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16) break; - /*FALL THROUGH*/ + /* FALLTHROUGH */ error: { char message[128]; @@ -5985,7 +6709,7 @@ 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, - PNG_CONST char *name, double digitization_error) + 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 @@ -5996,7 +6720,7 @@ transform_range_check(png_const_structp pp, unsigned int r, unsigned int g, unsigned int max = (1U< limit || !(out >= in_min && out <= in_max)) + if (debugonly(err > limit ||) !(out >= in_min && out <= in_max)) { char message[256]; size_t pos; @@ -6022,6 +6746,8 @@ transform_range_check(png_const_structp pp, unsigned int r, unsigned int g, png_error(pp, message); } + + UNUSED(limit) } static void @@ -6029,20 +6755,20 @@ transform_image_validate(transform_display *dp, png_const_structp pp, png_infop pi) { /* Constants for the loop below: */ - PNG_CONST png_store* PNG_CONST ps = dp->this.ps; - PNG_CONST png_byte in_ct = dp->this.colour_type; - PNG_CONST png_byte in_bd = dp->this.bit_depth; - PNG_CONST png_uint_32 w = dp->this.w; - PNG_CONST png_uint_32 h = dp->this.h; - PNG_CONST png_byte out_ct = dp->output_colour_type; - PNG_CONST png_byte out_bd = dp->output_bit_depth; - PNG_CONST png_byte sample_depth = (png_byte)(out_ct == + const png_store* const ps = dp->this.ps; + const png_byte in_ct = dp->this.colour_type; + const png_byte in_bd = dp->this.bit_depth; + const png_uint_32 w = dp->this.w; + const png_uint_32 h = dp->this.h; + const png_byte out_ct = dp->output_colour_type; + const png_byte out_bd = dp->output_bit_depth; + const png_byte sample_depth = (png_byte)(out_ct == PNG_COLOR_TYPE_PALETTE ? 8 : out_bd); - PNG_CONST png_byte red_sBIT = dp->this.red_sBIT; - PNG_CONST png_byte green_sBIT = dp->this.green_sBIT; - PNG_CONST png_byte blue_sBIT = dp->this.blue_sBIT; - PNG_CONST png_byte alpha_sBIT = dp->this.alpha_sBIT; - PNG_CONST int have_tRNS = dp->this.is_transparent; + const png_byte red_sBIT = dp->this.red_sBIT; + const png_byte green_sBIT = dp->this.green_sBIT; + const png_byte blue_sBIT = dp->this.blue_sBIT; + const png_byte alpha_sBIT = dp->this.alpha_sBIT; + const int have_tRNS = dp->this.is_transparent; double digitization_error; store_palette out_palette; @@ -6097,7 +6823,7 @@ transform_image_validate(transform_display *dp, png_const_structp pp, for (y=0; ythis, fault); @@ -6305,8 +7031,11 @@ static image_transform ITSTRUCT(name) =\ #define PT ITSTRUCT(end) /* stores the previous transform */ /* To save code: */ -static void -image_transform_default_ini(PNG_CONST image_transform *this, +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); @@ -6315,7 +7044,7 @@ image_transform_default_ini(PNG_CONST image_transform *this, #ifdef PNG_READ_BACKGROUND_SUPPORTED static int image_transform_default_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) UNUSED(bit_depth) @@ -6330,7 +7059,7 @@ image_transform_default_add(image_transform *this, #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_palette_to_rgb */ static void -image_transform_png_set_palette_to_rgb_set(PNG_CONST image_transform *this, +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); @@ -6338,9 +7067,9 @@ image_transform_png_set_palette_to_rgb_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_palette_to_rgb_mod(PNG_CONST image_transform *this, +image_transform_png_set_palette_to_rgb_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(that); @@ -6350,7 +7079,7 @@ image_transform_png_set_palette_to_rgb_mod(PNG_CONST image_transform *this, static int image_transform_png_set_palette_to_rgb_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -6368,28 +7097,42 @@ IT(palette_to_rgb); #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_tRNS_to_alpha */ static void -image_transform_png_set_tRNS_to_alpha_set(PNG_CONST image_transform *this, +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(PNG_CONST image_transform *this, +image_transform_png_set_tRNS_to_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + 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) - image_pixel_add_alpha(that, &display->this); +# 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 { @@ -6398,13 +7141,14 @@ image_transform_png_set_tRNS_to_alpha_mod(PNG_CONST image_transform *this, 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, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -6413,9 +7157,14 @@ image_transform_png_set_tRNS_to_alpha_add(image_transform *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. + * channel. In addition, after the bug fix in 1.7.0, there is no longer + * any action on a palette image. */ - return (colour_type & PNG_COLOR_MASK_ALPHA) == 0; + return +# if PNG_LIBPNG_VER >= 10700 + colour_type != PNG_COLOR_TYPE_PALETTE && +# endif + (colour_type & PNG_COLOR_MASK_ALPHA) == 0; } IT(tRNS_to_alpha); @@ -6426,17 +7175,18 @@ IT(tRNS_to_alpha); #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED /* png_set_gray_to_rgb */ static void -image_transform_png_set_gray_to_rgb_set(PNG_CONST image_transform *this, +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(PNG_CONST image_transform *this, +image_transform_png_set_gray_to_rgb_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + 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 @@ -6444,7 +7194,7 @@ image_transform_png_set_gray_to_rgb_mod(PNG_CONST image_transform *this, * 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); + 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) @@ -6467,7 +7217,7 @@ image_transform_png_set_gray_to_rgb_mod(PNG_CONST image_transform *this, static int image_transform_png_set_gray_to_rgb_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -6485,17 +7235,21 @@ IT(gray_to_rgb); #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_expand */ static void -image_transform_png_set_expand_set(PNG_CONST image_transform *this, +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(PNG_CONST image_transform *this, +image_transform_png_set_expand_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { /* The general expand case depends on what the colour type is: */ if (that->colour_type == PNG_COLOR_TYPE_PALETTE) @@ -6504,14 +7258,14 @@ image_transform_png_set_expand_mod(PNG_CONST image_transform *this, that->sample_depth = that->bit_depth = 8; if (that->have_tRNS) - image_pixel_add_alpha(that, &display->this); + 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, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -6531,31 +7285,53 @@ IT(expand); #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_expand_gray_1_2_4_to_8 - * LIBPNG BUG: this just does an 'expand' + * 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( - PNG_CONST image_transform *this, transform_display *that, png_structp pp, + 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( - PNG_CONST image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + 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, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + 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); @@ -6566,17 +7342,24 @@ IT(expand_gray_1_2_4_to_8); #ifdef PNG_READ_EXPAND_16_SUPPORTED /* png_set_expand_16 */ static void -image_transform_png_set_expand_16_set(PNG_CONST image_transform *this, +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(PNG_CONST image_transform *this, +image_transform_png_set_expand_16_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { /* Expect expand_16 to expand everything to 16 bits as a result of also * causing 'expand' to happen. @@ -6585,7 +7368,7 @@ image_transform_png_set_expand_16_mod(PNG_CONST image_transform *this, image_pixel_convert_PLTE(that); if (that->have_tRNS) - image_pixel_add_alpha(that, &display->this); + image_pixel_add_alpha(that, &display->this, 0/*!for background*/); if (that->bit_depth < 16) that->sample_depth = that->bit_depth = 16; @@ -6595,7 +7378,7 @@ image_transform_png_set_expand_16_mod(PNG_CONST image_transform *this, static int image_transform_png_set_expand_16_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) @@ -6614,17 +7397,21 @@ IT(expand_16); #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(PNG_CONST image_transform *this, +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(PNG_CONST image_transform *this, +image_transform_png_set_scale_16_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->bit_depth == 16) { @@ -6640,7 +7427,7 @@ image_transform_png_set_scale_16_mod(PNG_CONST image_transform *this, static int image_transform_png_set_scale_16_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) @@ -6658,17 +7445,21 @@ IT(scale_16); #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(PNG_CONST image_transform *this, +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(PNG_CONST image_transform *this, +image_transform_png_set_strip_16_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->bit_depth == 16) { @@ -6693,7 +7484,7 @@ image_transform_png_set_strip_16_mod(PNG_CONST image_transform *this, * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!) */ { - PNG_CONST double d = (255-128.5)/65535; + const double d = (255-128.5)/65535; that->rede += d; that->greene += d; that->bluee += d; @@ -6707,7 +7498,7 @@ image_transform_png_set_strip_16_mod(PNG_CONST image_transform *this, static int image_transform_png_set_strip_16_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) @@ -6725,7 +7516,7 @@ IT(strip_16); #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED /* png_set_strip_alpha */ static void -image_transform_png_set_strip_alpha_set(PNG_CONST image_transform *this, +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); @@ -6733,9 +7524,9 @@ image_transform_png_set_strip_alpha_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_strip_alpha_mod(PNG_CONST image_transform *this, +image_transform_png_set_strip_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) that->colour_type = PNG_COLOR_TYPE_GRAY; @@ -6750,7 +7541,7 @@ image_transform_png_set_strip_alpha_mod(PNG_CONST image_transform *this, static int image_transform_png_set_strip_alpha_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -6771,7 +7562,8 @@ IT(strip_alpha); * png_fixed_point green) * png_get_rgb_to_gray_status * - * The 'default' test here uses values known to be used inside libpng: + * The 'default' test here uses values known to be used inside libpng prior to + * 1.7.0: * * red: 6968 * green: 23434 @@ -6808,11 +7600,11 @@ static struct #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(PNG_CONST image_transform *this, +image_transform_png_set_rgb_to_gray_ini(const image_transform *this, transform_display *that) { png_modifier *pm = that->pm; - PNG_CONST color_encoding *e = pm->current_encoding; + const color_encoding *e = pm->current_encoding; UNUSED(this) @@ -6827,7 +7619,7 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this, /* Coefficients come from the encoding, but may need to be normalized to a * white point Y of 1.0 */ - PNG_CONST double whiteY = e->red.Y + e->green.Y + e->blue.Y; + const double whiteY = e->red.Y + e->green.Y + e->blue.Y; data.red_coefficient = e->red.Y; data.green_coefficient = e->green.Y; @@ -6844,9 +7636,15 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this, else { /* The default (built in) coeffcients, as above: */ - data.red_coefficient = 6968 / 32768.; - data.green_coefficient = 23434 / 32768.; - data.blue_coefficient = 2366 / 32768.; +# 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; @@ -6880,7 +7678,7 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this, png_uint_32 ru; double total; - RANDOMIZE(ru); + ru = random_u32(); data.green_coefficient = total = (ru & 0xffff) / 65535.; ru >>= 16; data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.; @@ -6921,14 +7719,15 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this, * 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( -# if PNG_MAX_GAMMA_8 < 14 - (that->this.bit_depth == 16 ? 8. : - 6. + (1<<(15-PNG_MAX_GAMMA_8))) -# else - 8. -# endif - /65535, data.gamma); + (that->this.bit_depth == 16 || that->max_gamma_8 > 14 ? + 8. : + 6. + (1<<(15-that->max_gamma_8)) + )/65535, data.gamma); } else @@ -6940,18 +7739,14 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this, * When DIGITIZE is set because a pre-1.7 version of libpng is being * tested allow a bigger slack. * - * NOTE: this magic number was determined by experiment to be 1.25. - * There's no great merit to the value below, however it only affects - * the limit used for checking for internal calculation errors, not - * the actual limit imposed by pngvalid on the output errors. + * NOTE: this number only affects the internal limit check in pngvalid, + * it has no effect on the limits applied to the libpng values. */ - that->pm->limit += pow( -# if DIGITIZE - 1.25 -# else - 1.0 -# endif - /255, data.gamma); +#if DIGITIZE + that->pm->limit += pow( 2.0/255, data.gamma); +#else + that->pm->limit += pow( 1.0/255, data.gamma); +#endif } } @@ -6966,10 +7761,10 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this, } static void -image_transform_png_set_rgb_to_gray_set(PNG_CONST image_transform *this, +image_transform_png_set_rgb_to_gray_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { - PNG_CONST int error_action = 1; /* no error, no defines in png.h */ + const 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); @@ -7006,7 +7801,7 @@ image_transform_png_set_rgb_to_gray_set(PNG_CONST image_transform *this, & PNG_INFO_cHRM) != 0) { double maxe; - PNG_CONST char *el; + const char *el; color_encoding e, o; /* Expect libpng to return a normalized result, but the original @@ -7093,26 +7888,32 @@ image_transform_png_set_rgb_to_gray_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, +image_transform_png_set_rgb_to_gray_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0) { double gray, err; - if (that->colour_type == PNG_COLOR_TYPE_PALETTE) - image_pixel_convert_PLTE(that); +# 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_CONST png_modifier *pm = display->pm; + png_modifier *pm = display->pm; const unsigned int sample_depth = that->sample_depth; const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 : sample_depth); - const unsigned int gamma_depth = (sample_depth == 16 ? 16 : - (pm->assume_16_bit_calculations ? PNG_MAX_GAMMA_8 : sample_depth)); + const 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; @@ -7125,56 +7926,73 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, * 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 = digitize(rlo, calc_depth, 1/*round*/); + rlo = DD(rlo, calc_depth, 1/*round*/); rhi += that->rede; - rhi = digitize(rhi, calc_depth, 1/*round*/); + rhi = DU(rhi, calc_depth, 1/*round*/); g = glo = ghi = that->greenf; glo -= that->greene; - glo = digitize(glo, calc_depth, 1/*round*/); + glo = DD(glo, calc_depth, 1/*round*/); ghi += that->greene; - ghi = digitize(ghi, calc_depth, 1/*round*/); + ghi = DU(ghi, calc_depth, 1/*round*/); b = blo = bhi = that->bluef; blo -= that->bluee; - blo = digitize(blo, calc_depth, 1/*round*/); - bhi += that->greene; - bhi = digitize(bhi, calc_depth, 1/*round*/); + 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) { - PNG_CONST double power = 1/data.gamma; - PNG_CONST double abse = calc_depth == 16 ? .5/65535 : .5/255; + const double power = 1/data.gamma; + const double abse = .5/(sample_depth == 16 ? 65535 : 255); - /* 'abse' is the absolute error permitted in linear calculations. It - * is used here to capture the error permitted in the handling - * (undoing) of the gamma encoding. Once again digitization occurs - * to handle the upper and lower bounds of the values. This is - * where the real errors are introduced. + /* 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 = digitize(pow(rlo, power)-abse, calc_depth, 1); - rhi = digitize(pow(rhi, power)+abse, calc_depth, 1); + rlo = DD(pow(rlo, power)-abse, calc_depth, 1); + rhi = DU(pow(rhi, power)+abse, calc_depth, 1); g = pow(g, power); - glo = digitize(pow(glo, power)-abse, calc_depth, 1); - ghi = digitize(pow(ghi, power)+abse, calc_depth, 1); + glo = DD(pow(glo, power)-abse, calc_depth, 1); + ghi = DU(pow(ghi, power)+abse, calc_depth, 1); b = pow(b, power); - blo = digitize(pow(blo, power)-abse, calc_depth, 1); - bhi = digitize(pow(bhi, power)+abse, calc_depth, 1); + 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 maxium error in an individual coefficient is always - * 1/32768, because even in the rounding case the requirement that + * 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 @@ -7184,32 +8002,46 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, b * data.blue_coefficient; { - PNG_CONST int do_round = data.gamma != 1 || calc_depth == 16; - PNG_CONST double ce = 1. / 32768; + const int do_round = data.gamma != 1 || calc_depth == 16; + const double ce = 2. / 32768; - graylo = digitize(rlo * (data.red_coefficient-ce) + + graylo = DD(rlo * (data.red_coefficient-ce) + glo * (data.green_coefficient-ce) + - blo * (data.blue_coefficient-ce), gamma_depth, do_round); - if (graylo <= 0) - graylo = 0; + blo * (data.blue_coefficient-ce), calc_depth, do_round); + if (graylo > gray) /* always accept the right answer */ + graylo = gray; - grayhi = digitize(rhi * (data.red_coefficient+ce) + + grayhi = DU(rhi * (data.red_coefficient+ce) + ghi * (data.green_coefficient+ce) + - bhi * (data.blue_coefficient+ce), gamma_depth, do_round); - if (grayhi >= 1) - grayhi = 1; + bhi * (data.blue_coefficient+ce), calc_depth, do_round); + if (grayhi < gray) + grayhi = gray; } /* And invert the gamma. */ if (data.gamma != 1) { - PNG_CONST double power = data.gamma; + 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 = digitize(pow(graylo, power), sample_depth, 1); - grayhi = digitize(pow(grayhi, power), sample_depth, 1); + 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 @@ -7221,9 +8053,11 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, 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) { @@ -7234,11 +8068,13 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, pos = safecatd(buffer, sizeof buffer, pos, err, 6); pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); - png_error(pp, buffer); + png_warning(pp, buffer); + pm->limit = err; } +#endif /* !RELEASE_BUILD */ } } -# else /* DIGITIZE */ +# else /* !DIGITIZE */ { double r = that->redf; double re = that->rede; @@ -7247,29 +8083,46 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, double b = that->bluef; double be = that->bluee; - /* The true gray case involves no math. */ - if (r == g && r == b) - { - gray = r; - err = re; - if (err < ge) err = ge; - if (err < be) err = be; - } +# 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 if (data.gamma == 1) + 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 1/32768 error in the coefficients because they only have - * 15 bits and are adjusted to make sure they add up to 32768, so - * the result may have an additional error up to 1/32768. (Note - * that adding the 1/32768 here avoids needing to increase the - * global error limits to take this into account.) + * 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 + 1./32768 + gray * 5 * DBL_EPSILON; + be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON; } else @@ -7280,10 +8133,10 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, * lookups in the calculation and each introduces a quantization * error defined by the table size. */ - PNG_CONST png_modifier *pm = display->pm; + 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<assume_16_bit_calculations ? .5/(1<max_gamma_8) : .5/255)); double rhi, ghi, bhi, grayhi; double g1 = 1/data.gamma; @@ -7304,7 +8157,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, * previously added input quantization error at this point. */ gray = r * data.red_coefficient + g * data.green_coefficient + - b * data.blue_coefficient - 1./32768 - out_qe; + b * data.blue_coefficient - 2./32768 - out_qe; if (gray <= 0) gray = 0; else @@ -7314,7 +8167,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, } grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient + - bhi * data.blue_coefficient + 1./32768 + out_qe; + bhi * data.blue_coefficient + 2./32768 + out_qe; grayhi *= (1 + 6 * DBL_EPSILON); if (grayhi >= 1) grayhi = 1; @@ -7330,6 +8183,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, 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.) */ @@ -7342,8 +8196,10 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, pos = safecatd(buffer, sizeof buffer, pos, err, 6); pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); - png_error(pp, buffer); + png_warning(pp, buffer); + pm->limit = err; } +#endif /* !RELEASE_BUILD */ } } # endif /* !DIGITIZE */ @@ -7370,7 +8226,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this, static int image_transform_png_set_rgb_to_gray_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -7401,7 +8257,7 @@ IT(rgb_to_gray); static image_pixel data; static void -image_transform_png_set_background_set(PNG_CONST image_transform *this, +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; @@ -7414,7 +8270,7 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this, * so we need to know what that is! The background colour is stored in the * transform_display. */ - RANDOMIZE(random_bytes); + R8(random_bytes); /* Read the random value, for colour type 3 the background colour is actually * expressed as a 24bit rgb, not an index. @@ -7429,6 +8285,9 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this, else { + if (that->this.has_tRNS) + that->this.is_transparent = 1; + bit_depth = that->this.bit_depth; expand = 1; } @@ -7439,7 +8298,7 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this, /* Extract the background colour from this image_pixel, but make sure the * unused fields of 'back' are garbage. */ - RANDOMIZE(back); + R8(back); if (colour_type & PNG_COLOR_MASK_COLOR) { @@ -7451,23 +8310,23 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this, 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 +#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(PNG_CONST image_transform *this, +image_transform_png_set_background_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + 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); + 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) @@ -7506,14 +8365,14 @@ image_transform_png_set_background_mod(PNG_CONST image_transform *this, /* 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 */ } + 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); } @@ -7546,7 +8405,7 @@ IT(background); * png_set_invert_alpha(png_structrp png_ptr) */ static void -image_transform_png_set_invert_alpha_set(PNG_CONST image_transform *this, +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); @@ -7554,9 +8413,9 @@ image_transform_png_set_invert_alpha_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_invert_alpha_mod(PNG_CONST image_transform *this, +image_transform_png_set_invert_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->colour_type & 4) that->alpha_inverted = 1; @@ -7566,7 +8425,7 @@ image_transform_png_set_invert_alpha_mod(PNG_CONST image_transform *this, static int image_transform_png_set_invert_alpha_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -7592,7 +8451,7 @@ IT(invert_alpha); * This only has an effect on RGB and RGBA pixels. */ static void -image_transform_png_set_bgr_set(PNG_CONST image_transform *this, +image_transform_png_set_bgr_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_bgr(pp); @@ -7600,9 +8459,9 @@ image_transform_png_set_bgr_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_bgr_mod(PNG_CONST image_transform *this, +image_transform_png_set_bgr_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_RGB || that->colour_type == PNG_COLOR_TYPE_RGBA) @@ -7613,7 +8472,7 @@ image_transform_png_set_bgr_mod(PNG_CONST image_transform *this, static int image_transform_png_set_bgr_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -7639,7 +8498,7 @@ IT(bgr); * This only has an effect on GA and RGBA pixels. */ static void -image_transform_png_set_swap_alpha_set(PNG_CONST image_transform *this, +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); @@ -7647,9 +8506,9 @@ image_transform_png_set_swap_alpha_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_swap_alpha_mod(PNG_CONST image_transform *this, +image_transform_png_set_swap_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_GA || that->colour_type == PNG_COLOR_TYPE_RGBA) @@ -7660,7 +8519,7 @@ image_transform_png_set_swap_alpha_mod(PNG_CONST image_transform *this, static int image_transform_png_set_swap_alpha_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -7684,7 +8543,7 @@ IT(swap_alpha); * png_set_swap(png_structrp png_ptr) */ static void -image_transform_png_set_swap_set(PNG_CONST image_transform *this, +image_transform_png_set_swap_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_swap(pp); @@ -7692,9 +8551,9 @@ image_transform_png_set_swap_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_swap_mod(PNG_CONST image_transform *this, +image_transform_png_set_swap_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->bit_depth == 16) that->swap16 = 1; @@ -7704,7 +8563,7 @@ image_transform_png_set_swap_mod(PNG_CONST image_transform *this, static int image_transform_png_set_swap_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) @@ -7738,14 +8597,14 @@ static struct } data; static void -image_transform_png_set_filler_set(PNG_CONST image_transform *this, +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. */ - RANDOMIZE(data.filler); + data.filler = random_u32(); data.flags = random_choice(); png_set_filler(pp, data.filler, data.flags); @@ -7759,15 +8618,15 @@ image_transform_png_set_filler_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_filler_mod(PNG_CONST image_transform *this, +image_transform_png_set_filler_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->bit_depth >= 8 && (that->colour_type == PNG_COLOR_TYPE_RGB || that->colour_type == PNG_COLOR_TYPE_GRAY)) { - PNG_CONST unsigned int max = (1U << that->bit_depth)-1; + const unsigned int max = (1U << that->bit_depth)-1; that->alpha = data.filler & max; that->alphaf = ((double)that->alpha) / max; that->alphae = 0; @@ -7787,7 +8646,7 @@ image_transform_png_set_filler_mod(PNG_CONST image_transform *this, static int image_transform_png_set_filler_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { this->next = *that; *that = this; @@ -7811,14 +8670,14 @@ static struct } data; static void -image_transform_png_set_add_alpha_set(PNG_CONST image_transform *this, +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. */ - RANDOMIZE(data.filler); + data.filler = random_u32(); data.flags = random_choice(); png_set_add_alpha(pp, data.filler, data.flags); @@ -7826,15 +8685,15 @@ image_transform_png_set_add_alpha_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_add_alpha_mod(PNG_CONST image_transform *this, +image_transform_png_set_add_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->bit_depth >= 8 && (that->colour_type == PNG_COLOR_TYPE_RGB || that->colour_type == PNG_COLOR_TYPE_GRAY)) { - PNG_CONST unsigned int max = (1U << that->bit_depth)-1; + const unsigned int max = (1U << that->bit_depth)-1; that->alpha = data.filler & max; that->alphaf = ((double)that->alpha) / max; that->alphae = 0; @@ -7848,7 +8707,7 @@ image_transform_png_set_add_alpha_mod(PNG_CONST image_transform *this, static int image_transform_png_set_add_alpha_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { this->next = *that; *that = this; @@ -7874,7 +8733,7 @@ IT(add_alpha); * per pixel. */ static void -image_transform_png_set_packing_set(PNG_CONST image_transform *this, +image_transform_png_set_packing_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_packing(pp); @@ -7883,9 +8742,9 @@ image_transform_png_set_packing_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_packing_mod(PNG_CONST image_transform *this, +image_transform_png_set_packing_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + 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 @@ -7899,7 +8758,7 @@ image_transform_png_set_packing_mod(PNG_CONST image_transform *this, static int image_transform_png_set_packing_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) @@ -7924,17 +8783,18 @@ IT(packing); * png_set_packswap(png_structrp png_ptr) */ static void -image_transform_png_set_packswap_set(PNG_CONST image_transform *this, +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(PNG_CONST image_transform *this, +image_transform_png_set_packswap_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->bit_depth < 8) that->littleendian = 1; @@ -7944,7 +8804,7 @@ image_transform_png_set_packswap_mod(PNG_CONST image_transform *this, static int image_transform_png_set_packswap_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) @@ -7968,7 +8828,7 @@ IT(packswap); * png_set_invert_mono(png_structrp png_ptr) */ static void -image_transform_png_set_invert_mono_set(PNG_CONST image_transform *this, +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); @@ -7976,9 +8836,9 @@ image_transform_png_set_invert_mono_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_invert_mono_mod(PNG_CONST image_transform *this, +image_transform_png_set_invert_mono_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { if (that->colour_type & 4) that->mono_inverted = 1; @@ -7988,7 +8848,7 @@ image_transform_png_set_invert_mono_mod(PNG_CONST image_transform *this, static int image_transform_png_set_invert_mono_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -8015,7 +8875,7 @@ IT(invert_mono); static png_color_8 data; static void -image_transform_png_set_shift_set(PNG_CONST image_transform *this, +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 @@ -8024,7 +8884,7 @@ image_transform_png_set_shift_set(PNG_CONST image_transform *this, * field is randomized independently. This acts as a check that * libpng does use the correct field. */ - PNG_CONST unsigned int depth = that->this.bit_depth; + const 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); @@ -8037,9 +8897,9 @@ image_transform_png_set_shift_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_shift_mod(PNG_CONST image_transform *this, +image_transform_png_set_shift_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { /* Copy the correct values into the sBIT fields, libpng does not do * anything to palette data: @@ -8070,7 +8930,7 @@ image_transform_png_set_shift_mod(PNG_CONST image_transform *this, static int image_transform_png_set_shift_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) @@ -8088,7 +8948,7 @@ IT(shift); #ifdef THIS_IS_THE_PROFORMA static void -image_transform_png_set_@_set(PNG_CONST image_transform *this, +image_transform_png_set_@_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_@(pp); @@ -8096,16 +8956,16 @@ image_transform_png_set_@_set(PNG_CONST image_transform *this, } static void -image_transform_png_set_@_mod(PNG_CONST image_transform *this, +image_transform_png_set_@_mod(const image_transform *this, image_pixel *that, png_const_structp pp, - PNG_CONST transform_display *display) + const transform_display *display) { this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_@_add(image_transform *this, - PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth) + const image_transform **that, png_byte colour_type, png_byte bit_depth) { this->next = *that; *that = this; @@ -8118,10 +8978,10 @@ IT(@); /* This may just be 'end' if all the transforms are disabled! */ -static image_transform *PNG_CONST image_transform_first = &PT; +static image_transform *const image_transform_first = &PT; static void -transform_enable(PNG_CONST char *name) +transform_enable(const char *name) { /* Everything starts out enabled, so if we see an 'enable' disabled * everything else the first time round. @@ -8154,7 +9014,7 @@ transform_enable(PNG_CONST char *name) } static void -transform_disable(PNG_CONST char *name) +transform_disable(const char *name) { image_transform *list = image_transform_first; @@ -8217,7 +9077,7 @@ image_transform_test_counter(png_uint_32 counter, unsigned int max) } static png_uint_32 -image_transform_add(PNG_CONST image_transform **this, unsigned int max, +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) { @@ -8301,7 +9161,8 @@ perform_transform_test(png_modifier *pm) png_byte bit_depth = 0; unsigned int palette_number = 0; - while (next_format(&colour_type, &bit_depth, &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; @@ -8312,7 +9173,7 @@ perform_transform_test(png_modifier *pm) for (;;) { size_t pos = base_pos; - PNG_CONST image_transform *list = 0; + const image_transform *list = 0; /* 'max' is currently hardwired to '1'; this should be settable on the * command line. @@ -8373,11 +9234,11 @@ 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, PNG_CONST png_color_16 *pointer_to_the_background_color, + 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, 0/*do_interlace*/, + standard_display_init(&dp->this, &pm->this, id, do_read_interlace, pm->use_update_info); /* Parameter fields */ @@ -8409,7 +9270,7 @@ gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi) /* If requested strip 16 to 8 bits - this is handled automagically below * because the output bit depth is read from the library. Note that there * are interactions with sBIT but, internally, libpng makes sbit at most - * PNG_MAX_GAMMA_8 when doing the following. + * PNG_MAX_GAMMA_8 prior to 1.7 when doing the following. */ if (dp->scale16) # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED @@ -8441,9 +9302,9 @@ gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi) * non-inverted, represenation. It provides a default for the PNG file * gamma, but since the file has a gAMA chunk this does not matter. */ - PNG_CONST double sg = dp->screen_gamma; + const double sg = dp->screen_gamma; # ifndef PNG_FLOATING_POINT_SUPPORTED - PNG_CONST png_fixed_point g = fix(sg); + const png_fixed_point g = fix(sg); # endif # ifdef PNG_FLOATING_POINT_SUPPORTED @@ -8489,9 +9350,9 @@ gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi) # ifdef PNG_READ_BACKGROUND_SUPPORTED /* NOTE: this assumes the caller provided the correct background gamma! */ - PNG_CONST double bg = dp->background_gamma; + const double bg = dp->background_gamma; # ifndef PNG_FLOATING_POINT_SUPPORTED - PNG_CONST png_fixed_point g = fix(bg); + const png_fixed_point g = fix(bg); # endif # ifdef PNG_FLOATING_POINT_SUPPORTED @@ -8565,7 +9426,7 @@ static void init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp, int in_depth, int out_depth) { - PNG_CONST unsigned int outmax = (1U<pp = pp; vi->dp = dp; @@ -8604,13 +9465,15 @@ init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp, 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 == 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) { - PNG_CONST double bg_inverse = 1/dp->background_gamma; + const double bg_inverse = 1/dp->background_gamma; double r, g, b; /* Caller must at least put the gray value into the red channel */ @@ -8634,7 +9497,7 @@ init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp, vi->background_blue = b; } } - else + else /* Do not expect any background processing */ vi->do_background = 0; if (vi->do_background == 0) @@ -8724,15 +9587,15 @@ gamma_component_compose(int do_background, double input_sample, double alpha, /* This API returns the encoded *input* component, in the range 0..1 */ static double -gamma_component_validate(PNG_CONST char *name, PNG_CONST validate_info *vi, - PNG_CONST unsigned int id, PNG_CONST unsigned int od, - PNG_CONST double alpha /* <0 for the alpha channel itself */, - PNG_CONST double background /* component background value */) +gamma_component_validate(const char *name, const validate_info *vi, + const unsigned int id, const unsigned int od, + const double alpha /* <0 for the alpha channel itself */, + const double background /* component background value */) { - PNG_CONST unsigned int isbit = id >> vi->isbit_shift; - PNG_CONST unsigned int sbit_max = vi->sbit_max; - PNG_CONST unsigned int outmax = vi->outmax; - PNG_CONST int do_background = vi->do_background; + const unsigned int isbit = id >> vi->isbit_shift; + const unsigned int sbit_max = vi->sbit_max; + const unsigned int outmax = vi->outmax; + const int do_background = vi->do_background; double i; @@ -9131,9 +9994,9 @@ gamma_component_validate(PNG_CONST char *name, PNG_CONST validate_info *vi, case PNG_BACKGROUND_GAMMA_FILE: case PNG_BACKGROUND_GAMMA_UNIQUE: use_background = (alpha >= 0 && alpha < 1); - /*FALL THROUGH*/ # 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: @@ -9297,14 +10160,14 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp, png_infop pi) { /* Get some constants derived from the input and output file formats: */ - PNG_CONST png_store* PNG_CONST ps = dp->this.ps; - PNG_CONST png_byte in_ct = dp->this.colour_type; - PNG_CONST png_byte in_bd = dp->this.bit_depth; - PNG_CONST png_uint_32 w = dp->this.w; - PNG_CONST png_uint_32 h = dp->this.h; - PNG_CONST size_t cbRow = dp->this.cbRow; - PNG_CONST png_byte out_ct = png_get_color_type(pp, pi); - PNG_CONST png_byte out_bd = png_get_bit_depth(pp, pi); + const png_store* const ps = dp->this.ps; + const png_byte in_ct = dp->this.colour_type; + const png_byte in_bd = dp->this.bit_depth; + const png_uint_32 w = dp->this.w; + const png_uint_32 h = dp->this.h; + const size_t cbRow = dp->this.cbRow; + const png_byte out_ct = png_get_color_type(pp, pi); + const 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 @@ -9345,11 +10208,12 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp, * The basic tests below do not do this, however if 'use_input_precision' * is set a subsequent test is performed above. */ - PNG_CONST unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U; + const unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U; int processing; png_uint_32 y; - PNG_CONST store_palette_entry *in_palette = dp->this.palette; - PNG_CONST int in_is_transparent = dp->this.is_transparent; + const store_palette_entry *in_palette = dp->this.palette; + const 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; @@ -9365,6 +10229,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp, 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 @@ -9395,18 +10260,18 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp, double alpha = 1; /* serves as a flag value */ /* Record the palette index for index images. */ - PNG_CONST unsigned int in_index = + const unsigned int in_index = in_ct == 3 ? sample(std, 3, in_bd, x, 0, 0, 0) : 256; - PNG_CONST unsigned int out_index = + const 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)) + if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 || + (in_ct == 3 && in_is_transparent)) { - PNG_CONST unsigned int input_alpha = in_ct == 3 ? + const 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); @@ -9436,6 +10301,35 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp, } } + 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, @@ -9502,15 +10396,15 @@ gamma_end(png_structp ppIn, png_infop pi) * maxpc: maximum percentage error (as a percentage) */ static void -gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn, - PNG_CONST png_byte bit_depthIn, PNG_CONST int palette_numberIn, - PNG_CONST int interlace_typeIn, - PNG_CONST double file_gammaIn, PNG_CONST double screen_gammaIn, - PNG_CONST png_byte sbitIn, PNG_CONST int threshold_testIn, - PNG_CONST char *name, - PNG_CONST int use_input_precisionIn, PNG_CONST int scale16In, - PNG_CONST int expand16In, PNG_CONST int do_backgroundIn, - PNG_CONST png_color_16 *bkgd_colorIn, double bkgd_gammaIn) +gamma_test(png_modifier *pmIn, const png_byte colour_typeIn, + const png_byte bit_depthIn, const int palette_numberIn, + const int interlace_typeIn, + const double file_gammaIn, const double screen_gammaIn, + const png_byte sbitIn, const int threshold_testIn, + const char *name, + const int use_input_precisionIn, const int scale16In, + const int expand16In, const int do_backgroundIn, + const png_color_16 *bkgd_colorIn, double bkgd_gammaIn) { gamma_display d; context(&pmIn->this, fault); @@ -9545,7 +10439,7 @@ gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn, modification_reset(d.pm->modifications); - /* Get a png_struct for writing the image. */ + /* 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); @@ -9684,9 +10578,13 @@ perform_gamma_threshold_tests(png_modifier *pm) /* 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, 1/*gamma*/)) - if (palette_number == 0) + 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) @@ -9709,11 +10607,11 @@ perform_gamma_threshold_tests(png_modifier *pm) } static void gamma_transform_test(png_modifier *pm, - PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth, - PNG_CONST int palette_number, - PNG_CONST int interlace_type, PNG_CONST double file_gamma, - PNG_CONST double screen_gamma, PNG_CONST png_byte sbit, - PNG_CONST int use_input_precision, PNG_CONST int scale16) + const png_byte colour_type, const png_byte bit_depth, + const int palette_number, + const int interlace_type, const double file_gamma, + const double screen_gamma, const png_byte sbit, + const int use_input_precision, const int scale16) { size_t pos = 0; char name[64]; @@ -9746,7 +10644,8 @@ static void perform_gamma_transform_tests(png_modifier *pm) png_byte bit_depth = 0; unsigned int palette_number = 0; - while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/)) + while (next_format(&colour_type, &bit_depth, &palette_number, + pm->test_lbg_gamma_transform, pm->test_tRNS)) { unsigned int i, j; @@ -9776,7 +10675,8 @@ static void perform_gamma_sbit_tests(png_modifier *pm) png_byte colour_type = 0, bit_depth = 0; unsigned int npalette = 0; - while (next_format(&colour_type, &bit_depth, &npalette, 1/*gamma*/)) + 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))) @@ -9811,7 +10711,11 @@ static void perform_gamma_scale16_tests(png_modifier *pm) # ifndef PNG_MAX_GAMMA_8 # define PNG_MAX_GAMMA_8 11 # endif -# define SBIT_16_TO_8 PNG_MAX_GAMMA_8 +# 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. @@ -9864,12 +10768,12 @@ static void perform_gamma_scale16_tests(png_modifier *pm) #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ defined(PNG_READ_ALPHA_MODE_SUPPORTED) static void gamma_composition_test(png_modifier *pm, - PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth, - PNG_CONST int palette_number, - PNG_CONST int interlace_type, PNG_CONST double file_gamma, - PNG_CONST double screen_gamma, - PNG_CONST int use_input_precision, PNG_CONST int do_background, - PNG_CONST int expand_16) + const png_byte colour_type, const png_byte bit_depth, + const int palette_number, + const int interlace_type, const double file_gamma, + const double screen_gamma, + const int use_input_precision, const int do_background, + const int expand_16) { size_t pos = 0; png_const_charp base; @@ -9967,8 +10871,17 @@ static void gamma_composition_test(png_modifier *pm, } 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. */ @@ -10017,9 +10930,18 @@ perform_gamma_composition_tests(png_modifier *pm, int do_background, /* 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, 1/*gamma*/)) - if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0) + 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; @@ -10238,7 +11160,7 @@ perform_gamma_test(png_modifier *pm, int summary) * be indexed adam7[y][x] and notice that the pass numbers are based at * 1, not 0 - the base libpng uses. */ -static PNG_CONST +static const png_byte adam7[8][8] = { { 1,6,4,6,2,6,4,6 }, @@ -10505,23 +11427,36 @@ perform_interlace_macro_validation(void) */ 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: */ - m = PNG_ROW_FROM_PASS_ROW(v, pass); - f = png_row_from_pass_row(v, pass); - if (m != f) + if (v < png_pass_rows(0xFFFFFFFFU, pass)) { - fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n", - v, pass, m, f); - exit(99); + 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); + } } - m = PNG_COL_FROM_PASS_COL(v, pass); - f = png_col_from_pass_col(v, pass); - if (m != f) + if (v < png_pass_cols(0xFFFFFFFFU, pass)) { - fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n", - v, pass, m, f); - exit(99); + 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); @@ -10589,7 +11524,7 @@ perform_interlace_macro_validation(void) * The png_modifier code assumes that encodings[0] is sRGB and treats it * specially: do not change the first entry in this list! */ -static PNG_CONST color_encoding test_encodings[] = +static const color_encoding test_encodings[] = { /* sRGB: must be first in this list! */ /*gamma:*/ { 1/2.2, @@ -10611,6 +11546,11 @@ static PNG_CONST color_encoding test_encodings[] = /*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 @@ -10682,11 +11622,11 @@ static void signal_handler(int signum) /* main program */ int main(int argc, char **argv) { - volatile int summary = 1; /* Print the error summary at the end */ - volatile int memstats = 0; /* Print memory statistics at the end */ + 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: */ - PNG_CONST char *volatile touch = NULL; + 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.) @@ -10702,6 +11642,10 @@ int main(int argc, char **argv) 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); @@ -10751,11 +11695,27 @@ int main(int argc, char **argv) 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); - pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */ +# 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 @@ -10781,7 +11741,11 @@ int main(int argc, char **argv) pm.maxout16 = .499; /* Error in *encoded* value */ pm.maxabs16 = .00005;/* 1/20000 */ pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */ - pm.maxcalcG = 1./((1< 0); - printf("%d tests including %d overflows, %d passed, %d failed (%d 64 bit " + printf("%d tests including %d overflows, %d passed, %d failed (%d 64-bit " "errors)\n", tested, overflow, passed, error, error64); return 0; } @@ -799,13 +799,13 @@ int validation_gamma(int argc, char **argv) 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", + 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); + printf("maximum 8-bit log error = %f\n", maxerr); maxerr = 0; for (i=0; i<65536; ++i) @@ -821,14 +821,14 @@ int validation_gamma(int argc, char **argv) { if (error > .68) /* By experiment error is less than .68 */ { - fprintf(stderr, "16 bit log error: %d: got %u, expected %f" + 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); + printf("maximum 16-bit log error = %f\n", maxerr); /* Now exponentiations. */ maxerr = 0; @@ -841,13 +841,13 @@ int validation_gamma(int argc, char **argv) maxerr = fabs(error); if (fabs(error) > 1883) /* By experiment. */ { - fprintf(stderr, "32 bit exp error: %d: got %u, expected %f" + 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); + printf("maximum 32-bit exp error = %f\n", maxerr); maxerr = 0; for (i=0; i<=0xfffff; ++i) @@ -859,13 +859,13 @@ int validation_gamma(int argc, char **argv) maxerr = fabs(error); if (fabs(error) > .50002) /* By experiment */ { - fprintf(stderr, "8 bit exp error: %d: got %u, expected %f" + 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); + printf("maximum 8-bit exp error = %f\n", maxerr); maxerr = 0; for (i=0; i<=0xfffff; ++i) @@ -877,13 +877,13 @@ int validation_gamma(int argc, char **argv) maxerr = fabs(error); if (fabs(error) > .524) /* By experiment */ { - fprintf(stderr, "16 bit exp error: %d: got %u, expected %f" + 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); + printf("maximum 16-bit exp error = %f\n", maxerr); } /* !onlygamma */ /* Test the overall gamma correction. */ @@ -913,7 +913,7 @@ int validation_gamma(int argc, char **argv) } if (!silent) - printf("gamma %f: maximum 8 bit error %f\n", g, maxerr); + printf("gamma %f: maximum 8-bit error %f\n", g, maxerr); maxerr = 0; for (j=0; j<65536; ++j) @@ -932,7 +932,7 @@ int validation_gamma(int argc, char **argv) } if (!silent) - printf("gamma %f: maximum 16 bit error %f\n", g, maxerr); + printf("gamma %f: maximum 16-bit error %f\n", g, maxerr); } return 0; diff --git a/src/third-party/libpng/contrib/libtests/timepng.c b/src/third-party/libpng/contrib/libtests/timepng.c index 7c937971c..3bcfde5a3 100644 --- a/src/third-party/libpng/contrib/libtests/timepng.c +++ b/src/third-party/libpng/contrib/libtests/timepng.c @@ -1,8 +1,8 @@ /* timepng.c * - * Copyright (c) 2013 John Cunningham Bowler + * Copyright (c) 2013,2016 John Cunningham Bowler * - * Last changed in libpng 1.6.1 [March 28, 2013] + * 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 @@ -10,15 +10,17 @@ * * 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. + * 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 #include #include +#include +#include #include @@ -35,36 +37,73 @@ # include "../../png.h" #endif -static int read_png(FILE *fp) +/* The following is to support direct compilation of this file as C++ */ +#ifdef __cplusplus +# define voidcast(type, value) static_cast(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 { - 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; + FILE *input; + FILE *output; +} io_data; - if (png_ptr == NULL) - return 0; +static PNG_CALLBACK(void, read_and_copy, + (png_structp png_ptr, png_bytep buffer, png_size_t cb)) +{ + io_data *io = (io_data*)png_get_io_ptr(png_ptr); - if (setjmp(png_jmpbuf(png_ptr))) + if (fread(buffer, cb, 1, io->input) != 1) + png_error(png_ptr, strerror(errno)); + + if (fwrite(buffer, cb, 1, io->output) != 1) { - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - if (row != NULL) free(row); - if (display != NULL) free(display); - return 0; + perror("temporary file"); + fprintf(stderr, "temporary file PNG write failed\n"); + exit(1); } +} - png_init_io(png_ptr, fp); +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; - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) - png_error(png_ptr, "OOM allocating info structure"); + 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); { png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); - row = malloc(rowbytes); - display = malloc(rowbytes); + 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"); @@ -81,7 +120,8 @@ static int read_png(FILE *fp) 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. + * 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); @@ -91,9 +131,51 @@ static int read_png(FILE *fp) /* 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 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; } @@ -108,7 +190,7 @@ static int mytime(struct timespec *t) return 0; } -static int perform_one_test(FILE *fp, int nfiles) +static int perform_one_test(FILE *fp, int nfiles, png_int_32 transforms) { int i; struct timespec before, after; @@ -120,7 +202,7 @@ static int perform_one_test(FILE *fp, int nfiles) { for (i=0; i {files}\n" +" Read the files into , output the count. Options are ignored.\n" +" timepng --dissemble [options]\n" +" Time files from , 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" +" --: implies by-image, use PNG_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; - FILE *fp = tmpfile(); + int err = 0; + int nfiles = 0; + int transforms = -1; /* by row */ + const char *assembly = NULL; + FILE *fp; - if (fp != NULL) + if (argc > 2 && strcmp(argv[1], "--assemble") == 0) { - int err = 0; - int nfiles = 0; - - if (argc > 1) + /* Just build the test file, argv[2] is the file name. */ + assembly = argv[2]; + fp = fopen(assembly, "wb"); + if (fp == NULL) { - int i; + perror(assembly); + fprintf(stderr, "timepng --assemble %s: could not open for write\n", + assembly); + usage(NULL); + } - for (i=1; i 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 : %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 0) + { + if (assembly != NULL) + { + if (fflush(fp) && !ferror(fp) && fclose(fp)) + { + perror(assembly); + fprintf(stderr, "%s: close failed\n", assembly); + } else { - err = 1; - break; + printf("%s %d\n", assembly, nfiles); + fflush(stdout); + ok = !ferror(stdout); } } + + else + { + ok = perform_one_test(fp, nfiles, transforms); + (void)fclose(fp); + } } else - { - 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 (add_one_file(fp, filename)) - ++nfiles; - - else - { - err = 1; - break; - } - } - - else - { - fprintf(stderr, "timepng: truncated file name ...%s\n", - filename+len-32); - err = 1; - break; - } - } - - if (ferror(stdin)) - { - fprintf(stderr, "timepng: stdin: read error\n"); - err = 1; - } - } - - if (!err) - { - if (nfiles > 0) - ok = perform_one_test(fp, nfiles); - - else - fprintf(stderr, "usage: timepng {files} or ls files | timepng\n"); - } - - (void)fclose(fp); + usage(fp); } else - fprintf(stderr, "timepng: could not open temporary file\n"); + (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/src/third-party/libpng/contrib/mips-msa/README b/src/third-party/libpng/contrib/mips-msa/README new file mode 100644 index 000000000..10acc9364 --- /dev/null +++ b/src/third-party/libpng/contrib/mips-msa/README @@ -0,0 +1,83 @@ +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/src/third-party/libpng/contrib/mips-msa/linux.c b/src/third-party/libpng/contrib/mips-msa/linux.c new file mode 100644 index 000000000..140215c4e --- /dev/null +++ b/src/third-party/libpng/contrib/mips-msa/linux.c @@ -0,0 +1,64 @@ +/* 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 and it assumes that /proc/cpuinfo is never localized. + */ + +#include +#include +#include + +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/src/third-party/libpng/contrib/oss-fuzz/Dockerfile b/src/third-party/libpng/contrib/oss-fuzz/Dockerfile new file mode 100644 index 000000000..7e4d1ebff --- /dev/null +++ b/src/third-party/libpng/contrib/oss-fuzz/Dockerfile @@ -0,0 +1,24 @@ +# 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 zlib1g-dev + +RUN git clone --depth 1 https://github.com/glennrp/libpng.git +RUN (cd libpng; git log | head -1) +WORKDIR libpng +COPY build.sh $SRC/ diff --git a/src/third-party/libpng/contrib/oss-fuzz/README.txt b/src/third-party/libpng/contrib/oss-fuzz/README.txt new file mode 100644 index 000000000..a2b673665 --- /dev/null +++ b/src/third-party/libpng/contrib/oss-fuzz/README.txt @@ -0,0 +1,37 @@ +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 and build.sh are copies of the files used by oss-fuzz. + 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/src/third-party/libpng/contrib/oss-fuzz/build.sh b/src/third-party/libpng/contrib/oss-fuzz/build.sh new file mode 100755 index 000000000..d2137b13e --- /dev/null +++ b/src/third-party/libpng/contrib/oss-fuzz/build.sh @@ -0,0 +1,50 @@ +#!/bin/bash -eu +# Copyright 2017 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.33 [September 28, 2017] +# +# Revisions by Glenn Randers-Pehson, 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. +################################################################################ + +# 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 library. +autoreconf -f -i +./configure +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/src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc b/src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc new file mode 100644 index 000000000..78c7c9ff0 --- /dev/null +++ b/src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc @@ -0,0 +1,180 @@ + +// libpng_read_fuzzer.cc +// Copyright 2017 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.32 [August 24, 2017] + +// 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 " which is needed on some platforms +// to provide memcpy(). +// 4. adding read_end_info() and creating an end_info structure. + +#include +#include +#include + +#include + +#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, png_size_t length) { + BufState* buf_state = static_cast(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 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); + png_handler.row_ptr = png_malloc( + png_handler.png_ptr, png_get_rowbytes(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; + } + + int passes = png_set_interlace_handling(png_handler.png_ptr); + png_start_read_image(png_handler.png_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_handler.row_ptr), nullptr); + } + } + + png_read_end(png_handler.png_ptr, png_handler.end_info_ptr); + + PNG_CLEANUP + return 0; +} diff --git a/src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.options b/src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.options new file mode 100644 index 000000000..2005291a0 --- /dev/null +++ b/src/third-party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.options @@ -0,0 +1,2 @@ +[libfuzzer] +dict = png.dict diff --git a/src/third-party/libpng/contrib/oss-fuzz/newcc b/src/third-party/libpng/contrib/oss-fuzz/newcc new file mode 100644 index 000000000..0fc9e206c --- /dev/null +++ b/src/third-party/libpng/contrib/oss-fuzz/newcc @@ -0,0 +1,190 @@ + +// libpng_read_fuzzer.cc +// Copyright 2017 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.33beta03 [September 27, 2017] + +// 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 " which is needed on some platforms +// to provide memcpy(). +// 4. adding read_end_info() and creating an end_info structure. + +#include +#include +#include + +#include + +#define PNG_INTERNAL +#include "png.h" + +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, png_size_t length) { + BufState* buf_state = static_cast(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 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; + } + +#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; \ + } + + 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; + } + + /* Treat benign errors as warnings */ + png_set_benign_errors(png_handler.png_ptr, 1); + + 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); + 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)); + + // 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; + } + + int passes = png_set_interlace_handling(png_handler.png_ptr); + png_start_read_image(png_handler.png_ptr); + + /* To do: prevent the optimizer from removing this code entirely */ + 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_handler.row_ptr), nullptr); + } + } + + png_read_end(png_handler.png_ptr, png_handler.end_info_ptr); + + PNG_CLEANUP + + /* TO do: exercise the progressive reader here */ + + return 0; +} diff --git a/src/third-party/libpng/contrib/oss-fuzz/png.dict b/src/third-party/libpng/contrib/oss-fuzz/png.dict new file mode 100644 index 000000000..3a8a11383 --- /dev/null +++ b/src/third-party/libpng/contrib/oss-fuzz/png.dict @@ -0,0 +1,39 @@ +# +# AFL dictionary for PNG images +# ----------------------------- +# +# Just the basic, standard-originating sections; does not include vendor +# extensions. +# +# Created by Michal Zalewski +# + +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/src/third-party/libpng/contrib/pngminus/README b/src/third-party/libpng/contrib/pngminus/README index bbe7407ec..fbcfc9861 100644 --- a/src/third-party/libpng/contrib/pngminus/README +++ b/src/third-party/libpng/contrib/pngminus/README @@ -146,7 +146,7 @@ The Turbo bug The end ------- Willem van Schaik -mailto:willem@schaik.com +mailto:willem at schaik.com http://www.schaik.com/png/ ------- Oct 1999 diff --git a/src/third-party/libpng/contrib/pngminus/png2pnm.c b/src/third-party/libpng/contrib/pngminus/png2pnm.c index dff4d0b3d..1420a783b 100644 --- a/src/third-party/libpng/contrib/pngminus/png2pnm.c +++ b/src/third-party/libpng/contrib/pngminus/png2pnm.c @@ -1,8 +1,12 @@ /* * png2pnm.c --- conversion from PNG-file to PGM/PPM-file - * copyright (C) 1999 by Willem van Schaik + * copyright (C) 1999,2017 by Willem van Schaik * * version 1.0 - 1999.10.15 - First version. + * 1.1 - 2017.04.22 - Add buffer-size check (Glenn Randers-Pehrson) + * 1.2 - 2017.08.24 - Fix potential overflow in buffer-size check + * (Glenn Randers-Pehrson) + * 1.3 - 2017.08.28 - Add PNGMINUS_UNUSED (Christian Hesse) * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, @@ -41,6 +45,7 @@ #define PNG_DEBUG 0 #endif + #include "png.h" /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ @@ -48,6 +53,14 @@ # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif +#ifndef PNGMINUS_UNUSED +/* Unused formal parameter warnings are silenced using the following macro + * which is expected to have no bad effects on performance (optimizing + * compilers will probably remove it entirely). + */ +# define PNGMINUS_UNUSED(param) (void)param +#endif + /* function prototypes */ int main (int argc, char *argv[]); @@ -266,7 +279,7 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, png_set_expand (png_ptr); #ifdef NJET - /* downgrade 16-bit images to 8 bit */ + /* downgrade 16-bit images to 8-bit */ if (bit_depth == 16) png_set_strip_16 (png_ptr); /* transform grayscale images into full-color */ @@ -320,14 +333,21 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, /* 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 (row_bytes * height * sizeof (png_byte))) == NULL) { + malloc ((size_t)row_bytes * (size_t)height * sizeof (png_byte))) == NULL) + { png_destroy_read_struct (&png_ptr, &info_ptr, NULL); return FALSE; } if ((row_pointers = (png_byte **) - malloc (height * sizeof (png_bytep))) == NULL) + malloc ((size_t)height * sizeof (png_bytep))) == NULL) { png_destroy_read_struct (&png_ptr, &info_ptr, NULL); free (png_pixels); @@ -408,7 +428,8 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, if (raw) fputc ((int) *pix_ptr++ , alpha_file); else - if (bit_depth == 16){ + if (bit_depth == 16) + { dep_16 = (long) *pix_ptr++; fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++); } @@ -432,6 +453,7 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, if (png_pixels != (unsigned char*) NULL) free (png_pixels); + PNGMINUS_UNUSED(raw); /* to quiet a Coverity defect */ return TRUE; } /* end of source */ diff --git a/src/third-party/libpng/contrib/pngminus/pnm2png.c b/src/third-party/libpng/contrib/pngminus/pnm2png.c index 7bf720f68..0d2caef96 100644 --- a/src/third-party/libpng/contrib/pngminus/pnm2png.c +++ b/src/third-party/libpng/contrib/pngminus/pnm2png.c @@ -1,8 +1,13 @@ /* * pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file - * copyright (C) 1999 by Willem van Schaik + * copyright (C) 1999,2015,2017 by Willem van Schaik * * version 1.0 - 1999.10.15 - First version. + * version 1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson) + * version 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) * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, @@ -46,6 +51,15 @@ # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif +#ifndef PNGMINUS_UNUSED +/* Unused formal parameter warnings are silenced using the following macro + * which is expected to have no bad effects on performance (optimizing + * compilers will probably remove it entirely). + */ +# define PNGMINUS_UNUSED(param) (void)param +#endif + + /* function prototypes */ int main (int argc, char *argv[]); @@ -200,17 +214,17 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, char width_token[16]; char height_token[16]; char maxval_token[16]; - volatile int color_type; + 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, height; - volatile png_uint_32 alpha_width, alpha_height; + 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; + int channels=0; int alpha_depth = 0; - int alpha_present; + int alpha_present=0; int row, col; BOOL raw, alpha_raw = FALSE; #if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) @@ -356,8 +370,10 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, channels = 3; else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) channels = 4; +#if 0 else - channels = 0; /* should not happen */ + channels = 0; /* cannot happen */ +#endif alpha_present = (channels - 1) % 2; @@ -367,11 +383,16 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, 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 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 (row_bytes * height * sizeof (png_byte))) == NULL) + malloc ((size_t)row_bytes * (size_t)height * sizeof (png_byte))) == NULL) return FALSE; /* read data from PNM file */ @@ -380,7 +401,8 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, for (row = 0; row < (int) height; row++) { #if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) - if (packed_bitmap) { + 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); @@ -429,12 +451,16 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, NULL); if (!png_ptr) { + free (png_pixels); + png_pixels = NULL; return FALSE; } info_ptr = png_create_info_struct (png_ptr); if (!info_ptr) { png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + free (png_pixels); + png_pixels = NULL; return FALSE; } @@ -449,7 +475,9 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, /* setjmp() must be called in every function that calls a PNG-reading libpng function */ if (setjmp (png_jmpbuf(png_ptr))) { - png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + png_destroy_write_struct (&png_ptr, &info_ptr); + free (png_pixels); + png_pixels = NULL; return FALSE; } @@ -470,7 +498,9 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) { - png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + png_destroy_write_struct (&png_ptr, &info_ptr); + free (png_pixels); + png_pixels = NULL; return FALSE; } } @@ -486,13 +516,15 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, png_write_end (png_ptr, info_ptr); /* clean up after the write, and free any memory allocated */ - png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + png_destroy_write_struct (&png_ptr, &info_ptr); if (row_pointers != (unsigned char**) NULL) free (row_pointers); if (png_pixels != (unsigned char*) NULL) free (png_pixels); + PNGMINUS_UNUSED(raw); /* Quiet a Coverity defect */ + return TRUE; } /* end of pnm2png */ @@ -509,7 +541,8 @@ void get_token(FILE *pnm_file, char *token) do { ret = fgetc(pnm_file); - if (ret == '#') { + if (ret == '#') + { /* the rest of this line is a comment */ do { diff --git a/src/third-party/libpng/contrib/pngsuite/README b/src/third-party/libpng/contrib/pngsuite/README index ec4af9473..53ba5c8f7 100644 --- a/src/third-party/libpng/contrib/pngsuite/README +++ b/src/third-party/libpng/contrib/pngsuite/README @@ -1,8 +1,8 @@ pngsuite -------- -(c) Willem van Schaik, 1999, 2011, 2012 -Two images are by Glenn Randers-Pehrson, 2012 +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. @@ -101,5 +101,5 @@ Testing basn6a16.png: PASS (1072 zero samples) libpng passes test Willem van Schaik - + October 1999 diff --git a/src/third-party/libpng/contrib/powerpc-vsx/README b/src/third-party/libpng/contrib/powerpc-vsx/README new file mode 100644 index 000000000..e566147ea --- /dev/null +++ b/src/third-party/libpng/contrib/powerpc-vsx/README @@ -0,0 +1,81 @@ +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 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/src/third-party/libpng/contrib/powerpc-vsx/linux.c b/src/third-party/libpng/contrib/powerpc-vsx/linux.c new file mode 100644 index 000000000..32ed9d749 --- /dev/null +++ b/src/third-party/libpng/contrib/powerpc-vsx/linux.c @@ -0,0 +1,57 @@ +/* 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 and it assumes that /proc/cpuinfo is never localized. + */ + +#include +#include +#include +#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/src/third-party/libpng/contrib/powerpc-vsx/linux_aux.c b/src/third-party/libpng/contrib/powerpc-vsx/linux_aux.c new file mode 100644 index 000000000..796922d77 --- /dev/null +++ b/src/third-party/libpng/contrib/powerpc-vsx/linux_aux.c @@ -0,0 +1,36 @@ +/* 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 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) +{ + + const 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/src/third-party/libpng/contrib/testpngs/crashers/bad_iCCP.png b/src/third-party/libpng/contrib/testpngs/crashers/bad_iCCP.png new file mode 100644 index 0000000000000000000000000000000000000000..0b7b863795ac5c70bb618927bc32813d455667a8 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0y~yP*@FQGjae4hDL$(qd>Murn7T^X0kE^gT!U+goHiE z7+8F`czBK)PI7(c*f&vdVj$NWacd*ViiUueMoq(=I~o|7B=-K5iM`t#qbwP4V0$)C zkHV{+>%tpWTQO%ks7u0uB`1_QQ&I{ph{4c;i*UeM2nNhJD}<1ws&T&LR*&M7y`9BD z?)x?ay~v=z>zP>)+PR`*&dO_)7n#$LF{6n_#UYV9AI{UPYBD7Y%4H3 z$lXam=JGi(JH$1}THx+15WB=RqGX!W(N-|q)7SN<@vZY9b`{VK*_G8FflOwgF|G{^ v4XeK|tpZ66Q*Uy4x;Tb#Tu)8_dXb5N@sZ*lV<2m|`j)}d)z4*}Q$iB}2@uDU literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_IDAT.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_IDAT.png new file mode 100644 index 0000000000000000000000000000000000000000..efee66cf369959441e1737c5798fd5481b25b830 GIT binary patch literal 79 zcmeAS@N?(olHy`uVBq!ia0vp^Od!kwBL7~QRc!zN|9?*x#}JO|$$#n}m@qRl3j;9_ ZFvwkF>U&qmrVUic;OXk;vd$@?2>|7F6gmI^ literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_bKGD_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_bKGD_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..fd571fd2c93a2e7fe0f510d752a6e50766a6ee14 GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|NnoIx4R3I?!A9NAqG!ZKbLh* G2~7Y_@D6nV literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_cHRM_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_cHRM_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..698e7c46dd7c26f98076301cb533121a4a88600f GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|NnooN09HgeUU{#AqG!ZKbLh* G2~7Z5hYtGy literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_eXIf_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_eXIf_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..7d4160196686cb0433d965ef67af2aa749895e87 GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|Nnn#glF2R%IPdXAqG!ZKbLh* G2~7Y}=?;7V literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_gAMA_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_gAMA_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..b089c1859710c5d8a7f72b8bde95320039d10589 GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|Nnowqp#zphuh_WLJXd+elF{r G5}E*3<_^&S literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_hIST_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_hIST_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..6d6fcb53343aa7a5c356e49a690ef5ad656758d6 GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|Nno6XK+X?ukKNx5QC?ypUXO@ GgeCw;XAR~6 literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_iCCP_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_iCCP_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..fbcb7615395e78a2233c05a6d85779fb70abd21a GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|Nnocvva`GPDwkU5QC?ypUXO@ GgeCw=b`ACb literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_iTXt_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_iTXt_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..098262017efb2dbb89eff3e6542e38f99ef98535 GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|NnnxNJNR|)#e7E5QC?ypUXO@ GgeCx0aSpry literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb106f4a2b2cd74bf5277d7c89c19a0a15006ca GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|Nnnhsh{@>!5P6oAqG!ZKbLh* G2~7Y`+zw6v literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..85252b7dc54b1ccd6e4d2911f6d7f2f6a94635e9 GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|NnnhsbBWw`W>@@LJXd+elF{r G5}E*9h7T_Q literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/crashers/huge_pCAL_chunk.png b/src/third-party/libpng/contrib/testpngs/crashers/huge_pCAL_chunk.png new file mode 100644 index 0000000000000000000000000000000000000000..bc12a8f247357b98c7458131ff00884d1ba19cf1 GIT binary patch literal 57 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn=$j|Nno1v!l_ literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-1-1.8-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-1-1.8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..0fc6cb7dba1b9907a4f4973940cd7e6718c83924 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y2qYNpL^`PhDVB6cUq_%&>E_A%I)HqIWRD45bDP46hOx7_4S6Fo+k-*%fF5lwc|e@(Tv)o$_}bkf&4P z8d2h$Urk*GW zt+&@s=DH`5$aTB3D$kv(V^*!!ikyPpdzbnPW^JC<*S@(VsVMJYcHA=lvdy>dD?NPQ zw(#7oeMWuB8sf80T|U8UY^2q6W5!ybFB!NzT^vI=t|y-W21_18Zp4STD}bU5p00i_ I>zopr07Fe_=>Px# literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-1-1.8.png b/src/third-party/libpng/contrib/testpngs/gray-1-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..5db4d7915c600289a83979832b122d4989cf398d GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y2qYNpL^`PhDVB6cUq_%&>E_A%I)HqIWRD45bDP46hOx7_4S6Fo+k-*%fF5l+Y=0jVN)>FQ_caOwTA` zSgBxSU}&rZBuo{&@-y-joJ;faGV{_i5_1)t^2>8li)u@X{{i)tWQIhP_+%!h<`n~_ z85kK-^B5R7uIu*r@--_6w66d3h*4&D?(_=5mg!zfJdGQ<{nvBG*4t|*bKR3jx3yK|>k2)0c3QsQac$nC$L zGq&DdJDKaAL?YMi&Z<0ju8vu?S}Sr2dhcE8FPOD?T3`F-lBA-%gV}M*_{%omy07%` zecQrwxAqzJC2NS!K6Uv7ud$I<(~TKxfxcwm@^o-mUt7BHJ){2~h-g}q&3ubMe*4MtdB&jIxV0PRx{<6)t?khcf-?s4Ft$jv)$r|Fb xPhCF2Yiy*|bYsR^puZTnJY5_^IIbt300u-JLvF-}w=00644$rjF6*2UngBX_W^n)j literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-1-sRGB-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-1-sRGB-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..80cec4b5eda87dbb62339094799b5ee2992cc539 GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y2qYNpL^`R1IK@HkPR!=VeS?7G3PuKo#yUX4RKY7hBTvD(G%qhRFFhkMSHUU2JSVlN zwxswUP+v)ANJNQGW^!s?F;JR;ks&pYfq~>F!J&8oF+nrT;?pz(SYPDA66!hM^)L$@b^R&M9%_T`ic?YxOmhqQu zzI9*e;rq6Q=WgvY>PyxTpMC1`30`9(t)?3@)~W&R=kj!M4B@z*d;;jtJcite4{uih PMHxI@{an^LB{Ts56k%Qg literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-1-sRGB.png b/src/third-party/libpng/contrib/testpngs/gray-1-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..484fd18c4f64f1166bc8d27840187c7334471fde GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y2qYNpL^`R1IK@HkPR!=VeS?7G3PuKo#yUX4RKY7hBTvD(G%qhRFFhkMSHUU2JSVlNwxswUP+v)ANJNQG zW^!s?F;JR;ks&pYfq~>F! zJ&8oF+nrT;?pz(SYPDA66!hM^)L$@b^R&M9%_T`ic?YxOmhqQuzI9*e;rq6Q=WgvY z>PyxTpMC1`30`9(t)?3@)~W&R=kj!M4B@z*d;;jRJcite4{uihMHxI@{an^LB{Ts5 De4koZ literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-1-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-1-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..a988db9686e25a1abbc150bc6cc92c62e5647a50 GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y2qYNpL^`R11WJPZf`LL){;mV^bV^(!N}Tfx zDvL7HGfEg%Di|3U8tVWFQw6X5j64PB(!9LPy!4F3Tm`56@|@J7+LGdbKz${dArU1$ znaQbn#XxBWMuyZp1_qAnx;?&p%?bjo>pwkWl-Zp-y+W{Mx|b49<3?`(^_;Qw_S(r@ z_aqXzZg*DYxpQ^Qs?}PNQ_y?wQh&j$&C~kYHKD=E46lL&q^>bP0l+XkK DA>~^U literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-1.png b/src/third-party/libpng/contrib/testpngs/gray-1.png new file mode 100644 index 0000000000000000000000000000000000000000..71e37a336385e6432e94a7d9ff63ee51450e082a GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y2qYNpL^`PhDV-A6h!W@gg36-I^o$aQl?p}% zhQ>NT!c@U4KO;}Uxil{?GcP?OF;~GUzdR?ksJ5i|A5dROW=KSdPiAszUNKObfsr9K zkAZ>Xx^9mzU$cTh>-tZR7-e?nPOlJbneL^;)3}k_e?4bxy}foa*FA|uuG^hedG1^t zvud?gEZjfh39VVGwMs$5TAYO@(EsJ sBdw+zGuEmB?dS4zaSY+Oo_qr6nLLKvh!1a907V%*UHx3vIVCg!0JB3^X8-^I literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-16-1.8-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-16-1.8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..06cc0c138e80cf81da4acfe4e1dcfacf5a392c0e GIT binary patch literal 744 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583ceNgJ!4pPawsT?&#~tz{ps-dGfvvAYUQb zBgmJ5p-PQ`p`nF=;TKS-;RORjsR0ASs{{rHs~HRo;stYd1=;{5bV^(!N}TfxDvL7H zGfEg%Di|3U8tVWFQw6X5j64PB(!9LPy!4F3Tm`56@|@J7+LGdbKz${dArU1$naQbn z#XxDGgHrPt7&xx$_W1HOD+si%|MZAaW_RxN3c;4?UP?TT8@c`0bH>)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn<#yFFbTLn>~)y<`Xs501kdc>gb|{OBOXoxAG1@2PY)0|vGO v3=#~?2@E_9j04OW6pnxd!vKc_*bjwCVjmF-a8!2krFu6{1-oD!M)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn<#yFFbTLn>~)y<`Xs501kdc>gb|{OBOXoxAG1@2PY)0|vGO v3=#~?2@E_9j04OW6pnxd!vKc_*bjwCVjmF-a8!2krFu6{1-oD!M)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn<#yFFbTLn>~)y<`Xs501kdc>gb|{OBOXoxAG1@2PY)0|vGO v3=#~?2@E_9j04OW6pnxd!vKc_*bjwCVjmF-a8!2krFu6{1-oD!M<)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn<#yFFbTLn>~)y<`Xs501kdc>gb|{OBOXoxAG1@2PY)0|vGO v3=#~?2@E_9j04OW6pnxd!vKc_*bjwCVjmF-a8!2krFu6{1-oD!M<kvm^Vo;z2^tXi!VIR(A(1RR@H}L*nRQb_CiaU4JdEZm% zYz7Q$2N)z6m=hRy8W;zdGbkJZ35Ed<39uusGaX4{<}2Hwyn_Jkvm^Vo;z2^tXi!VIR(A(1RR@H}L*nRQb_CiaU4JdEZm% zYz7Q$2N)z6m=hRy8W;zdGbkJZ35Ed<39uusGaX4{<}2Hwyn_JQ)?6_t8Wt(r^S91+lJYzG)57?=|n qcp4Z7m@_CG0SSfy4hgU$t}`7;V&*H`p}d0u2s~Z=T-G@yGywqIAfV*{ literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-16.png b/src/third-party/libpng/contrib/testpngs/gray-16.png new file mode 100644 index 0000000000000000000000000000000000000000..4826d61eb7fab6977de0135762596f6220847a51 GIT binary patch literal 684 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583ceNgJ!4pPavgJ;u=xnoL^8`l$oAU!mv`o z$iUE82S}JIc;#p0DL9wrQ)?6_t8Wt(r^S91+lJYzG)57?=|n qcp4Z7m@_CG0SSfy4hgU$t}`7;V&*H`p}d0u2s~Z=T-G@yGywqIAfV*{ literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-2-1.8-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-2-1.8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..a1c6854c96cac7f43c66695fcb529ede2d6d5d34 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c21SA-yJ@?oE5=eLSb!1>dfX$D4y)I0_Tj_bNTzI@FJ0MksZvXY1 zvGw-a$z1m&61i@7R^_>KbOT9H%Gd+$_Bo*Zy%#K^eU$*(yeWi!* z+ZLX?wa=(8SwnpGsmmvLjg7RLZp>H<^d$qAr;B3<$Mxh1Yzz#t3^FQJZiCnik ztMc5rI%d^st;i|py?3d{TVVKNT0D@ikn9oU z%fL{j#=y|f!octgDAe$RfuYoZf#FpG1B2BJ1_tqhIlBUFfD%k4L4LsujEqzMt^@LP zN?apKobwARi!#$QN*Gou7#SEE>i`K;1+V;!JO$^{yu8f3^o+z@1*iP-oYbP)lHz|r zeI=P85hXsE$*Fn8Kxqa>hSWR;29E2xJ-&R+3IeU`KRsfU*_}JRLa=4Jml99oMsEN0 zoU!%x+R0q^Boeu9cUI-Ob9KzB)mo8L(0lJvf5EKH)B4&smn0SC9n6kf#$UGi)_tXi z@7orhyS2}#FIhu;_NmJ!c#Vy;nr_Tk3-l!em#2$k2*>s032Y1uvJ5gRRd17lq70s{ KelF{r5}E*50%{TVVKNT0D@ikn9oU z%fL{j#=y|f!octgDAe$RfuYoZf#FpG1B2BJ1_tqhIlBUFfD$?-t`Q~9`303lnduoN z3@a6k3=EBRfP|@nSAIsGf^%tJUS?i;Mq;jlQ+|0)YEf-T@jsxxlFX2Z5}(ZE)VyM# zGy@|;Y90dv$93HvU%qAqf!6h(9x=-7&YfN%*fQNqiKlTRxBq(1*m`^IWUhM>iCnik ztMc5rI%d^st;i|py?3dEFf`Ty5~d1X`5Ac%&ZT*InR)3MiMa|+`Q+Q9Zx$a3Ma^3E%%5&%Hm{qH_BB!AD-lhJ6S(~TzwQnv-D#|;U9k-0X zZ1b)AN)O++Ej)K?pHW}3hWPALmrw8-8)-G&n6Xw3Xg`;yi(?4K_2da`3=FaiGAdPX QlYycPp00i_>zopr0LZ3Y7XSbN literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-2-sRGB.png b/src/third-party/libpng/contrib/testpngs/gray-2-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..a6bde60afe4a37ac48cac5461c8e7ffd015c4940 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c21SA-yJ@?oE;uHtDJ29Id_YDSebV^(!N}Tfx zDvL7HGfEg%Di|3U8tVWFQw6X5j64PB(!9LPy!4F3Tm`56@|@J7+LGdbKz${dArU1$ znaQbn#XxBWMuyZp1_qAnx;?&p%?bjo>pwkWl-Zp-y+W{Mx|b49<3?`(^_;Qw_S(r@ z_aqXzZg*DYxpQ^Qs?}PNQ_y?wQh&j$&C~kYH}(hQ6Ysd)?x9M^SweEFIc1X|aBdc-KRJ9m18V9RtbC7#BO-2Ur1W9#j; zlez9mBy!#Etjcre>X=olwIZjW_ui%cf?1oV^|fysu_zijiZ`$`Yrw=Fz( zYoAeHvWEEVQdBs3!21bU| zJO&1i>$*L@e9a01t?NHMVwBmPJH0}%WxAIVPvb^z|Mi@)_4eAyT=ygrxo&q><+*cp z%&OH|kyFrn?^1uktj*K<+BcUZ73Cewj$6iGw)xh5rHAj^7M{Dc&!{h1LwxqB%O`k^ sjkKC>%vh@iw4ck<#W95Adh!G|1_oIM8I`KH$v{yCPgg&ebxsLQ08p7$eEI(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!uqB*-rqsCUZWbwHj@ ziEBiObACZ(QD%BZ3ByVSBLhQY9Ux(<;FX_|r{G+gmzSBBo{^ZV;FMpUlUh_;Qv467 zuOu@hqQoaNIW?~sD9ymgkebK9z;Ru-$Cs~JL7;X0r$>x3yK|>k2)0c3QsQac$nC$L zGq&DdJDKaAL?YMi&Z<0ju8vu?S}Sr2dhcE8FPOD?T3`F-lBA-%gV}M*_{%omy07%` zecQrwxAqzJC2NS!K6Uv7ud$I<(~TKxfxcwm@pN$v;kcfh5&{el=1UA8Pv&%-2Z}Rz My85}Sb4q9e0OT}lpa1{> literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-4-1.8.png b/src/third-party/libpng/contrib/testpngs/gray-4-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..bc8da98761cf9ecf3b9e0f1195b58a19f672ae5a GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j0wfsBAI)h3QY`6?zK#rxjHR0=@9O~a6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4NyX-#5JPCIlrK?C^J2y zgkhzEk%6JH4v;Wa@XF7~Q*bWL%gfA5&q&NwaLO;wNiC`^DgFo4SCSbLQR0)CoSIh* zlxARLNX=tl;JB{aJlB9ZHM zXH}j%SI4Yctra;1z4tEl7tGo`t*?D^Nm5bX!R)wY{AHVO-B)_}zHQ;TTlBfw;Kz}jtc)B=-a9mGL2?2%x^CgClCv!T^1H~CUUHx3vIVCg!0F@$V A_5c6? literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-4-linear-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-4-linear-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..45c063d8542ccc7429dc4709fa8487244748d9fb GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j0wfsBAI)h3QY`6?zK#rxZ3_%vOp6Ed6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!uqB*-tAfst{_-*rHq zPKj$oiF1BIWl?5&MhU}81tSAPV;vx2s^FEMk*DBXnwOWEm!6TBtKgJho|9TsTT=WF zsIMe5B%;J8GdVS{7%0ua$dH=Hz`$``x5t;SSwWz6{ijEaGP`r9R|vLD_fq0%+{o>} zo-?-IUOSoVoMxkJd0Jol=8~kMyo1?s%lOMS-@32# z@O|6DbGP;x^(AYF&pvhe1h27?R@03cYk|IG;PG^E4B@z*oDu>I59Uh@A5Z3VoCk_C Nc)I$ztaD0e0stKXYtjG! literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-4-linear.png b/src/third-party/libpng/contrib/testpngs/gray-4-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..0bd068d73fe1cb710b6f1eeed6c34dae1de8d718 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j0wfsBAI)h3QY`6?zK#rxZ3_%vOp6Ed6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4NyX-#5JPCIlrK?C^J2y zgkhzEk%6JH4v;Wa@XF7~Q*bWL%gfA5&q&NwaLO;wNiC`^DgFo4SCSbLQR0)CoSIh* zlxARLNX=tl;JB{aJlB9ZHM zXH}j%SI4Yctra;1z4tEl7tGo`t*?D^Nm5bX!R)wY{AHVO-B)_}zHQ;TTlBfw;Kz}jtc)B=-a9mGL2?2%x^CgClCv!T^1H~CUUHx3vIVCg!0Lvw4 AC;$Ke literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-4-sRGB-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-4-sRGB-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..be8521049c4bd55335297e587ad8679808c193df GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j0wfsBAI)h3af*Z7otVv!`vwC!OeH~n!3>Oy zQ~s_4@^ngEBTAg}3o45;(=$pKRw@`77#iyU2~!2H{ER#W=hD2q%)IoB#9RfZ{PLXC zqS}(;e?WaDnIRD+KAFj>dBs3!21bU|JO&1i>$*L@e9a01t?NHMVwBmPJH0}%WxAIV zPvb^z|Mi@)_4eAyT=ygrxo&q><+*cp%&OH|kyFrn?^1uktj*K<+BcUZ73Cewj$6iG zw)xh5rHAj^7M{Dc&!{h1LwxqB%O`k^jkKC>%vh@iw4cY*#W95AdU8q#(1XmE7(SlN S={OG*XYh3Ob6Mw<&;$T}LSMK5 literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-4-sRGB.png b/src/third-party/libpng/contrib/testpngs/gray-4-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..38a79228d93ba2f043ba3edb84d78cd58ea7a6a3 GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j0wfsBAI)h3af*Z7otVv!`vwC!Iwh_VCC>Q; zl|`B986^xW6^slFjdg&8se)I2MxKImXzuy+_^et)oQKCDd@d-slQ;>=4pNHn@f_4@(yOlE#oiSeCxi_!}o0q&)wQ* z)R(LwKKs<=6THSoT1_`*tW^Wr&*SOh7{YNqIVA+>CFV;EA5Z3VoCk_Cc)I$ztaD0e F0sz(ETn+#L literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-4-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-4-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..14c4f1fb3aadad1b986d1ff32b99ae5eb50421e5 GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j0wfsBAI)h3QcNX5e!&ckj8p!u1M+lATq8=H z^9w4AGSf3k7*;A685kPt00~nCul$TW1?SSdyv)4xjKo|8r~LAq)S}vw;(tJWC7B@+ zB|e$Ssd>dfX$D4y)I0_Tj_bNTzI@FJ0MksZvXY1vGw-a z$z1m&61i@7R^_>KbOT9H%Gd+$_Bo*Zy%#K^eU$*(yeWi!*+ZLX? zwa=(8SwnpGsmmvLjg7RLZp>J#2DG2Y)5S4_<9c#R2+&W=ml!^t%;`7}6ld^s^>bP0 Hl+XkKeMDTy literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-4.png b/src/third-party/libpng/contrib/testpngs/gray-4.png new file mode 100644 index 0000000000000000000000000000000000000000..16bcada820e9317d7b3815e635f35201d0574d92 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j0wfsBAI)h3QaUBB5hc#~1(ija=@}&qD;10k z42^YwgsFm8eny^xb7@{)W?p(mVy=QyetAx6QEf@_KcK#n%#er@pUmXcykej<10zFf z9s>i%b=@9czGel1*7ctrG0N=Don9f>GTlpwr*R{<|9Z~YdVB3;u6q)RT(>)`^4z&P zX4Pt~$SLT(cd5T%*5+w_?VC%Iit-L-$1US8+kET3(!=*{3(wu!XVjOhAwK)m`wkAjOjI=T?gdp zl(t7BHJ){2~h-g}q&3ubMe*4MtdB&jIxV0PRx{<6)t?khcf z-?s4Ft$jv)$r|FbPhCF2Yiy*|bYsR^pf4GCJY5_^BrYeX$UJ0VXli0)GOYaq^d$p> Mr>mdKI;Vst0EUNYpa1{> literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-8-1.8.png b/src/third-party/libpng/contrib/testpngs/gray-8-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..4bba74cfa63e2e81fb6b7bc7ad83282cd9b94f8f GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K57&$`wkAjOjI=i`K;1+V;!JO$^{yu8f3^o+z@1*iP-oYbP)lHz|reI=P85hXsE$*Fn8 zKxv?(Qu7!XIIipV`0_O?2(+&M^oUVrckc8G!ItS>N<57lx&7C3#@5?wCv)ACNaVWR zS(WF`)iJA9Yeh~$@4ZX?1+z9!>ucX!l2nv;FgtD;f7#|+_mv*LZ(Dfo);^=YWDW7z zr!Jr1H8#>}x-nxd&|eHZo-U3d5|@)xWF9gwG&M0Y8P`wkAjOjI=6ExelsM-XR2F5XXOu9kR4_6yG}ZwUrV3v98F>oMrFnUodFdI6xe8AC zfci=@Ln2CiGLuvDih}y literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-8-linear.png b/src/third-party/libpng/contrib/testpngs/gray-8-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..91be367ee5c1ac540bc68888aa4253292636f31d GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K57&$`wkAjOjI=i`K;1+V;!JO$^{yu8f3^o+z@1*iP-oYbP)lHz|reI=P85hXsE$*Fn8 zKxv?(Qu7!XIIipV`0_O?2(+&M^oUVrckc8G!ItS>N<57lx&7C3#@5?wCv)ACNaVWR zS(WF`)iJA9Yeh~$@4ZX?1+z9!>ucX!l2nv;FgtD;f7#|+_mv*LZ(Dfo);^=YWDW7z zr!Jr1H8#>}x-nxd&|eHZo-U3d5|@)xWF9gwG&M0Y8P`wk5T`iE-HF-!xNk6!!&DOF7tFxO zIOXp;AWx^nHKN2hzo4=xGd-h(VWonRfuXSukT6y7%FoDCa4yZu%gjs9NX%7m$}i7J zEvhXk{s+`ok{J?F;**)2npX^z2HKgL$H2gGUAM=VuUSE$b^WJDj551(r&kEJO!rda zY23)|zn(L;-d;PI>z+g+*X_=#Ja?{+S+!a#ateCyUFt8GwRu`!`{t6QqP&CIam)D2 zHs89h^zeP#!gIIw8TBP=h|fNC`2?@Akyg`<8Ee&m_VakUIEF}EPEL_|$iUFl#K>e= S`(*}DoWax8&t;ucLK6U0(_Od# literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-8-sRGB.png b/src/third-party/libpng/contrib/testpngs/gray-8-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae6377ff956395a0e6b948f0236e057db3d3a9e GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K57&$`wk5T`iE-HF-!xNk6!qf_D9WEQo+c;&{zjZm@0VXXXGh3m*(YV=A~yO<|;Vlm*=Dw)s__h1L`Zu42dZ5 z$xKeoD+WpfZAr~zVBol}+vCgEtRT?3{?j8ynccb5D+F7ndnxfWZshh~&ly{9ubs?w zPa=`)c4t+dJ6Ff7TCEj11-%!g4ftctLes!wQ4~7c|2VlLnJOIr^q~HU}$P$WHPM%G6N{i;OXk;vd$@? F2>`uKS`GjJ literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-8-tRNS.png b/src/third-party/libpng/contrib/testpngs/gray-8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..842245f1d9f192857edd85f43f2d8d6ca8874c01 GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K57&$`wkAjMP?KCsyuhDj#;%@D{=~Y?_KIIn6-IYU;E~gq@uio*>TJG%QoM-uk`SJ+ro3V z_8IjhYlzQ2b@>FZv5{8OjTvjzfcEovx;TbNTux4rdC0)f)WpbSSo>uLP@KWj)z4*} HQ$iB}V~<+M literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-8.png b/src/third-party/libpng/contrib/testpngs/gray-8.png new file mode 100644 index 0000000000000000000000000000000000000000..23af27e141a5f6a6dbd411dc738418a087997bb2 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K57&$`wkAf;2{8d2h$Urkvm^Vo;z2^ ztXi!VIR(A)Uwxm)&VJ&bVpxD21drx&6D?a0Qm~Z z9znhg3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fgp;O`-QR19mP+63j zo>9WEQo+c;&{zjZm@0VXXXGh3m*(YV=A~yO<|;Vlm*=Dw)s__h1L`Zu42dZ5$xKeo zD+Wpf9h92Kz`$``x5t;SSwWz6{ijEaGP`r9R|vLD_fq0%+{o>}o-?-IUOSoVoMxkJd0Jol=8~kMyo1?s%lOMS-@32#@O|6DbGP;x^(AYF z&pvhe1h27?R@03cYk~e^%JOt^45_&F_R3D)0}edQj$Zqg|L?nd=&2ObWrpUpDw@X9 zJJ;pMCoJ<@&wNIOL4lzGsE2`rY7CABVFyq&urLTPP>UhJpiX61DggcKM`c$!0R1b& mNX@VWMGn)Uwxm)&VJ&bVpxD2FA7phA*bY1NjQc z9znhg3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fgp;O`-QR19mP+63j zo>9WEQo+c;&{zjZm@0VXXXGh3m*(YV=A~yO<|;Vlm*=Dw)s__h1L`Zu42dZ5$xKeo zD+Wpf9h92Kz`$``x5t;SSwWz6{ijEaGP`r9R|vLD_fq0%+{o>}o-?-IUOSoVoMxkJd0Jol=8~kMyo1?s%lOMS-@32#@O|6DbGP;x^(AYF z&pvhe1h27?R@03cYk~e^%JOt^45_&F_R3D)0}edQj$Zqg|L?nd=&2ObWrpUpDw@X9 zJJ;pMCoJ<@&wNIOL4lzGsE2`rY7CABVFyq&urLTPP>UhJpiX61DggcKM`c$!0R1b& mNX@VWMGn)Uwxm)`57%LGDh>=Er@5fgGI@*N775 z{DR7&%=C;BhLs9N28PBuK*ChPD?cMo!MQXqFEcMaBQaOODZe}?wWzkF_#aSTNoGhy ziBD#7YF;r=8fZgm9s>i%b=@9czGel1*7ctrG0N=Don9f>GTlpwr*R{<|9Z~YdVB3; zu6q)RT(>)`^4z&PX4Pt~$SLT(cd5T%*5+w_?VC%Iit-L-$1US8+kET3(!=*{3(wu! zXVjOhAwK)m`33#;ldN^Wf*|K)78&qol`;+0FSbi?f?J) literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-alpha-16.png b/src/third-party/libpng/contrib/testpngs/gray-alpha-16.png new file mode 100644 index 0000000000000000000000000000000000000000..689879737fc6df3cb65e3b210067b9ddbac53a38 GIT binary patch literal 859 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583b5>)Uwxm)&VJ<64!_l=lp`oqRjM+5{8uu zMh1q)IzYly!7D!_PriCniktMc5r zI%d^st;i|py?3d@n#R&Q*X742 zEc08>d`5*qfuRAYhk=7?42}k22T)M5FbFVEiy^?EPGwgr0R8JnWmh@?{VT&r&9DST h4%IzQEh9fXVBe?mZ{fld>tz^#z|+;wWt~$(69BnNk^TSx literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-alpha-8-1.8.png b/src/third-party/libpng/contrib/testpngs/gray-alpha-8-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..68883a52d5c6828f5389a43634f81e7ad5f158ef GIT binary patch literal 744 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?K*|-O<;PfswIv^W=RUK)yn< zN02WALzNl>LqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A=#;odlsM-XR2F5X zXOu9kR4_6yG}ZwUrV3v98F>oMrFnUodFdI6xe8ACfci=@Ln2CiGLuvD zih#L^h5-%LUUHx3vIVCg!0N07Ip#T5? literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-alpha-8-linear.png b/src/third-party/libpng/contrib/testpngs/gray-alpha-8-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..cdc07031d7faddef7b738b60f3035a067bf1a3c4 GIT binary patch literal 744 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w?K*|-O<;Pfw66Y;frbUK)yn< zN02WALzNl>LqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bX-A=#;odlsM-XR2F5X zXOu9kR4_6yG}ZwUrV3v98F>oMrFnUodFdI6xe8ACfci=@Ln2CiGLuvD zih#L^h5-%LUUHx3vIVCg!0Ab0n(*OVf literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/gray-alpha-8-sRGB.png b/src/third-party/libpng/contrib/testpngs/gray-alpha-8-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..7c37c88836fcb80c0470388e24ff7eae95d7c223 GIT binary patch literal 697 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K588}#g)VJz{w;*0|kh>GJ`ElQ1AV;UfHKN2h zzo4=xGd-h(VWonRfuXSukT6y7%FoDCa4yZu%gjs9NX%7m$}i7JEvhXk{s+`ok{J?F z;**)2npX^z2HKFC$H2gGUAM=VuUSE$b^WJDj551(r&kEJO!rdaY23)|zn(L;-d;PI z>z+g+*X_=#Ja?{+S+!a#ateCyUFt8GwRu`!`{t6QqP&CIam)D2Hs89h^zeP#!gIIw z8TBP=h|fNC`2?@Akyg`<8Ee&me%S5l;uunK>+K~&pa(e)Z{YpEsPdzO6nE~b^S-Cj z*$f!i4lqbCFefnZG%yY@XHYl-5)1KCsyuhD zj#;%@D{=~Y?_KIIn6-IYU;E~gq@uio*>TJG%QoM-uk`SJ+ro3V_8IjhYlzQ2b@>FZ zv5{8OjTvjzfS%ax>EaktaqI0RL!h5H4sYQ7zo_z~gA{k}s`I|5(%B3c*bXpAFfb=D q@H8+EFlSIW0ul@Z91>thTxU9x#LQQ=LwN@S5O})!xvX&2 + echo " $0 [--all|--coverage|--small]" >&2 + exit 1 +esac diff --git a/src/third-party/libpng/contrib/testpngs/palette-1-1.8-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-1-1.8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..7bf60410d52879bca6b5a3965f040f06e0465630 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y$P6UUy?J{QNU@|l`Z@xIN;gm5*8$`!Bzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffhPl)S(28RFt|2xW> z2m(bIOM?7@862M7NCR?oN?apKobwARi!#$QN*Gou7#SEE>i`K;1+V;!JO$^{yu8f3 z^o+z@1*iP-oYbP)lHz|reI=P85hXsE$*Fn8Kxqa>hSWR;29E2xJ-&R+3IeU`KRsfU z*_}JRLa=4Jml99oMsEN0oU!%x+R0q^Boeu9cUI-Ob9KzB)mo8L(0lJvf5EKH)B4&s zmn0SC9n6kf#$UGi)_tXi@7orhyS2}#FIhu;_NmJ!c#Vy;nr_Tk3-mSvm#2$k2*>s0 b6O0TDc?`J`AKtD2iZXb*`njxgN@xNASRHY? literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-1-1.8.png b/src/third-party/libpng/contrib/testpngs/palette-1-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..73965b724e48d70cfff04a965f847929ea97a08e GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y$P6UUy?J{QNU@|l`Z@xIN;gm5*8$`!Bzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffhPl)S(28RFt|2xW> z2m(cPN?apKobwARi!#$QN*Gou7#SEE>i`K;1+V;!JO$^{yu8f3^o+z@1*iP-oYbP) zlHz|reI=P85hXsE$*Fn8Kxqa>hSWR;29E2xJ-&R+3IeU`KRsfU*_}JRLa=4Jml99o zMsEN0oU!%x+R0q^Boeu9cUI-Ob9KzB)mo8L(0lJvf5EKH)B4&smn0SC9n6kf#$UGi z)_tXi@7orhyS2}#FIhu;_NmJ!c#Vy;nr_Tk3-l=im#2$k2*>s06O0TDc?`J`AKtD2 PiZXb*`njxgN@xNAtTk=! literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-1-linear-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-1-linear-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0133dc9f55261e271d8a4fc5f1dde99b272bc8 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y$P6UUy?J{QNU@|l`Z_W&wkzz`*b-fq}tl1_Oh5!JJ)zHb4os0G|-o{|pTO|NnQC zH4y}gFqQ=Q1v5B2yO9Ru=#;odlsM-XR2F5XXOu9kR4_6yG}ZwUrV3v98F>oMrFnUo zdFdI6xe8ACfci=@Ln2CiGLuvDih0vdWB%ibT1{I#*N(m>p5fV?X{D+?nxwa-R`W)bLZ-qRjaikr=a)VrT&6ho2T`) zZ!SqH$~%}Hw~W7R^R4?z58t;fJa=oKQD3r#`0P`cPw*NWX*J!Lu@>lU1};w*#}JO| c$tM^Y81fi$BR;%c0TgBMboFyt=akR{0F%mb>;M1& literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-1-linear.png b/src/third-party/libpng/contrib/testpngs/palette-1-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..bf232fd33cf07bbb08474c875067fb4497539830 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y$P6UUy?J{QNU@|l`Z_W&wkzz`*b-fq}tl1_Oh5!JJ)zHb4os0G|-o{|pTO|NnQC zH4y}g=#;odlsM-XR2F5XXOu9kR4_6yG}ZwUrV3v98F>oMrFnUodFdI6xe8ACfci=@Ln2CiGLuvDih0vdWB%ibT1{I z#*N(m>p5fV?X{D+?nxwa-R`W)bLZ-qRjaikr=a)VrT&6ho2T`)Z!SqH$~%}Hw~W7R z^R4?z58t;fJa=oKQD3r#`0P`cPw*NWX*J!Lu@>l41};w*#}JO|$tM^Y81fi$BR;%c Q0TgBMboFyt=akR{0OeS2AOHXW literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-1-sRGB-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-1-sRGB-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..1c6f262b336f2e797050c858469769bc7417361d GIT binary patch literal 295 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y$P6UUy?J{Q#3>GPcVad_?i&o`um$*pxc+Bg z`2YXEqpXP_NV+7*FPOpM*^M+HN2kO!qQp7Bpt2}4J)?wSrGk-xp|K8-Fjer%&&X47 zF3ro!%uCNm%vEs8FV9IWsx2x02h>-R84^+AlbM{FR}7S9U}Q+mV_@L8uG{0w*Q_AW zy8hE6Mw#8Y(<=m9rh6&zG;ZYfU(Xp^Z?B!qbx$IZ>vm^Vo;z2^tXi!VIR(AGPcVad_?i&o`um$*pxc+Bg z`2YXEqpXP_P(-K1HKN2hzo4=xGd-h(VWonRfuXSukT6y7%FoDCa4yZu%gjs9NX%7m z$}i7JEvhXk{s+`ok{J?F;**)2npX^zW?*DU&0}ETxUSpd%h#+R(7OK9BSx9sxzj5I zTc&#{@icDa_FvB#TW_zO%ymy9k?VG6Rh~On$E;ed6*&dH_b&Ap%-TGyuYGe#Qc>Q) z?6_t8Wt(r^S9N8oT^vI=t|y;hWMIf+ V$c^~$b_GzB!PC{xWt~$(69D&rVg>*J literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-1-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-1-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..8f1642b7b01c30ced4d2aef6cf0823d80e79e8ef GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y$P6UUy?J{QNU;U@gt-1^VEF(4zoV>)AV|6- z$S;_|;n|HeAV;UfHKN2hzo4=xGd-h(VWonRfuXSukT6y7%FoDCa4yZu%gjs9NX%7m z$}i7JEvhXk{s+`ok{J?F;**)2npX^zW?*DU&0}ETxUSpd%h#+R(7OK9BSx9sxzj5I zTc&#{@icDa_FvB#TW_zO%ymy9k?VG6Rh~On$E;ed6*&dH_b&Ap%-TGyuYGe#Qc>Q) z?6_t8Wt(r^S9N8oT^vI=t|y;hWMIf+ V$c^~$b_GzB!PC{xWt~$(69CLpV&VV* literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-1.png b/src/third-party/libpng/contrib/testpngs/palette-1.png new file mode 100644 index 0000000000000000000000000000000000000000..a27d1362a2b59c6f76ed0188be16f8eff02e3ca6 GIT binary patch literal 269 zcmeAS@N?(olHy`uVBq!ia0vp^OhC-Y$P6UUy?J{QNU;U@gt-1^VEF(4zoV>)AW%f7 z#5JPCIlrK?C^J2ygkhzEk%6JH4v;Wa@XF7~Q*bWL%gfA5&q&NwaLO;wNiC`^DgFo4 zSCSbLQR0)CoSIh*lxARLNX=tl;JB{aJlB9ZHMXH}j%SI4Yctra;1z4tEl7tGo`t*?D^Nm5bX!R)wY{AHVO-B)_} zzHQ;TTlBfw;YC!wBJY5_^IIbt3U}Rv(W5|v8@OA}Il)=;0 K&t;ucLK6Vta$gnz literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-2-1.8-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-2-1.8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2ab16564ab7c7bbdc84d1b8907946bc4912751 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c2#0(@`f}Y2L1kxRS9T^xIOE*v6*8$`!Bzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaf5VPl)UP|NrCSKo|(b zs^)P5#hFWj{DS{K+bp-pEg#6$DRGS`an3KOEXqvJC}CKsU}RuutOF!W6}<8@@)Vp) z^YSwD(lZis6`b)&YbSHvlSt&c-C33A&ebuiR%=C0LGQgw{ROi& zPwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY*{3d_;59bVYPvCFEztW6T%InD fAsp9}C$KRv$TG;NRJ~0GiZXb*`njxgN@xNA)(Lca literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-2-1.8.png b/src/third-party/libpng/contrib/testpngs/palette-2-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..cdcf28329b96889057f6c9c10da21423ee4f9203 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c2#0(@`f}Y2L1kxRS9T^xIOE*v6*8$`!Bzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaf5VPl)UP|NrCSKo|(b zs^)P5#dS(tBTAg}3o45;(=$pKRw@`77#iyU2~!2H{ER#W=hD2q%)IoB#9RfZ{PLXC zqS}(;e?WaDnIRD+KAFj>dBs3!21bU|JO&1i>$*L@e9a01t?NHMVwBmPJH0}%WxAIV zPvb^z|Mi@)_4eAyT=ygrxo&q><+*cp%&OH|kyFrn?^1uktj*K<+BcUZ73Cewj$6iG zw)xh5rHAj^7M{Dc&!{h1LwxqB%O`k^jkKC>%vcNbF9VmSi(?4K_2da`3=FaiGAdPX QlYycPp00i_>zopr08LtN0{{R3 literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-2-linear-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-2-linear-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..d346d40071c738076bd4864327c3be3bb087da7b GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c2#0(@`f}Y2L1kxRS9T^zg78t&m77yerBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaf5VPl)UP|Nkv4Ko|)A zOo{pq6lX38@(cd|Y_r@Vw|pR1r^Gd)#5up9vM4h>ql96lf{}rtu?~eulnVgze43uVIWJt|pVBol}+vCgEtRT?3 z{?j8ynccb5D+F7ndnxfWZshh~&ly{9ubs?wPa=`)c4t+dJ6Ff7TCEj11-%!g4ftctLes!wLtGPaCy2o fhHzX@p1{VyAj=@5QuQ_&D9YgJ>gTe~DWM4fpjmZH literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-2-linear.png b/src/third-party/libpng/contrib/testpngs/palette-2-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..5c2f6d335dfb5ce156a6541631014175b0e2506f GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c2#0(@`f}Y2L1kxRS9T^zg78t&m77yerBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaf5VPl)UP|Nkv4Ko|)A zOo{pq6xS(njVN)>FQ_caOwTA`SgBxSU}&rZBuo{&@-y-joJ;faGV{_i5_1)t^2>8l zi)u@X{{i)tWQIhP_+%!h<`n~_85kK-^B5R7uIu*r@--_6w66d3h*4&D?(_=5mg!zf zJdGQ<{nvBG*4t|*bKR3jQ)?6_t8Wt(r^S9N8oT^vI=t|w1mV_=YFkWs06n+z0X@O1TaS?83{1OPHiYJdO$ literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-2-sRGB.png b/src/third-party/libpng/contrib/testpngs/palette-2-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..a3bf9a2f3b0e5c39cec1140880877246e0a78fc5 GIT binary patch literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c2#0(@`f}Y2LIK@HkPR!=VeS?7)&YbSHvlSt&c-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6j zcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY*{3d_;59bVYPvCFts2mNE>9Q75RU7~6WACS XWEo^ss@^68MHxI@{an^LB{Ts5KSE^* literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-2-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-2-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..c34a6986d008247f312c147f0f368941cdc4fdc7 GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c2#0(@`f}Y0#DV_kI5ZC|z|2H&%Fc4f=n2-h( zXD$iy3;zFXv)m%Ld>~h+#5JPCIlrK?C^J2ygkhzEk%6JH4v;Wa@XF7~Q*bWL%gfA5 z&q&NwaLO;wNiC`^DgFo4SCSbLQR0)CoSIh*lxARLNX=tl;JB{aJlB9ZHMXH}j%SI4Yctra;1z4tEl7tGo`t*?D^ zNm5bX!R)wY{AHVO-B)_}zHQ;TTlBfw;YC!wBJY5_^IIbs8 aU}IpAWsp&+dYcRsW$<+Mb6Mw<&;$VQsb`P? literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-2.png b/src/third-party/libpng/contrib/testpngs/palette-2.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf4536e09bed285c717cf5babbee81b156b7d78 GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^EI`c2#0(@`f}Y0#DV_kI5ZC|z|2H&%Fc4f=n2-h( z*C}z0C~?j&s4U7%&nRJ7sbFMaXsiPyOclKHGx8LiOY`zF^U^aCa}}KO%X3nTYD-PBaH7f|TuK)CiQD%4U^a{b2>0U}ajT^cB z*K@|!+iNFt-IGYl|c<$CdqrPMf@!6*?pWrn%(rUUfW33v{elAZJ#}JO|$rIQZ7-Sh_RI1)414S7; MUHx3vIVCg!04Tp=82|tP literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-4-1.8-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-4-1.8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..20cb465cece78b066cfdb2a5c972b870bdabf3f6 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j!VDx;!;N!*6id3JuOkB^W9jC}`#OMpg=CK) zUj~LMH3o);76yi2K%s^g3=E|P3=FRl7#OT(FffQ0%-I!a1C%fb@CkAK|NsAr760Sn z{wpbgSSuP=#Ko;pvI7YLSwNr!mRn&5q?ME!m6Vbhp8@sqmjw9*|Nr#t=FO8kS8kr) zQ`u9NFz?wfZlIJ-iEBiObACZ(QD%BZ3ByVSBLhQY9Ux(<;FX_|r{G+gmzSBBo{^ZV z;FMpUlUh_;Qv467uOu@hqQoaNIW?~sD9ymgkebK9z;Ru-$Cs~JL7;X0r$>x3yK|>k z2)0c3QsQac$nC$LGq&DdJDKaAL?YMi&Z<0ju8vu?S}Sr2dhcE8FPOD?T3`F-lBA-% zgV}M*_{%omy07%`ecQrwxAqzJC2NS!K6Uv7ud$I<(~TKxfx*SVzopr00W|r^#A|> literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-4-1.8.png b/src/third-party/libpng/contrib/testpngs/palette-4-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..c2318ff82ed838af1bbb7bae3422588947958c9b GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j!VDx;!;N!*6id3JuOkB^W9jC}`#OMpg=CK) zUj~LMH3o);76yi2K%s^g3=E|P3=FRl7#OT(FffQ0%-I!a1C%fb@CkAK|NsAr760Sn z{wpbgSSuP=#Ko;pvI7YLSwNr!mRn&5q?ME!m6Vbhp8@sil(?>Wdwltt6$Dz>e|p3yvpaWsg<#8cFD0JFjokk0Ib-YXwUfE-NhEUJ?ySml z=jxbMtF{FLd x@ERLwHQku878oWBJf1F&Asp9}Q$m^;7?>|Hd_0-caULkn;OXk;vd$@?2>>5Lfr$VB literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-4-linear-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-4-linear-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..4d96a47241327d17d0c749411ec888d23a267554 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j!VDx;!;N!*6id3JuOkCv+XBNE)8c`Ag=CK) zUj~LMH3o);76yi2K%s^g3=E|P3=FRl7#OT(FffQ0%-I!a1C%fb@CkAK|Nnn``+p0I z|2#Y(R(n*tg+)7$97qVr0sdCz`v1Eq9ITq8=H^9w4AGSf3k7*;A685kPt00~nCul$TW1?SSdyv)4xjKo|8 zr~LAq)S}vw;(tJWC7B@+B|e$Ssd>dfX$D4y)I0_Tj_bNTzI@FJ0MksZvXY1vGw-a$z1m&61i@7R^_>KbOT9H%Gd+$_Bo*Zy z%#K^eU$*(yeWi!*+ZLX?wa=(8SwnpGsmmvLjg7RLZp>H<3@!#9PZ!4!j_b)OAx#Vn Y%$FEGp3Lbu4-{wcboFyt=akR{0N?727XSbN literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-4-linear.png b/src/third-party/libpng/contrib/testpngs/palette-4-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..dfc5a868ee2413ffd6e34fa8d2e389db674af3a7 GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j!VDx;!;N!*6id3JuOkCv+XBNE)8c`Ag=CK) zUj~LMH3o);76yi2K%s^g3=E|P3=FRl7#OT(FffQ0%-I!a1C%fb@CkAK|Nnn``+p0I z|2#Y(R(n*tg+)7$97qVr0sJlB9ZHMXH}j% zSI4Yctra;1z4tEl7tGo`t*?D^Nm5bX!R)wY{AHVO-B)_}zHQ;TTlBfw;z%XIp@pN$v;kcfh64J!Lz;M1% z_wWDT(D2{E0mRxre}6;6euo5*5Re4~4q&cnsUjC9Gzu^C$p5458 za_7p;^Lr|L$`a;1`^62E(kXF`C~?j&s4U7%&nRJ7sbFMaXsiPyOclKHGx8LiOY`zF z^U^aCa}}KO%X3nTYD|Hd_0-caULkn;OXk;vd$@?2>>lMh=c$D literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-4-sRGB.png b/src/third-party/libpng/contrib/testpngs/palette-4-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..26ea9e5ab1490f215d2039b6ba673694ffbcaac2 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j!VDx;!;N!5oZ=vNCuZ~GzQI6_L4Z$)>;M1% z_wWDT(D2{E0mRxre}6;6euo5*5Re4~4q&cnsUY!!xh!W@gg36-I z^o$aQl?p}%hQ>NT!c@U4KO;}Uxil{?GcP?OF;~GUzdR?ksJ5i|A5dROW=KSdPiAsz zUNKObfsr8zuy+_^et)oQKCDd@d-slQ;>=4pNHn@f_4@(yOlE#oiSeCxi_!}o0q&)wQ*)R(Lw zKKs<=6THSoT1_`*tW^Wr&*SOh7{YNqIVGftfr0rF!^e|39p{1K44$rjF6*2Ung9{c BdKdrz literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-4-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-4-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..429f6b95394f3cefa274d8235a861b8f6b8ece3c GIT binary patch literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j!VDx;!;N!*ltF+`i0l9V|M&0z-_Y>i!2!hD zKYxEi!+wVZkPwgs1P)-i{Ru$Y!C}6GoXO-opkDrxAiv=MpPt>kd2;8<&GUOId&&~# zJ^RHCl+r12jVN)>FQ_caOwTA`SgBxSU}&rZBuo{&@-y-joJ;faGV{_i5_1)t^2>8l zi)u@X{{i)tWQIhP_+%!h<`n~_85kK-ffjLG*X{A;YgQ0wUH|D3qs;Ey=@o)4)4h~< z8aHzLujh=dx7SYQx+jsyb-S}F&z-AdR;|{GoPyqam--84ZJyTGzPTi+DDPl)+%o>M z&A09=J$&D`@Z7C^Mt#W|;9k S({Uas&fw|l=d#Wzp$PzE{e_eO literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-4.png b/src/third-party/libpng/contrib/testpngs/palette-4.png new file mode 100644 index 0000000000000000000000000000000000000000..82f3489940e4916a1a78a74bc85ccc370b9d33fa GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~j!VDx;!;N!*ltF+`i0l9V|M&0z-_Y>i!2!hD zKYxEi!+wVZkPwgs1P)-i{Ru$Y!C}6GoXO-opkAF4*N775{DR7&%=C;BhLs9N28PBu zK*ChPD?cMo!MQXqFEcMaBQaOODZe}?wWzkF_#aSTNoGhyiBD#7YF;r=nt_oa6=)jA zb=@9czGel1*7ctrG0N=Don9f>GTlpwr*R{<|9Z~YdVB3;u6q)RT(>)`^4z&PX4Pt~ z$SLT(cd5T%*5+w_?VC%Iit-L-$1US8+kET3(!=*{3(wu!XVjOhAwK)mumRr+5PN$`|{rR zy?tAkE?EH6pG*e;!0^K2G62%-BS;%R&Yll-cZBTi!Mb^D9!N`DJG|@E7R%Yug=GwY z4LJaGYy#jP`>MkLuyz&zf7Ad_uonQ7*ncAO9023M(!~`a-}jC2wf2?rJuoRQy3}=v>tfeMt_xk)8S9EEWjexCIrA!+tYV^?@fFsWu~m%L zG7@Dt#!#HW2Ie#dEi^?`ho}luk5L(+qLT7z8C_<1&tQe3rK$?Q23t|b;AcV)DGaAgOnc(OQM`bzQR7d7HqR8Q;Ryl_?I<(ax zy$&95(2xU19p{qsKk&FJAcW?3W`aPaMB}^ZJ!B_(Fa5@zKMFu3q}_{JF12P6lxB-2-o3`1b45 zr%oI{cI1$SH+SziGjj6Nk3Rh1{lS6$-8;8!*`z)h4ov&^?AqSb)zO+7K63D#xA*n! z?CsvzzCM{)ZK;3vj@LJf)>Ly-JnD{7SI4XCUT%D;cEz%?K5Mg-SRJcbUb(a+)Y~mu z$EdoZG+a!d-Po40o;3l@fBu==8S7h`>S~u)29!U0`jp9u`sm7Kk&vRx&sr##q%mAU5vh%c?*Ef&a?++xBY3?9RT6b LlHwypHJ$$h>0Uyi literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-8-1.8.png b/src/third-party/libpng/contrib/testpngs/palette-8-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..cc09ee60f1e7c375ded9e848697ac5e746d1afbd GIT binary patch literal 1093 zcmW+#O=z4&7@ln%shf^J5SSt%EOQ8^)=rxe0zt-Pn~!$ePSb6&u!K78x-QwQ+sTsM zxLT5!iCx=M6Q>S@q}Af7z;P*=ajNS$SH$K0Ye;t6m;M|$%D2`+AW9MRPV`E~iW2Is#V}!tuOgk)xxIP=^N`>T|F+!Qs2sZCkr(&AQbqRyD1xS|Kc-vMgum zm?a|?AGT<~!u|xb-!e`cyKam!x^0v+vSNfVykHnNG%|!4JYo5?j{3LgIZl|~@a9!kThRX{fmh+38l{hVPQsKDDQH{fT(n6nQ zE@C#v3}-seRDsEvkeKljV--egj7Wx?47C|tO8V`GsT-wsjGBn*(^TcDECv*mmno}J z+MuLO@d`y93O5pQ_(9?*u_MGVq9dX>k%a)6@Csp)&^958;B|sDfm?}^d_Q&r*dE4a z1nV)Za#&7<`Y^9z*2HuLlXZ+YG1|tko5;@hBG-rP05TNmQKTXy^MMS+YlyWG?I5BN z-bUyyg1d=EeGhcK(Dp+!2=y>jStut1bCA~|TY_{0k}Zh45bZ+v2=0mgm2fAJ->z2{mRrq#!@t(tbg^}2 zu3VAL@Ei9r01{D+wrJKev2OZDBqeCxfJuHHID_N#AuCcDqQ`N12nmeWrT zl+wT4xFS!auisfdXzGoRpSVvNcXl>!UfXHCwIIKHM|}ChyE~76B~SnS=!+j8KNz}M zeg%K_!^7{!YDLK`)stW0-8%d|2}OH;c#I#Xlij5ALCQB&Raa{t(SKlhw_=A7?2 z_iSD`pN$PX6aWB>EuB+R0RS|Q0FFlHv}AYG-0q7P&npIS<7=VY{WXR&>*rL=17OX= z0CcYh;BWJ)`!)b8rvmU>EdY=10U)()-?7+Z03fiiyfW%}p6hyAdrEmydO~=ddyILG z<5B9_wnvDEv1eHxLLP*^w|mmngRbgxWv46RF0XP~)O8$}=DK#4OHy5&;#vV0CAn~v zAKD$%dZ$)BS_&;{G>>T((T<~OP}|v>q-#vHm8{Vi4U_yl+&-mylxkP9L5XU`%M~kD zj-zOvvU3#4P&iFl;}l9(FyJTcc1kUzYLJpk5tE!r7M6}9X-L{sl5B}>X{AX-Buw!u zbmKzT2vsd)Oo%eUBZ3tP#}PDN*g-)i3!E*i41v-GO!eh(tGJGFRn8^jBEor?vqJ7T zoEC69#7U52%B>uZvN_E1wR59PN0=&RGR#B~SYlFx96S$PZv8O-&C zHrg3EOob+ClZOdyyv;=&$95dzIM{J4$3cz*N4nzXQXQl!kIE1g`IHw>Hr@DAI+NOk zloU}MrdBaU5elPz3*9VRXWJ^rmedwOn}=*xU;^8;(6+-iiP)IgR=JI0Hmvgd?WPi) zPE-bw*+fhxJV;o+$%4=#Vn+xmBREE^YJzGAjQhjkreIC5O2g8|A{%pxS;(Y}X&BoK zlNiPvTMZZq3_JZvas!r5w$wOFrdcAx;yD(}Gxb@t*s{wlQf=V|%WAh!j|Kbuv2&A< z9)naek_3r##Iq3#8Zi)!AUlRg4Z;FhJqYbYaL}JocNEk~Pz9h&fg%<1EXZ<=a*#%$ zT?I)T;!bGwK{N>ANtiNg(ZA*=@e&pDANT(G>(6_4@BI49ts6gGxpd*Yf!}ZceDnI% z%in){?(FGPcShjS#q(dE`E2;av7@(cT)R91pC14CgChqIT>0UQxij2%mj6jKt>>O@4et!{6QHzmOS%>1dLX;aMcNM@O6YR!zSY;A3BjW^Y`WX={H z%NyIf5-a{Q-zAzWs}tqT^^L77jM?m}##R7EUk+}Wm%J`BWy9fnx8Q_NT6RD4;QHNV z6LHUx`xhJ@v*fvOZhheT_`1Ng&1+g&VADVs9bDeF_4EFFV;6qxCuaSFB}!> S`opX{07|3tOAgJh?foBkCGgw; literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-8-linear.png b/src/third-party/libpng/contrib/testpngs/palette-8-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..40d413cd660350acbc6346e5894d196db7ccc59e GIT binary patch literal 1093 zcmW+#O=z4&7@oTM}FbbX$|K3AQ_7 zyY;6bn8ez#pp`&rOZDJfBp$R#ZVChTBpy82gHoAFJrys4coOt;KIbsM@4P(k^FGhD z)2C#A>X{S(pnvA%^cetP*aEl@g&CX8YFM6VRpu%HUj4NA_+~SlbBia>%mHxuSpYV# z0PuIX+I$Sar6U0Reine|Zv&8B`{e8T3jiQ+x;9^p+TZhT*V`R$*1c|dwcusd3*q^gXTzRmJ;`{S@~GFto+P#3b?%0< zTh3^wn@-i8jGPdT7aYqwI_L;>IPFlMgS`n3zhm8&wH<4gtZrCUv$A4^uzcLI5le?G z8L)W2MQICD3247=oHlmJ7-e+bC~0Kb2w`~9Fm7nx5N7azLDaxZQlW2Y*VMM5O)|8P-M@p5IoK!+6KA~7q(Sjme;Sq)M z3JxdS`Kol0v=wQ}Qcp=WDdlk~gyhF0n~=05Nm1f)i3$>qB}51A0v(~k06O3ZsY7%a zTnHuv6@mzXg+M~U|GVPHxGQiw&P|c)5?2#k9t*LYALne6(I^O<{q|Yv2B{sQCQtP!RRtq| zp&JP9CK~lU(Dg!_f+hoX7OG(=#{zSZS0P(~v<1mJ#5)k}LU<2mUVQnVV3Nb#YNH$J zwYNK~t(7kLJXbnWJbE}x&*f(IN;?-_YPVP0t(9{Zawqhg=a)Mh-HZQ*f8EvjMz^-Q zxZJ)No`XS`+W_qQsqn#E`rTaSy}N(@1`mF7;nrJEU%54Vh-`iJ{+3o)T D7Ij$p literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-8-sRGB-tRNS.png b/src/third-party/libpng/contrib/testpngs/palette-8-sRGB-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..b8863ec2b8ffe01421c1fd561ddf880de73af07e GIT binary patch literal 1313 zcmW-hZEO`q6ozjlF<3#zU!ox}A;B1^$xvdzCc+4}q2;5DrIbbrnSRM_XfNaK+Lqel zw543?r3_7l3$1lRs@7s)tW~NMSQ{(_6-TLpfMHS+jYg75i2g7!uCv`AlYRD_J^P+_ z&Q2#OST{HG>C8wZGB-ajS{R9BxZ6m^>{)JoILUKEs4HBzX4Z9&1p=dkm8|CXk-2vP0MxQdD z#C%MBRN_P8gS@aqJEY8j(*4R$E7h%JN{J4|xnfO@~XteXr+2J~LqMZ&`+GV?oaZWiWoMX-r=a6$Svnw{ijK_36^Bb9JVzQZu zeJ+==Rz}+y>0mg?P$z>a2D-v6w3XDvsIH+tqspVQk&0$ln6h?Cla!<=78LbRn5LjF z+;3YL+l3fT3_WY#ufQ>k{l!tYTO)EE=6; z%#xT2Owt%jj0Q1O7>tIKWOI;-B3*#|5~RwJtU;pQ^@ms|qCJT8BRq)EFoI(UOoU@+ zv!GcCbrkvps!}LpPn#xI;Zd(YgtIRjsw|KhXZ)2D9z^ux8Q6XO>`7<&I?zy47K)Hb@1kfkuyW@$-ZOV zhm!64_Ihl$qu!%OQU_X_8xpm#ik&mm!QZHVt>)FT(rtyuT+9*MT}8KVB^z=NC0mnfS zcD%WIX+`GUd1aY*I-BC_G7t8)Ecvj8b=|!#SntTO!^sh^JP{w?z4L>|>ql;zMbq}c z$?tAo%syQ4?2~<8PhFY2JbOvo&&N+c90bVtOvj6}9 literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-8-sRGB.png b/src/third-party/libpng/contrib/testpngs/palette-8-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..90f8912043164c8a6cc451a6c74183cea0e6498c GIT binary patch literal 1046 zcmW+#&uiR86#vG6)V0y^WRXyY9z^O2(-g7f;+Ss8rnGUWA?zW_bhDw~;P#tg^L1U9 zq)xJ~>#}Z#5^+nHFi60-2OUBVIV?DM2oVnsxCf;|hxiW+h-bgf*Eu}q$9r!+@AE#d zO%~=RGOuKUAeflX=WYkVnBN9t=f=H#w#8@D!^Z8onen$yZ@m`;;{mz3IGZGibBVQy zF^SfRQi+s_5DDiAV+o}RAqmC_LJ5Qk0I9b-b9Us+iPOhU4V>&d(RG|VR&liC$dbc( zho&9OI&d*f?MBv~S~Ij-S+#Fv&x(%a+_Kox(2`|~iA6aJuUU{yakvv>hsGQlePGm{ zk-J8;4d;ec4J{i|G`L{Uf`K^$rc==FSX-sdf!0#1o|Zz3mgZcunx;&XP-Ci5K|`WJ zKCRFVl-*ZmPwAdg50&gF(Nvr(R#!AuBvLq3sHotw0!t|!t}ks*nq8@dR2?Z>QZyvz zl5I*_lO&dyNmQ0Fl%SMy=eojnglP-i5~?X=Lx^p`xnTDN-4vuQa8019fUy9TlxWYL zr^8q1L312*Ol~r9-}^GQ&1i#>Cc`a; z+6;CW=%y`nC2B)z%2YF|Vk&D?Z2H8MH7IRS(xF&Tv`b-+f_~a>w?ynRF-4+7q9P(= zBI+ImVNF6igghj;N6;RD`veS9akxCT1e*fZ6sr(RhDFUo#;k>@z@&$<#OMG+g~4&E zBsYz04w(g{3rH1_EF)3%^&!?qbQh65gbxrpL~w|}Nh&*+h4vaWIj9L#%TR_;#GVYu zI*|4t*@sv`G=%UJf>EkbcM;euFw;Qifm#Bx1VqI%2Ur)-J|F{tj{!OXa0I{^_$m`k z`oYM?vxWHjI{T!ub~lWJ0h~ftu4cV?6W&-4BY6FzC|Zl|hIj74ne~s$tCg*I<6j>a zuPqkhn`j$l)xLApP`tXBqU#uQIv6s%==imJL z6hGw_A*}9w$v7< zE#*=#WoRl~Xsr`cwH5~!LyHM6sy%=SEQc40wmqvvJ0TQ6(o47Wa*V)>po!^7)~^TRN-HZ&&GI#eo@G87`@ zJY+1SG$bU%IQ0Dxp%B6lfGFEeSu<(%gjJ(f4q4G>d6#9((xfF-7MEDRz@j`0b1aw_ zm9~?{TrzshC~4$?5gEhNhA~3}L*fRP86O)IGjO>9Igt)Kq0N}q!&(h$*{?;9=AD`` zP3twO)wn|Yr5Y7!7}Fpx5^YD7kxCCLC6vr4!4*#_#uRN-gen|YK2fMtL99SQ)S(@c zWtWF)+O=Hc3rDbv;#$R5nr3O!*#{OKB@5?G$%VKSfa| zg=q@9qAj#l#KeiNC5jRm5Yb3@vnxz!J0U58)5PZl^$?gLpfB2QTY^m)))iRAu}okQ zVBX|ZVA_F68sl#4XE5r=Z~%j$XgF+vZ?LaReMNj3_XYKNqm%5@lux*iGrli;H0VR= zgVAV`Y#uT(q>GR$MX~~kTEy#Je~5M>(t~h6@&^$bMsN&)iD>L>4m8W5jzNW?EQ2Br zdEm@|G!01x;sNMOh{hni1i@r9qjnxJIY8$DRRClO5LJLDopXS80n!KX5b#F@fBydK)SX*5e*FIGm5UedO~ds` z{q5zi#?PHOeb?N+F%4gy{o=FXlP7Ne^uyIF6XWM17<&JBzy9XZh4W`le{$-CgJXve zT^v96`KKR$G&t~X@8RyQ{d>=jjzpn%GCc?1>R`<;J-N4W~939rjPkZNt7rdNtL6vkFO*WS|L zGD$?MpI@GvvwK(F_VO*8B3ia&@xuAErgH1%m)6BrxY)w^Ppn+lv&~tN6Xcf$t9R1f z$(rr)z#D?OXvxwXw>%5i?u;kk>emyAn#A^ac^zD}v!S*+*%Ivf&%GDa6qg3;YbvV~ zyIk0vH`NKxn|b4z11~<(4nc>!e>ZFHSY4*^vAvnK3ud(rKfFOcwDrxEiz~D5%qh>l z-Px2_lfA#UWzmPVwCm0_PJ2g=988S_70JZ-j%^=2T0e5jESR$Uj(>OSeD1-@ryuY8 zdh+t@rMZjRem;8gDfj(Zg|Qck=S)^s&7JbRwzjMXmbCnJ)IIkK^NV7qR*|;<0gfDi A!vFvP literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/palette-8.png b/src/third-party/libpng/contrib/testpngs/palette-8.png new file mode 100644 index 0000000000000000000000000000000000000000..2502d305b57df2ce24deb63bae3c39a1d9629fc7 GIT binary patch literal 1033 zcmW+#!E0Pa7=N)Kb!~J!StOL92a&qMG({-6IBhp{Q)(O}ggr!=ZZ`CVZeND&>vmm| zI?1}O%eoy(#8^oIK&<%N;%&1SbM=ePK3DQ|D4^Q)5!CQ>9WVQz25$ zQ^rzCQ$kXVQ-o3oQvkATckJxgnIoqUof{aV@Jm98@*@Lj*;6&bPeZ*)eWs0 zQZ~3`(7b^K17{(^K$qKJ!#LwL;GyM z80VC8!a3#~aSk~L|98dJn2njKGu>dS$>cf{_kAv7n~b&?X*1kmsLNoFfqvFPSD`kf zrb;!VDyFhQ#kvQktVL;uk{-o^qHPKj3I0hxKEOGuTG ztRhkO^&!?pbQ_T!g!d5IM{tC|QD!@rhxQ^g1*i#BOHhVT#9j=@dXOfN>_V&{8bSC3 zf^p_icLvxzFf%|Gfm#Hz0z}O#2Us7_0U$$w4*@y?a16jP_$C)k`H{%Sv!(dT8vCra zdNYiJA)H3%FXVlAA6{DvBY5R*6s<-#!yC8Z<+Xd&mD)yp=U@LWUR@}~*H@QUqC5WD z57|l-1Sg-q_w|RbwIFD#zyF$;8r@DBZ+wwlJ9}z#|J9GwE1!J+!Mn@37pHIJ{_HlR ztGTZpZ=Cy~%K9(<5bW{6w+}i8ak&=#a_iIYU#}lLw`Y&tm*4&V{O9Qh%kR87_-*{_ w)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn=geV#6kAr-gYUfs@kz=4O^(2MW=hX4ES9b9{WiFw0LuSrYJ zoXNSdYg_VNeb1s)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn=geV#6kAr-gYUfs@kz=4O^(2MW=hX4ES9b9{WiFw0LuSrYJ zoXNSdYg_VNeb1s)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn=geV#6kAr-gYUfs@kz=4O^(2MW=hX4ES9b9{WiFw0LuSrYJ zoXNSdYg_VNeb1s)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn=geV#6kAr-gYUfs@kz=4O^(2MW=hX4ES9b9{WiFw0LuSrYJ zoXNSdYg_VNeb1skvm^Vo;z2^tXi!VIR(ApX8&otIR6H3K zJh>P=$&g|!U?Ec{Hv3o)uu|q6bVI4(MTD754>+h5ZV*Gs2yldJFk+CpaRE#g6r~Jw zhc02TXref|p%{u004TB~Mtu;2j3fE^;?GO=V3m(+&+WZ47g#bdc)I$ztaD0e0stU; BHA?^h literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-16-sRGB.png b/src/third-party/libpng/contrib/testpngs/rgb-16-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..2cf2209e01d6eb8253a77f91f1de55fa8a4900fd GIT binary patch literal 1164 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583dSsRCB}QA`q`Q$lZzA{J3v0kfT%L8d2h$ zUrkvm^Vo;z2^tXi!VIR(ApX8&otIR6H3K zJh>P=$&g|!U?Ec{Hv3o)uu|q6bVI4(MTD754>+h5ZV*Gs2yldJFk+CpaRE#g6r~Jw zhc02TXref|p%{u004TB~Mtu;2j3fE^;?GO=V3m(+&+WZ47g#bdc)I$ztaD0e0stU; BHA?^h literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-16-tRNS.png b/src/third-party/libpng/contrib/testpngs/rgb-16-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..28643528d6bc2fbfd8c9da72c9fb60eec0d23e48 GIT binary patch literal 1151 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583dSsRCB}QA|Rzx;u=xnoL^8`l$oAU!mv`o z$iUE82S}JIc;#p0DL9wrQ)?6_t8Wt(r^S9 zTk>6f&!Sm#@11|G=;;^C;1R^&F^S1xk_f}3B@7c(SQ}I{8B{zO6+F2ZJjsw^EMOs1 zCpP<753o|^9CSme;YEa*Obbni$p~Q)?6_t8Wt(r^S9 zTk>6f&!Sm#@11|G=;;^C;1R^&F^S1xk_f}3B@7c(SQ}I{8B{zO6+F2ZJjsw^EMOs1 zCpP<753o|^9CSme;YEa*Obbni$p~KCsyuhDj#;%@D{=~Y?_KIIn6-IYU;E~gq@uio*>TJG%QoM- zuk`SJ+ro3V_8IjhYlzQ2b@>FZv5{8OjTvi!K4oI_ba4!+xb^ljBQJvj5A(sihWgVQ zGn!(Hxn|XCssm^72z)Bl~;ZCNd>p_+< q?w~=iz+DdtaE=4qv)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn;~Y@RNTAr-gYUS{NFP~c%cnAcE$T4P32Y%$lY8dc5BYhPRO zUwieXbt_8)g9C#Cg8%~u0}BHa10&VBEDu;|V=&ywv~)el62=`g2o|{OK>^NjfSVS< cpYVk-{vlKN?^u~#z!b^g>FVdQ&MBb@050yAXaE2J literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-8-linear-tRNS.png b/src/third-party/libpng/contrib/testpngs/rgb-8-linear-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..5a2ed9f009af9200ffa7c6485accbfe524a6d056 GIT binary patch literal 837 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLmKCsyuhDj#;%@D{=~Y?_KIIn6-IYU;E~gq@uio*>TJG%QoM- zuk`SJ+ro3V_8IjhYlzQ2b@>FZv5{8OjTvi!K4oI_ba4!+xb^ljBQJvj5A(sihWgVQ zGn!(Hxn|XCssm^72z)Bl~;ZCNd>p_+< q?w~=iz+DdtaE=4qv)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn;~Y@RNTAr-gYUS{NFP~c%cnAcE$T4P32Y%$lY8dc5BYhPRO zUwieXbt_8)g9C#Cg8%~u0}BHa10&VBEDu;|V=&ywv~)el62=`g2o|{OK>^NjfSVS< cpYVk-{vlKN?^u~#z!b^g>FVdQ&MBb@0LR6bng9R* literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-8-sRGB-tRNS.png b/src/third-party/libpng/contrib/testpngs/rgb-8-sRGB-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..f8b4ecbdc69d05e45b655031ea6856ebcf5cb672 GIT binary patch literal 790 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLlCbx$lZzA{J3v0ki%9IG3PuKo#yUX4RKY7hBTvD(G%qhRFFhkMSHUU2 zJSVlNwxswUP+v)ANJNQGW^!s?F;E(4U}_!%1IKmU9$&s@1%cM}pB^#F?9QEDA=onA zONpm(Be(y0&e(c;?PRWd5{X>5JFD{CxjJUmYOTmA=)HHTzhKtpX?^XROOlH64ra$K z<1gEM>%P*%_iYQ$-P&i=m#iT^`_$zVyv9aaO*dw&RbyaaV)Jxy45_&F_A(kvm^Vo;z2^tXi!VIR(A< z&CP3HTk&6e^`&(yO9O)gg93v90|x^O0}}%y)wwJWSZQN0+{v_bJ;)Nq9W)3Qxa&ay i&T)X77QvtJg)#miQ~2*#nO(pX$>8bg=d#Wzp$PyHMvH&| literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-8-tRNS.png b/src/third-party/libpng/contrib/testpngs/rgb-8-tRNS.png new file mode 100644 index 0000000000000000000000000000000000000000..cdb1642ebad2e8e697f0e48a7ff5b2376ad51661 GIT binary patch literal 777 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLm>F!J&8oF+nrT;?pz(SYPDA66!hM^)L$@b^R&M9%_T`ic?YxOmhqQuzI9*e;rq6Q z=WgvY>PyxTpMC1`30`9(t)?3@)~YcuFtK^MIEGZ*dV86XmqCGt`Cwi{{b`LEO|ivX zvuac|H?Mtd#eeP9m)5N;4Gazp3Jd}a91JWBObm=v=dwItrH#RGC)3jPAWIl`&>&dg lt_KA;#{q6y1b@O8#`uR!;lE>Lb^%i)gQu&X%Q~loCIAqyiyQy| literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-8.png b/src/third-party/libpng/contrib/testpngs/rgb-8.png new file mode 100644 index 0000000000000000000000000000000000000000..e69c71bfd57998b71aba94b56dee8a0d20265ec7 GIT binary patch literal 759 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLm;J7;u=xnoL^8`l$oAU!mv`o z$iUE82S}JIc;#p0DL9wrQ)?6_t8Wt(r^S9W7P#v{0nTxNn-;;J@P#q{ XAyfG8SeaeG6v^P}>gTe~DWM4fcDIO- literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-alpha-16-1.8.png b/src/third-party/libpng/contrib/testpngs/rgb-alpha-16-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..ad65d150e23f08e419facaa791faa5d17c4784d4 GIT binary patch literal 1437 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583fpX6wjj)RUpNZ?&#~tz{ps-dGfvvAYUQb zBgmJ5p-PQ`p`nF=;TKS-;RORjsR0ASs{{rHs~HRo;stYd1=;{5bV^(!N}TfxDvL7H zGfEg%Di|3U8tVWFQw6X5j64PB(!9LPy!4F3Tm`56@|@J7+LGdbKz${dArU1$naQbn z#XxDGgHrPt7&xx$_W1HOD+si%|MZAaW_RxN3c;4?UP?TT8@c`0bH>)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn;q1)eUBAr-gYUR%j{z<`Iv(fjAzgjpqll7BeV#1~E)f@nm$Eq{7PJIZ1>;g-GJf`)&^w{N&*JWRb&SYs-q~2EV!E}j4ZgD z7$0y@oPt1(TEbAkLU9s8xQg;*4RI9Z$r|J)>SZ+uQAKNj PWgmm5tDnm{r-UW|VN`y; literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-alpha-16-linear.png b/src/third-party/libpng/contrib/testpngs/rgb-alpha-16-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..1f399003173a558a55e7a0312f4a796b39cf99a2 GIT binary patch literal 1437 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583fpX6wjj)RUpNZ?&#~tz}U9H@Wr%vAYUQb zBgmJ5p-PQ`p`nF=;TKS-;RORjsR0ASs{{rHs~HRo;stYd1=;{5bV^(!N}TfxDvL7H zGfEg%Di|3U8tVWFQw6X5j64PB(!9LPy!4F3Tm`56@|@J7+LGdbKz${dArU1$naQbn z#XxDGgHrPt7&xx$_W1HOD+si%|MZAaW_RxN3c;4?UP?TT8@c`0bH>)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn;q1)eUBAr-gYUR%j{z<`Iv(fjAzgjpqll7BeV#1~E)f@nm$Eq{7PJIZ1>;g-GJf`)&^w{N&*JWRb&SYs-q~2EV!E}j4ZgD z7$0y@oPt1(TEbAkLU9s8xQg;*4RI9Z$r|J)>SZ+uQAKNj PWgmm5tDnm{r-UW|a_)Zc literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-alpha-16-sRGB.png b/src/third-party/libpng/contrib/testpngs/rgb-alpha-16-sRGB.png new file mode 100644 index 0000000000000000000000000000000000000000..d9cea633a5e781eedf91a5bc4ffdad0e9f16e799 GIT binary patch literal 1390 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K583fpX6wjj)RS>T@$lZzA{J3v0kfT%L8d2h$ zUrkvm^Vo;z2^tXi!VIR(AV%HTOkgh7Q| z0Zj&vNlSp{O=4Q)?6_t8Wt(r^S9 KpUXO@geCyOk#FVz literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/testpngs/rgb-alpha-8-1.8.png b/src/third-party/libpng/contrib/testpngs/rgb-alpha-8-1.8.png new file mode 100644 index 0000000000000000000000000000000000000000..f4d08ec04714b59ce33cb9cdf731e898561b42a2 GIT binary patch literal 919 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$6&2?&#~tz{ps-dGfvvAYUQb zBgmJ5p-PQ`p`nF=;TKS-;RORjsR0ASs{{rHs~HRo;stYd1=;{5bV^(!N}TfxDvL7H zGfEg%Di|3U8tVWFQw6X5j64PB(!9LPy!4F3Tm`56@|@J7+LGdbKz${dArU1$naQbn z#XxDGgHrPt7&xx$_W1HOD+si%|MZAaW_RxN3c;4?UP?TT8@c`0bH>)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn;~S)MMAAr-gYUfIcez=4O^(QDuG|9y84J(Xg*%+S16MblV% z=eqp(gk^r~na`*&C@?et^)PTyjlt0%>;Q@e76t(ZYB2;D)T!)B1)zWZsO(Aypnqi; msTr1_$f3H&sb%Dc2kiS){w-X1V!aFl5O})!xvX)&YbSHvlSt&c z-C33A&ebuiR%=C0LGQgw{ROi&PwQ*nT#{6jcQ89{8GqU4TlbY7zHeK2?$$n|zGMyY z*{3d_;59bVYPvCFEzn;~S)MMAAr-gYUfIcez=4O^(QDuG|9y84J(Xg*%+S16MblV% z=eqp(gk^r~na`*&C@?et^)PTyjlt0%>;Q@e76t(ZYB2;D)T!)B1)zWZsO(Aypnqi; msTr1_$f3H&sb%Dc2kiS){w-X1V!aFl5O})!xvXkvm^Vo;z2^tXi!VIR(A`DcofBmTJ sN(Z2SWf-X$mY~R?y2q(yQ)?6_t8Wt(r^S9018SL1_1_YF$5UYsq9Jxpnv_S>`Diqe`Oe{8J3{P hp}NPZW#oqk?E6&yEnIkFy$k~oc)I$ztaD0e0ssVnkl6qL literal 0 HcmV?d00001 diff --git a/src/third-party/libpng/contrib/tools/README.txt b/src/third-party/libpng/contrib/tools/README.txt index 5ddae02ce..f53be6df9 100644 --- a/src/third-party/libpng/contrib/tools/README.txt +++ b/src/third-party/libpng/contrib/tools/README.txt @@ -23,4 +23,5 @@ ORIGINAL AUTHORS of the people below claim any rights with regard to the contents of this directory. - John Bowler + John Bowler + Glenn Randers-Pehrson diff --git a/src/third-party/libpng/contrib/tools/chkfmt b/src/third-party/libpng/contrib/tools/chkfmt index 9da6475fd..a1b88ccbf 100755 --- a/src/third-party/libpng/contrib/tools/chkfmt +++ b/src/third-party/libpng/contrib/tools/chkfmt @@ -1,4 +1,11 @@ #!/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. diff --git a/src/third-party/libpng/contrib/tools/genpng.c b/src/third-party/libpng/contrib/tools/genpng.c new file mode 100644 index 000000000..0b3f98196 --- /dev/null +++ b/src/third-party/libpng/contrib/tools/genpng.c @@ -0,0 +1,881 @@ +/*- 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 ::= + * shape ::= circle|square|line + * x1 ::= + * x2 ::= + * y1 ::= + * y2 ::= + * + * 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 +#include +#include +#include +#include + +/* Normally use 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: + * + * xx1, 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; icolor = 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\n" + " shape ::= circle|square|line\n" + " x1,x2 ::= \n" + " y1,y2 ::= \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/src/third-party/libpng/contrib/tools/png-fix-itxt.c b/src/third-party/libpng/contrib/tools/png-fix-itxt.c index 1210bd9c8..c7654c113 100644 --- a/src/third-party/libpng/contrib/tools/png-fix-itxt.c +++ b/src/third-party/libpng/contrib/tools/png-fix-itxt.c @@ -1,14 +1,14 @@ /* png-fix-itxt version 1.0.0 * - * Copyright 2013 Glenn Randers-Pehrson - * Last changed in libpng 1.6.3 [July 18, 2013] + * 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: + * Usage: * * png-fix-itxt.exe < bad.png > good.png * @@ -34,8 +34,10 @@ #define MAX_LENGTH 500000 -#define GETBREAK ((unsigned char)(inchar=getchar())); if (inchar == EOF) break - +/* 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) { @@ -48,25 +50,25 @@ main(void) /* Skip 8-byte signature */ for (i=8; i; i--) { - c=GETBREAK; + GETBREAK; putchar(c); } -if (inchar != EOF) +if (inchar == c) /* !EOF */ for (;;) { /* Read the length */ unsigned long length; /* must be 32 bits! */ - c=GETBREAK; buf[0] = c; length = c; length <<= 8; - c=GETBREAK; buf[1] = c; length += c; length <<= 8; - c=GETBREAK; buf[2] = c; length += c; length <<= 8; - c=GETBREAK; buf[3] = c; length += c; + 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 */ - c=GETBREAK; buf[4] = c; - c=GETBREAK; buf[5] = c; - c=GETBREAK; buf[6] = c; - c=GETBREAK; buf[7] = c; + 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) */ @@ -81,19 +83,22 @@ for (;;) /* Copy the data bytes */ for (i=8; i < length + 12; i++) { - c=GETBREAK; buf[i] = c; + 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) & 0xff) == buf[length+8] && - ((crc >> 16) & 0xff) == buf[length+9] && - ((crc >> 8) & 0xff) == buf[length+10] && - ((crc ) & 0xff) == buf[length+11]) + 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++; @@ -101,18 +106,21 @@ for (;;) if (length >= MAX_LENGTH-12) break; - c=GETBREAK; - buf[length+11]=c; + 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) & 0xff); - buf[1] = (unsigned char)((length << 16) & 0xff); - buf[2] = (unsigned char)((length << 8) & 0xff); - buf[3] = (unsigned char)((length ) & 0xff); + 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 +#endif + +#include + +/* Define the following to use this test against your installed libpng, rather + * than the one being built here: + */ +#ifdef PNG_FREESTANDING_TESTS +# include +#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 +#include +#include +#include +#include +#include + +#include +#include + +#include + +#ifndef PNG_SETJMP_SUPPORTED +# include /* because png.h did *not* include this */ +#endif + +#ifdef __cplusplus +# define voidcast(type, value) static_cast(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 /* 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<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 : "", 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; jerrset ? 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) +{ + const 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. + */ +{ + const 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). + */ + const 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, const 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; + const 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 = ""; + 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, png_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; iread_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 = ""; + + else + { + if (filename != NULL) + { + dp->output_file = filename; + dp->fp = fopen(filename, "wb"); + } + + else + { + dp->output_file = ""; + 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, png_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 desireable 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; spcsp; ++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) /* interating 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(const int argc, const char * const * const 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 + */ + { + const 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 -#if defined(PNG_READ_SUPPORTED) && defined(PNG_EASY_ACCESS_SUPPORTED) +#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. @@ -71,8 +73,8 @@ * with older builds. */ #if ZLIB_VERNUM < 0x1260 -# define PNGZ_MSG_CAST(s) png_constcast(char*,s) -# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) +# 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) @@ -86,17 +88,17 @@ /* Copied from pngpriv.h */ #ifdef __cplusplus -# define png_voidcast(type, value) static_cast(value) -# define png_constcast(type, value) const_cast(value) -# define png_aligncast(type, value) \ +# define voidcast(type, value) static_cast(value) +# define constcast(type, value) const_cast(value) +# define aligncast(type, value) \ static_cast(static_cast(value)) -# define png_aligncastconst(type, value) \ +# define aligncastconst(type, value) \ static_cast(static_cast(value)) #else -# define png_voidcast(type, value) (value) -# define png_constcast(type, value) ((type)(value)) -# define png_aligncast(type, value) ((void*)(value)) -# define png_aligncastconst(type, value) ((const void*)(value)) +# 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 @@ -134,7 +136,7 @@ #define png_zTXt PNG_U32(122, 84, 88, 116) #endif -/* The 8 byte signature as a pair of 32 bit quantities */ +/* 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) @@ -156,7 +158,7 @@ */ #define UNREACHED 0 -/* 80-bit number handling - a PNG image can be up to (2^31-1)x(2^31-1) 8 byte +/* 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 @@ -316,13 +318,13 @@ uarb_mult32(uarb acc, int a_digits, uarb num, int n_digits, png_uint_32 val) a_digits = uarb_mult_digit(acc, a_digits, num, n_digits, (png_uint_16)(val & 0xffff)); - /* Because n_digits and val are >0 the following must be true: */ - assert(a_digits > 0); - 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; @@ -446,7 +448,7 @@ 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 = png_voidcast(png_bytep, pv); + 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. @@ -584,7 +586,7 @@ chunk_type_valid(png_uint_32 c) c &= ~PNG_U32(32,32,0,32); t = (c & ~0x1f1f1f1f) ^ 0x40404040; - /* Subtract 65 for each 8 bit quantity, this must not overflow + /* 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); @@ -667,8 +669,8 @@ IDAT_list_extend(struct IDAT_list *tail) if (length < tail->length) /* arithmetic overflow */ length = tail->length; - - next = png_voidcast(IDAT_list*, malloc(IDAT_list_size(NULL, length))); + + next = voidcast(IDAT_list*, malloc(IDAT_list_size(NULL, length))); CLEAR(*next); /* The caller must handle this: */ @@ -921,7 +923,7 @@ emit_string(const char *str, FILE *out) else if (isspace(UCHAR_MAX & *str)) putc('_', out); - + else fprintf(out, "\\%.3o", *str); } @@ -1821,7 +1823,7 @@ IDAT_init(struct IDAT * const idat, struct file * const file) } static png_uint_32 -rechunk_length(struct IDAT *idat) +rechunk_length(struct IDAT *idat, int start) /* Return the length for the next IDAT chunk, taking into account * rechunking. */ @@ -1833,7 +1835,7 @@ rechunk_length(struct IDAT *idat) const struct IDAT_list *cur; unsigned int count; - if (idat->idat_index == 0) /* at the new chunk (first time) */ + if (start) return idat->idat_length; /* use the cache */ /* Otherwise rechunk_length is called at the end of a chunk for the length @@ -1945,7 +1947,7 @@ process_IDAT(struct file *file) 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; @@ -1992,7 +1994,7 @@ process_IDAT(struct file *file) 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); + file->chunk->chunk_length = rechunk_length(idat, 1/*start*/); /* Change the state to writing IDAT chunks */ file->state = STATE_IDAT; @@ -2218,7 +2220,7 @@ zlib_init(struct zlib *zlib, struct IDAT *idat, struct chunk *chunk, /* These values are sticky across reset (in addition to the stuff in the * first block, which is actually constant.) */ - zlib->file_bits = 16; + zlib->file_bits = 24; zlib->ok_bits = 16; /* unset */ zlib->cksum = 0; /* set when a checksum error is detected */ @@ -2301,10 +2303,12 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes) zlib->file_bits = file_bits; /* Check against the existing value - it may not need to be - * changed. + * 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; + 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)); @@ -2325,8 +2329,7 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes) if (bIn != b2) { /* If the first byte wasn't changed this indicates an error in - * the checksum calculation; signal this by setting file_bits - * (not window_bits) to 0. + * the checksum calculation; signal this by setting 'cksum'. */ if (zlib->file_bits == zlib->window_bits) zlib->cksum = 1; @@ -2412,7 +2415,7 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes) endrc = ZLIB_TOO_FAR_BACK; break; } - /* FALL THROUGH */ + /* FALLTHROUGH */ default: zlib_message(zlib, 0/*stream error*/); @@ -2566,7 +2569,7 @@ zlib_run(struct zlib *zlib) list->lengths[i] -= zlib->extra_bytes; list->count = i+1; zlib->idat->idat_list_tail = list; - /* FALL THROUGH */ + /* FALLTHROUGH */ default: return rc; @@ -2585,7 +2588,7 @@ zlib_run(struct zlib *zlib) { struct chunk *chunk = zlib->chunk; int rc; - + assert(zlib->rewrite_offset < chunk->chunk_length); rc = zlib_advance(zlib, chunk->chunk_length - zlib->rewrite_offset); @@ -2669,7 +2672,7 @@ zlib_check(struct file *file, png_uint_32 offset) /* Truncated stream; unrecoverable, gets converted to ZLIB_FATAL */ zlib.z.msg = PNGZ_MSG_CAST("[truncated]"); zlib_message(&zlib, 0/*expected*/); - /* FALL THROUGH */ + /* FALLTHROUGH */ default: /* Unrecoverable error; skip the chunk; a zlib_message has already @@ -3337,7 +3340,7 @@ read_callback(png_structp png_ptr, png_bytep buffer, size_t count) if (file->state != STATE_IDAT && length > 0) setpos(chunk); } - /* FALL THROUGH */ + /* FALLTHROUGH */ default: assert(chunk != NULL); @@ -3469,7 +3472,8 @@ read_callback(png_structp png_ptr, png_bytep buffer, size_t count) /* Write another IDAT chunk. Call rechunk_length to * calculate the length required. */ - length = chunk->chunk_length = rechunk_length(file->idat); + 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 */ @@ -3535,7 +3539,7 @@ 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 = png_voidcast(struct control*, + struct control *control = voidcast(struct control*, png_get_error_ptr(png_ptr)); return &control->file; } @@ -3543,7 +3547,7 @@ get_control(png_const_structrp png_ptr) static void allocate(struct file *file, int allocate_idat) { - struct control *control = png_voidcast(struct control*, file->alloc_ptr); + struct control *control = voidcast(struct control*, file->alloc_ptr); if (allocate_idat) { @@ -3853,6 +3857,7 @@ usage(const char *prog) 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; @@ -3955,7 +3960,6 @@ main(int argc, const char **argv) else { size_t outlen = strlen(*argv); - char temp_name[FILENAME_MAX+1]; if (outfile == NULL) /* else this takes precedence */ { @@ -4030,7 +4034,7 @@ main(void) int main(void) { - fprintf(stderr, "pngfix does not work without read support\n"); + fprintf(stderr, "pngfix does not work without read deinterlace support\n"); return 77; } #endif /* PNG_READ_SUPPORTED && PNG_EASY_ACCESS_SUPPORTED */ diff --git a/src/third-party/libpng/contrib/tools/reindent b/src/third-party/libpng/contrib/tools/reindent new file mode 100755 index 000000000..f4df309b6 --- /dev/null +++ b/src/third-party/libpng/contrib/tools/reindent @@ -0,0 +1,25 @@ +#!/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/src/third-party/libpng/contrib/tools/sRGB.h b/src/third-party/libpng/contrib/tools/sRGB.h index 22c8f7c0e..d1ece5129 100644 --- a/src/third-party/libpng/contrib/tools/sRGB.h +++ b/src/third-party/libpng/contrib/tools/sRGB.h @@ -14,7 +14,7 @@ * 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 - * http://en.wikipedia.org/wiki/SRGB). + * https://en.wikipedia.org/wiki/SRGB). */ static double sRGB_from_linear(double l) diff --git a/src/third-party/libpng/contrib/visupng/PngFile.c b/src/third-party/libpng/contrib/visupng/PngFile.c index e563e9292..d46318f44 100644 --- a/src/third-party/libpng/contrib/visupng/PngFile.c +++ b/src/third-party/libpng/contrib/visupng/PngFile.c @@ -2,7 +2,7 @@ * PNGFILE.C -- Image File Functions *------------------------------------- * - * Copyright 2000, Willem van Schaik. + * Copyright 2000,2017 Willem van Schaik. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -136,7 +136,7 @@ BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, /* create the two png(-info) structures */ - png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), NULL, + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); if (!png_ptr) { @@ -236,6 +236,10 @@ BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, 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) { @@ -313,7 +317,7 @@ BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData, /* prepare the standard PNG structures */ - png_ptr = png_create_write_struct(png_get_libpng_ver(NULL), NULL, + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); if (!png_ptr) { diff --git a/src/third-party/libpng/contrib/visupng/VisualPng.c b/src/third-party/libpng/contrib/visupng/VisualPng.c index 236525a59..20e1625fa 100644 --- a/src/third-party/libpng/contrib/visupng/VisualPng.c +++ b/src/third-party/libpng/contrib/visupng/VisualPng.c @@ -2,7 +2,7 @@ * VisualPng.C -- Shows a PNG image *------------------------------------ * - * Copyright 2000, Willem van Schaik. + * Copyright 2000,2017 Willem van Schaik. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -726,6 +726,10 @@ BOOL DisplayImage (HWND hwnd, BYTE **ppDib, 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))) { @@ -847,6 +851,10 @@ BOOL FillBitmap ( 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; diff --git a/src/third-party/libpng/example.c b/src/third-party/libpng/example.c index 945546c25..99d2f054a 100644 --- a/src/third-party/libpng/example.c +++ b/src/third-party/libpng/example.c @@ -2,8 +2,8 @@ #if 0 /* in case someone actually tries to compile this */ /* example.c - an example of using libpng - * Last changed in libpng 1.6.15 [November 20, 2014] - * Maintained 1998-2014 Glenn Randers-Pehrson + * Last changed in libpng 1.6.24 [August 4, 2016] + * Maintained 1998-2016 Glenn Randers-Pehrson * Maintained 1996, 1997 Andreas Dilger) * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * To the extent possible under law, the authors have waived @@ -97,7 +97,7 @@ int main(int argc, const char **argv) */ if (buffer != NULL && png_image_finish_read(&image, NULL/*background*/, buffer, - 0/*row_stride*/, NULL/*colormap*/) != 0) + 0/*row_stride*/, NULL/*colormap*/) != 0) { /* Now write the image out to the second argument. In the write * call 'convert_to_8bit' allows 16-bit data to be squashed down to @@ -105,7 +105,7 @@ int main(int argc, const char **argv) * to the 8-bit format. */ if (png_image_write_to_file(&image, argv[2], 0/*convert_to_8bit*/, - buffer, 0/*row_stride*/, NULL/*colormap*/) != 0) + buffer, 0/*row_stride*/, NULL/*colormap*/) != 0) { /* The image has been written successfully. */ exit(0); @@ -114,13 +114,13 @@ int main(int argc, const char **argv) else { - /* Calling png_free_image is optional unless the simplified API was + /* Calling png_image_free is optional unless the simplified API was * not run to completion. In this case if there wasn't enough * memory for 'buffer' we didn't complete the read, so we must free * the image: */ if (buffer == NULL) - png_free_image(&image); + png_image_free(&image); else free(buffer); @@ -271,7 +271,7 @@ void read_png(char *file_name) /* We need to open the file */ { png_structp png_ptr; png_infop info_ptr; - unsigned int sig_read = 0; + int sig_read = 0; png_uint_32 width, height; int bit_depth, color_type, interlace_type; FILE *fp; @@ -280,7 +280,7 @@ void read_png(char *file_name) /* We need to open the file */ return (ERROR); #else no_open_file /* prototype 2 */ -void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ +void read_png(FILE *fp, int sig_read) /* File is already open */ { png_structp png_ptr; png_infop info_ptr; @@ -295,7 +295,7 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, - png_voidp user_error_ptr, user_error_fn, user_warning_fn); + png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (png_ptr == NULL) { @@ -370,12 +370,12 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ * are mutually exclusive. */ - /* Tell libpng to strip 16 bit/color files down to 8 bits/color. + /* Tell libpng to strip 16 bits/color files down to 8 bits/color. * Use accurate scaling if it's available, otherwise just chop off the * low byte. */ #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_set_scale_16(png_ptr); + png_set_scale_16(png_ptr); #else png_set_strip_16(png_ptr); #endif @@ -419,10 +419,10 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0) png_set_background(png_ptr, image_background, - PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, - PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); /* Some suggestions as to how to get a screen gamma value * @@ -466,7 +466,7 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ } #ifdef PNG_READ_QUANTIZE_SUPPORTED - /* Quantize RGB files down to 8 bit palette or reduce palettes + /* Quantize RGB files down to 8-bit palette or reduce palettes * to the number of colors available on your screen. */ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) @@ -481,7 +481,7 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ png_color std_color_cube[MAX_SCREEN_COLORS]; png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS, - MAX_SCREEN_COLORS, NULL, 0); + MAX_SCREEN_COLORS, NULL, 0); } /* This reduces the image to the palette supplied in the file */ else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) != 0) @@ -491,7 +491,7 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ png_get_hIST(png_ptr, info_ptr, &histogram); png_set_quantize(png_ptr, palette, num_palette, - max_screen_colors, histogram, 0); + max_screen_colors, histogram, 0); } } #endif /* READ_QUANTIZE */ @@ -518,11 +518,11 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ png_set_swap_alpha(png_ptr); - /* Swap bytes of 16 bit files to least significant byte first */ + /* Swap bytes of 16-bit files to least significant byte first */ png_set_swap(png_ptr); /* Add filler (or alpha) byte (before/after each RGB triplet) */ - png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); + png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER); #ifdef PNG_READ_INTERLACING_SUPPORTED /* Turn on interlace handling. REQUIRED if you are not using @@ -530,7 +530,7 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ * see the png_read_row() method below: */ number_passes = png_set_interlace_handling(png_ptr); -#else +#else /* !READ_INTERLACING */ number_passes = 1; #endif /* READ_INTERLACING */ @@ -552,7 +552,7 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ for (row = 0; row < height; row++) row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, - info_ptr)); + info_ptr)); /* Now it's time to read the image. One of these methods is REQUIRED */ #ifdef entire /* Read the entire image in one go */ @@ -574,10 +574,10 @@ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ { #ifdef sparkle /* Read the image using the "sparkle" effect. */ png_read_rows(png_ptr, &row_pointers[y], NULL, - number_of_rows); + number_of_rows); #else no_sparkle /* Read the image using the "rectangle" effect */ png_read_rows(png_ptr, NULL, &row_pointers[y], - number_of_rows); + number_of_rows); #endif no_sparkle /* Use only one of these two methods */ } @@ -614,7 +614,7 @@ initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr) * linked libraries. */ *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, - png_voidp user_error_ptr, user_error_fn, user_warning_fn); + png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (*png_ptr == NULL) { @@ -649,14 +649,14 @@ initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr) * the function png_get_progressive_ptr(png_ptr). */ png_set_progressive_read_fn(*png_ptr, (void *)stream_data, - info_callback, row_callback, end_callback); + info_callback, row_callback, end_callback); return (OK); } int process_data(png_structp *png_ptr, png_infop *info_ptr, - png_bytep buffer, png_uint_32 length) + png_bytep buffer, png_uint_32 length) { if (setjmp(png_jmpbuf((*png_ptr)))) { @@ -691,7 +691,7 @@ info_callback(png_structp png_ptr, png_infop info) } row_callback(png_structp png_ptr, png_bytep new_row, - png_uint_32 row_num, int pass) + png_uint_32 row_num, int pass) { /* * This function is called for every row in the image. If the @@ -780,7 +780,7 @@ void write_png(char *file_name /* , ... other image information ... */) * in case we are using dynamically linked libraries. REQUIRED. */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, - png_voidp user_error_ptr, user_error_fn, user_warning_fn); + png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (png_ptr == NULL) { @@ -819,7 +819,7 @@ void write_png(char *file_name /* , ... other image information ... */) * png_init_io() here you would call */ png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn, - user_IO_flush_function); + user_IO_flush_function); /* where user_io_ptr is a structure you want available to the callbacks */ #endif no_streams /* Only use one initialization method */ @@ -842,7 +842,7 @@ void write_png(char *file_name /* , ... other image information ... */) * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED */ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???, - PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* Set the palette if there is one. REQUIRED for indexed-color images */ palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH @@ -966,7 +966,7 @@ void write_png(char *file_name /* , ... other image information ... */) /* Swap bytes of 16-bit files to most significant byte first */ png_set_swap(png_ptr); - /* Swap bits of 1, 2, 4 bit packed pixel formats */ + /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */ png_set_packswap(png_ptr); /* Turn on interlace handling if you are not using png_write_image() */ @@ -983,16 +983,21 @@ void write_png(char *file_name /* , ... other image information ... */) png_uint_32 k, height, width; /* In this example, "image" is a one-dimensional array of bytes */ + + /* Guard against integer overflow */ + if (height > PNG_SIZE_MAX/(width*bytes_per_pixel)) { + png_error(png_ptr, "Image_data buffer would be too large"); + } png_byte image[height*width*bytes_per_pixel]; png_bytep row_pointers[height]; if (height > PNG_UINT_32_MAX/(sizeof (png_bytep))) - png_error (png_ptr, "Image is too tall to process in memory"); + png_error (png_ptr, "Image is too tall to process in memory"); /* Set up pointers into your "image" byte array */ for (k = 0; k < height; k++) - row_pointers[k] = image + k*width*bytes_per_pixel; + row_pointers[k] = image + k*width*bytes_per_pixel; /* One of the following output methods is REQUIRED */ diff --git a/src/third-party/libpng/intel/filter_sse2_intrinsics.c b/src/third-party/libpng/intel/filter_sse2_intrinsics.c new file mode 100644 index 000000000..5e8553fbb --- /dev/null +++ b/src/third-party/libpng/intel/filter_sse2_intrinsics.c @@ -0,0 +1,406 @@ + +/* filter_sse2_intrinsics.c - SSE2 optimized filter functions + * + * Copyright (c) 2016-2017 Glenn Randers-Pehrson + * Written by Mike Klein and Matt Sarett + * Derived from arm/filter_neon_intrinsics.c + * + * Last changed in libpng 1.6.31 [July 27, 2017] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#if PNG_INTEL_SSE_IMPLEMENTATION > 0 + +#include + +/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d). + * They're positioned like this: + * prev: c b + * row: a d + * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be + * whichever of a, b, or c is closest to p=a+b-c. + */ + +static __m128i load4(const void* p) { + return _mm_cvtsi32_si128(*(const int*)p); +} + +static void store4(void* p, __m128i v) { + *(int*)p = _mm_cvtsi128_si32(v); +} + +static __m128i load3(const void* p) { + /* We'll load 2 bytes, then 1 byte, + * then mask them together, and finally load into SSE. + */ + const png_uint_16* p01 = (png_const_uint_16p)p; + const png_byte* p2 = (const png_byte*)(p01+1); + + png_uint_32 v012 = (png_uint_32)(*p01) + | (png_uint_32)(*p2) << 16; + return load4(&v012); +} + +static void store3(void* p, __m128i v) { + /* We'll pull from SSE as a 32-bit int, then write + * its bottom two bytes, then its third byte. + */ + png_uint_32 v012; + png_uint_16* p01; + png_byte* p2; + + store4(&v012, v); + + p01 = (png_uint_16p)p; + p2 = (png_byte*)(p01+1); + *p01 = (png_uint_16)v012; + *p2 = (png_byte)(v012 >> 16); +} + +void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Sub filter predicts each pixel as the previous pixel, a. + * There is no pixel to the left of the first pixel. It's encoded directly. + * That works with our main loop if we just say that left pixel was zero. + */ + png_size_t rb; + + __m128i a, d = _mm_setzero_si128(); + + png_debug(1, "in png_read_filter_row_sub3_sse2"); + + rb = row_info->rowbytes; + while (rb >= 4) { + a = d; d = load4(row); + d = _mm_add_epi8(d, a); + store3(row, d); + + row += 3; + rb -= 3; + } + if (rb > 0) { + a = d; d = load3(row); + d = _mm_add_epi8(d, a); + store3(row, d); + + row += 3; + rb -= 3; + } + PNG_UNUSED(prev) +} + +void png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Sub filter predicts each pixel as the previous pixel, a. + * There is no pixel to the left of the first pixel. It's encoded directly. + * That works with our main loop if we just say that left pixel was zero. + */ + png_size_t rb; + + __m128i a, d = _mm_setzero_si128(); + + png_debug(1, "in png_read_filter_row_sub4_sse2"); + + rb = row_info->rowbytes+4; + while (rb > 4) { + a = d; d = load4(row); + d = _mm_add_epi8(d, a); + store4(row, d); + + row += 4; + rb -= 4; + } + PNG_UNUSED(prev) +} + +void png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Avg filter predicts each pixel as the (truncated) average of a and b. + * There's no pixel to the left of the first pixel. Luckily, it's + * predicted to be half of the pixel above it. So again, this works + * perfectly with our loop if we make sure a starts at zero. + */ + + png_size_t rb; + + const __m128i zero = _mm_setzero_si128(); + + __m128i b; + __m128i a, d = zero; + + png_debug(1, "in png_read_filter_row_avg3_sse2"); + rb = row_info->rowbytes; + while (rb >= 4) { + __m128i avg; + b = load4(prev); + a = d; d = load4(row ); + + /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ + avg = _mm_avg_epu8(a,b); + /* ...but we can fix it up by subtracting off 1 if it rounded up. */ + avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), + _mm_set1_epi8(1))); + d = _mm_add_epi8(d, avg); + store3(row, d); + + prev += 3; + row += 3; + rb -= 3; + } + if (rb > 0) { + __m128i avg; + b = load3(prev); + a = d; d = load3(row ); + + /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ + avg = _mm_avg_epu8(a,b); + /* ...but we can fix it up by subtracting off 1 if it rounded up. */ + avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), + _mm_set1_epi8(1))); + + d = _mm_add_epi8(d, avg); + store3(row, d); + + prev += 3; + row += 3; + rb -= 3; + } +} + +void png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Avg filter predicts each pixel as the (truncated) average of a and b. + * There's no pixel to the left of the first pixel. Luckily, it's + * predicted to be half of the pixel above it. So again, this works + * perfectly with our loop if we make sure a starts at zero. + */ + png_size_t rb; + const __m128i zero = _mm_setzero_si128(); + __m128i b; + __m128i a, d = zero; + + png_debug(1, "in png_read_filter_row_avg4_sse2"); + + rb = row_info->rowbytes+4; + while (rb > 4) { + __m128i avg; + b = load4(prev); + a = d; d = load4(row ); + + /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ + avg = _mm_avg_epu8(a,b); + /* ...but we can fix it up by subtracting off 1 if it rounded up. */ + avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), + _mm_set1_epi8(1))); + + d = _mm_add_epi8(d, avg); + store4(row, d); + + prev += 4; + row += 4; + rb -= 4; + } +} + +/* Returns |x| for 16-bit lanes. */ +static __m128i abs_i16(__m128i x) { +#if PNG_INTEL_SSE_IMPLEMENTATION >= 2 + return _mm_abs_epi16(x); +#else + /* Read this all as, return x<0 ? -x : x. + * To negate two's complement, you flip all the bits then add 1. + */ + __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128()); + + /* Flip negative lanes. */ + x = _mm_xor_si128(x, is_negative); + + /* +1 to negative lanes, else +0. */ + x = _mm_sub_epi16(x, is_negative); + return x; +#endif +} + +/* Bytewise c ? t : e. */ +static __m128i if_then_else(__m128i c, __m128i t, __m128i e) { +#if PNG_INTEL_SSE_IMPLEMENTATION >= 3 + return _mm_blendv_epi8(e,t,c); +#else + return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e)); +#endif +} + +void png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* Paeth tries to predict pixel d using the pixel to the left of it, a, + * and two pixels from the previous row, b and c: + * prev: c b + * row: a d + * The Paeth function predicts d to be whichever of a, b, or c is nearest to + * p=a+b-c. + * + * The first pixel has no left context, and so uses an Up filter, p = b. + * This works naturally with our main loop's p = a+b-c if we force a and c + * to zero. + * Here we zero b and d, which become c and a respectively at the start of + * the loop. + */ + png_size_t rb; + const __m128i zero = _mm_setzero_si128(); + __m128i c, b = zero, + a, d = zero; + + png_debug(1, "in png_read_filter_row_paeth3_sse2"); + + rb = row_info->rowbytes; + while (rb >= 4) { + /* It's easiest to do this math (particularly, deal with pc) with 16-bit + * intermediates. + */ + __m128i pa,pb,pc,smallest,nearest; + c = b; b = _mm_unpacklo_epi8(load4(prev), zero); + a = d; d = _mm_unpacklo_epi8(load4(row ), zero); + + /* (p-a) == (a+b-c - a) == (b-c) */ + + pa = _mm_sub_epi16(b,c); + + /* (p-b) == (a+b-c - b) == (a-c) */ + pb = _mm_sub_epi16(a,c); + + /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ + pc = _mm_add_epi16(pa,pb); + + pa = abs_i16(pa); /* |p-a| */ + pb = abs_i16(pb); /* |p-b| */ + pc = abs_i16(pc); /* |p-c| */ + + smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); + + /* Paeth breaks ties favoring a over b over c. */ + nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, + if_then_else(_mm_cmpeq_epi16(smallest, pb), b, + c)); + + /* Note `_epi8`: we need addition to wrap modulo 255. */ + d = _mm_add_epi8(d, nearest); + store3(row, _mm_packus_epi16(d,d)); + + prev += 3; + row += 3; + rb -= 3; + } + if (rb > 0) { + /* It's easiest to do this math (particularly, deal with pc) with 16-bit + * intermediates. + */ + __m128i pa,pb,pc,smallest,nearest; + c = b; b = _mm_unpacklo_epi8(load3(prev), zero); + a = d; d = _mm_unpacklo_epi8(load3(row ), zero); + + /* (p-a) == (a+b-c - a) == (b-c) */ + pa = _mm_sub_epi16(b,c); + + /* (p-b) == (a+b-c - b) == (a-c) */ + pb = _mm_sub_epi16(a,c); + + /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ + pc = _mm_add_epi16(pa,pb); + + pa = abs_i16(pa); /* |p-a| */ + pb = abs_i16(pb); /* |p-b| */ + pc = abs_i16(pc); /* |p-c| */ + + smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); + + /* Paeth breaks ties favoring a over b over c. */ + nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, + if_then_else(_mm_cmpeq_epi16(smallest, pb), b, + c)); + + /* Note `_epi8`: we need addition to wrap modulo 255. */ + d = _mm_add_epi8(d, nearest); + store3(row, _mm_packus_epi16(d,d)); + + prev += 3; + row += 3; + rb -= 3; + } +} + +void png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* Paeth tries to predict pixel d using the pixel to the left of it, a, + * and two pixels from the previous row, b and c: + * prev: c b + * row: a d + * The Paeth function predicts d to be whichever of a, b, or c is nearest to + * p=a+b-c. + * + * The first pixel has no left context, and so uses an Up filter, p = b. + * This works naturally with our main loop's p = a+b-c if we force a and c + * to zero. + * Here we zero b and d, which become c and a respectively at the start of + * the loop. + */ + png_size_t rb; + const __m128i zero = _mm_setzero_si128(); + __m128i pa,pb,pc,smallest,nearest; + __m128i c, b = zero, + a, d = zero; + + png_debug(1, "in png_read_filter_row_paeth4_sse2"); + + rb = row_info->rowbytes+4; + while (rb > 4) { + /* It's easiest to do this math (particularly, deal with pc) with 16-bit + * intermediates. + */ + c = b; b = _mm_unpacklo_epi8(load4(prev), zero); + a = d; d = _mm_unpacklo_epi8(load4(row ), zero); + + /* (p-a) == (a+b-c - a) == (b-c) */ + pa = _mm_sub_epi16(b,c); + + /* (p-b) == (a+b-c - b) == (a-c) */ + pb = _mm_sub_epi16(a,c); + + /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ + pc = _mm_add_epi16(pa,pb); + + pa = abs_i16(pa); /* |p-a| */ + pb = abs_i16(pb); /* |p-b| */ + pc = abs_i16(pc); /* |p-c| */ + + smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); + + /* Paeth breaks ties favoring a over b over c. */ + nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, + if_then_else(_mm_cmpeq_epi16(smallest, pb), b, + c)); + + /* Note `_epi8`: we need addition to wrap modulo 255. */ + d = _mm_add_epi8(d, nearest); + store4(row, _mm_packus_epi16(d,d)); + + prev += 4; + row += 4; + rb -= 4; + } +} + +#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ +#endif /* READ */ diff --git a/src/third-party/libpng/intel/intel_init.c b/src/third-party/libpng/intel/intel_init.c new file mode 100644 index 000000000..8f08baf8c --- /dev/null +++ b/src/third-party/libpng/intel/intel_init.c @@ -0,0 +1,53 @@ + +/* intel_init.c - SSE2 optimized filter functions + * + * Copyright (c) 2016-2017 Glenn Randers-Pehrson + * Written by Mike Klein and Matt Sarett, Google, Inc. + * Derived from arm/arm_init.c + * + * 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 + */ + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED +#if PNG_INTEL_SSE_IMPLEMENTATION > 0 + +void +png_init_filter_functions_sse2(png_structp pp, unsigned int bpp) +{ + /* The techniques used to implement each of these filters in SSE operate on + * one pixel at a time. + * So they generally speed up 3bpp images about 3x, 4bpp images about 4x. + * They can scale up to 6 and 8 bpp images and down to 2 bpp images, + * but they'd not likely have any benefit for 1bpp images. + * Most of these can be implemented using only MMX and 64-bit registers, + * but they end up a bit slower than using the equally-ubiquitous SSE2. + */ + png_debug(1, "in png_init_filter_functions_sse2"); + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth3_sse2; + } + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_sse2; + } + + /* No need optimize PNG_FILTER_VALUE_UP. The compiler should + * autovectorize. + */ +} + +#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/src/third-party/libpng/libpng-manual.txt b/src/third-party/libpng/libpng-manual.txt index f0dae987f..d4407ef2e 100644 --- a/src/third-party/libpng/libpng-manual.txt +++ b/src/third-party/libpng/libpng-manual.txt @@ -1,9 +1,9 @@ libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.17 - March 26, 2015 + libpng version 1.6.34 - September 29, 2017 Updated and distributed by Glenn Randers-Pehrson - Copyright (c) 1998-2015 Glenn Randers-Pehrson + Copyright (c) 1998-2017 Glenn Randers-Pehrson This document is released under the libpng license. For conditions of distribution and use, see the disclaimer @@ -11,9 +11,9 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.6.17 - March 26, 2015 + libpng versions 0.97, January 1998, through 1.6.34 - September 29, 2017 Updated and distributed by Glenn Randers-Pehrson - Copyright (c) 1998-2015 Glenn Randers-Pehrson + Copyright (c) 1998-2017 Glenn Randers-Pehrson libpng 1.0 beta 6 - version 0.96 - May 28, 1997 Updated and distributed by Andreas Dilger @@ -66,19 +66,20 @@ file format in application programs. The PNG specification (second edition), November 2003, is available as a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at -. It is technically equivalent +. +It is technically equivalent to the PNG specification (second edition) but has some additional material. -The PNG-1.0 specification is available -as RFC 2083 and as a -W3C Recommendation . +The PNG-1.0 specification is available as RFC 2083 + and as a +W3C Recommendation . Some additional chunks are described in the special-purpose public chunks -documents at . +documents at Other information about PNG, and the latest version of libpng, can be found at the PNG home @@ -100,7 +101,7 @@ majority of the needs of its users. Libpng uses zlib for its compression and decompression of PNG files. Further information about zlib, and the latest version of zlib, can -be found at the zlib home page, . +be found at the zlib home page, . The zlib compression utility is a general purpose utility that is useful for more than PNG files, and can be used without libpng. See the documentation delivered with zlib for more details. @@ -466,8 +467,9 @@ the default, use The values for png_set_crc_action() say how libpng is to handle CRC errors in ancillary and critical chunks, and whether to use the data contained -therein. Note that it is impossible to "discard" data in a critical -chunk. +therein. Starting with libpng-1.6.26, this also governs how an ADLER32 error +is handled while reading the IDAT chunk. Note that it is impossible to +"discard" data in a critical chunk. Choices for (int) crit_action are PNG_CRC_DEFAULT 0 error/quit @@ -484,6 +486,9 @@ Choices for (int) ancil_action are PNG_CRC_QUIET_USE 4 quiet/use data PNG_CRC_NO_CHANGE 5 use the current value +When the setting for crit_action is PNG_CRC_QUIET_USE, the CRC and ADLER32 +checksums are not only ignored, but they are not evaluated. + Setting up callback code You can set up a callback function to handle any unknown chunks in the @@ -558,7 +563,7 @@ non-interlaced case the row that was just handled is simply one less than the passed in row number, and pass will always be 0. For the interlaced case the same applies unless the row value is 0, in which case the row just handled was the last one from one of the preceding passes. Because interlacing may skip a -pass you cannot be sure that the preceding pass is just 'pass-1', if you really +pass you cannot be sure that the preceding pass is just 'pass-1'; if you really need to know what the last pass is record (row,pass) from the callback and use the last recorded value each time. @@ -649,6 +654,7 @@ User limits The PNG specification allows the width and height of an image to be as large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns. +For safety, libpng imposes a default limit of 1 million rows and columns. Larger images will be rejected immediately with a png_error() call. If you wish to change these limits, you can use @@ -669,8 +675,11 @@ If you need to retrieve the limits that are being applied, use height_max = png_get_user_height_max(png_ptr); The PNG specification sets no limit on the number of ancillary chunks -allowed in a PNG datastream. You can impose a limit on the total number -of sPLT, tEXt, iTXt, zTXt, and unknown chunks that will be stored, with +allowed in a PNG datastream. By default, libpng imposes a limit of +a total of 1000 sPLT, tEXt, iTXt, zTXt, and unknown chunks to be stored. +If you have set up both info_ptr and end_info_ptr, the limit applies +separately to each. You can change the limit on the total number of such +chunks that will be stored, with png_set_chunk_cache_max(png_ptr, user_chunk_cache_max); @@ -678,8 +687,10 @@ where 0x7fffffffL means unlimited. You can retrieve this limit with chunk_cache_max = png_get_chunk_cache_max(png_ptr); -You can also set a limit on the amount of memory that a compressed chunk -other than IDAT can occupy, with +Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of +memory that any chunk other than IDAT can occupy, originally or when +decompressed (prior to libpng-1.6.32 the limit was only applied to compressed +chunks after decompression). You can change this limit with png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max); @@ -975,8 +986,17 @@ premultiplication. png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); -This is the default libpng handling of the alpha channel - it is not -pre-multiplied into the color components. In addition the call states +Choices for the alpha_mode are + + PNG_ALPHA_PNG 0 /* according to the PNG standard */ + PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ + PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ + PNG_ALPHA_PREMULTIPLIED 1 /* as above */ + PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ + PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_ALPHA_PNG is the default libpng handling of the alpha channel. It is not +pre-multiplied into the color components. In addition the call states that the output is for a sRGB system and causes all PNG files without gAMA chunks to be assumed to be encoded using sRGB. @@ -991,7 +1011,7 @@ early Mac systems behaved. This is the classic Jim Blinn approach and will work in academic environments where everything is done by the book. It has the shortcoming of assuming that input PNG data with no gamma information is linear - this -is unlikely to be correct unless the PNG files where generated locally. +is unlikely to be correct unless the PNG files were generated locally. Most of the time the output precision will be so low as to show significant banding in dark areas of the image. @@ -1180,7 +1200,20 @@ row_pointers prior to calling png_read_png() with png_set_rows(png_ptr, info_ptr, &row_pointers); Alternatively you could allocate your image in one big block and define -row_pointers[i] to point into the proper places in your block. +row_pointers[i] to point into the proper places in your block, but first +be sure that your platform is able to allocate such a large buffer: + + /* Guard against integer overflow */ + if (height > PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + + png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size); + + for (int i=0; i, in section 9: +Copyright (c) 2006-11-28 Charles Poynton, in section 9: - + Y = 0.2126 * R + 0.7152 * G + 0.0722 * B @@ -2134,6 +2179,16 @@ are allocating one large chunk, you will need to build an array of pointers to each row, as it will be needed for some of the functions below. +Be sure that your platform can allocate the buffer that you'll need. +libpng internally checks for oversize width, but you'll need to +do your own check for number_of_rows*width*pixel_size if you are using +a multiple-row buffer: + + /* Guard against integer overflow */ + if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + Remember: Before you call png_read_update_info(), the png_get_*() functions return the values corresponding to the original PNG image. After you call png_read_update_info the values refer to the image @@ -2222,7 +2277,8 @@ is exactly the same. If you are planning on displaying the image after each pass, the "rectangle" effect is generally considered the better looking one. -If you only want the "sparkle" effect, just call png_read_rows() as +If you only want the "sparkle" effect, just call png_read_row() or +png_read_rows() as normal, with the third parameter NULL. Make sure you make pass over the image number_of_passes times, and you don't change the data in the rows between calls. You can change the locations of the data, just @@ -2231,6 +2287,8 @@ pass, and assumes the data from previous passes is still valid. png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); + or + png_read_row(png_ptr, row_pointers, NULL); If you only want the first effect (the rectangles), do the same as before except pass the row buffer in the third parameter, and leave @@ -2238,6 +2296,8 @@ the second parameter NULL. png_read_rows(png_ptr, NULL, row_pointers, number_of_rows); + or + png_read_row(png_ptr, NULL, row_pointers); If you don't want libpng to handle the interlacing details, just call png_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images. @@ -2453,6 +2513,7 @@ your application instead of by libpng, you can use PNG_INFO_gAMA, PNG_INFO_sBIT, PNG_INFO_cHRM, PNG_INFO_PLTE, PNG_INFO_tRNS, PNG_INFO_bKGD, + PNG_INFO_eXIf, PNG_INFO_hIST, PNG_INFO_pHYs, PNG_INFO_oFFs, PNG_INFO_tIME, PNG_INFO_pCAL, PNG_INFO_sRGB, @@ -2834,7 +2895,7 @@ filter types. PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| - PNG_ALL_FILTERS); + PNG_ALL_FILTERS | PNG_FAST_FILTERS); If an application wants to start and stop using particular filters during compression, it should start out with all of the filters (to ensure that @@ -2952,6 +3013,7 @@ width, height, bit_depth, and color_type must be the same in each call. (array of png_color) num_palette - number of entries in the palette + png_set_gAMA(png_ptr, info_ptr, file_gamma); png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); @@ -3051,6 +3113,11 @@ width, height, bit_depth, and color_type must be the same in each call. single transparent color for non-paletted images (PNG_INFO_tRNS) + png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif); + + exif - Exif profile (array of + png_byte) (PNG_INFO_eXIf) + png_set_hIST(png_ptr, info_ptr, hist); hist - histogram of palette (array of @@ -3716,21 +3783,26 @@ as a wide variety of APIs to manipulate ancilliary information. To read a PNG file using the simplified API: - 1) Declare a 'png_image' structure (see below) on the - stack and memset() it to all zero. + 1) Declare a 'png_image' structure (see below) on the stack, set the + version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL + (this is REQUIRED, your program may crash if you don't do it.) 2) Call the appropriate png_image_begin_read... function. - 3) Set the png_image 'format' member to the required - format and allocate a buffer for the image. + 3) Set the png_image 'format' member to the required sample format. - 4) Call png_image_finish_read to read the image into - your buffer. + 4) Allocate a buffer for the image and, if required, the color-map. + + 5) Call png_image_finish_read to read the image and, if required, the + color-map into your buffers. There are no restrictions on the format of the PNG input itself; all valid color types, bit depths, and interlace methods are acceptable, and the input image is transformed as necessary to the requested in-memory format -during the png_image_finish_read() step. +during the png_image_finish_read() step. The only caveat is that if you +request a color-mapped image from a PNG that is full-color or makes +complex use of an alpha channel the transformation is extremely lossy and the +result may look terrible. To write a PNG file using the simplified API: @@ -3739,34 +3811,35 @@ To write a PNG file using the simplified API: 2) Initialize the members of the structure that describe the image, setting the 'format' member to the format of the - image in memory. + image samples. 3) Call the appropriate png_image_write... function with a - pointer to the image to write the PNG data. + pointer to the image and, if necessary, the color-map to write + the PNG data. png_image is a structure that describes the in-memory format of an image -when it is being read or define the in-memory format of an image that you +when it is being read or defines the in-memory format of an image that you need to write. The "png_image" structure contains the following members: + png_controlp opaque Initialize to NULL, free with png_image_free png_uint_32 version Set to PNG_IMAGE_VERSION png_uint_32 width Image width in pixels (columns) png_uint_32 height Image height in pixels (rows) png_uint_32 format Image format as defined below png_uint_32 flags A bit mask containing informational flags - png_controlp opaque Initialize to NULL, free with png_image_free png_uint_32 colormap_entries; Number of entries in the color-map png_uint_32 warning_or_error; char message[64]; -In the event of an error or warning the following field warning_or_error +In the event of an error or warning the "warning_or_error" field will be set to a non-zero value and the 'message' field will contain a '\0' terminated string with the libpng error or warning message. If both warnings and an error were encountered, only the error is recorded. If there are multiple warnings, only the first one is recorded. -The upper 30 bits of this value are reserved; the low two bits contain -a two bit code such that a value more than 1 indicates a failure in the API -just called: +The upper 30 bits of the "warning_or_error" value are reserved; the low two +bits contain a two bit code such that a value more than 1 indicates a failure +in the API just called: 0 - no warning or error 1 - warning @@ -3798,64 +3871,72 @@ channels are linear. Color channels use the RGB encoding (RGB end-points) of the sRGB specification. This encoding is identified by the PNG_FORMAT_FLAG_LINEAR flag below. +When the simplified API needs to convert between sRGB and linear colorspaces, +the actual sRGB transfer curve defined in the sRGB specification (see the +article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 +approximation used elsewhere in libpng. + When an alpha channel is present it is expected to denote pixel coverage of the color or luminance channels and is returned as an associated alpha channel: the color/gray channels are scaled (pre-multiplied) by the alpha value. -When a color-mapped image is used as a result of calling -png_image_read_colormap or png_image_write_colormap the channels are encoded -in the color-map and the descriptions above apply to the color-map entries. -The image data is encoded as small integers, value 0..255, that index the -entries in the color-map. One integer (one byte) is stored for each pixel. +The samples are either contained directly in the image data, between 1 and 8 +bytes per pixel according to the encoding, or are held in a color-map indexed +by bytes in the image data. In the case of a color-map the color-map entries +are individual samples, encoded as above, and the image data has one byte per +pixel to select the relevant sample from the color-map. PNG_FORMAT_* The #defines to be used in png_image::format. Each #define identifies a particular layout of channel data and, if present, alpha values. There are -separate defines for each of the two channel encodings. +separate defines for each of the two component encodings. -A format is built up using single bit flag values. Not all combinations are -valid: use the bit flag values below for testing a format returned by the -read APIs, but set formats from the derived values. +A format is built up using single bit flag values. All combinations are +valid. Formats can be built up from the flag values or you can use one of +the predefined values below. When testing formats always use the FORMAT_FLAG +macros to test for individual features - future versions of the library may +add new flags. When reading or writing color-mapped images the format should be set to the format of the entries in the color-map then png_image_{read,write}_colormap called to read or write the color-map and set the format correctly for the image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! -NOTE: libpng can be built with particular features disabled, if you see +NOTE: libpng can be built with particular features disabled. If you see compiler errors because the definition of one of the following flags has been compiled out it is because libpng does not have the required support. It is possible, however, for the libpng configuration to enable the format on just -read or just write; in that case you may see an error at run time. You can -guard against this by checking for the definition of: +read or just write; in that case you may see an error at run time. +You can guard against this by checking for the definition of the +appropriate "_SUPPORTED" macro, one of: PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED - PNG_FORMAT_FLAG_ALPHA 0x01 format with an alpha channel - PNG_FORMAT_FLAG_COLOR 0x02 color format: otherwise grayscale - PNG_FORMAT_FLAG_LINEAR 0x04 png_uint_16 channels else png_byte - PNG_FORMAT_FLAG_COLORMAP 0x08 libpng use only - PNG_FORMAT_FLAG_BGR 0x10 BGR colors, else order is RGB - PNG_FORMAT_FLAG_AFIRST 0x20 alpha channel comes first + PNG_FORMAT_FLAG_ALPHA format with an alpha channel + PNG_FORMAT_FLAG_COLOR color format: otherwise grayscale + PNG_FORMAT_FLAG_LINEAR 2-byte channels else 1-byte + PNG_FORMAT_FLAG_COLORMAP image data is color-mapped + PNG_FORMAT_FLAG_BGR BGR colors, else order is RGB + PNG_FORMAT_FLAG_AFIRST alpha channel comes first Supported formats are as follows. Future versions of libpng may support more formats; for compatibility with older versions simply check if the format macro is defined using #ifdef. These defines describe the in-memory layout of the components of the pixels of the image. -First the single byte formats: +First the single byte (sRGB) formats: - PNG_FORMAT_GRAY 0 - PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA - PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) - PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR - PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) - PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) - PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) - PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) - PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) + PNG_FORMAT_GRAY + PNG_FORMAT_GA + PNG_FORMAT_AG + PNG_FORMAT_RGB + PNG_FORMAT_BGR + PNG_FORMAT_RGBA + PNG_FORMAT_ARGB + PNG_FORMAT_BGRA + PNG_FORMAT_ABGR Then the linear 2-byte formats. When naming these "Y" is used to indicate a luminance (gray) channel. The component order within the pixel @@ -3864,22 +3945,22 @@ components in the linear format. The components are 16-bit integers in the native byte order for your platform, and there is no provision for swapping the bytes to a different endian condition. - PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR + PNG_FORMAT_LINEAR_Y PNG_FORMAT_LINEAR_Y_ALPHA - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) PNG_FORMAT_LINEAR_RGB - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) PNG_FORMAT_LINEAR_RGB_ALPHA - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR| - PNG_FORMAT_FLAG_ALPHA) -Color-mapped formats are obtained by calling png_image_{read,write}_colormap, -as appropriate after setting png_image::format to the format of the color-map -to be read or written. Applications may check the value of -PNG_FORMAT_FLAG_COLORMAP to see if they have called the colormap API. The -format of the color-map may be extracted using the following macro. +With color-mapped formats the image data is one byte for each pixel. The byte +is an index into the color-map which is formatted as above. To obtain a +color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP +to one of the above definitions, or you can use one of the definitions below. - PNG_FORMAT_OF_COLORMAP(fmt) ((fmt) & ~PNG_FORMAT_FLAG_COLORMAP) + PNG_FORMAT_RGB_COLORMAP + PNG_FORMAT_BGR_COLORMAP + PNG_FORMAT_RGBA_COLORMAP + PNG_FORMAT_ARGB_COLORMAP + PNG_FORMAT_BGRA_COLORMAP + PNG_FORMAT_ABGR_COLORMAP PNG_IMAGE macros @@ -3887,9 +3968,9 @@ These are convenience macros to derive information from a png_image structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the actual image sample values - either the entries in the color-map or the pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values -for the pixels and will always return 1 after a call to -png_image_{read,write}_colormap. The remaining macros return information -about the rows in the image and the complete image. +for the pixels and will always return 1 for color-mapped formats. The +remaining macros return information about the rows in the image and the +complete image. NOTE: All the macros that take a png_image::format parameter are compile time constants if the format parameter is, itself, a constant. Therefore these @@ -3897,46 +3978,39 @@ macros can be used in array declarations and case labels where required. Similarly the macros are also pre-processor constants (sizeof is not used) so they can be used in #if tests. -First the information about the samples. - PNG_IMAGE_SAMPLE_CHANNELS(fmt) Returns the total number of channels in a given format: 1..4 PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt) Returns the size in bytes of a single component of a pixel or color-map - entry (as appropriate) in the image. + entry (as appropriate) in the image: 1 or 2. PNG_IMAGE_SAMPLE_SIZE(fmt) This is the size of the sample data for one sample. If the image is color-mapped it is the size of one color-map entry (and image pixels are one byte in size), otherwise it is the size of one image pixel. + PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt) + The maximum size of the color-map required by the format expressed in a + count of components. This can be used to compile-time allocate a + color-map: + + png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; + + png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; + + Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the + information from one of the png_image_begin_read_ APIs and dynamically + allocate the required memory. + PNG_IMAGE_COLORMAP_SIZE(fmt) The size of the color-map required by the format; this is the size of the - color-map buffer passed to the png_image_{read,write}_colormap APIs, it is + color-map buffer passed to the png_image_{read,write}_colormap APIs. It is a fixed number determined by the format so can easily be allocated on the stack if necessary. -#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) - /* The maximum size of the color-map required by the format expressed in a - * count of components. This can be used to compile-time allocate a - * color-map: - * - * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; - * - * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; - * - * Alternatively, use the PNG_IMAGE_COLORMAP_SIZE macro below to use the - * information from one of the png_image_begin_read_ APIs and dynamically - * allocate the required memory. - */ - - Corresponding information about the pixels - PNG_IMAGE_PIXEL_(test,fmt) - PNG_IMAGE_PIXEL_CHANNELS(fmt) The number of separate channels (components) in a pixel; 1 for a color-mapped image. @@ -3962,19 +4036,54 @@ Information about the whole row, or whole image to start the next row on a 4-byte boundary. PNG_IMAGE_BUFFER_SIZE(image, row_stride) - Returns the size, in bytes, of an image buffer given a png_image and a row - stride - the number of components to leave space for in each row. This - macro takes care of multiplying row_stride by PNG_IMAGE_PIXEL_COMONENT_SIZE - when the image has 2-byte components. + Return the size, in bytes, of an image buffer given a png_image and a row + stride - the number of components to leave space for in each row. + + PNG_IMAGE_SIZE(image) + Return the size, in bytes, of the image in memory given just a png_image; + the row stride is the minimum stride required for the image. + + PNG_IMAGE_COLORMAP_SIZE(image) + Return the size, in bytes, of the color-map of this image. If the image + format is not a color-map format this will return a size sufficient for + 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if + you don't want to allocate a color-map in this case. + +PNG_IMAGE_FLAG_* + +Flags containing additional information about the image are held in +the 'flags' field of png_image. PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01 This indicates the the RGB values of the in-memory bitmap do not correspond to the red, green and blue end-points defined by sRGB. - PNG_IMAGE_FLAG_COLORMAP == 0x02 - The PNG is color-mapped. If this flag is set png_image_read_colormap - can be used without further loss of image information. If it is not set - png_image_read_colormap will cause significant loss if the image has any + PNG_IMAGE_FLAG_FAST == 0x02 + On write emphasise speed over compression; the resultant PNG file will be + larger but will be produced significantly faster, particular for large + images. Do not use this option for images which will be distributed, only + used it when producing intermediate files that will be read back in + repeatedly. For a typical 24-bit image the option will double the read + speed at the cost of increasing the image size by 25%, however for many + more compressible images the PNG file can be 10 times larger with only a + slight speed gain. + + PNG_IMAGE_FLAG_16BIT_sRGB == 0x04 + On read if the image is a 16-bit per component image and there is no gAMA + or sRGB chunk assume that the components are sRGB encoded. Notice that + images output by the simplified API always have gamma information; setting + this flag only affects the interpretation of 16-bit images from an + external source. It is recommended that the application expose this flag + to the user; the user can normally easily recognize the difference between + linear and sRGB encoding. This flag has no effect on write - the data + passed to the write APIs must have the correct encoding (as defined + above.) + + If the flag is not set (the default) input 16-bit per component data is + assumed to be linear. + + NOTE: the flag can only be set after the png_image_begin_read_ call, + because that call initializes the 'flags' field. READ APIs @@ -4028,7 +4137,7 @@ READ APIs When the simplified API needs to convert between sRGB and linear colorspaces, the actual sRGB transfer curve defined in the sRGB specification (see the -article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 +article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 approximation used elsewhere in libpng. WRITE APIS @@ -4052,6 +4161,13 @@ be written: Write the image to the named file. + int png_image_write_to_memory (png_imagep image, void *memory, + png_alloc_size_t * PNG_RESTRICT memory_bytes, + int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride, + const void *colormap)); + + Write the image to memory. + int png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8_bit, const void *buffer, png_int_32 row_stride, const void *colormap) @@ -4065,10 +4181,11 @@ a 16-bit linear encoded PNG file is written. With all APIs row_stride is handled as in the read APIs - it is the spacing from one row to the next in component sized units (float) and if negative -indicates a bottom-up row layout in the buffer. +indicates a bottom-up row layout in the buffer. If you pass zero, libpng will +calculate the row_stride for you from the width and number of channels. Note that the write API does not support interlacing, sub-8-bit pixels, -and indexed (paletted) images. +indexed (paletted) images, or most ancillary chunks. VI. Modifying/Customizing libpng @@ -4178,8 +4295,6 @@ functions after png_create_*_struct() has been called by calling: png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn); - png_voidp error_ptr = png_get_error_ptr(png_ptr); - If NULL is supplied for either error_fn or warning_fn, then the libpng default function will be used, calling fprintf() and/or longjmp() if a problem is encountered. The replacement error functions should have @@ -4191,6 +4306,11 @@ parameters as follows: void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg); +Then, within your user_error_fn or user_warning_fn, you can retrieve +the error_ptr if you need it, by calling + + png_voidp error_ptr = png_get_error_ptr(png_ptr); + The motivation behind using setjmp() and longjmp() is the C++ throw and catch exception handling methods. This makes the code much easier to write, as there is no need to check every return code of every function call. @@ -4198,7 +4318,7 @@ However, there are some uncertainties about the status of local variables after a longjmp, so the user may want to be careful about doing anything after setjmp returns non-zero besides returning itself. Consult your compiler documentation for more details. For an alternative approach, you -may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net), +may wish to use the "cexcept" facility (see https://cexcept.sourceforge.io/), which is illustrated in pngvalid.c and in contrib/visupng. Beginning in libpng-1.4.0, the png_set_benign_errors() API became available. @@ -4328,8 +4448,9 @@ for any images with bit depths less than 8 bits/pixel. The 'method' parameter sets the main filtering method, which is currently only '0' in the PNG 1.2 specification. The 'filters' parameter sets which filter(s), if any, should be used for each -scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS -to turn filtering on and off, respectively. +scanline. Possible values are PNG_ALL_FILTERS, PNG_NO_FILTERS, +or PNG_FAST_FILTERS to turn filtering on and off, or to turn on +just the fast-decoding subset of filters, respectively. Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise @@ -4343,12 +4464,19 @@ means the first row must always be adaptively filtered, because libpng currently does not allocate the filter buffers until png_write_row() is called for the first time.) - filters = PNG_FILTER_NONE | PNG_FILTER_SUB + filters = PNG_NO_FILTERS; + filters = PNG_ALL_FILTERS; + filters = PNG_FAST_FILTERS; + + or + + filters = PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | - PNG_FILTER_PAETH | PNG_ALL_FILTERS; + PNG_FILTER_PAETH; png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters); + The second parameter can also be PNG_INTRAPIXEL_DIFFERENCING if you are writing a PNG to be embedded in a MNG @@ -4356,41 +4484,6 @@ is called for the first time.) same as the value of filter_method used in png_set_IHDR(). -It is also possible to influence how libpng chooses from among the -available filters. This is done in one or both of two ways - by -telling it how important it is to keep the same filter for successive -rows, and by telling it the relative computational costs of the filters. - - double weights[3] = {1.5, 1.3, 1.1}, - costs[PNG_FILTER_VALUE_LAST] = - {1.0, 1.3, 1.3, 1.5, 1.7}; - - png_set_filter_heuristics(png_ptr, - PNG_FILTER_HEURISTIC_WEIGHTED, 3, - weights, costs); - -The weights are multiplying factors that indicate to libpng that the -row filter should be the same for successive rows unless another row filter -is that many times better than the previous filter. In the above example, -if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a -"sum of absolute differences" 1.5 x 1.3 times higher than other filters -and still be chosen, while the NONE filter could have a sum 1.1 times -higher than other filters and still be chosen. Unspecified weights are -taken to be 1.0, and the specified weights should probably be declining -like those above in order to emphasize recent filters over older filters. - -The filter costs specify for each filter type a relative decoding cost -to be considered when selecting row filters. This means that filters -with higher costs are less likely to be chosen over filters with lower -costs, unless their "sum of absolute differences" is that much smaller. -The costs do not necessarily reflect the exact computational speeds of -the various filters, since this would unduly influence the final image -size. - -Note that the numbers above were invented purely for this example and -are given only to help explain the function usage. Little testing has -been done to find optimum values for either the costs or the weights. - Requesting debug printout The macro definition PNG_DEBUG can be used to request debugging @@ -4453,7 +4546,7 @@ in a MNG datastream. As a minimum, it must have the MNG 8-byte signature and the MHDR and MEND chunks. Libpng does not provide support for these or any other MNG chunks; your application must provide its own support for them. You may wish to consider using libmng (available at -http://www.libmng.com) instead. +https://www.libmng.com/) instead. VIII. Changes to Libpng from version 0.88 @@ -4758,7 +4851,8 @@ There are no substantial API changes between the non-deprecated parts of the 1.4.5 API and the 1.5.0 API; however, the ability to directly access members of the main libpng control structures, png_struct and png_info, deprecated in earlier versions of libpng, has been completely removed from -libpng 1.5. +libpng 1.5, and new private "pngstruct.h", "pnginfo.h", and "pngdebug.h" +header files were created. We no longer include zlib.h in png.h. The include statement has been moved to pngstruct.h, where it is not accessible by applications. Applications that @@ -4875,22 +4969,18 @@ PNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said that it could be used to override them. Now this function will reduce or increase the limits. -Starting in libpng-1.5.10, the user limits can be set en masse with the -configuration option PNG_SAFE_LIMITS_SUPPORTED. If this option is enabled, -a set of "safe" limits is applied in pngpriv.h. These can be overridden by -application calls to png_set_user_limits(), png_set_user_chunk_cache_max(), -and/or png_set_user_malloc_max() that increase or decrease the limits. Also, -in libpng-1.5.10 the default width and height limits were increased -from 1,000,000 to 0x7ffffff (i.e., made unlimited). Therefore, the -limits are now - default safe +Starting in libpng-1.5.22, default user limits were established. These +can be overridden by application calls to png_set_user_limits(), +png_set_user_chunk_cache_max(), and/or png_set_user_malloc_max(). +The limits are now + max possible default png_user_width_max 0x7fffffff 1,000,000 png_user_height_max 0x7fffffff 1,000,000 - png_user_chunk_cache_max 0 (unlimited) 128 + png_user_chunk_cache_max 0 (unlimited) 1000 png_user_chunk_malloc_max 0 (unlimited) 8,000,000 The png_set_option() function (and the "options" member of the png struct) was -added to libpng-1.5.15. +added to libpng-1.5.15, with option PNG_ARM_NEON. The library now supports a complete fixed point implementation and can thus be used on systems that have no floating point support or very @@ -4998,6 +5088,7 @@ includes the following: png_image_free() write functions png_image_write_to_file() + png_image_write_to_memory() png_image_write_to_stdio() Starting with libpng-1.6.0, you can configure libpng to prefix all exported @@ -5032,9 +5123,9 @@ The signatures of many exported functions were changed, such that png_infop became png_inforp or png_const_inforp where "rp" indicates a "restricted pointer". -The support for FAR/far types has been eliminated and the definition of -png_alloc_size_t is now controlled by a flag so that 'small size_t' systems -can select it if necessary. +Dropped support for 16-bit platforms. The support for FAR/far types has +been eliminated and the definition of png_alloc_size_t is now controlled +by a flag so that 'small size_t' systems can select it if necessary. Error detection in some chunks has improved; in particular the iCCP chunk reader now does pretty complete validation of the basic format. Some bad @@ -5061,6 +5152,10 @@ enforced. The sRGB chunk is allowed to appear in images with any color type and is interpreted by libpng to convey a one-tracer-curve gray profile or a three-tracer-curve RGB profile as appropriate. +Libpng 1.5.x erroneously used /MD for Debug DLL builds; if you used the debug +builds in your app and you changed your app to use /MD you will need to +change it back to /MDd for libpng 1.6.x. + Prior to libpng-1.6.0 a warning would be issued if the iTXt chunk contained an empty language field or an empty translated keyword. Both of these are allowed by the PNG specification, so these warnings are no longer issued. @@ -5109,6 +5204,33 @@ length, which resulted in PNG files that cannot be read beyond the bad iTXt chunk. This error was fixed in libpng-1.6.3, and a tool (called contrib/tools/png-fix-itxt) has been added to the libpng distribution. +Starting with libpng-1.6.17, the PNG_SAFE_LIMITS macro was eliminated +and safe limits are used by default (users who need larger limits +can still override them at compile time or run time, as described above). + +The new limits are + default spec limit + png_user_width_max 1,000,000 2,147,483,647 + png_user_height_max 1,000,000 2,147,483,647 + png_user_chunk_cache_max 128 unlimited + png_user_chunk_malloc_max 8,000,000 unlimited + +Starting with libpng-1.6.18, a PNG_RELEASE_BUILD macro was added, which allows +library builders to control compilation for an installed system (a release build). +It can be set for testing debug or beta builds to ensure that they will compile +when the build type is switched to RC or STABLE. In essence this overrides the +PNG_LIBPNG_BUILD_BASE_TYPE definition which is not directly user controllable. + +Starting with libpng-1.6.19, attempting to set an over-length PLTE chunk +is an error. Previously this requirement of the PNG specification was not +enforced, and the palette was always limited to 256 entries. An over-length +PLTE chunk found in an input PNG is silently truncated. + +Starting with libpng-1.6.31, the eXIf chunk is supported. Libpng does not +attempt to decode the Exif profile; it simply returns a byte array +containing the profile to the calling application which must do its own +decoding. + XIII. Detecting libpng The png_get_io_ptr() function has been present since libpng-0.88, has never @@ -5125,27 +5247,33 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files going back to version 0.70. You can access the git repository (read only) at - git://git.code.sf.net/p/libpng/code + https://github.com/glennrp/libpng or + https://git.code.sf.net/p/libpng/code.git -or you can browse it with a web browser by selecting the "code" button at +or you can browse it with a web browser at - https://sourceforge.net/projects/libpng + https://github.com/glennrp/libpng or + https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ Patches can be sent to glennrp at users.sourceforge.net or to png-mng-implement at lists.sourceforge.net or you can upload them to the libpng bug tracker at - http://libpng.sourceforge.net + https://libpng.sourceforge.io/ + +or as a "pull request" to + + https://github.com/glennrp/libpng/pulls We also accept patches built from the tar or zip distributions, and simple verbal discriptions of bug fixes, reported either to the SourceForge bug tracker, to the png-mng-implement at lists.sf.net -mailing list, or directly to glennrp. +mailing list, as github issues, or directly to glennrp. XV. Coding style Our coding style is similar to the "Allman" style -(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly +(See https://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly braces on separate lines: if (condition) @@ -5246,7 +5374,7 @@ Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as though it were a function. Control keywords if, for, while, and switch are always followed by a space -to distinguish them from function calls, which have no trailing space. +to distinguish them from function calls, which have no trailing space. We put a space after each comma and after each semicolon in "for" statements, and we put spaces before and after each @@ -5262,14 +5390,17 @@ We prefer #ifdef and #ifndef to #if defined() and #if !defined() when there is only one macro being tested. We always use parentheses with "defined". -We prefer to express integers that are used as bit masks in hex format, -with an even number of lower-case hex digits (e.g., 0x00, 0xff, 0x0100). +We express integer constants that are used as bit masks in hex format, +with an even number of lower-case hex digits, and to make them unsigned +(e.g., 0x00U, 0xffU, 0x0100U) and long if they are greater than 0x7fff +(e.g., 0xffffUL). -We prefer to use underscores in variable names rather than camelCase, except +We prefer to use underscores rather than camelCase in names, except for a few type names that we inherit from zlib.h. -We prefer "if (something != 0)" and "if (something == 0)" -over "if (something)" and if "(!something)", respectively. +We prefer "if (something != 0)" and "if (something == 0)" over +"if (something)" and if "(!something)", respectively, and for pointers +we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)". We do not use the TAB character for indentation in the C sources. @@ -5279,13 +5410,11 @@ Other rules can be inferred by inspecting the libpng source. XVI. Y2K Compliance in libpng -March 26, 2015 - Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and -upward through 1.6.17 are Y2K compliant. It is my belief that earlier +upward through 1.6.34 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has two year fields. One is a 2-byte unsigned integer diff --git a/src/third-party/libpng/libpng.3 b/src/third-party/libpng/libpng.3 index dfc4484c3..3c8d62ab2 100644 --- a/src/third-party/libpng/libpng.3 +++ b/src/third-party/libpng/libpng.3 @@ -1,6 +1,6 @@ -.TH LIBPNG 3 "March 26, 2015" +.TH LIBPNG 3 "September 29, 2017" .SH NAME -libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17 +libpng \- Portable Network Graphics (PNG) Reference Library 1.6.34 .SH SYNOPSIS \fB #include \fP @@ -97,6 +97,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17 \fBpng_byte png_get_header_version (png_const_structp \fIpng_ptr\fP\fB);\fP +\fBpng_uint_32 png_get_eXIf (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fI*exif\fP\fB);\fP + +\fBpng_uint_32 png_get_eXIf_1 (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_unit_32 \fP\fI*num_exif\fP\fB, png_bytep \fI*exif\fP\fB);\fP + \fBpng_uint_32 png_get_hIST (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP \fBpng_uint_32 png_get_iCCP (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_bytepp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP @@ -119,6 +123,8 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17 \fBpng_byte png_get_libpng_ver (png_const_structp \fIpng_ptr\fP\fB);\fP +\fBint png_get_palette_max(png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fIinfo_ptr\fP\fB);\fP + \fBpng_voidp png_get_mem_ptr (png_const_structp \fIpng_ptr\fP\fB);\fP \fBpng_uint_32 png_get_oFFs (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP @@ -227,6 +233,8 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17 \fBint png_image_write_to_file (png_imagep \fP\fIimage\fP\fB, const char \fP\fI*file\fP\fB, int \fP\fIconvert_to_8bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap\fP\fB);\fP +\fBint png_image_write_to_memory (png_imagep \fP\fIimage\fP\fB, void \fP\fI*memory\fP\fB, png_alloc_size_t * PNG_RESTRICT \fP\fImemory_bytes\fP\fB, int \fP\fIconvert_to_8_bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, const void \fI*colormap)\fP\fB);\fP + \fBint png_image_write_to_stdio (png_imagep \fP\fIimage\fP\fB, FILE \fP\fI*file\fP\fB, int \fP\fIconvert_to_8_bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap)\fP\fB);\fP \fBvoid png_info_init_3 (png_infopp \fP\fIinfo_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP @@ -343,6 +351,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17 \fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP +\fBvoid png_set_eXIf (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fIexif\fP\fB);\fP + +\fBvoid png_set_eXIf_1 (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, const png_uint_32 \fP\fInum_exif\fP\fB, png_bytep \fIexif\fP\fB);\fP + \fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP \fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_const_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_const_bytep \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP @@ -369,6 +381,8 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17 \fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP +\fBint png_set_option(png_structrp \fP\fIpng_ptr\fP\fB, int \fP\fIoption\fP\fB, int \fIonoff\fP\fB);\fP + \fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP \fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP @@ -504,10 +518,10 @@ Following is a copy of the libpng-manual.txt file that accompanies libpng. .SH LIBPNG.TXT libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.17 - March 26, 2015 + libpng version 1.6.34 - September 29, 2017 Updated and distributed by Glenn Randers-Pehrson - Copyright (c) 1998-2015 Glenn Randers-Pehrson + Copyright (c) 1998-2017 Glenn Randers-Pehrson This document is released under the libpng license. For conditions of distribution and use, see the disclaimer @@ -515,9 +529,9 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.6.17 - March 26, 2015 + libpng versions 0.97, January 1998, through 1.6.34 - September 29, 2017 Updated and distributed by Glenn Randers-Pehrson - Copyright (c) 1998-2015 Glenn Randers-Pehrson + Copyright (c) 1998-2017 Glenn Randers-Pehrson libpng 1.0 beta 6 - version 0.96 - May 28, 1997 Updated and distributed by Andreas Dilger @@ -570,19 +584,20 @@ file format in application programs. The PNG specification (second edition), November 2003, is available as a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at -. It is technically equivalent +. +It is technically equivalent to the PNG specification (second edition) but has some additional material. -The PNG-1.0 specification is available -as RFC 2083 and as a -W3C Recommendation . +The PNG-1.0 specification is available as RFC 2083 + and as a +W3C Recommendation . Some additional chunks are described in the special-purpose public chunks -documents at . +documents at Other information about PNG, and the latest version of libpng, can be found at the PNG home @@ -604,7 +619,7 @@ majority of the needs of its users. Libpng uses zlib for its compression and decompression of PNG files. Further information about zlib, and the latest version of zlib, can -be found at the zlib home page, . +be found at the zlib home page, . The zlib compression utility is a general purpose utility that is useful for more than PNG files, and can be used without libpng. See the documentation delivered with zlib for more details. @@ -970,8 +985,9 @@ the default, use The values for png_set_crc_action() say how libpng is to handle CRC errors in ancillary and critical chunks, and whether to use the data contained -therein. Note that it is impossible to "discard" data in a critical -chunk. +therein. Starting with libpng-1.6.26, this also governs how an ADLER32 error +is handled while reading the IDAT chunk. Note that it is impossible to +"discard" data in a critical chunk. Choices for (int) crit_action are PNG_CRC_DEFAULT 0 error/quit @@ -988,6 +1004,9 @@ Choices for (int) ancil_action are PNG_CRC_QUIET_USE 4 quiet/use data PNG_CRC_NO_CHANGE 5 use the current value +When the setting for crit_action is PNG_CRC_QUIET_USE, the CRC and ADLER32 +checksums are not only ignored, but they are not evaluated. + .SS Setting up callback code You can set up a callback function to handle any unknown chunks in the @@ -1062,7 +1081,7 @@ non-interlaced case the row that was just handled is simply one less than the passed in row number, and pass will always be 0. For the interlaced case the same applies unless the row value is 0, in which case the row just handled was the last one from one of the preceding passes. Because interlacing may skip a -pass you cannot be sure that the preceding pass is just 'pass\-1', if you really +pass you cannot be sure that the preceding pass is just 'pass\-1'; if you really need to know what the last pass is record (row,pass) from the callback and use the last recorded value each time. @@ -1153,6 +1172,7 @@ callback function: The PNG specification allows the width and height of an image to be as large as 2^(31\-1 (0x7fffffff), or about 2.147 billion rows and columns. +For safety, libpng imposes a default limit of 1 million rows and columns. Larger images will be rejected immediately with a png_error() call. If you wish to change these limits, you can use @@ -1173,8 +1193,11 @@ If you need to retrieve the limits that are being applied, use height_max = png_get_user_height_max(png_ptr); The PNG specification sets no limit on the number of ancillary chunks -allowed in a PNG datastream. You can impose a limit on the total number -of sPLT, tEXt, iTXt, zTXt, and unknown chunks that will be stored, with +allowed in a PNG datastream. By default, libpng imposes a limit of +a total of 1000 sPLT, tEXt, iTXt, zTXt, and unknown chunks to be stored. +If you have set up both info_ptr and end_info_ptr, the limit applies +separately to each. You can change the limit on the total number of such +chunks that will be stored, with png_set_chunk_cache_max(png_ptr, user_chunk_cache_max); @@ -1182,8 +1205,10 @@ where 0x7fffffffL means unlimited. You can retrieve this limit with chunk_cache_max = png_get_chunk_cache_max(png_ptr); -You can also set a limit on the amount of memory that a compressed chunk -other than IDAT can occupy, with +Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of +memory that any chunk other than IDAT can occupy, originally or when +decompressed (prior to libpng-1.6.32 the limit was only applied to compressed +chunks after decompression). You can change this limit with png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max); @@ -1479,8 +1504,17 @@ premultiplication. png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); -This is the default libpng handling of the alpha channel - it is not -pre-multiplied into the color components. In addition the call states +Choices for the alpha_mode are + + PNG_ALPHA_PNG 0 /* according to the PNG standard */ + PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ + PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ + PNG_ALPHA_PREMULTIPLIED 1 /* as above */ + PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ + PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_ALPHA_PNG is the default libpng handling of the alpha channel. It is not +pre-multiplied into the color components. In addition the call states that the output is for a sRGB system and causes all PNG files without gAMA chunks to be assumed to be encoded using sRGB. @@ -1495,7 +1529,7 @@ early Mac systems behaved. This is the classic Jim Blinn approach and will work in academic environments where everything is done by the book. It has the shortcoming of assuming that input PNG data with no gamma information is linear - this -is unlikely to be correct unless the PNG files where generated locally. +is unlikely to be correct unless the PNG files were generated locally. Most of the time the output precision will be so low as to show significant banding in dark areas of the image. @@ -1684,7 +1718,20 @@ row_pointers prior to calling png_read_png() with png_set_rows(png_ptr, info_ptr, &row_pointers); Alternatively you could allocate your image in one big block and define -row_pointers[i] to point into the proper places in your block. +row_pointers[i] to point into the proper places in your block, but first +be sure that your platform is able to allocate such a large buffer: + + /* Guard against integer overflow */ + if (height > PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + + png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size); + + for (int i=0; i, in section 9: +Copyright (c) 2006-11-28 Charles Poynton, in section 9: - + Y = 0.2126 * R + 0.7152 * G + 0.0722 * B @@ -2638,6 +2697,16 @@ are allocating one large chunk, you will need to build an array of pointers to each row, as it will be needed for some of the functions below. +Be sure that your platform can allocate the buffer that you'll need. +libpng internally checks for oversize width, but you'll need to +do your own check for number_of_rows*width*pixel_size if you are using +a multiple-row buffer: + + /* Guard against integer overflow */ + if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) { + png_error(png_ptr,"image_data buffer would be too large"); + } + Remember: Before you call png_read_update_info(), the png_get_*() functions return the values corresponding to the original PNG image. After you call png_read_update_info the values refer to the image @@ -2726,7 +2795,8 @@ is exactly the same. If you are planning on displaying the image after each pass, the "rectangle" effect is generally considered the better looking one. -If you only want the "sparkle" effect, just call png_read_rows() as +If you only want the "sparkle" effect, just call png_read_row() or +png_read_rows() as normal, with the third parameter NULL. Make sure you make pass over the image number_of_passes times, and you don't change the data in the rows between calls. You can change the locations of the data, just @@ -2735,6 +2805,8 @@ pass, and assumes the data from previous passes is still valid. png_read_rows(png_ptr, row_pointers, NULL, number_of_rows); + or + png_read_row(png_ptr, row_pointers, NULL); If you only want the first effect (the rectangles), do the same as before except pass the row buffer in the third parameter, and leave @@ -2742,6 +2814,8 @@ the second parameter NULL. png_read_rows(png_ptr, NULL, row_pointers, number_of_rows); + or + png_read_row(png_ptr, NULL, row_pointers); If you don't want libpng to handle the interlacing details, just call png_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images. @@ -2957,6 +3031,7 @@ your application instead of by libpng, you can use PNG_INFO_gAMA, PNG_INFO_sBIT, PNG_INFO_cHRM, PNG_INFO_PLTE, PNG_INFO_tRNS, PNG_INFO_bKGD, + PNG_INFO_eXIf, PNG_INFO_hIST, PNG_INFO_pHYs, PNG_INFO_oFFs, PNG_INFO_tIME, PNG_INFO_pCAL, PNG_INFO_sRGB, @@ -3338,7 +3413,7 @@ filter types. PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| - PNG_ALL_FILTERS); + PNG_ALL_FILTERS | PNG_FAST_FILTERS); If an application wants to start and stop using particular filters during compression, it should start out with all of the filters (to ensure that @@ -3456,6 +3531,7 @@ width, height, bit_depth, and color_type must be the same in each call. (array of png_color) num_palette - number of entries in the palette + png_set_gAMA(png_ptr, info_ptr, file_gamma); png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); @@ -3555,6 +3631,11 @@ width, height, bit_depth, and color_type must be the same in each call. single transparent color for non-paletted images (PNG_INFO_tRNS) + png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif); + + exif - Exif profile (array of + png_byte) (PNG_INFO_eXIf) + png_set_hIST(png_ptr, info_ptr, hist); hist - histogram of palette (array of @@ -4220,21 +4301,26 @@ as a wide variety of APIs to manipulate ancilliary information. To read a PNG file using the simplified API: - 1) Declare a 'png_image' structure (see below) on the - stack and memset() it to all zero. + 1) Declare a 'png_image' structure (see below) on the stack, set the + version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL + (this is REQUIRED, your program may crash if you don't do it.) 2) Call the appropriate png_image_begin_read... function. - 3) Set the png_image 'format' member to the required - format and allocate a buffer for the image. + 3) Set the png_image 'format' member to the required sample format. - 4) Call png_image_finish_read to read the image into - your buffer. + 4) Allocate a buffer for the image and, if required, the color-map. + + 5) Call png_image_finish_read to read the image and, if required, the + color-map into your buffers. There are no restrictions on the format of the PNG input itself; all valid color types, bit depths, and interlace methods are acceptable, and the input image is transformed as necessary to the requested in-memory format -during the png_image_finish_read() step. +during the png_image_finish_read() step. The only caveat is that if you +request a color-mapped image from a PNG that is full-color or makes +complex use of an alpha channel the transformation is extremely lossy and the +result may look terrible. To write a PNG file using the simplified API: @@ -4243,34 +4329,35 @@ To write a PNG file using the simplified API: 2) Initialize the members of the structure that describe the image, setting the 'format' member to the format of the - image in memory. + image samples. 3) Call the appropriate png_image_write... function with a - pointer to the image to write the PNG data. + pointer to the image and, if necessary, the color-map to write + the PNG data. png_image is a structure that describes the in-memory format of an image -when it is being read or define the in-memory format of an image that you +when it is being read or defines the in-memory format of an image that you need to write. The "png_image" structure contains the following members: + png_controlp opaque Initialize to NULL, free with png_image_free png_uint_32 version Set to PNG_IMAGE_VERSION png_uint_32 width Image width in pixels (columns) png_uint_32 height Image height in pixels (rows) png_uint_32 format Image format as defined below png_uint_32 flags A bit mask containing informational flags - png_controlp opaque Initialize to NULL, free with png_image_free png_uint_32 colormap_entries; Number of entries in the color-map png_uint_32 warning_or_error; char message[64]; -In the event of an error or warning the following field warning_or_error +In the event of an error or warning the "warning_or_error" field will be set to a non-zero value and the 'message' field will contain a '\0' terminated string with the libpng error or warning message. If both warnings and an error were encountered, only the error is recorded. If there are multiple warnings, only the first one is recorded. -The upper 30 bits of this value are reserved; the low two bits contain -a two bit code such that a value more than 1 indicates a failure in the API -just called: +The upper 30 bits of the "warning_or_error" value are reserved; the low two +bits contain a two bit code such that a value more than 1 indicates a failure +in the API just called: 0 - no warning or error 1 - warning @@ -4302,64 +4389,72 @@ channels are linear. Color channels use the RGB encoding (RGB end-points) of the sRGB specification. This encoding is identified by the PNG_FORMAT_FLAG_LINEAR flag below. +When the simplified API needs to convert between sRGB and linear colorspaces, +the actual sRGB transfer curve defined in the sRGB specification (see the +article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 +approximation used elsewhere in libpng. + When an alpha channel is present it is expected to denote pixel coverage of the color or luminance channels and is returned as an associated alpha channel: the color/gray channels are scaled (pre-multiplied) by the alpha value. -When a color-mapped image is used as a result of calling -png_image_read_colormap or png_image_write_colormap the channels are encoded -in the color-map and the descriptions above apply to the color-map entries. -The image data is encoded as small integers, value 0..255, that index the -entries in the color-map. One integer (one byte) is stored for each pixel. +The samples are either contained directly in the image data, between 1 and 8 +bytes per pixel according to the encoding, or are held in a color-map indexed +by bytes in the image data. In the case of a color-map the color-map entries +are individual samples, encoded as above, and the image data has one byte per +pixel to select the relevant sample from the color-map. PNG_FORMAT_* The #defines to be used in png_image::format. Each #define identifies a particular layout of channel data and, if present, alpha values. There are -separate defines for each of the two channel encodings. +separate defines for each of the two component encodings. -A format is built up using single bit flag values. Not all combinations are -valid: use the bit flag values below for testing a format returned by the -read APIs, but set formats from the derived values. +A format is built up using single bit flag values. All combinations are +valid. Formats can be built up from the flag values or you can use one of +the predefined values below. When testing formats always use the FORMAT_FLAG +macros to test for individual features - future versions of the library may +add new flags. When reading or writing color-mapped images the format should be set to the format of the entries in the color-map then png_image_{read,write}_colormap called to read or write the color-map and set the format correctly for the image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! -NOTE: libpng can be built with particular features disabled, if you see +NOTE: libpng can be built with particular features disabled. If you see compiler errors because the definition of one of the following flags has been compiled out it is because libpng does not have the required support. It is possible, however, for the libpng configuration to enable the format on just -read or just write; in that case you may see an error at run time. You can -guard against this by checking for the definition of: +read or just write; in that case you may see an error at run time. +You can guard against this by checking for the definition of the +appropriate "_SUPPORTED" macro, one of: PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED - PNG_FORMAT_FLAG_ALPHA 0x01 format with an alpha channel - PNG_FORMAT_FLAG_COLOR 0x02 color format: otherwise grayscale - PNG_FORMAT_FLAG_LINEAR 0x04 png_uint_16 channels else png_byte - PNG_FORMAT_FLAG_COLORMAP 0x08 libpng use only - PNG_FORMAT_FLAG_BGR 0x10 BGR colors, else order is RGB - PNG_FORMAT_FLAG_AFIRST 0x20 alpha channel comes first + PNG_FORMAT_FLAG_ALPHA format with an alpha channel + PNG_FORMAT_FLAG_COLOR color format: otherwise grayscale + PNG_FORMAT_FLAG_LINEAR 2-byte channels else 1-byte + PNG_FORMAT_FLAG_COLORMAP image data is color-mapped + PNG_FORMAT_FLAG_BGR BGR colors, else order is RGB + PNG_FORMAT_FLAG_AFIRST alpha channel comes first Supported formats are as follows. Future versions of libpng may support more formats; for compatibility with older versions simply check if the format macro is defined using #ifdef. These defines describe the in-memory layout of the components of the pixels of the image. -First the single byte formats: +First the single byte (sRGB) formats: - PNG_FORMAT_GRAY 0 - PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA - PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) - PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR - PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) - PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) - PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) - PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) - PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) + PNG_FORMAT_GRAY + PNG_FORMAT_GA + PNG_FORMAT_AG + PNG_FORMAT_RGB + PNG_FORMAT_BGR + PNG_FORMAT_RGBA + PNG_FORMAT_ARGB + PNG_FORMAT_BGRA + PNG_FORMAT_ABGR Then the linear 2-byte formats. When naming these "Y" is used to indicate a luminance (gray) channel. The component order within the pixel @@ -4368,22 +4463,22 @@ components in the linear format. The components are 16-bit integers in the native byte order for your platform, and there is no provision for swapping the bytes to a different endian condition. - PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR + PNG_FORMAT_LINEAR_Y PNG_FORMAT_LINEAR_Y_ALPHA - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) PNG_FORMAT_LINEAR_RGB - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) PNG_FORMAT_LINEAR_RGB_ALPHA - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR| - PNG_FORMAT_FLAG_ALPHA) -Color-mapped formats are obtained by calling png_image_{read,write}_colormap, -as appropriate after setting png_image::format to the format of the color-map -to be read or written. Applications may check the value of -PNG_FORMAT_FLAG_COLORMAP to see if they have called the colormap API. The -format of the color-map may be extracted using the following macro. +With color-mapped formats the image data is one byte for each pixel. The byte +is an index into the color-map which is formatted as above. To obtain a +color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP +to one of the above definitions, or you can use one of the definitions below. - PNG_FORMAT_OF_COLORMAP(fmt) ((fmt) & ~PNG_FORMAT_FLAG_COLORMAP) + PNG_FORMAT_RGB_COLORMAP + PNG_FORMAT_BGR_COLORMAP + PNG_FORMAT_RGBA_COLORMAP + PNG_FORMAT_ARGB_COLORMAP + PNG_FORMAT_BGRA_COLORMAP + PNG_FORMAT_ABGR_COLORMAP PNG_IMAGE macros @@ -4391,9 +4486,9 @@ These are convenience macros to derive information from a png_image structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the actual image sample values - either the entries in the color-map or the pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values -for the pixels and will always return 1 after a call to -png_image_{read,write}_colormap. The remaining macros return information -about the rows in the image and the complete image. +for the pixels and will always return 1 for color-mapped formats. The +remaining macros return information about the rows in the image and the +complete image. NOTE: All the macros that take a png_image::format parameter are compile time constants if the format parameter is, itself, a constant. Therefore these @@ -4401,46 +4496,39 @@ macros can be used in array declarations and case labels where required. Similarly the macros are also pre-processor constants (sizeof is not used) so they can be used in #if tests. -First the information about the samples. - PNG_IMAGE_SAMPLE_CHANNELS(fmt) Returns the total number of channels in a given format: 1..4 PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt) Returns the size in bytes of a single component of a pixel or color-map - entry (as appropriate) in the image. + entry (as appropriate) in the image: 1 or 2. PNG_IMAGE_SAMPLE_SIZE(fmt) This is the size of the sample data for one sample. If the image is color-mapped it is the size of one color-map entry (and image pixels are one byte in size), otherwise it is the size of one image pixel. + PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt) + The maximum size of the color-map required by the format expressed in a + count of components. This can be used to compile-time allocate a + color-map: + + png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; + + png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; + + Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the + information from one of the png_image_begin_read_ APIs and dynamically + allocate the required memory. + PNG_IMAGE_COLORMAP_SIZE(fmt) The size of the color-map required by the format; this is the size of the - color-map buffer passed to the png_image_{read,write}_colormap APIs, it is + color-map buffer passed to the png_image_{read,write}_colormap APIs. It is a fixed number determined by the format so can easily be allocated on the stack if necessary. -#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) - /* The maximum size of the color-map required by the format expressed in a - * count of components. This can be used to compile-time allocate a - * color-map: - * - * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; - * - * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; - * - * Alternatively, use the PNG_IMAGE_COLORMAP_SIZE macro below to use the - * information from one of the png_image_begin_read_ APIs and dynamically - * allocate the required memory. - */ - - Corresponding information about the pixels - PNG_IMAGE_PIXEL_(test,fmt) - PNG_IMAGE_PIXEL_CHANNELS(fmt) The number of separate channels (components) in a pixel; 1 for a color-mapped image. @@ -4466,19 +4554,54 @@ Information about the whole row, or whole image to start the next row on a 4-byte boundary. PNG_IMAGE_BUFFER_SIZE(image, row_stride) - Returns the size, in bytes, of an image buffer given a png_image and a row - stride - the number of components to leave space for in each row. This - macro takes care of multiplying row_stride by PNG_IMAGE_PIXEL_COMONENT_SIZE - when the image has 2-byte components. + Return the size, in bytes, of an image buffer given a png_image and a row + stride - the number of components to leave space for in each row. + + PNG_IMAGE_SIZE(image) + Return the size, in bytes, of the image in memory given just a png_image; + the row stride is the minimum stride required for the image. + + PNG_IMAGE_COLORMAP_SIZE(image) + Return the size, in bytes, of the color-map of this image. If the image + format is not a color-map format this will return a size sufficient for + 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if + you don't want to allocate a color-map in this case. + +PNG_IMAGE_FLAG_* + +Flags containing additional information about the image are held in +the 'flags' field of png_image. PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01 This indicates the the RGB values of the in-memory bitmap do not correspond to the red, green and blue end-points defined by sRGB. - PNG_IMAGE_FLAG_COLORMAP == 0x02 - The PNG is color-mapped. If this flag is set png_image_read_colormap - can be used without further loss of image information. If it is not set - png_image_read_colormap will cause significant loss if the image has any + PNG_IMAGE_FLAG_FAST == 0x02 + On write emphasise speed over compression; the resultant PNG file will be + larger but will be produced significantly faster, particular for large + images. Do not use this option for images which will be distributed, only + used it when producing intermediate files that will be read back in + repeatedly. For a typical 24-bit image the option will double the read + speed at the cost of increasing the image size by 25%, however for many + more compressible images the PNG file can be 10 times larger with only a + slight speed gain. + + PNG_IMAGE_FLAG_16BIT_sRGB == 0x04 + On read if the image is a 16-bit per component image and there is no gAMA + or sRGB chunk assume that the components are sRGB encoded. Notice that + images output by the simplified API always have gamma information; setting + this flag only affects the interpretation of 16-bit images from an + external source. It is recommended that the application expose this flag + to the user; the user can normally easily recognize the difference between + linear and sRGB encoding. This flag has no effect on write - the data + passed to the write APIs must have the correct encoding (as defined + above.) + + If the flag is not set (the default) input 16-bit per component data is + assumed to be linear. + + NOTE: the flag can only be set after the png_image_begin_read_ call, + because that call initializes the 'flags' field. READ APIs @@ -4532,7 +4655,7 @@ READ APIs When the simplified API needs to convert between sRGB and linear colorspaces, the actual sRGB transfer curve defined in the sRGB specification (see the -article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 +article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 approximation used elsewhere in libpng. WRITE APIS @@ -4556,6 +4679,13 @@ be written: Write the image to the named file. + int png_image_write_to_memory (png_imagep image, void *memory, + png_alloc_size_t * PNG_RESTRICT memory_bytes, + int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride, + const void *colormap)); + + Write the image to memory. + int png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8_bit, const void *buffer, png_int_32 row_stride, const void *colormap) @@ -4569,10 +4699,11 @@ a 16-bit linear encoded PNG file is written. With all APIs row_stride is handled as in the read APIs - it is the spacing from one row to the next in component sized units (float) and if negative -indicates a bottom-up row layout in the buffer. +indicates a bottom-up row layout in the buffer. If you pass zero, libpng will +calculate the row_stride for you from the width and number of channels. Note that the write API does not support interlacing, sub-8-bit pixels, -and indexed (paletted) images. +indexed (paletted) images, or most ancillary chunks. .SH VI. Modifying/Customizing libpng @@ -4682,8 +4813,6 @@ functions after png_create_*_struct() has been called by calling: png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn); - png_voidp error_ptr = png_get_error_ptr(png_ptr); - If NULL is supplied for either error_fn or warning_fn, then the libpng default function will be used, calling fprintf() and/or longjmp() if a problem is encountered. The replacement error functions should have @@ -4695,6 +4824,11 @@ parameters as follows: void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg); +Then, within your user_error_fn or user_warning_fn, you can retrieve +the error_ptr if you need it, by calling + + png_voidp error_ptr = png_get_error_ptr(png_ptr); + The motivation behind using setjmp() and longjmp() is the C++ throw and catch exception handling methods. This makes the code much easier to write, as there is no need to check every return code of every function call. @@ -4702,7 +4836,7 @@ However, there are some uncertainties about the status of local variables after a longjmp, so the user may want to be careful about doing anything after setjmp returns non-zero besides returning itself. Consult your compiler documentation for more details. For an alternative approach, you -may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net), +may wish to use the "cexcept" facility (see https://cexcept.sourceforge.io/), which is illustrated in pngvalid.c and in contrib/visupng. Beginning in libpng-1.4.0, the png_set_benign_errors() API became available. @@ -4832,8 +4966,9 @@ for any images with bit depths less than 8 bits/pixel. The 'method' parameter sets the main filtering method, which is currently only '0' in the PNG 1.2 specification. The 'filters' parameter sets which filter(s), if any, should be used for each -scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS -to turn filtering on and off, respectively. +scanline. Possible values are PNG_ALL_FILTERS, PNG_NO_FILTERS, +or PNG_FAST_FILTERS to turn filtering on and off, or to turn on +just the fast-decoding subset of filters, respectively. Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise @@ -4847,12 +4982,19 @@ means the first row must always be adaptively filtered, because libpng currently does not allocate the filter buffers until png_write_row() is called for the first time.) - filters = PNG_FILTER_NONE | PNG_FILTER_SUB + filters = PNG_NO_FILTERS; + filters = PNG_ALL_FILTERS; + filters = PNG_FAST_FILTERS; + + or + + filters = PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | - PNG_FILTER_PAETH | PNG_ALL_FILTERS; + PNG_FILTER_PAETH; png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters); + The second parameter can also be PNG_INTRAPIXEL_DIFFERENCING if you are writing a PNG to be embedded in a MNG @@ -4860,41 +5002,6 @@ is called for the first time.) same as the value of filter_method used in png_set_IHDR(). -It is also possible to influence how libpng chooses from among the -available filters. This is done in one or both of two ways - by -telling it how important it is to keep the same filter for successive -rows, and by telling it the relative computational costs of the filters. - - double weights[3] = {1.5, 1.3, 1.1}, - costs[PNG_FILTER_VALUE_LAST] = - {1.0, 1.3, 1.3, 1.5, 1.7}; - - png_set_filter_heuristics(png_ptr, - PNG_FILTER_HEURISTIC_WEIGHTED, 3, - weights, costs); - -The weights are multiplying factors that indicate to libpng that the -row filter should be the same for successive rows unless another row filter -is that many times better than the previous filter. In the above example, -if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a -"sum of absolute differences" 1.5 x 1.3 times higher than other filters -and still be chosen, while the NONE filter could have a sum 1.1 times -higher than other filters and still be chosen. Unspecified weights are -taken to be 1.0, and the specified weights should probably be declining -like those above in order to emphasize recent filters over older filters. - -The filter costs specify for each filter type a relative decoding cost -to be considered when selecting row filters. This means that filters -with higher costs are less likely to be chosen over filters with lower -costs, unless their "sum of absolute differences" is that much smaller. -The costs do not necessarily reflect the exact computational speeds of -the various filters, since this would unduly influence the final image -size. - -Note that the numbers above were invented purely for this example and -are given only to help explain the function usage. Little testing has -been done to find optimum values for either the costs or the weights. - .SS Requesting debug printout The macro definition PNG_DEBUG can be used to request debugging @@ -4957,7 +5064,7 @@ in a MNG datastream. As a minimum, it must have the MNG 8-byte signature and the MHDR and MEND chunks. Libpng does not provide support for these or any other MNG chunks; your application must provide its own support for them. You may wish to consider using libmng (available at -http://www.libmng.com) instead. +https://www.libmng.com/) instead. .SH VIII. Changes to Libpng from version 0.88 @@ -5262,7 +5369,8 @@ There are no substantial API changes between the non-deprecated parts of the 1.4.5 API and the 1.5.0 API; however, the ability to directly access members of the main libpng control structures, png_struct and png_info, deprecated in earlier versions of libpng, has been completely removed from -libpng 1.5. +libpng 1.5, and new private "pngstruct.h", "pnginfo.h", and "pngdebug.h" +header files were created. We no longer include zlib.h in png.h. The include statement has been moved to pngstruct.h, where it is not accessible by applications. Applications that @@ -5379,22 +5487,18 @@ PNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said that it could be used to override them. Now this function will reduce or increase the limits. -Starting in libpng-1.5.10, the user limits can be set en masse with the -configuration option PNG_SAFE_LIMITS_SUPPORTED. If this option is enabled, -a set of "safe" limits is applied in pngpriv.h. These can be overridden by -application calls to png_set_user_limits(), png_set_user_chunk_cache_max(), -and/or png_set_user_malloc_max() that increase or decrease the limits. Also, -in libpng-1.5.10 the default width and height limits were increased -from 1,000,000 to 0x7ffffff (i.e., made unlimited). Therefore, the -limits are now - default safe +Starting in libpng-1.5.22, default user limits were established. These +can be overridden by application calls to png_set_user_limits(), +png_set_user_chunk_cache_max(), and/or png_set_user_malloc_max(). +The limits are now + max possible default png_user_width_max 0x7fffffff 1,000,000 png_user_height_max 0x7fffffff 1,000,000 - png_user_chunk_cache_max 0 (unlimited) 128 + png_user_chunk_cache_max 0 (unlimited) 1000 png_user_chunk_malloc_max 0 (unlimited) 8,000,000 The png_set_option() function (and the "options" member of the png struct) was -added to libpng-1.5.15. +added to libpng-1.5.15, with option PNG_ARM_NEON. The library now supports a complete fixed point implementation and can thus be used on systems that have no floating point support or very @@ -5502,6 +5606,7 @@ includes the following: png_image_free() write functions png_image_write_to_file() + png_image_write_to_memory() png_image_write_to_stdio() Starting with libpng-1.6.0, you can configure libpng to prefix all exported @@ -5536,9 +5641,9 @@ The signatures of many exported functions were changed, such that png_infop became png_inforp or png_const_inforp where "rp" indicates a "restricted pointer". -The support for FAR/far types has been eliminated and the definition of -png_alloc_size_t is now controlled by a flag so that 'small size_t' systems -can select it if necessary. +Dropped support for 16-bit platforms. The support for FAR/far types has +been eliminated and the definition of png_alloc_size_t is now controlled +by a flag so that 'small size_t' systems can select it if necessary. Error detection in some chunks has improved; in particular the iCCP chunk reader now does pretty complete validation of the basic format. Some bad @@ -5565,6 +5670,10 @@ enforced. The sRGB chunk is allowed to appear in images with any color type and is interpreted by libpng to convey a one-tracer-curve gray profile or a three-tracer-curve RGB profile as appropriate. +Libpng 1.5.x erroneously used /MD for Debug DLL builds; if you used the debug +builds in your app and you changed your app to use /MD you will need to +change it back to /MDd for libpng 1.6.x. + Prior to libpng-1.6.0 a warning would be issued if the iTXt chunk contained an empty language field or an empty translated keyword. Both of these are allowed by the PNG specification, so these warnings are no longer issued. @@ -5613,6 +5722,33 @@ length, which resulted in PNG files that cannot be read beyond the bad iTXt chunk. This error was fixed in libpng-1.6.3, and a tool (called contrib/tools/png-fix-itxt) has been added to the libpng distribution. +Starting with libpng-1.6.17, the PNG_SAFE_LIMITS macro was eliminated +and safe limits are used by default (users who need larger limits +can still override them at compile time or run time, as described above). + +The new limits are + default spec limit + png_user_width_max 1,000,000 2,147,483,647 + png_user_height_max 1,000,000 2,147,483,647 + png_user_chunk_cache_max 128 unlimited + png_user_chunk_malloc_max 8,000,000 unlimited + +Starting with libpng-1.6.18, a PNG_RELEASE_BUILD macro was added, which allows +library builders to control compilation for an installed system (a release build). +It can be set for testing debug or beta builds to ensure that they will compile +when the build type is switched to RC or STABLE. In essence this overrides the +PNG_LIBPNG_BUILD_BASE_TYPE definition which is not directly user controllable. + +Starting with libpng-1.6.19, attempting to set an over-length PLTE chunk +is an error. Previously this requirement of the PNG specification was not +enforced, and the palette was always limited to 256 entries. An over-length +PLTE chunk found in an input PNG is silently truncated. + +Starting with libpng-1.6.31, the eXIf chunk is supported. Libpng does not +attempt to decode the Exif profile; it simply returns a byte array +containing the profile to the calling application which must do its own +decoding. + .SH XIII. Detecting libpng The png_get_io_ptr() function has been present since libpng-0.88, has never @@ -5629,27 +5765,33 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files going back to version 0.70. You can access the git repository (read only) at - git://git.code.sf.net/p/libpng/code + https://github.com/glennrp/libpng or + https://git.code.sf.net/p/libpng/code.git -or you can browse it with a web browser by selecting the "code" button at +or you can browse it with a web browser at - https://sourceforge.net/projects/libpng + https://github.com/glennrp/libpng or + https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ Patches can be sent to glennrp at users.sourceforge.net or to png-mng-implement at lists.sourceforge.net or you can upload them to the libpng bug tracker at - http://libpng.sourceforge.net + https://libpng.sourceforge.io/ + +or as a "pull request" to + + https://github.com/glennrp/libpng/pulls We also accept patches built from the tar or zip distributions, and simple verbal discriptions of bug fixes, reported either to the SourceForge bug tracker, to the png-mng-implement at lists.sf.net -mailing list, or directly to glennrp. +mailing list, as github issues, or directly to glennrp. .SH XV. Coding style Our coding style is similar to the "Allman" style -(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly +(See https://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly braces on separate lines: if (condition) @@ -5750,7 +5892,7 @@ Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as though it were a function. Control keywords if, for, while, and switch are always followed by a space -to distinguish them from function calls, which have no trailing space. +to distinguish them from function calls, which have no trailing space. We put a space after each comma and after each semicolon in "for" statements, and we put spaces before and after each @@ -5766,14 +5908,17 @@ We prefer #ifdef and #ifndef to #if defined() and #if !defined() when there is only one macro being tested. We always use parentheses with "defined". -We prefer to express integers that are used as bit masks in hex format, -with an even number of lower-case hex digits (e.g., 0x00, 0xff, 0x0100). +We express integer constants that are used as bit masks in hex format, +with an even number of lower-case hex digits, and to make them unsigned +(e.g., 0x00U, 0xffU, 0x0100U) and long if they are greater than 0x7fff +(e.g., 0xffffUL). -We prefer to use underscores in variable names rather than camelCase, except +We prefer to use underscores rather than camelCase in names, except for a few type names that we inherit from zlib.h. -We prefer "if (something != 0)" and "if (something == 0)" -over "if (something)" and if "(!something)", respectively. +We prefer "if (something != 0)" and "if (something == 0)" over +"if (something)" and if "(!something)", respectively, and for pointers +we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)". We do not use the TAB character for indentation in the C sources. @@ -5783,13 +5928,11 @@ Other rules can be inferred by inspecting the libpng source. .SH XVI. Y2K Compliance in libpng -March 26, 2015 - Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and -upward through 1.6.17 are Y2K compliant. It is my belief that earlier +upward through 1.6.34 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has two year fields. One is a 2-byte unsigned integer @@ -5851,199 +5994,47 @@ the first widely used release: source png.h png.h shared-lib version string int version ------- ------ ----- ---------- - 0.89c ("beta 3") 0.89 89 1.0.89 - 0.90 ("beta 4") 0.90 90 0.90 - 0.95 ("beta 5") 0.95 95 0.95 - 0.96 ("beta 6") 0.96 96 0.96 - 0.97b ("beta 7") 1.00.97 97 1.0.1 - 0.97c 0.97 97 2.0.97 - 0.98 0.98 98 2.0.98 - 0.99 0.99 98 2.0.99 - 0.99a-m 0.99 99 2.0.99 - 1.00 1.00 100 2.1.0 - 1.0.0 1.0.0 100 2.1.0 - 1.0.0 (from here on, the 100 2.1.0 - 1.0.1 png.h string is 10001 2.1.0 - 1.0.1a-e identical to the 10002 from here on, the - 1.0.2 source version) 10002 shared library is 2.V - 1.0.2a-b 10003 where V is the source - 1.0.1 10001 code version except as - 1.0.1a-e 10002 2.1.0.1a-e noted. - 1.0.2 10002 2.1.0.2 - 1.0.2a-b 10003 2.1.0.2a-b - 1.0.3 10003 2.1.0.3 - 1.0.3a-d 10004 2.1.0.3a-d - 1.0.4 10004 2.1.0.4 - 1.0.4a-f 10005 2.1.0.4a-f - 1.0.5 (+ 2 patches) 10005 2.1.0.5 - 1.0.5a-d 10006 2.1.0.5a-d - 1.0.5e-r 10100 2.1.0.5e-r - 1.0.5s-v 10006 2.1.0.5s-v - 1.0.6 (+ 3 patches) 10006 2.1.0.6 - 1.0.6d-g 10007 2.1.0.6d-g - 1.0.6h 10007 10.6h - 1.0.6i 10007 10.6i - 1.0.6j 10007 2.1.0.6j - 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 - 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 - 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 - 1.0.7 1 10007 2.1.0.7 - 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 - 1.0.8rc1 1 10008 2.1.0.8rc1 - 1.0.8 1 10008 2.1.0.8 - 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 - 1.0.9rc1 1 10009 2.1.0.9rc1 - 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 - 1.0.9rc2 1 10009 2.1.0.9rc2 - 1.0.9 1 10009 2.1.0.9 - 1.0.10beta1 1 10010 2.1.0.10beta1 - 1.0.10rc1 1 10010 2.1.0.10rc1 - 1.0.10 1 10010 2.1.0.10 - 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 - 1.0.11rc1 1 10011 2.1.0.11rc1 - 1.0.11 1 10011 2.1.0.11 - 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 - 1.0.12rc1 2 10012 2.1.0.12rc1 - 1.0.12 2 10012 2.1.0.12 - 1.1.0a-f - 10100 2.1.1.0a-f abandoned - 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 - 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 - 1.2.0rc1 3 10200 3.1.2.0rc1 - 1.2.0 3 10200 3.1.2.0 - 1.2.1beta-4 3 10201 3.1.2.1beta1-4 - 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 - 1.2.1 3 10201 3.1.2.1 - 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 - 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 - 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 - 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 - 1.0.13 10 10013 10.so.0.1.0.13 - 1.2.2 12 10202 12.so.0.1.2.2 - 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 - 1.2.3 12 10203 12.so.0.1.2.3 - 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 - 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 - 1.0.14 10 10014 10.so.0.1.0.14 - 1.2.4 13 10204 12.so.0.1.2.4 - 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 - 1.0.15rc1 10 10015 10.so.0.1.0.15rc1 - 1.0.15 10 10015 10.so.0.1.0.15 - 1.2.5 13 10205 12.so.0.1.2.5 - 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 - 1.2.6rc1-5 13 10206 12.so.0.1.2.6rc1-5 - 1.0.16 10 10016 10.so.0.1.0.16 - 1.2.6 13 10206 12.so.0.1.2.6 - 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 - 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 - 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 - 1.0.17 10 10017 12.so.0.1.0.17 - 1.2.7 13 10207 12.so.0.1.2.7 - 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 - 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 - 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 - 1.0.18 10 10018 12.so.0.1.0.18 - 1.2.8 13 10208 12.so.0.1.2.8 - 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 - 1.2.9beta4-11 13 10209 12.so.0.9[.0] - 1.2.9rc1 13 10209 12.so.0.9[.0] - 1.2.9 13 10209 12.so.0.9[.0] - 1.2.10beta1-7 13 10210 12.so.0.10[.0] - 1.2.10rc1-2 13 10210 12.so.0.10[.0] - 1.2.10 13 10210 12.so.0.10[.0] - 1.4.0beta1-6 14 10400 14.so.0.0[.0] - 1.2.11beta1-4 13 10210 12.so.0.11[.0] - 1.4.0beta7-8 14 10400 14.so.0.0[.0] - 1.2.11 13 10211 12.so.0.11[.0] - 1.2.12 13 10212 12.so.0.12[.0] - 1.4.0beta9-14 14 10400 14.so.0.0[.0] - 1.2.13 13 10213 12.so.0.13[.0] - 1.4.0beta15-36 14 10400 14.so.0.0[.0] - 1.4.0beta37-87 14 10400 14.so.14.0[.0] - 1.4.0rc01 14 10400 14.so.14.0[.0] - 1.4.0beta88-109 14 10400 14.so.14.0[.0] - 1.4.0rc02-08 14 10400 14.so.14.0[.0] - 1.4.0 14 10400 14.so.14.0[.0] - 1.4.1beta01-03 14 10401 14.so.14.1[.0] - 1.4.1rc01 14 10401 14.so.14.1[.0] - 1.4.1beta04-12 14 10401 14.so.14.1[.0] - 1.4.1 14 10401 14.so.14.1[.0] - 1.4.2 14 10402 14.so.14.2[.0] - 1.4.3 14 10403 14.so.14.3[.0] - 1.4.4 14 10404 14.so.14.4[.0] - 1.5.0beta01-58 15 10500 15.so.15.0[.0] - 1.5.0rc01-07 15 10500 15.so.15.0[.0] - 1.5.0 15 10500 15.so.15.0[.0] - 1.5.1beta01-11 15 10501 15.so.15.1[.0] - 1.5.1rc01-02 15 10501 15.so.15.1[.0] - 1.5.1 15 10501 15.so.15.1[.0] - 1.5.2beta01-03 15 10502 15.so.15.2[.0] - 1.5.2rc01-03 15 10502 15.so.15.2[.0] - 1.5.2 15 10502 15.so.15.2[.0] - 1.5.3beta01-10 15 10503 15.so.15.3[.0] - 1.5.3rc01-02 15 10503 15.so.15.3[.0] - 1.5.3beta11 15 10503 15.so.15.3[.0] - 1.5.3 [omitted] - 1.5.4beta01-08 15 10504 15.so.15.4[.0] - 1.5.4rc01 15 10504 15.so.15.4[.0] - 1.5.4 15 10504 15.so.15.4[.0] - 1.5.5beta01-08 15 10505 15.so.15.5[.0] - 1.5.5rc01 15 10505 15.so.15.5[.0] - 1.5.5 15 10505 15.so.15.5[.0] - 1.5.6beta01-07 15 10506 15.so.15.6[.0] - 1.5.6rc01-03 15 10506 15.so.15.6[.0] - 1.5.6 15 10506 15.so.15.6[.0] - 1.5.7beta01-05 15 10507 15.so.15.7[.0] - 1.5.7rc01-03 15 10507 15.so.15.7[.0] - 1.5.7 15 10507 15.so.15.7[.0] - 1.6.0beta01-40 16 10600 16.so.16.0[.0] - 1.6.0rc01-08 16 10600 16.so.16.0[.0] - 1.6.0 16 10600 16.so.16.0[.0] - 1.6.1beta01-09 16 10601 16.so.16.1[.0] - 1.6.1rc01 16 10601 16.so.16.1[.0] - 1.6.1 16 10601 16.so.16.1[.0] - 1.6.2beta01 16 10602 16.so.16.2[.0] - 1.6.2rc01-06 16 10602 16.so.16.2[.0] - 1.6.2 16 10602 16.so.16.2[.0] - 1.6.3beta01-11 16 10603 16.so.16.3[.0] - 1.6.3rc01 16 10603 16.so.16.3[.0] - 1.6.3 16 10603 16.so.16.3[.0] - 1.6.4beta01-02 16 10604 16.so.16.4[.0] - 1.6.4rc01 16 10604 16.so.16.4[.0] - 1.6.4 16 10604 16.so.16.4[.0] - 1.6.5 16 10605 16.so.16.5[.0] - 1.6.6 16 10606 16.so.16.6[.0] - 1.6.7beta01-04 16 10607 16.so.16.7[.0] - 1.6.7rc01-02 16 10607 16.so.16.7[.0] - 1.6.7 16 10607 16.so.16.7[.0] - 1.6.8beta01-02 16 10608 16.so.16.8[.0] - 1.6.8rc01-02 16 10608 16.so.16.8[.0] - 1.6.8 16 10608 16.so.16.8[.0] - 1.6.9beta01-04 16 10609 16.so.16.9[.0] - 1.6.9rc01-02 16 10609 16.so.16.9[.0] - 1.6.9 16 10609 16.so.16.9[.0] - 1.6.10beta01-03 16 10610 16.so.16.10[.0] - 1.6.10rc01-03 16 10610 16.so.16.10[.0] - 1.6.10 16 10610 16.so.16.10[.0] - 1.6.11beta01-06 16 10611 16.so.16.11[.0] - 1.6.11rc01-02 16 10611 16.so.16.11[.0] - 1.6.11 16 10611 16.so.16.11[.0] - 1.6.12rc01 16 10612 16.so.16.12[.0] - 1.6.12 16 10612 16.so.16.12[.0] - 1.6.13beta01-04 16 10613 16.so.16.13[.0] - 1.6.13rc01-02 16 10613 16.so.16.13[.0] - 1.6.13 16 10613 16.so.16.13[.0] - 1.6.14beta01-07 16 10614 16.so.16.14[.0] - 1.6.14rc01-02 16 10614 16.so.16.14[.0] - 1.6.14 16 10614 16.so.16.14[.0] - 1.6.15beta01-08 16 10615 16.so.16.15[.0] - 1.6.15rc01-03 16 10615 16.so.16.15[.0] - 1.6.15 16 10615 16.so.16.15[.0] - 1.6.16beta01-03 16 10616 16.so.16.16[.0] - 1.6.16rc01-02 16 10616 16.so.16.16[.0] - 1.6.16 16 10616 16.so.16.16[.0] - 1.6.17beta01-06 16 10617 16.so.16.17[.0] - 1.6.17rc01-06 16 10617 16.so.16.17[.0] - 1.6.17 16 10617 16.so.16.17[.0] + 0.89c "1.0 beta 3" 0.89 89 1.0.89 + 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + 0.97c 0.97 97 2.0.97 + 0.98 0.98 98 2.0.98 + 0.99 0.99 98 2.0.99 + 0.99a-m 0.99 99 2.0.99 + 1.00 1.00 100 2.1.0 [100 should be 10000] + 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + 1.0.1 png.h string is 10001 2.1.0 + 1.0.1a-e identical to the 10002 from here on, the shared library + 1.0.2 source version) 10002 is 2.V where V is the source code + 1.0.2a-b 10003 version, except as noted. + 1.0.3 10003 + 1.0.3a-d 10004 + 1.0.4 10004 + 1.0.4a-f 10005 + 1.0.5 (+ 2 patches) 10005 + 1.0.5a-d 10006 + 1.0.5e-r 10100 (not source compatible) + 1.0.5s-v 10006 (not binary compatible) + 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + 1.0.6d-f 10007 (still binary incompatible) + 1.0.6g 10007 + 1.0.6h 10007 10.6h (testing xy.z so-numbering) + 1.0.6i 10007 10.6i + 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + 1.0.7 1 10007 (still compatible) + ... + 1.0.19 10 10019 10.so.0.19[.0] + ... + 1.2.59 13 10259 12.so.0.59[.0] + ... + 1.5.30 15 10530 15.so.15.30[.0] + ... + 1.6.34 16 10634 16.so.16.34[.0] Henceforth the source version will match the shared-library minor and patch numbers; the shared-library major version number will be @@ -6053,15 +6044,14 @@ for applications, is an unsigned integer of the form xyyzz corresponding to the source version x.y.z (leading zeros in y and z). Beta versions were given the previous public release number plus a letter, until version 1.0.6j; from then on they were given the upcoming public -release number plus "betaNN" or "rcN". +release number plus "betaNN" or "rcNN". .SH "SEE ALSO" -.BR "png"(5), " libpngpf"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5) - +.IR libpngpf(3) ", " png(5) .LP .IR libpng : .IP -http://libpng.sourceforge.net (follow the [DOWNLOAD] link) +https://libpng.sourceforge.io/ (follow the [DOWNLOAD] link) http://www.libpng.org/pub/png .LP @@ -6071,7 +6061,7 @@ http://www.libpng.org/pub/png .I libpng or at .br -ftp://ftp.info-zip.org/pub/infozip/zlib +https://zlib.net/ .LP .IR PNG specification: RFC 2083 @@ -6080,11 +6070,11 @@ ftp://ftp.info-zip.org/pub/infozip/zlib .I libpng or at .br -ftp://ds.internic.net/rfc/rfc2083.txt +https://www.ietf.org/rfc/rfc2083.txt .br or (as a W3C Recommendation) at .br -http://www.w3.org/TR/REC-png.html +https://www.w3.org/TR/REC-png.html .LP In the case of any inconsistency between the PNG specification @@ -6100,7 +6090,7 @@ possible without all of you. Thanks to Frank J. T. Wojcik for helping with the documentation. -Libpng version 1.6.17 - March 26, 2015: +Libpng version 1.6.34 - September 29, 2017: Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc. Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). @@ -6112,56 +6102,63 @@ png-mng-implement at lists.sourceforge.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe). -.SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: +.SH NOTICES: -(This copy of the libpng notices is provided for your convenience. In case of +This copy of the libpng notices is provided for your convenience. In case of any discrepancy between this copy and the notices in the file png.h that is -included in the libpng distribution, the latter shall prevail.) +included in the libpng distribution, the latter shall prevail. + +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: If you modify libpng you may insert additional notices immediately following this sentence. This code is released under the libpng license. -libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are -Copyright (c) 2004,2006-2015 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.2.5 -with the following individual added to the list of Contributing Authors - - Cosmin Truta - -libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are -Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are -distributed according to the same disclaimer and license as libpng-1.0.6 -with the following individuals added to the list of Contributing Authors +libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are +Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are +derived from libpng-1.0.6, and are distributed according to the same +disclaimer and license as libpng-1.0.6 with the following individuals +added to the list of Contributing Authors: Simon-Pierre Cadieux Eric S. Raymond + Mans Rullgard + Cosmin Truta Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov and with the following additions to the disclaimer: - There is no warranty against interference with your - enjoyment of the library or against infringement. - There is no warranty that our efforts or the library - will fulfill any of your particular purposes or needs. - This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and - effort is with the user. + There is no warranty against interference with your enjoyment of the + library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is with + the user. + +Some files in the "contrib" directory and some configure-generated +files that are distributed with libpng have other copyright owners and +are released under other open source licenses. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are -Copyright (c) 1998, 1999 Glenn Randers-Pehrson -Distributed according to the same disclaimer and license as libpng-0.96, -with the following individuals added to the list of Contributing Authors: +Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from +libpng-0.96, and are distributed according to the same disclaimer and +license as libpng-0.96, with the following individuals added to the list +of Contributing Authors: Tom Lane Glenn Randers-Pehrson Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are -Copyright (c) 1996, 1997 Andreas Dilger -Distributed according to the same disclaimer and license as libpng-0.88, -with the following individuals added to the list of Contributing Authors: +Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, +and are distributed according to the same disclaimer and license as +libpng-0.88, with the following individuals added to the list of +Contributing Authors: John Bowler Kevin Bracey @@ -6170,8 +6167,11 @@ with the following individuals added to the list of Contributing Authors: Greg Roelofs Tom Tanner +Some files in the "scripts" directory have other copyright owners +but are released under this license. + libpng versions 0.5, May 1995, through 0.88, January 1996, are -Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. +Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: @@ -6194,13 +6194,13 @@ Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: -1. The origin of this source code must not be misrepresented. + 1. The origin of this source code must not be misrepresented. -2. Altered versions must be plainly marked as such and - must not be misrepresented as being the original source. + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. -3. This Copyright notice may not be removed or altered from - any source or altered source distribution. + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to @@ -6208,21 +6208,42 @@ supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. +END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. + +TRADEMARK: + +The name "libpng" has not been registered by the Copyright owner +as a trademark in any jurisdiction. However, because libpng has +been distributed and maintained world-wide, continually since 1995, +the Copyright owner claims "common-law trademark protection" in any +jurisdiction where common-law trademark is recognized. + +OSI CERTIFICATION: + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is +a certification mark of the Open Source Initiative. OSI has not addressed +the additional disclaimers inserted at version 1.0.7. + +EXPORT CONTROL: + +The Copyright owner believes that the Export Control Classification +Number (ECCN) for libpng is EAR99, which means not subject to export +controls or International Traffic in Arms Regulations (ITAR) because +it is open source, publicly available software, that does not contain +any encryption software. See the EAR, paragraphs 734.3(b)(3) and +734.7(b). A "png_get_copyright" function is available, for convenient use in "about" boxes and the like: - printf("%s",png_get_copyright(NULL)); + printf("%s", png_get_copyright(NULL)); Also, the PNG logo (in PNG format, of course) is supplied in the files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). -Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a -certification mark of the Open Source Initiative. - Glenn Randers-Pehrson glennrp at users.sourceforge.net -March 26, 2015 +September 29, 2017 .\" end of man page diff --git a/src/third-party/libpng/libpng.pc.in b/src/third-party/libpng/libpng.pc.in index 3e7e2c58a..9708e9af2 100644 --- a/src/third-party/libpng/libpng.pc.in +++ b/src/third-party/libpng/libpng.pc.in @@ -6,6 +6,7 @@ includedir=@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ Name: libpng Description: Loads and saves PNG files Version: @PNGLIB_VERSION@ +Requires: zlib Libs: -L${libdir} -lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ Libs.private: @LIBS@ Cflags: -I${includedir} diff --git a/src/third-party/libpng/libpngpf.3 b/src/third-party/libpng/libpngpf.3 index d0dd5be57..8cea87a71 100644 --- a/src/third-party/libpng/libpngpf.3 +++ b/src/third-party/libpng/libpngpf.3 @@ -1,11 +1,11 @@ -.TH LIBPNGPF 3 "March 26, 2015" +.TH LIBPNGPF 3 "April 1, 2017" .SH NAME -libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17 +libpng \- Portable Network Graphics (PNG) Reference Library 1.6.34 (private functions) .SH SYNOPSIS -\fB#include \fI"pngpriv.h" +\fB\fB#include \fI\fI"pngpriv.h" -\fBAs of libpng version \fP\fI1.5.1\fP\fB, this section is no longer \fP\fImaintained\fP\fB, now that the private function prototypes are hidden in pngpriv.h and not accessible to applications. Look in pngpriv.h for the prototypes and a short description of each \fIfunction. +\fB\fBAs of libpng version \fP\fI\fP\fI1.5.1\fP\fB\fP\fB, this section is no longer \fP\fI\fP\fImaintained\fP\fB\fP\fB, now that the private function prototypes are hidden in pngpriv.h and not accessible to applications. Look in pngpriv.h for the prototypes and a short description of each \fI\fIfunction. .SH DESCRIPTION The functions previously listed here are used privately by libpng and are not diff --git a/src/third-party/libpng/ltmain.sh b/src/third-party/libpng/ltmain.sh old mode 100644 new mode 100755 diff --git a/src/third-party/libpng/mips/filter_msa_intrinsics.c b/src/third-party/libpng/mips/filter_msa_intrinsics.c new file mode 100644 index 000000000..943bb3d05 --- /dev/null +++ b/src/third-party/libpng/mips/filter_msa_intrinsics.c @@ -0,0 +1,807 @@ + +/* filter_msa_intrinsics.c - MSA optimised filter functions + * + * Copyright (c) 2016 Glenn Randers-Pehrson + * Written by Mandar Sahastrabuddhe, August 2016. + * Last changed in libpng 1.6.25 [September 1, 2016] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ +#include +#include +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* This code requires -mfpu=msa on the command line: */ +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ + +#include + +/* libpng row pointers are not necessarily aligned to any particular boundary, + * however this code will only work with appropriate alignment. mips/mips_init.c + * checks for this (and will not compile unless it is done). This code uses + * variants of png_aligncast to avoid compiler warnings. + */ +#define png_ptr(type,pointer) png_aligncast(type *,pointer) +#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) + +/* The following relies on a variable 'temp_pointer' being declared with type + * 'type'. This is written this way just to hide the GCC strict aliasing + * warning; note that the code is safe because there never is an alias between + * the input and output pointers. + */ +#define png_ldr(type,pointer)\ + (temp_pointer = png_ptr(type,pointer), *temp_pointer) + +#if PNG_MIPS_MSA_OPT > 0 + +#ifdef CLANG_BUILD + #define MSA_SRLI_B(a, b) __msa_srli_b((v16i8) a, b) + + #define LW(psrc) \ + ( { \ + uint8_t *psrc_lw_m = (uint8_t *) (psrc); \ + uint32_t val_m; \ + \ + asm volatile ( \ + "lw %[val_m], %[psrc_lw_m] \n\t" \ + \ + : [val_m] "=r" (val_m) \ + : [psrc_lw_m] "m" (*psrc_lw_m) \ + ); \ + \ + val_m; \ + } ) + + #define SH(val, pdst) \ + { \ + uint8_t *pdst_sh_m = (uint8_t *) (pdst); \ + uint16_t val_m = (val); \ + \ + asm volatile ( \ + "sh %[val_m], %[pdst_sh_m] \n\t" \ + \ + : [pdst_sh_m] "=m" (*pdst_sh_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + + #define SW(val, pdst) \ + { \ + uint8_t *pdst_sw_m = (uint8_t *) (pdst); \ + uint32_t val_m = (val); \ + \ + asm volatile ( \ + "sw %[val_m], %[pdst_sw_m] \n\t" \ + \ + : [pdst_sw_m] "=m" (*pdst_sw_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + + #if (__mips == 64) + #define SD(val, pdst) \ + { \ + uint8_t *pdst_sd_m = (uint8_t *) (pdst); \ + uint64_t val_m = (val); \ + \ + asm volatile ( \ + "sd %[val_m], %[pdst_sd_m] \n\t" \ + \ + : [pdst_sd_m] "=m" (*pdst_sd_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + #else + #define SD(val, pdst) \ + { \ + uint8_t *pdst_sd_m = (uint8_t *) (pdst); \ + uint32_t val0_m, val1_m; \ + \ + val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \ + val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \ + \ + SW(val0_m, pdst_sd_m); \ + SW(val1_m, pdst_sd_m + 4); \ + } + #endif +#else + #define MSA_SRLI_B(a, b) (a >> b) + +#if (__mips_isa_rev >= 6) + #define LW(psrc) \ + ( { \ + uint8_t *psrc_lw_m = (uint8_t *) (psrc); \ + uint32_t val_m; \ + \ + asm volatile ( \ + "lw %[val_m], %[psrc_lw_m] \n\t" \ + \ + : [val_m] "=r" (val_m) \ + : [psrc_lw_m] "m" (*psrc_lw_m) \ + ); \ + \ + val_m; \ + } ) + + #define SH(val, pdst) \ + { \ + uint8_t *pdst_sh_m = (uint8_t *) (pdst); \ + uint16_t val_m = (val); \ + \ + asm volatile ( \ + "sh %[val_m], %[pdst_sh_m] \n\t" \ + \ + : [pdst_sh_m] "=m" (*pdst_sh_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + + #define SW(val, pdst) \ + { \ + uint8_t *pdst_sw_m = (uint8_t *) (pdst); \ + uint32_t val_m = (val); \ + \ + asm volatile ( \ + "sw %[val_m], %[pdst_sw_m] \n\t" \ + \ + : [pdst_sw_m] "=m" (*pdst_sw_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + + #if (__mips == 64) + #define SD(val, pdst) \ + { \ + uint8_t *pdst_sd_m = (uint8_t *) (pdst); \ + uint64_t val_m = (val); \ + \ + asm volatile ( \ + "sd %[val_m], %[pdst_sd_m] \n\t" \ + \ + : [pdst_sd_m] "=m" (*pdst_sd_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + #else + #define SD(val, pdst) \ + { \ + uint8_t *pdst_sd_m = (uint8_t *) (pdst); \ + uint32_t val0_m, val1_m; \ + \ + val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \ + val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \ + \ + SW(val0_m, pdst_sd_m); \ + SW(val1_m, pdst_sd_m + 4); \ + } + #endif +#else // !(__mips_isa_rev >= 6) + #define LW(psrc) \ + ( { \ + uint8_t *psrc_lw_m = (uint8_t *) (psrc); \ + uint32_t val_m; \ + \ + asm volatile ( \ + "ulw %[val_m], %[psrc_lw_m] \n\t" \ + \ + : [val_m] "=r" (val_m) \ + : [psrc_lw_m] "m" (*psrc_lw_m) \ + ); \ + \ + val_m; \ + } ) + + #define SH(val, pdst) \ + { \ + uint8_t *pdst_sh_m = (uint8_t *) (pdst); \ + uint16_t val_m = (val); \ + \ + asm volatile ( \ + "ush %[val_m], %[pdst_sh_m] \n\t" \ + \ + : [pdst_sh_m] "=m" (*pdst_sh_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + + #define SW(val, pdst) \ + { \ + uint8_t *pdst_sw_m = (uint8_t *) (pdst); \ + uint32_t val_m = (val); \ + \ + asm volatile ( \ + "usw %[val_m], %[pdst_sw_m] \n\t" \ + \ + : [pdst_sw_m] "=m" (*pdst_sw_m) \ + : [val_m] "r" (val_m) \ + ); \ + } + + #define SD(val, pdst) \ + { \ + uint8_t *pdst_sd_m = (uint8_t *) (pdst); \ + uint32_t val0_m, val1_m; \ + \ + val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \ + val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \ + \ + SW(val0_m, pdst_sd_m); \ + SW(val1_m, pdst_sd_m + 4); \ + } + + #define SW_ZERO(pdst) \ + { \ + uint8_t *pdst_m = (uint8_t *) (pdst); \ + \ + asm volatile ( \ + "usw $0, %[pdst_m] \n\t" \ + \ + : [pdst_m] "=m" (*pdst_m) \ + : \ + ); \ + } +#endif // (__mips_isa_rev >= 6) +#endif + +#define LD_B(RTYPE, psrc) *((RTYPE *) (psrc)) +#define LD_UB(...) LD_B(v16u8, __VA_ARGS__) +#define LD_B2(RTYPE, psrc, stride, out0, out1) \ +{ \ + out0 = LD_B(RTYPE, (psrc)); \ + out1 = LD_B(RTYPE, (psrc) + stride); \ +} +#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__) +#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) \ +{ \ + LD_B2(RTYPE, (psrc), stride, out0, out1); \ + LD_B2(RTYPE, (psrc) + 2 * stride , stride, out2, out3); \ +} +#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__) + +#define ST_B(RTYPE, in, pdst) *((RTYPE *) (pdst)) = (in) +#define ST_UB(...) ST_B(v16u8, __VA_ARGS__) +#define ST_B2(RTYPE, in0, in1, pdst, stride) \ +{ \ + ST_B(RTYPE, in0, (pdst)); \ + ST_B(RTYPE, in1, (pdst) + stride); \ +} +#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__) +#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) \ +{ \ + ST_B2(RTYPE, in0, in1, (pdst), stride); \ + ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \ +} +#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__) + +#define ADD2(in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = in0 + in1; \ + out1 = in2 + in3; \ +} +#define ADD3(in0, in1, in2, in3, in4, in5, \ + out0, out1, out2) \ +{ \ + ADD2(in0, in1, in2, in3, out0, out1); \ + out2 = in4 + in5; \ +} +#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, \ + out0, out1, out2, out3) \ +{ \ + ADD2(in0, in1, in2, in3, out0, out1); \ + ADD2(in4, in5, in6, in7, out2, out3); \ +} + +#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1); \ + out1 = (RTYPE) __msa_ilvr_b((v16i8) in2, (v16i8) in3); \ +} +#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__) + +#define HSUB_UB2(RTYPE, in0, in1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_hsub_u_h((v16u8) in0, (v16u8) in0); \ + out1 = (RTYPE) __msa_hsub_u_h((v16u8) in1, (v16u8) in1); \ +} +#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__) + +#define SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val) \ +{ \ + v16i8 zero_m = { 0 }; \ + out0 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in0, slide_val); \ + out1 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in1, slide_val); \ +} +#define SLDI_B2_0_UB(...) SLDI_B2_0(v16u8, __VA_ARGS__) + +#define SLDI_B3_0(RTYPE, in0, in1, in2, out0, out1, out2, slide_val) \ +{ \ + v16i8 zero_m = { 0 }; \ + SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val); \ + out2 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in2, slide_val); \ +} +#define SLDI_B3_0_UB(...) SLDI_B3_0(v16u8, __VA_ARGS__) + +#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_ilvev_w((v4i32) in1, (v4i32) in0); \ + out1 = (RTYPE) __msa_ilvev_w((v4i32) in3, (v4i32) in2); \ +} +#define ILVEV_W2_UB(...) ILVEV_W2(v16u8, __VA_ARGS__) + +#define ADD_ABS_H3(RTYPE, in0, in1, in2, out0, out1, out2) \ +{ \ + RTYPE zero = {0}; \ + \ + out0 = __msa_add_a_h((v8i16) zero, in0); \ + out1 = __msa_add_a_h((v8i16) zero, in1); \ + out2 = __msa_add_a_h((v8i16) zero, in2); \ +} +#define ADD_ABS_H3_SH(...) ADD_ABS_H3(v8i16, __VA_ARGS__) + +#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \ +{ \ + out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0); \ + out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2); \ +} +#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__) + +#define CMP_AND_SELECT(inp0, inp1, inp2, inp3, inp4, inp5, out0) \ +{ \ + v8i16 _sel_h0, _sel_h1; \ + v16u8 _sel_b0, _sel_b1; \ + _sel_h0 = (v8i16) __msa_clt_u_h((v8u16) inp1, (v8u16) inp0); \ + _sel_b0 = (v16u8) __msa_pckev_b((v16i8) _sel_h0, (v16i8) _sel_h0); \ + inp0 = (v8i16) __msa_bmnz_v((v16u8) inp0, (v16u8) inp1, (v16u8) _sel_h0); \ + inp4 = (v16u8) __msa_bmnz_v(inp3, inp4, _sel_b0); \ + _sel_h1 = (v8i16) __msa_clt_u_h((v8u16) inp2, (v8u16) inp0); \ + _sel_b1 = (v16u8) __msa_pckev_b((v16i8) _sel_h1, (v16i8) _sel_h1); \ + inp4 = (v16u8) __msa_bmnz_v(inp4, inp5, _sel_b1); \ + out0 += inp4; \ +} + +void png_read_filter_row_up_msa(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i, cnt, cnt16, cnt32; + png_size_t istop = row_info->rowbytes; + png_bytep rp = row; + png_const_bytep pp = prev_row; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7; + + for (i = 0; i < (istop >> 6); i++) + { + LD_UB4(rp, 16, src0, src1, src2, src3); + LD_UB4(pp, 16, src4, src5, src6, src7); + pp += 64; + + ADD4(src0, src4, src1, src5, src2, src6, src3, src7, + src0, src1, src2, src3); + + ST_UB4(src0, src1, src2, src3, rp, 16); + rp += 64; + } + + if (istop & 0x3F) + { + cnt32 = istop & 0x20; + cnt16 = istop & 0x10; + cnt = istop & 0xF; + + if(cnt32) + { + if (cnt16 && cnt) + { + LD_UB4(rp, 16, src0, src1, src2, src3); + LD_UB4(pp, 16, src4, src5, src6, src7); + + ADD4(src0, src4, src1, src5, src2, src6, src3, src7, + src0, src1, src2, src3); + + ST_UB4(src0, src1, src2, src3, rp, 16); + rp += 64; + } + else if (cnt16 || cnt) + { + LD_UB2(rp, 16, src0, src1); + LD_UB2(pp, 16, src4, src5); + pp += 32; + src2 = LD_UB(rp + 32); + src6 = LD_UB(pp); + + ADD3(src0, src4, src1, src5, src2, src6, src0, src1, src2); + + ST_UB2(src0, src1, rp, 16); + rp += 32; + ST_UB(src2, rp); + rp += 16; + } + else + { + LD_UB2(rp, 16, src0, src1); + LD_UB2(pp, 16, src4, src5); + + ADD2(src0, src4, src1, src5, src0, src1); + + ST_UB2(src0, src1, rp, 16); + rp += 32; + } + } + else if (cnt16 && cnt) + { + LD_UB2(rp, 16, src0, src1); + LD_UB2(pp, 16, src4, src5); + + ADD2(src0, src4, src1, src5, src0, src1); + + ST_UB2(src0, src1, rp, 16); + rp += 32; + } + else if (cnt16 || cnt) + { + src0 = LD_UB(rp); + src4 = LD_UB(pp); + pp += 16; + + src0 += src4; + + ST_UB(src0, rp); + rp += 16; + } + } +} + +void png_read_filter_row_sub4_msa(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t count; + png_size_t istop = row_info->rowbytes; + png_bytep src = row; + png_bytep nxt = row + 4; + int32_t inp0; + v16u8 src0, src1, src2, src3, src4; + v16u8 dst0, dst1; + v16u8 zero = { 0 }; + + istop -= 4; + + inp0 = LW(src); + src += 4; + src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0); + + for (count = 0; count < istop; count += 16) + { + src1 = LD_UB(src); + src += 16; + + src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 4); + src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 8); + src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 12); + src1 += src0; + src2 += src1; + src3 += src2; + src4 += src3; + src0 = src4; + ILVEV_W2_UB(src1, src2, src3, src4, dst0, dst1); + dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0); + + ST_UB(dst0, nxt); + nxt += 16; + } +} + +void png_read_filter_row_sub3_msa(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t count; + png_size_t istop = row_info->rowbytes; + png_bytep src = row; + png_bytep nxt = row + 3; + int64_t out0; + int32_t inp0, out1; + v16u8 src0, src1, src2, src3, src4, dst0, dst1; + v16u8 zero = { 0 }; + v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 }; + + istop -= 3; + + inp0 = LW(src); + src += 3; + src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0); + + for (count = 0; count < istop; count += 12) + { + src1 = LD_UB(src); + src += 12; + + src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 3); + src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 6); + src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 9); + src1 += src0; + src2 += src1; + src3 += src2; + src4 += src3; + src0 = src4; + VSHF_B2_UB(src1, src2, src3, src4, mask0, mask0, dst0, dst1); + dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0); + out0 = __msa_copy_s_d((v2i64) dst0, 0); + out1 = __msa_copy_s_w((v4i32) dst0, 2); + + SD(out0, nxt); + nxt += 8; + SW(out1, nxt); + nxt += 4; + } +} + +void png_read_filter_row_avg4_msa(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_bytep src = row; + png_bytep nxt = row; + png_const_bytep pp = prev_row; + png_size_t istop = row_info->rowbytes - 4; + int32_t inp0, inp1, out0; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1; + v16u8 zero = { 0 }; + + inp0 = LW(pp); + pp += 4; + inp1 = LW(src); + src += 4; + src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0); + src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1); + src0 = (v16u8) MSA_SRLI_B(src0, 1); + src1 += src0; + out0 = __msa_copy_s_w((v4i32) src1, 0); + SW(out0, nxt); + nxt += 4; + + for (i = 0; i < istop; i += 16) + { + src2 = LD_UB(pp); + pp += 16; + src6 = LD_UB(src); + src += 16; + + SLDI_B2_0_UB(src2, src6, src3, src7, 4); + SLDI_B2_0_UB(src2, src6, src4, src8, 8); + SLDI_B2_0_UB(src2, src6, src5, src9, 12); + src2 = __msa_ave_u_b(src2, src1); + src6 += src2; + src3 = __msa_ave_u_b(src3, src6); + src7 += src3; + src4 = __msa_ave_u_b(src4, src7); + src8 += src4; + src5 = __msa_ave_u_b(src5, src8); + src9 += src5; + src1 = src9; + ILVEV_W2_UB(src6, src7, src8, src9, dst0, dst1); + dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0); + + ST_UB(dst0, nxt); + nxt += 16; + } +} + +void png_read_filter_row_avg3_msa(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_size_t i; + png_bytep src = row; + png_bytep nxt = row; + png_const_bytep pp = prev_row; + png_size_t istop = row_info->rowbytes - 3; + int64_t out0; + int32_t inp0, inp1, out1; + int16_t out2; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1; + v16u8 zero = { 0 }; + v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 }; + + inp0 = LW(pp); + pp += 3; + inp1 = LW(src); + src += 3; + src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0); + src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1); + src0 = (v16u8) MSA_SRLI_B(src0, 1); + src1 += src0; + out2 = __msa_copy_s_h((v8i16) src1, 0); + SH(out2, nxt); + nxt += 2; + nxt[0] = src1[2]; + nxt++; + + for (i = 0; i < istop; i += 12) + { + src2 = LD_UB(pp); + pp += 12; + src6 = LD_UB(src); + src += 12; + + SLDI_B2_0_UB(src2, src6, src3, src7, 3); + SLDI_B2_0_UB(src2, src6, src4, src8, 6); + SLDI_B2_0_UB(src2, src6, src5, src9, 9); + src2 = __msa_ave_u_b(src2, src1); + src6 += src2; + src3 = __msa_ave_u_b(src3, src6); + src7 += src3; + src4 = __msa_ave_u_b(src4, src7); + src8 += src4; + src5 = __msa_ave_u_b(src5, src8); + src9 += src5; + src1 = src9; + VSHF_B2_UB(src6, src7, src8, src9, mask0, mask0, dst0, dst1); + dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0); + out0 = __msa_copy_s_d((v2i64) dst0, 0); + out1 = __msa_copy_s_w((v4i32) dst0, 2); + + SD(out0, nxt); + nxt += 8; + SW(out1, nxt); + nxt += 4; + } +} + +void png_read_filter_row_paeth4_msa(png_row_infop row_info, + png_bytep row, + png_const_bytep prev_row) +{ + int32_t count, rp_end; + png_bytep nxt; + png_const_bytep prev_nxt; + int32_t inp0, inp1, res0; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9; + v16u8 src10, src11, src12, src13, dst0, dst1; + v8i16 vec0, vec1, vec2; + v16u8 zero = { 0 }; + + nxt = row; + prev_nxt = prev_row; + + inp0 = LW(nxt); + inp1 = LW(prev_nxt); + prev_nxt += 4; + src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0); + src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1); + + src1 += src0; + res0 = __msa_copy_s_w((v4i32) src1, 0); + + SW(res0, nxt); + nxt += 4; + + /* Remainder */ + rp_end = row_info->rowbytes - 4; + + for (count = 0; count < rp_end; count += 16) + { + src2 = LD_UB(prev_nxt); + prev_nxt += 16; + src6 = LD_UB(prev_row); + prev_row += 16; + src10 = LD_UB(nxt); + + SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 4); + SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 8); + SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 12); + ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10); + ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11); + ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12); + ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13); + src1 = src13; + ILVEV_W2_UB(src10, src11, src12, src1, dst0, dst1); + dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0); + + ST_UB(dst0, nxt); + nxt += 16; + } +} + +void png_read_filter_row_paeth3_msa(png_row_infop row_info, + png_bytep row, + png_const_bytep prev_row) +{ + int32_t count, rp_end; + png_bytep nxt; + png_const_bytep prev_nxt; + int64_t out0; + int32_t inp0, inp1, out1; + int16_t out2; + v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1; + v16u8 src10, src11, src12, src13; + v8i16 vec0, vec1, vec2; + v16u8 zero = { 0 }; + v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 }; + + nxt = row; + prev_nxt = prev_row; + + inp0 = LW(nxt); + inp1 = LW(prev_nxt); + prev_nxt += 3; + src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0); + src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1); + + src1 += src0; + out2 = __msa_copy_s_h((v8i16) src1, 0); + + SH(out2, nxt); + nxt += 2; + nxt[0] = src1[2]; + nxt++; + + /* Remainder */ + rp_end = row_info->rowbytes - 3; + + for (count = 0; count < rp_end; count += 12) + { + src2 = LD_UB(prev_nxt); + prev_nxt += 12; + src6 = LD_UB(prev_row); + prev_row += 12; + src10 = LD_UB(nxt); + + SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 3); + SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 6); + SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 9); + ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10); + ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11); + ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12); + ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1); + HSUB_UB2_SH(vec0, vec1, vec0, vec1); + vec2 = vec0 + vec1; + ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2); + CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13); + src1 = src13; + VSHF_B2_UB(src10, src11, src12, src13, mask0, mask0, dst0, dst1); + dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0); + out0 = __msa_copy_s_d((v2i64) dst0, 0); + out1 = __msa_copy_s_w((v4i32) dst0, 2); + + SD(out0, nxt); + nxt += 8; + SW(out1, nxt); + nxt += 4; + } +} + +#endif /* PNG_MIPS_MSA_OPT > 0 */ +#endif /* PNG_MIPS_MSA_IMPLEMENTATION == 1 (intrinsics) */ +#endif /* READ */ diff --git a/src/third-party/libpng/mips/mips_init.c b/src/third-party/libpng/mips/mips_init.c new file mode 100644 index 000000000..0bfb7a32e --- /dev/null +++ b/src/third-party/libpng/mips/mips_init.c @@ -0,0 +1,129 @@ + +/* mips_init.c - MSA optimised filter functions + * + * Copyright (c) 2016 Glenn Randers-Pehrson + * Written by Mandar Sahastrabuddhe, 2016. + * Last changed in libpng 1.6.25 [September 1, 2016] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ +/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are + * called. + */ +#define _POSIX_SOURCE 1 + +#include +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#if PNG_MIPS_MSA_OPT > 0 +#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED /* Do run-time checks */ +/* WARNING: it is strongly recommended that you do not build libpng with + * run-time checks for CPU features if at all possible. In the case of the MIPS + * MSA instructions there is no processor-specific way of detecting the + * presence of the required support, therefore run-time detection is extremely + * OS specific. + * + * You may set the macro PNG_MIPS_MSA_FILE to the file name of file containing + * a fragment of C source code which defines the png_have_msa function. There + * are a number of implementations in contrib/mips-msa, but the only one that + * has partial support is contrib/mips-msa/linux.c - a generic Linux + * implementation which reads /proc/cpufino. + */ +#ifndef PNG_MIPS_MSA_FILE +# ifdef __linux__ +# define PNG_MIPS_MSA_FILE "contrib/mips-msa/linux.c" +# endif +#endif + +#ifdef PNG_MIPS_MSA_FILE + +#include /* for sig_atomic_t */ +static int png_have_msa(png_structp png_ptr); +#include PNG_MIPS_MSA_FILE + +#else /* PNG_MIPS_MSA_FILE */ +# error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks" +#endif /* PNG_MIPS_MSA_FILE */ +#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */ + +#ifndef PNG_ALIGNED_MEMORY_SUPPORTED +# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" +#endif + +void +png_init_filter_functions_msa(png_structp pp, unsigned int bpp) +{ + /* The switch statement is compiled in for MIPS_MSA_API, the call to + * png_have_msa is compiled in for MIPS_MSA_CHECK. If both are defined + * the check is only performed if the API has not set the MSA option on + * or off explicitly. In this case the check controls what happens. + */ + +#ifdef PNG_MIPS_MSA_API_SUPPORTED + switch ((pp->options >> PNG_MIPS_MSA) & 3) + { + case PNG_OPTION_UNSET: + /* Allow the run-time check to execute if it has been enabled - + * thus both API and CHECK can be turned on. If it isn't supported + * this case will fall through to the 'default' below, which just + * returns. + */ +#endif /* PNG_MIPS_MSA_API_SUPPORTED */ +#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED + { + static volatile sig_atomic_t no_msa = -1; /* not checked */ + + if (no_msa < 0) + no_msa = !png_have_msa(pp); + + if (no_msa) + return; + } +#ifdef PNG_MIPS_MSA_API_SUPPORTED + break; +#endif +#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */ + +#ifdef PNG_MIPS_MSA_API_SUPPORTED + default: /* OFF or INVALID */ + return; + + case PNG_OPTION_ON: + /* Option turned on */ + break; + } +#endif + + /* IMPORTANT: any new external functions used here must be declared using + * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the + * 'prefix' option to configure works: + * + * ./configure --with-libpng-prefix=foobar_ + * + * Verify you have got this right by running the above command, doing a build + * and examining pngprefix.h; it must contain a #define for every external + * function you add. (Notice that this happens automatically for the + * initialization function.) + */ + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_msa; + + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_msa; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_msa; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_msa; + } + + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_msa; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_msa; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_msa; + } +} +#endif /* PNG_MIPS_MSA_OPT > 0 */ +#endif /* READ */ diff --git a/src/third-party/libpng/png.5 b/src/third-party/libpng/png.5 index 10c4c3cb1..b0cbd2cfa 100644 --- a/src/third-party/libpng/png.5 +++ b/src/third-party/libpng/png.5 @@ -1,4 +1,4 @@ -.TH PNG 5 "March 26, 2015" +.TH PNG 5 "April 1, 2017" .SH NAME png \- Portable Network Graphics (PNG) format .SH DESCRIPTION @@ -23,11 +23,11 @@ platforms. PNG specification (second edition), November 2003: .IP .br - 8) + if (num_bytes < 0) + nb = 0; + + if (nb > 8) png_error(png_ptr, "Too many bytes for PNG signature"); - png_ptr->sig_bytes = (png_byte)((num_bytes < 0 ? 0 : num_bytes) & 0xff); + png_ptr->sig_bytes = (png_byte)nb; } /* Checks whether the supplied bytes match the PNG signature. We allow @@ -80,7 +105,7 @@ png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) if (items >= (~(png_alloc_size_t)0)/size) { png_warning (png_voidcast(png_structrp, png_ptr), - "Potential overflow in png_zalloc()"); + "Potential overflow in png_zalloc()"); return NULL; } @@ -101,7 +126,7 @@ png_zfree(voidpf png_ptr, voidpf ptr) void /* PRIVATE */ png_reset_crc(png_structrp png_ptr) { - /* The cast is safe because the crc is a 32 bit value. */ + /* The cast is safe because the crc is a 32-bit value. */ png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); } @@ -129,7 +154,7 @@ png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length) } /* 'uLong' is defined in zlib.h as unsigned long; this means that on some - * systems it is a 64 bit value. crc32, however, returns 32 bits so the + * systems it is a 64-bit value. crc32, however, returns 32 bits so the * following cast is safe. 'uInt' may be no more than 16 bits, so it is * necessary to perform a loop here. */ @@ -167,10 +192,10 @@ png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length) int png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) { - /* Libpng versions 1.0.0 and later are binary compatible if the version - * string matches through the second '.'; we must recompile any - * applications that use any older library version. - */ + /* Libpng versions 1.0.0 and later are binary compatible if the version + * string matches through the second '.'; we must recompile any + * applications that use any older library version. + */ if (user_png_ver != NULL) { @@ -243,15 +268,15 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, create_struct.user_height_max = PNG_USER_HEIGHT_MAX; # ifdef PNG_USER_CHUNK_CACHE_MAX - /* Added at libpng-1.2.43 and 1.4.0 */ - create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; + /* Added at libpng-1.2.43 and 1.4.0 */ + create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; # endif # ifdef PNG_USER_CHUNK_MALLOC_MAX - /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists - * in png_struct regardless. - */ - create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; + /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists + * in png_struct regardless. + */ + create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; # endif # endif @@ -275,7 +300,9 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, # ifdef PNG_SETJMP_SUPPORTED if (!setjmp(create_jmp_buf)) +# endif { +# ifdef PNG_SETJMP_SUPPORTED /* Temporarily fake out the longjmp information until we have * successfully completed this function. This only works if we have * setjmp() support compiled in, but it is safe - this stuff should @@ -284,15 +311,13 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, create_struct.jmp_buf_ptr = &create_jmp_buf; create_struct.jmp_buf_size = 0; /*stack allocation*/ create_struct.longjmp_fn = longjmp; -# else - { # endif /* Call the general version checker (shared with read and write code): */ if (png_user_version_check(&create_struct, user_png_ver) != 0) { png_structrp png_ptr = png_voidcast(png_structrp, - png_malloc_warn(&create_struct, (sizeof *png_ptr))); + png_malloc_warn(&create_struct, (sizeof *png_ptr))); if (png_ptr != NULL) { @@ -304,10 +329,10 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, create_struct.zstream.opaque = png_ptr; # ifdef PNG_SETJMP_SUPPORTED - /* Eliminate the local error handling: */ - create_struct.jmp_buf_ptr = NULL; - create_struct.jmp_buf_size = 0; - create_struct.longjmp_fn = 0; + /* Eliminate the local error handling: */ + create_struct.jmp_buf_ptr = NULL; + create_struct.jmp_buf_size = 0; + create_struct.longjmp_fn = 0; # endif *png_ptr = create_struct; @@ -341,7 +366,7 @@ png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) * has always been done in 'example.c'. */ info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, - (sizeof *info_ptr))); + (sizeof *info_ptr))); if (info_ptr != NULL) memset(info_ptr, 0, (sizeof *info_ptr)); @@ -397,7 +422,7 @@ png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) */ PNG_FUNCTION(void,PNGAPI png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), - PNG_DEPRECATED) + PNG_DEPRECATED) { png_inforp info_ptr = *ptr_ptr; @@ -412,7 +437,9 @@ png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), /* The following line is why this API should not be used: */ free(info_ptr); info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, - (sizeof *info_ptr))); + (sizeof *info_ptr))); + if (info_ptr == NULL) + return; *ptr_ptr = info_ptr; } @@ -423,7 +450,7 @@ png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), /* The following API is not called internally */ void PNGAPI png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, - int freer, png_uint_32 mask) + int freer, png_uint_32 mask) { png_debug(1, "in png_data_freer"); @@ -442,7 +469,7 @@ png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, void PNGAPI png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, - int num) + int num) { png_debug(1, "in png_free_data"); @@ -451,7 +478,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, #ifdef PNG_TEXT_SUPPORTED /* Free text item num or (if num == -1) all text items */ - if (info_ptr->text != 0 && + if (info_ptr->text != NULL && ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0) { if (num != -1) @@ -470,6 +497,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, png_free(png_ptr, info_ptr->text); info_ptr->text = NULL; info_ptr->num_text = 0; + info_ptr->max_text = 0; } } #endif @@ -534,7 +562,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, #ifdef PNG_sPLT_SUPPORTED /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ - if (info_ptr->splt_palettes != 0 && + if (info_ptr->splt_palettes != NULL && ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0) { if (num != -1) @@ -564,7 +592,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, #endif #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks != 0 && + if (info_ptr->unknown_chunks != NULL && ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0) { if (num != -1) @@ -587,6 +615,26 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, } #endif +#ifdef PNG_eXIf_SUPPORTED + /* Free any eXIf entry */ + if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0) + { +# ifdef PNG_READ_eXIf_SUPPORTED + if (info_ptr->eXIf_buf) + { + png_free(png_ptr, info_ptr->eXIf_buf); + info_ptr->eXIf_buf = NULL; + } +# endif + if (info_ptr->exif) + { + png_free(png_ptr, info_ptr->exif); + info_ptr->exif = NULL; + } + info_ptr->valid &= ~PNG_INFO_eXIf; + } +#endif + #ifdef PNG_hIST_SUPPORTED /* Free any hIST entry */ if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0) @@ -610,7 +658,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, /* Free any image bits attached to the info structure */ if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0) { - if (info_ptr->row_pointers != 0) + if (info_ptr->row_pointers != NULL) { png_uint_32 row; for (row = 0; row < info_ptr->height; row++) @@ -664,19 +712,20 @@ png_init_io(png_structrp png_ptr, png_FILE_p fp) # endif # ifdef PNG_SAVE_INT_32_SUPPORTED -/* The png_save_int_32 function assumes integers are stored in two's - * complement format. If this isn't the case, then this routine needs to - * be modified to write data in two's complement format. Note that, - * the following works correctly even if png_int_32 has more than 32 bits - * (compare the more complex code required on read for sign extension.) +/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90 + * defines a cast of a signed integer to an unsigned integer either to preserve + * the value, if it is positive, or to calculate: + * + * (UNSIGNED_MAX+1) + integer + * + * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the + * negative integral value is added the result will be an unsigned value + * correspnding to the 2's complement representation. */ void PNGAPI png_save_int_32(png_bytep buf, png_int_32 i) { - buf[0] = (png_byte)((i >> 24) & 0xff); - buf[1] = (png_byte)((i >> 16) & 0xff); - buf[2] = (png_byte)((i >> 8) & 0xff); - buf[3] = (png_byte)(i & 0xff); + png_save_uint_32(buf, (png_uint_32)i); } # endif @@ -722,6 +771,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) APPEND(':'); APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ + PNG_UNUSED (pos) # undef APPEND # undef APPEND_NUMBER @@ -766,14 +816,15 @@ png_get_copyright(png_const_structrp png_ptr) #else # ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.6.17 - March 26, 2015" PNG_STRING_NEWLINE \ - "Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ - "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ - "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ - PNG_STRING_NEWLINE; + "libpng version 1.6.34 - September 29, 2017" PNG_STRING_NEWLINE \ + "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \ + PNG_STRING_NEWLINE \ + "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ + "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ + PNG_STRING_NEWLINE; # else - return "libpng version 1.6.17 - March 26, 2015\ - Copyright (c) 1998-2015 Glenn Randers-Pehrson\ + return "libpng version 1.6.34 - September 29, 2017\ + Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; # endif @@ -811,9 +862,9 @@ png_get_header_version(png_const_structrp png_ptr) #ifdef __STDC__ return PNG_HEADER_VERSION_STRING # ifndef PNG_READ_SUPPORTED - " (NO READ SUPPORT)" + " (NO READ SUPPORT)" # endif - PNG_STRING_NEWLINE; + PNG_STRING_NEWLINE; #else return PNG_HEADER_VERSION_STRING; #endif @@ -1023,7 +1074,7 @@ png_zstream_error(png_structrp png_ptr, int ret) #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ static int png_colorspace_check_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA, int from) + png_colorspacerp colorspace, png_fixed_point gAMA, int from) /* This is called to check a new gamma value against an existing one. The * routine returns false if the new gamma value should not be written. * @@ -1037,7 +1088,7 @@ png_colorspace_check_gamma(png_const_structrp png_ptr, png_fixed_point gtest; if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || + (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || png_gamma_significant(gtest) != 0)) { /* Either this is an sRGB image, in which case the calculated gamma @@ -1049,7 +1100,7 @@ png_colorspace_check_gamma(png_const_structrp png_ptr, if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) { png_chunk_report(png_ptr, "gamma value does not match sRGB", - PNG_CHUNK_ERROR); + PNG_CHUNK_ERROR); /* Do not overwrite an sRGB value */ return from == 2; } @@ -1057,7 +1108,7 @@ png_colorspace_check_gamma(png_const_structrp png_ptr, else /* sRGB tag not involved */ { png_chunk_report(png_ptr, "gamma value does not match libpng estimate", - PNG_CHUNK_WARNING); + PNG_CHUNK_WARNING); return from == 1; } } @@ -1067,7 +1118,7 @@ png_colorspace_check_gamma(png_const_structrp png_ptr, void /* PRIVATE */ png_colorspace_set_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA) + png_colorspacerp colorspace, png_fixed_point gAMA) { /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't * occur. Since the fixed point representation is asymetrical it is @@ -1086,10 +1137,10 @@ png_colorspace_set_gamma(png_const_structrp png_ptr, errmsg = "gamma value out of range"; # ifdef PNG_READ_gAMA_SUPPORTED - /* Allow the application to set the gamma value more than once */ - else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) - errmsg = "duplicate"; + /* Allow the application to set the gamma value more than once */ + else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) + errmsg = "duplicate"; # endif /* Do nothing if the colorspace is already invalid */ @@ -1130,31 +1181,31 @@ png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) PNG_INFO_iCCP); # ifdef PNG_COLORSPACE_SUPPORTED - /* Clean up the iCCP profile now if it won't be used. */ - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); + /* Clean up the iCCP profile now if it won't be used. */ + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); # else - PNG_UNUSED(png_ptr) + PNG_UNUSED(png_ptr) # endif } else { # ifdef PNG_COLORSPACE_SUPPORTED - /* Leave the INFO_iCCP flag set if the pngset.c code has already set - * it; this allows a PNG to contain a profile which matches sRGB and - * yet still have that profile retrievable by the application. - */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) - info_ptr->valid |= PNG_INFO_sRGB; + /* Leave the INFO_iCCP flag set if the pngset.c code has already set + * it; this allows a PNG to contain a profile which matches sRGB and + * yet still have that profile retrievable by the application. + */ + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) + info_ptr->valid |= PNG_INFO_sRGB; - else - info_ptr->valid &= ~PNG_INFO_sRGB; + else + info_ptr->valid &= ~PNG_INFO_sRGB; - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - info_ptr->valid |= PNG_INFO_cHRM; + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + info_ptr->valid |= PNG_INFO_cHRM; - else - info_ptr->valid &= ~PNG_INFO_cHRM; + else + info_ptr->valid &= ~PNG_INFO_cHRM; # endif if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) @@ -1235,16 +1286,17 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) /* Check xy and, implicitly, z. Note that wide gamut color spaces typically * have end points with 0 tristimulus values (these are impossible end - * points, but they are used to cover the possible colors.) + * points, but they are used to cover the possible colors). We check + * xy->whitey against 5, not 0, to avoid a possible integer overflow. */ - if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; - if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; + if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; + if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; - if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; - if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; + if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; + if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; - if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1; + if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1; /* The reverse calculation is more difficult because the original tristimulus * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 @@ -1624,8 +1676,8 @@ static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ static int png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, - int preferred) + png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, + int preferred) { if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) return 0; @@ -1672,7 +1724,7 @@ png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, int /* PRIVATE */ png_colorspace_set_chromaticities(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, int preferred) + png_colorspacerp colorspace, const png_xy *xy, int preferred) { /* We must check the end points to ensure they are reasonable - in the past * color management systems have crashed as a result of getting bogus @@ -1686,7 +1738,7 @@ png_colorspace_set_chromaticities(png_const_structrp png_ptr, { case 0: /* success */ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, - preferred); + preferred); case 1: /* We can't invert the chromaticities so we can't produce value XYZ @@ -1702,7 +1754,6 @@ png_colorspace_set_chromaticities(png_const_structrp png_ptr, */ colorspace->flags |= PNG_COLORSPACE_INVALID; png_error(png_ptr, "internal error checking chromaticities"); - break; } return 0; /* failed */ @@ -1710,7 +1761,7 @@ png_colorspace_set_chromaticities(png_const_structrp png_ptr, int /* PRIVATE */ png_colorspace_set_endpoints(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) + png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) { png_XYZ XYZ = *XYZ_in; png_xy xy; @@ -1719,7 +1770,7 @@ png_colorspace_set_endpoints(png_const_structrp png_ptr, { case 0: return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, - preferred); + preferred); case 1: /* End points are invalid. */ @@ -1730,7 +1781,6 @@ png_colorspace_set_endpoints(png_const_structrp png_ptr, default: colorspace->flags |= PNG_COLORSPACE_INVALID; png_error(png_ptr, "internal error checking chromaticities"); - break; } return 0; /* failed */ @@ -1777,7 +1827,7 @@ is_ICC_signature(png_alloc_size_t it) static int png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_alloc_size_t value, png_const_charp reason) + png_const_charp name, png_alloc_size_t value, png_const_charp reason) { size_t pos; char message[196]; /* see below for calculation */ @@ -1802,8 +1852,8 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ pos = png_safecat(message, (sizeof message), pos, - png_format_number(number, number+(sizeof number), - PNG_NUMBER_FORMAT_x, value)); + png_format_number(number, number+(sizeof number), + PNG_NUMBER_FORMAT_x, value)); pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ } # endif @@ -1817,7 +1867,7 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, * application errors the PNG won't be written.) */ png_chunk_report(png_ptr, message, - (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); + (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); return 0; } @@ -1826,7 +1876,7 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, #ifdef PNG_sRGB_SUPPORTED int /* PRIVATE */ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, - int intent) + int intent) { /* sRGB sets known gamma, end points and (from the chunk) intent. */ /* IMPORTANT: these are not necessarily the values found in an ICC profile @@ -1863,12 +1913,12 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, */ if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (unsigned)intent, "invalid sRGB rendering intent"); + (png_alloc_size_t)intent, "invalid sRGB rendering intent"); if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && - colorspace->rendering_intent != intent) + colorspace->rendering_intent != intent) return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (unsigned)intent, "inconsistent rendering intents"); + (png_alloc_size_t)intent, "inconsistent rendering intents"); if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) { @@ -1880,8 +1930,8 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, * warn but overwrite the value with the correct one. */ if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && - !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, - 100)) + !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, + 100)) png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", PNG_CHUNK_ERROR); @@ -1889,7 +1939,7 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, * returns true when the 'from' argument corresponds to sRGB (2). */ (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, - 2/*from sRGB*/); + 2/*from sRGB*/); /* intent: bugs in GCC force 'int' to be used as the parameter type. */ colorspace->rendering_intent = (png_uint_16)intent; @@ -1922,21 +1972,54 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, static const png_byte D50_nCIEXYZ[12] = { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; -int /* PRIVATE */ -png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) +static int /* bool */ +icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_charp name, png_uint_32 profile_length) { if (profile_length < 132) return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "too short"); - + "too short"); return 1; } +#ifdef PNG_READ_iCCP_SUPPORTED +int /* PRIVATE */ +png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, + png_const_charp name, png_uint_32 profile_length) +{ + if (!icc_check_length(png_ptr, colorspace, name, profile_length)) + return 0; + + /* This needs to be here because the 'normal' check is in + * png_decompress_chunk, yet this happens after the attempt to + * png_malloc_base the required data. We only need this on read; on write + * the caller supplies the profile buffer so libpng doesn't allocate it. See + * the call to icc_check_length below (the write case). + */ +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + else if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < profile_length) + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, + "exceeds application limits"); +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 + else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length) + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, + "exceeds libpng limits"); +# else /* !SET_USER_LIMITS */ + /* This will get compiled out on all 32-bit and better systems. */ + else if (PNG_SIZE_MAX < profile_length) + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, + "exceeds system limits"); +# endif /* !SET_USER_LIMITS */ + + return 1; +} +#endif /* READ_iCCP */ + int /* PRIVATE */ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile/* first 132 bytes only */, int color_type) + png_const_charp name, png_uint_32 profile_length, + png_const_bytep profile/* first 132 bytes only */, int color_type) { png_uint_32 temp; @@ -1948,18 +2031,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, temp = png_get_uint_32(profile); if (temp != profile_length) return png_icc_profile_error(png_ptr, colorspace, name, temp, - "length does not match profile"); + "length does not match profile"); temp = (png_uint_32) (*(profile+8)); if (temp > 3 && (profile_length & 3)) return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "invalid length"); + "invalid length"); temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ profile_length < 132+12*temp) /* truncated tag table */ return png_icc_profile_error(png_ptr, colorspace, name, temp, - "tag count too large"); + "tag count too large"); /* The 'intent' must be valid or we can't store it, ICC limits the intent to * 16 bits. @@ -1967,14 +2050,14 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, temp = png_get_uint_32(profile+64); if (temp >= 0xffff) /* The ICC limit */ return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid rendering intent"); + "invalid rendering intent"); /* This is just a warning because the profile may be valid in future * versions. */ if (temp >= PNG_sRGB_INTENT_LAST) (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "intent outside defined range"); + "intent outside defined range"); /* At this point the tag table can't be checked because it hasn't necessarily * been loaded; however, various header fields can be checked. These checks @@ -1991,7 +2074,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, temp = png_get_uint_32(profile+36); /* signature 'ascp' */ if (temp != 0x61637370) return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid signature"); + "invalid signature"); /* Currently the PCS illuminant/adopted white point (the computational * white point) are required to be D50, @@ -2002,7 +2085,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, */ if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, - "PCS illuminant is not D50"); + "PCS illuminant is not D50"); /* The PNG spec requires this: * "If the iCCP chunk is present, the image samples conform to the colour @@ -2030,18 +2113,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, case 0x52474220: /* 'RGB ' */ if ((color_type & PNG_COLOR_MASK_COLOR) == 0) return png_icc_profile_error(png_ptr, colorspace, name, temp, - "RGB color space not permitted on grayscale PNG"); + "RGB color space not permitted on grayscale PNG"); break; case 0x47524159: /* 'GRAY' */ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) return png_icc_profile_error(png_ptr, colorspace, name, temp, - "Gray color space not permitted on RGB PNG"); + "Gray color space not permitted on RGB PNG"); break; default: return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid ICC profile color space"); + "invalid ICC profile color space"); } /* It is up to the application to check that the profile class matches the @@ -2056,8 +2139,8 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, temp = png_get_uint_32(profile+12); /* profile/device class */ switch (temp) { - case 0x73636E72: /* 'scnr' */ - case 0x6D6E7472: /* 'mntr' */ + case 0x73636e72: /* 'scnr' */ + case 0x6d6e7472: /* 'mntr' */ case 0x70727472: /* 'prtr' */ case 0x73706163: /* 'spac' */ /* All supported */ @@ -2066,9 +2149,9 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, case 0x61627374: /* 'abst' */ /* May not be embedded in an image */ return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid embedded Abstract ICC profile"); + "invalid embedded Abstract ICC profile"); - case 0x6C696E6B: /* 'link' */ + case 0x6c696e6b: /* 'link' */ /* DeviceLink profiles cannot be interpreted in a non-device specific * fashion, if an app uses the AToB0Tag in the profile the results are * undefined unless the result is sent to the intended device, @@ -2076,15 +2159,15 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, * PNG. */ return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected DeviceLink ICC profile class"); + "unexpected DeviceLink ICC profile class"); - case 0x6E6D636C: /* 'nmcl' */ + case 0x6e6d636c: /* 'nmcl' */ /* A NamedColor profile is also device specific, however it doesn't * contain an AToB0 tag that is open to misinterpretation. Almost * certainly it will fail the tests below. */ (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unexpected NamedColor ICC profile class"); + "unexpected NamedColor ICC profile class"); break; default: @@ -2094,7 +2177,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, * understood profiles. */ (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unrecognized ICC profile class"); + "unrecognized ICC profile class"); break; } @@ -2104,13 +2187,13 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, temp = png_get_uint_32(profile+20); switch (temp) { - case 0x58595A20: /* 'XYZ ' */ - case 0x4C616220: /* 'Lab ' */ + case 0x58595a20: /* 'XYZ ' */ + case 0x4c616220: /* 'Lab ' */ break; default: return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected ICC PCS encoding"); + "unexpected ICC PCS encoding"); } return 1; @@ -2118,8 +2201,8 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, int /* PRIVATE */ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */) + png_const_charp name, png_uint_32 profile_length, + png_const_bytep profile /* header plus whole tag table */) { png_uint_32 tag_count = png_get_uint_32(profile+128); png_uint_32 itag; @@ -2140,22 +2223,23 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, * being in range. All defined tag types have an 8 byte header - a 4 byte * type signature then 0. */ - if ((tag_start & 3) != 0) - { - /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is - * only a warning here because libpng does not care about the - * alignment. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, - "ICC profile tag start not a multiple of 4"); - } /* This is a hard error; potentially it can cause read outside the * profile. */ if (tag_start > profile_length || tag_length > profile_length - tag_start) return png_icc_profile_error(png_ptr, colorspace, name, tag_id, - "ICC profile tag outside profile"); + "ICC profile tag outside profile"); + + if ((tag_start & 3) != 0) + { + /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is + * only a warning here because libpng does not care about the + * alignment. + */ + (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, + "ICC profile tag start not a multiple of 4"); + } } return 1; /* success, maybe with warnings */ @@ -2183,22 +2267,22 @@ static const struct */ /* adler32, crc32, MD5[4], intent, date, length, file-name */ PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, - PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, - "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") + PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, + "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") /* ICC sRGB v2 perceptual no black-compensation: */ PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, - PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, - "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") + PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, + "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, - PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, - "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") + PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, + "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") /* ICC sRGB v4 perceptual */ PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, - PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, - "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") + PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, + "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") /* The following profiles have no known MD5 checksum. If there is a match * on the (empty) MD5 the other fields are used to attempt a match and @@ -2206,8 +2290,8 @@ static const struct * which suggests that they were also made by Hewlett Packard. */ PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, - "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, + "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not * match the D50 PCS illuminant in the header (it is in fact the D65 values, @@ -2217,17 +2301,17 @@ static const struct * chromaticAdaptationTag. */ PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, + "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, + "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") }; static int png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, - png_const_bytep profile, uLong adler) + png_const_bytep profile, uLong adler) { /* The quick check is to verify just the MD5 signature and trust the * rest of the data. Because the profile has already been verified for @@ -2275,8 +2359,8 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, } /* Length *and* intent must match */ - if (length == png_sRGB_checks[i].length && - intent == png_sRGB_checks[i].intent) + if (length == (png_uint_32) png_sRGB_checks[i].length && + intent == (png_uint_32) png_sRGB_checks[i].intent) { /* Now calculate the adler32 if not done already. */ if (adler == 0) @@ -2311,7 +2395,7 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, * which is made irrelevant by this error. */ png_chunk_report(png_ptr, "known incorrect sRGB profile", - PNG_CHUNK_ERROR); + PNG_CHUNK_ERROR); } /* Warn that this being done; this isn't even an error since @@ -2321,8 +2405,8 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, else if (png_sRGB_checks[i].have_md5 == 0) { png_chunk_report(png_ptr, - "out-of-date sRGB profile with no signature", - PNG_CHUNK_WARNING); + "out-of-date sRGB profile with no signature", + PNG_CHUNK_WARNING); } return 1+png_sRGB_checks[i].is_broken; @@ -2335,7 +2419,7 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, * Fall through to "no match". */ png_chunk_report(png_ptr, - "Not recognizing known sRGB profile that has been edited", + "Not recognizing known sRGB profile that has been edited", PNG_CHUNK_WARNING); break; # endif @@ -2345,38 +2429,36 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, return 0; /* no match */ } -#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ void /* PRIVATE */ png_icc_set_sRGB(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_bytep profile, uLong adler) + png_colorspacerp colorspace, png_const_bytep profile, uLong adler) { /* Is this profile one of the known ICC sRGB profiles? If it is, just set * the sRGB information. */ -#if PNG_sRGB_PROFILE_CHECKS >= 0 if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) -#endif (void)png_colorspace_set_sRGB(png_ptr, colorspace, (int)/*already checked*/png_get_uint_32(profile+64)); } +#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ #endif /* sRGB */ int /* PRIVATE */ png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, - int color_type) + png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, + int color_type) { if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) return 0; - if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && + if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, - color_type) != 0 && + color_type) != 0 && png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, - profile) != 0) + profile) != 0) { -# ifdef PNG_sRGB_SUPPORTED +# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 /* If no sRGB support, don't try storing sRGB information */ png_icc_set_sRGB(png_ptr, colorspace, profile, 0); # endif @@ -2435,7 +2517,7 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr) /* Check for an internal error. */ if (r+g+b != 32768) png_error(png_ptr, - "internal error handling cHRM coefficients"); + "internal error handling cHRM coefficients"); else { @@ -2461,7 +2543,7 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr) static int /* PRIVATE */ png_gt(size_t a, size_t b) { - return a > b; + return a > b; } #else # define png_gt(a,b) ((a) > (b)) @@ -2469,9 +2551,9 @@ png_gt(size_t a, size_t b) void /* PRIVATE */ png_check_IHDR(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) { int error = 0; @@ -2488,7 +2570,7 @@ png_check_IHDR(png_const_structrp png_ptr, error = 1; } - if (png_gt(((width + 7) & (~7)), + if (png_gt(((width + 7) & (~7U)), ((PNG_SIZE_MAX - 48 /* big_row_buf hack */ - 1) /* filter byte */ @@ -2634,7 +2716,7 @@ png_check_IHDR(png_const_structrp png_ptr, int /* PRIVATE */ png_check_fp_number(png_const_charp string, png_size_t size, int *statep, - png_size_tp whereami) + png_size_tp whereami) { int state = *statep; png_size_t i = *whereami; @@ -2790,7 +2872,7 @@ png_pow10(int power) if (power < 0) { if (power < DBL_MIN_10_EXP) return 0; - recip = 1, power = -power; + recip = 1; power = -power; } if (power > 0) @@ -2815,6 +2897,14 @@ png_pow10(int power) /* Function to format a floating point value in ASCII with a given * precision. */ +#if GCC_STRICT_OVERFLOW +#pragma GCC diagnostic push +/* The problem arises below with exp_b10, which can never overflow because it + * comes, originally, from frexp and is therefore limited to a range which is + * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)). + */ +#pragma GCC diagnostic warning "-Wstrict-overflow=2" +#endif /* GCC_STRICT_OVERFLOW */ void /* PRIVATE */ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, double fp, unsigned int precision) @@ -2843,7 +2933,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, if (fp >= DBL_MIN && fp <= DBL_MAX) { - int exp_b10; /* A base 10 exponent */ + int exp_b10; /* A base 10 exponent */ double base; /* 10^exp_b10 */ /* First extract a base 10 exponent of the number, @@ -2868,7 +2958,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, double test = png_pow10(exp_b10+1); if (test <= DBL_MAX) - ++exp_b10, base = test; + { + ++exp_b10; base = test; + } else break; @@ -2882,7 +2974,10 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, * test on DBL_MAX above. */ fp /= base; - while (fp >= 1) fp /= 10, ++exp_b10; + while (fp >= 1) + { + fp /= 10; ++exp_b10; + } /* Because of the code above fp may, at this point, be * less than .1, this is ok because the code below can @@ -2891,7 +2986,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, */ { - int czero, clead, cdigits; + unsigned int czero, clead, cdigits; char exponent[10]; /* Allow up to two leading zeros - this will not lengthen @@ -2899,7 +2994,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, */ if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ { - czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ + czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */ exp_b10 = 0; /* Dot added below before first output. */ } else @@ -2921,7 +3016,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, * of the loop don't break the number into parts so * that the final digit is rounded. */ - if (cdigits+czero-clead+1 < (int)precision) + if (cdigits+czero+1 < precision+clead) fp = modf(fp, &d); else @@ -2933,7 +3028,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, /* Rounding up to 10, handle that here. */ if (czero > 0) { - --czero, d = 1; + --czero; d = 1; if (cdigits == 0) --clead; } else @@ -2947,7 +3042,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, else if (ch == 46) { - ch = *--ascii, ++size; + ch = *--ascii; ++size; /* Advance exp_b10 to '1', so that the * decimal point happens after the * previous digit. @@ -2974,7 +3069,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, int ch = *--ascii; if (ch == 46) - ++size, exp_b10 = 1; + { + ++size; exp_b10 = 1; + } /* Else lost a leading zero, so 'exp_b10' is * still ok at (-1) @@ -3010,30 +3107,35 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, */ if (exp_b10 != (-1)) { - if (exp_b10 == 0) *ascii++ = 46, --size; + if (exp_b10 == 0) + { + *ascii++ = 46; --size; + } /* PLUS 1: TOTAL 4 */ --exp_b10; } - *ascii++ = 48, --czero; + *ascii++ = 48; --czero; } if (exp_b10 != (-1)) { if (exp_b10 == 0) - *ascii++ = 46, --size; /* counted above */ + { + *ascii++ = 46; --size; /* counted above */ + } --exp_b10; } - *ascii++ = (char)(48 + (int)d), ++cdigits; + *ascii++ = (char)(48 + (int)d); ++cdigits; } } - while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); + while (cdigits+czero < precision+clead && fp > DBL_MIN); /* The total output count (max) is now 4+precision */ /* Check for an exponent, if we don't need one we are * done and just need to terminate the string. At - * this point exp_b10==(-1) is effectively if flag - it got + * this point exp_b10==(-1) is effectively a flag - it got * to '-1' because of the decrement after outputting * the decimal point above (the exponent required is * *not* -1!) @@ -3047,7 +3149,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, * zeros were *not* output, so this doesn't increase * the output count. */ - while (--exp_b10 >= 0) *ascii++ = 48; + while (exp_b10-- > 0) *ascii++ = 48; *ascii = 0; @@ -3065,7 +3167,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, */ size -= cdigits; - *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ + *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */ /* The following use of an unsigned temporary avoids ambiguities in * the signed arithmetic on exp_b10 and permits GCC at least to do @@ -3076,12 +3178,12 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, if (exp_b10 < 0) { - *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ - uexp_b10 = -exp_b10; + *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */ + uexp_b10 = 0U-exp_b10; } else - uexp_b10 = exp_b10; + uexp_b10 = 0U+exp_b10; cdigits = 0; @@ -3095,7 +3197,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, /* Need another size check here for the exponent digits, so * this need not be considered above. */ - if ((int)size > cdigits) + if (size > cdigits) { while (cdigits > 0) *ascii++ = exponent[--cdigits]; @@ -3124,6 +3226,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, /* Here on buffer too small. */ png_error(png_ptr, "ASCII conversion buffer too small"); } +#if GCC_STRICT_OVERFLOW +#pragma GCC diagnostic pop +#endif /* GCC_STRICT_OVERFLOW */ # endif /* FLOATING_POINT */ @@ -3143,9 +3248,11 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, /* Avoid overflow here on the minimum integer. */ if (fp < 0) - *ascii++ = 45, --size, num = -fp; + { + *ascii++ = 45; num = (png_uint_32)(-fp); + } else - num = fp; + num = (png_uint_32)fp; if (num <= 0x80000000) /* else overflowed */ { @@ -3181,7 +3288,10 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, * then ndigits digits to first: */ i = 5; - while (ndigits < i) *ascii++ = 48, --i; + while (ndigits < i) + { + *ascii++ = 48; --i; + } while (ndigits >= first) *ascii++ = digits[--ndigits]; /* Don't output the trailing zeros! */ } @@ -3232,6 +3342,15 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) * the nearest .00001). Overflow and divide by zero are signalled in * the result, a boolean - true on success, false on overflow. */ +#if GCC_STRICT_OVERFLOW /* from above */ +/* It is not obvious which comparison below gets optimized in such a way that + * signed overflow would change the result; looking through the code does not + * reveal any tests which have the form GCC complains about, so presumably the + * optimizer is moving an add or subtract into the 'if' somewhere. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic warning "-Wstrict-overflow=2" +#endif /* GCC_STRICT_OVERFLOW */ int png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, png_int_32 divisor) @@ -3346,6 +3465,9 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, return 0; } +#if GCC_STRICT_OVERFLOW +#pragma GCC diagnostic pop +#endif /* GCC_STRICT_OVERFLOW */ #endif /* READ_GAMMA || INCH_CONVERSIONS */ #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) @@ -3639,7 +3761,7 @@ png_log16bit(png_uint_32 x) * 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 + * fractional 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 @@ -3674,7 +3796,7 @@ png_exp(png_fixed_point x) if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ { /* Obtain a 4-bit approximation */ - png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; + png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f]; /* Incorporate the low 12 bits - these decrease the returned value by * multiplying by a number less than 1 if the bit is set. The multiplier @@ -3797,25 +3919,25 @@ png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) { if (value > 0 && value < 65535) { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* The same (unsigned int)->(double) constraints apply here as above, - * however in this case the (unsigned int) to (int) conversion can - * overflow on an ANSI-C90 compliant system so the cast needs to ensure - * that this is not possible. - */ - double r = floor(65535*pow((png_int_32)value/65535., - gamma_val*.00001)+.5); - return (png_uint_16)r; -# else - png_int_32 lg2 = png_log16bit(value); - png_fixed_point res; +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* The same (unsigned int)->(double) constraints apply here as above, + * however in this case the (unsigned int) to (int) conversion can + * overflow on an ANSI-C90 compliant system so the cast needs to ensure + * that this is not possible. + */ + double r = floor(65535*pow((png_int_32)value/65535., + gamma_val*.00001)+.5); + return (png_uint_16)r; +# else + png_int_32 lg2 = png_log16bit(value); + png_fixed_point res; - if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) - return png_exp16bit(res); + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) + return png_exp16bit(res); - /* Overflow. */ - value = 0; -# endif + /* Overflow. */ + value = 0; +# endif } return (png_uint_16)value; @@ -3854,7 +3976,7 @@ png_gamma_correct(png_structrp png_ptr, unsigned int value, */ static void png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) { /* Various values derived from 'shift': */ PNG_CONST unsigned int num = 1U << (8U - shift); @@ -3931,7 +4053,7 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, */ static void png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) { PNG_CONST unsigned int num = 1U << (8U - shift); PNG_CONST unsigned int max = (1U << (16U - shift))-1U; @@ -3999,7 +4121,7 @@ png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, */ static void png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, - PNG_CONST png_fixed_point gamma_val) + PNG_CONST png_fixed_point gamma_val) { unsigned int i; png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); @@ -4079,131 +4201,133 @@ png_destroy_gamma_table(png_structrp png_ptr) void /* PRIVATE */ png_build_gamma_table(png_structrp png_ptr, int bit_depth) { - png_debug(1, "in png_build_gamma_table"); + png_debug(1, "in png_build_gamma_table"); - /* Remove any existing table; this copes with multiple calls to - * png_read_update_info. The warning is because building the gamma tables - * multiple times is a performance hit - it's harmless but the ability to call - * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible - * to warn if the app introduces such a hit. - */ - if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) - { - png_warning(png_ptr, "gamma table being rebuilt"); - png_destroy_gamma_table(png_ptr); - } + /* Remove any existing table; this copes with multiple calls to + * png_read_update_info. The warning is because building the gamma tables + * multiple times is a performance hit - it's harmless but the ability to + * call png_read_update_info() multiple times is new in 1.5.6 so it seems + * sensible to warn if the app introduces such a hit. + */ + if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) + { + png_warning(png_ptr, "gamma table being rebuilt"); + png_destroy_gamma_table(png_ptr); + } - if (bit_depth <= 8) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_table, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); + if (bit_depth <= 8) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, + png_ptr->screen_gamma > 0 ? + png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma) : PNG_FP_1); #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, - png_reciprocal(png_ptr->colorspace.gamma)); + if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, + png_reciprocal(png_ptr->colorspace.gamma)); - png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, + png_ptr->screen_gamma > 0 ? + png_reciprocal(png_ptr->screen_gamma) : + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + } #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } + } #ifdef PNG_16BIT_SUPPORTED - else - { - png_byte shift, sig_bit; + else + { + png_byte shift, sig_bit; - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - sig_bit = png_ptr->sig_bit.red; + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + sig_bit = png_ptr->sig_bit.red; - if (png_ptr->sig_bit.green > sig_bit) - sig_bit = png_ptr->sig_bit.green; + if (png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; - if (png_ptr->sig_bit.blue > sig_bit) - sig_bit = png_ptr->sig_bit.blue; - } - else - sig_bit = png_ptr->sig_bit.gray; + if (png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + else + sig_bit = png_ptr->sig_bit.gray; - /* 16-bit gamma code uses this equation: - * - * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] - * - * Where 'iv' is the input color value and 'ov' is the output value - - * pow(iv, gamma). - * - * Thus the gamma table consists of up to 256 256-entry tables. The table - * is selected by the (8-gamma_shift) most significant of the low 8 bits of - * the color value then indexed by the upper 8 bits: - * - * table[low bits][high 8 bits] - * - * So the table 'n' corresponds to all those 'iv' of: - * - * ..<(n+1 << gamma_shift)-1> - * - */ - if (sig_bit > 0 && sig_bit < 16U) - /* shift == insignificant bits */ - shift = (png_byte)((16U - sig_bit) & 0xff); + /* 16-bit gamma code uses this equation: + * + * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] + * + * Where 'iv' is the input color value and 'ov' is the output value - + * pow(iv, gamma). + * + * Thus the gamma table consists of up to 256 256-entry tables. The table + * is selected by the (8-gamma_shift) most significant of the low 8 bits + * of the color value then indexed by the upper 8 bits: + * + * table[low bits][high 8 bits] + * + * So the table 'n' corresponds to all those 'iv' of: + * + * ..<(n+1 << gamma_shift)-1> + * + */ + if (sig_bit > 0 && sig_bit < 16U) + /* shift == insignificant bits */ + shift = (png_byte)((16U - sig_bit) & 0xff); - else - shift = 0; /* keep all 16 bits */ + else + shift = 0; /* keep all 16 bits */ - if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - { - /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively - * the significant bits in the *input* when the output will - * eventually be 8 bits. By default it is 11. - */ - if (shift < (16U - PNG_MAX_GAMMA_8)) - shift = (16U - PNG_MAX_GAMMA_8); - } + if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) + { + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively + * the significant bits in the *input* when the output will + * eventually be 8 bits. By default it is 11. + */ + if (shift < (16U - PNG_MAX_GAMMA_8)) + shift = (16U - PNG_MAX_GAMMA_8); + } - if (shift > 8U) - shift = 8U; /* Guarantees at least one table! */ + if (shift > 8U) + shift = 8U; /* Guarantees at least one table! */ - png_ptr->gamma_shift = shift; + png_ptr->gamma_shift = shift; - /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now - * PNG_COMPOSE). This effectively smashed the background calculation for - * 16-bit output because the 8-bit table assumes the result will be reduced - * to 8 bits. - */ - if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); + /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now + * PNG_COMPOSE). This effectively smashed the background calculation for + * 16-bit output because the 8-bit table assumes the result will be + * reduced to 8 bits. + */ + if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma) : PNG_FP_1); - else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); + else + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma) : PNG_FP_1); #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, - png_reciprocal(png_ptr->colorspace.gamma)); + if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) + { + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, + png_reciprocal(png_ptr->colorspace.gamma)); - /* Notice that the '16 from 1' table should be full precision, however - * the lookup on this table still uses gamma_shift, so it can't be. - * TODO: fix this. - */ - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, so it can't be. + * TODO: fix this. + */ + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + } #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } + } #endif /* 16BIT */ } #endif /* READ_GAMMA */ @@ -4216,13 +4340,13 @@ png_set_option(png_structrp png_ptr, int option, int onoff) if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && (option & 1) == 0) { - int mask = 3 << option; - int setting = (2 + (onoff != 0)) << option; - int current = png_ptr->options; + png_uint_32 mask = 3U << option; + png_uint_32 setting = (2U + (onoff != 0)) << option; + png_uint_32 current = png_ptr->options; - png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff); + png_ptr->options = (png_uint_32)(((current & ~mask) | setting) & 0xff); - return (current & mask) >> option; + return (int)(current & mask) >> option; } return PNG_OPTION_INVALID; @@ -4234,9 +4358,9 @@ png_set_option(png_structrp png_ptr, int option, int onoff) defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) /* sRGB conversion tables; these are machine generated with the code in * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the - * specification (see the article at http://en.wikipedia.org/wiki/SRGB) + * specification (see the article at https://en.wikipedia.org/wiki/SRGB) * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. - * The sRGB to linear table is exact (to the nearest 16 bit linear fraction). + * The sRGB to linear table is exact (to the nearest 16-bit linear fraction). * The inverse (linear to sRGB) table has accuracies as follows: * * For all possible (255*65535+1) input values: diff --git a/src/third-party/libpng/png.h b/src/third-party/libpng/png.h index 372599bfb..4c873f5c2 100644 --- a/src/third-party/libpng/png.h +++ b/src/third-party/libpng/png.h @@ -1,9 +1,9 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.17, March 26, 2015 + * libpng version 1.6.34, September 29, 2017 * - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -11,17 +11,164 @@ * * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat - * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.17, March 26, 2015: Glenn + * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.6.34, September 29, 2017: + * Glenn Randers-Pehrson. * See also "Contributing Authors", below. + */ + +/* + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: * - * Note about libpng version numbers: + * If you modify libpng you may insert additional notices immediately following + * this sentence. * - * Due to various miscommunications, unforeseen code incompatibilities - * and occasional factors outside the authors' control, version numbering - * on the library has not always been consistent and straightforward. - * The following table summarizes matters since version 0.89c, which was - * the first widely used release: + * This code is released under the libpng license. + * + * libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are + * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are + * derived from libpng-1.0.6, and are distributed according to the same + * disclaimer and license as libpng-1.0.6 with the following individuals + * added to the list of Contributing Authors: + * + * Simon-Pierre Cadieux + * Eric S. Raymond + * Mans Rullgard + * Cosmin Truta + * Gilles Vollant + * James Yu + * Mandar Sahastrabuddhe + * Google Inc. + * Vadim Barkov + * + * and with the following additions to the disclaimer: + * + * There is no warranty against interference with your enjoyment of the + * library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is with + * the user. + * + * Some files in the "contrib" directory and some configure-generated + * files that are distributed with libpng have other copyright owners and + * are released under other open source licenses. + * + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from + * libpng-0.96, and are distributed according to the same disclaimer and + * license as libpng-0.96, with the following individuals added to the list + * of Contributing Authors: + * + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik + * + * libpng versions 0.89, June 1996, through 0.96, May 1997, are + * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, + * and are distributed according to the same disclaimer and license as + * libpng-0.88, with the following individuals added to the list of + * Contributing Authors: + * + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner + * + * Some files in the "scripts" directory have other copyright owners + * but are released under this license. + * + * libpng versions 0.5, May 1995, through 0.88, January 1996, are + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * For the purposes of this copyright and license, "Contributing Authors" + * is defined as the following set of individuals: + * + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner + * + * The PNG Reference Library is supplied "AS IS". The Contributing Authors + * and Group 42, Inc. disclaim all warranties, expressed or implied, + * including, without limitation, the warranties of merchantability and of + * fitness for any purpose. The Contributing Authors and Group 42, Inc. + * assume no liability for direct, indirect, incidental, special, exemplary, + * or consequential damages, which may result from the use of the PNG + * Reference Library, even if advised of the possibility of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject + * to the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. + * + * 2. Altered versions must be plainly marked as such and must not + * be misrepresented as being the original source. + * + * 3. This Copyright notice may not be removed or altered from any + * source or altered source distribution. + * + * The Contributing Authors and Group 42, Inc. specifically permit, without + * fee, and encourage the use of this source code as a component to + * supporting the PNG file format in commercial products. If you use this + * source code in a product, acknowledgment is not required but would be + * appreciated. + * + * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. + * + * TRADEMARK: + * + * The name "libpng" has not been registered by the Copyright owner + * as a trademark in any jurisdiction. However, because libpng has + * been distributed and maintained world-wide, continually since 1995, + * the Copyright owner claims "common-law trademark protection" in any + * jurisdiction where common-law trademark is recognized. + * + * OSI CERTIFICATION: + * + * Libpng is OSI Certified Open Source Software. OSI Certified Open Source is + * a certification mark of the Open Source Initiative. OSI has not addressed + * the additional disclaimers inserted at version 1.0.7. + * + * EXPORT CONTROL: + * + * The Copyright owner believes that the Export Control Classification + * Number (ECCN) for libpng is EAR99, which means not subject to export + * controls or International Traffic in Arms Regulations (ITAR) because + * it is open source, publicly available software, that does not contain + * any encryption software. See the EAR, paragraphs 734.3(b)(3) and + * 734.7(b). + */ + +/* + * A "png_get_copyright" function is available, for convenient use in "about" + * boxes and the like: + * + * printf("%s", png_get_copyright(NULL)); + * + * Also, the PNG logo (in PNG format, of course) is supplied in the + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + */ + +/* + * The contributing authors would like to thank all those who helped + * with testing, bug fixes, and patience. This wouldn't have been + * possible without all of you. + * + * Thanks to Frank J. T. Wojcik for helping with the documentation. + */ + +/* Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: * * source png.h png.h shared-lib * version string int version @@ -59,313 +206,48 @@ * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) * 1.0.7 1 10007 (still compatible) - * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 - * 1.0.8rc1 1 10008 2.1.0.8rc1 - * 1.0.8 1 10008 2.1.0.8 - * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 - * 1.0.9rc1 1 10009 2.1.0.9rc1 - * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 - * 1.0.9rc2 1 10009 2.1.0.9rc2 - * 1.0.9 1 10009 2.1.0.9 - * 1.0.10beta1 1 10010 2.1.0.10beta1 - * 1.0.10rc1 1 10010 2.1.0.10rc1 - * 1.0.10 1 10010 2.1.0.10 - * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 - * 1.0.11rc1 1 10011 2.1.0.11rc1 - * 1.0.11 1 10011 2.1.0.11 - * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 - * 1.0.12rc1 2 10012 2.1.0.12rc1 - * 1.0.12 2 10012 2.1.0.12 - * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) - * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 - * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 - * 1.2.0rc1 3 10200 3.1.2.0rc1 - * 1.2.0 3 10200 3.1.2.0 - * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 - * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 - * 1.2.1 3 10201 3.1.2.1 - * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 - * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 - * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 - * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 - * 1.0.13 10 10013 10.so.0.1.0.13 - * 1.2.2 12 10202 12.so.0.1.2.2 - * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 - * 1.2.3 12 10203 12.so.0.1.2.3 - * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 - * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 - * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 - * 1.0.14 10 10014 10.so.0.1.0.14 - * 1.2.4 13 10204 12.so.0.1.2.4 - * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 - * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 - * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 - * 1.0.15 10 10015 10.so.0.1.0.15 - * 1.2.5 13 10205 12.so.0.1.2.5 - * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 - * 1.0.16 10 10016 10.so.0.1.0.16 - * 1.2.6 13 10206 12.so.0.1.2.6 - * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 - * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 - * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 - * 1.0.17 10 10017 12.so.0.1.0.17 - * 1.2.7 13 10207 12.so.0.1.2.7 - * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 - * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5 - * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 - * 1.0.18 10 10018 12.so.0.1.0.18 - * 1.2.8 13 10208 12.so.0.1.2.8 - * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 - * 1.2.9beta4-11 13 10209 12.so.0.9[.0] - * 1.2.9rc1 13 10209 12.so.0.9[.0] - * 1.2.9 13 10209 12.so.0.9[.0] - * 1.2.10beta1-7 13 10210 12.so.0.10[.0] - * 1.2.10rc1-2 13 10210 12.so.0.10[.0] - * 1.2.10 13 10210 12.so.0.10[.0] - * 1.4.0beta1-5 14 10400 14.so.0.0[.0] - * 1.2.11beta1-4 13 10211 12.so.0.11[.0] - * 1.4.0beta7-8 14 10400 14.so.0.0[.0] - * 1.2.11 13 10211 12.so.0.11[.0] - * 1.2.12 13 10212 12.so.0.12[.0] - * 1.4.0beta9-14 14 10400 14.so.0.0[.0] - * 1.2.13 13 10213 12.so.0.13[.0] - * 1.4.0beta15-36 14 10400 14.so.0.0[.0] - * 1.4.0beta37-87 14 10400 14.so.14.0[.0] - * 1.4.0rc01 14 10400 14.so.14.0[.0] - * 1.4.0beta88-109 14 10400 14.so.14.0[.0] - * 1.4.0rc02-08 14 10400 14.so.14.0[.0] - * 1.4.0 14 10400 14.so.14.0[.0] - * 1.4.1beta01-03 14 10401 14.so.14.1[.0] - * 1.4.1rc01 14 10401 14.so.14.1[.0] - * 1.4.1beta04-12 14 10401 14.so.14.1[.0] - * 1.4.1 14 10401 14.so.14.1[.0] - * 1.4.2 14 10402 14.so.14.2[.0] - * 1.4.3 14 10403 14.so.14.3[.0] - * 1.4.4 14 10404 14.so.14.4[.0] - * 1.5.0beta01-58 15 10500 15.so.15.0[.0] - * 1.5.0rc01-07 15 10500 15.so.15.0[.0] - * 1.5.0 15 10500 15.so.15.0[.0] - * 1.5.1beta01-11 15 10501 15.so.15.1[.0] - * 1.5.1rc01-02 15 10501 15.so.15.1[.0] - * 1.5.1 15 10501 15.so.15.1[.0] - * 1.5.2beta01-03 15 10502 15.so.15.2[.0] - * 1.5.2rc01-03 15 10502 15.so.15.2[.0] - * 1.5.2 15 10502 15.so.15.2[.0] - * 1.5.3beta01-10 15 10503 15.so.15.3[.0] - * 1.5.3rc01-02 15 10503 15.so.15.3[.0] - * 1.5.3beta11 15 10503 15.so.15.3[.0] - * 1.5.3 [omitted] - * 1.5.4beta01-08 15 10504 15.so.15.4[.0] - * 1.5.4rc01 15 10504 15.so.15.4[.0] - * 1.5.4 15 10504 15.so.15.4[.0] - * 1.5.5beta01-08 15 10505 15.so.15.5[.0] - * 1.5.5rc01 15 10505 15.so.15.5[.0] - * 1.5.5 15 10505 15.so.15.5[.0] - * 1.5.6beta01-07 15 10506 15.so.15.6[.0] - * 1.5.6rc01-03 15 10506 15.so.15.6[.0] - * 1.5.6 15 10506 15.so.15.6[.0] - * 1.5.7beta01-05 15 10507 15.so.15.7[.0] - * 1.5.7rc01-03 15 10507 15.so.15.7[.0] - * 1.5.7 15 10507 15.so.15.7[.0] - * 1.6.0beta01-40 16 10600 16.so.16.0[.0] - * 1.6.0rc01-08 16 10600 16.so.16.0[.0] - * 1.6.0 16 10600 16.so.16.0[.0] - * 1.6.1beta01-09 16 10601 16.so.16.1[.0] - * 1.6.1rc01 16 10601 16.so.16.1[.0] - * 1.6.1 16 10601 16.so.16.1[.0] - * 1.6.2beta01 16 10602 16.so.16.2[.0] - * 1.6.2rc01-06 16 10602 16.so.16.2[.0] - * 1.6.2 16 10602 16.so.16.2[.0] - * 1.6.3beta01-11 16 10603 16.so.16.3[.0] - * 1.6.3rc01 16 10603 16.so.16.3[.0] - * 1.6.3 16 10603 16.so.16.3[.0] - * 1.6.4beta01-02 16 10604 16.so.16.4[.0] - * 1.6.4rc01 16 10604 16.so.16.4[.0] - * 1.6.4 16 10604 16.so.16.4[.0] - * 1.6.5 16 10605 16.so.16.5[.0] - * 1.6.6 16 10606 16.so.16.6[.0] - * 1.6.7beta01-04 16 10607 16.so.16.7[.0] - * 1.6.7rc01-03 16 10607 16.so.16.7[.0] - * 1.6.7 16 10607 16.so.16.7[.0] - * 1.6.8beta01-02 16 10608 16.so.16.8[.0] - * 1.6.8rc01-02 16 10608 16.so.16.8[.0] - * 1.6.8 16 10608 16.so.16.8[.0] - * 1.6.9beta01-04 16 10609 16.so.16.9[.0] - * 1.6.9rc01-02 16 10609 16.so.16.9[.0] - * 1.6.9 16 10609 16.so.16.9[.0] - * 1.6.10beta01-03 16 10610 16.so.16.10[.0] - * 1.6.10rc01-03 16 10610 16.so.16.10[.0] - * 1.6.10 16 10610 16.so.16.10[.0] - * 1.6.11beta01-06 16 10611 16.so.16.11[.0] - * 1.6.11rc01-02 16 10611 16.so.16.11[.0] - * 1.6.11 16 10611 16.so.16.11[.0] - * 1.6.12rc01-03 16 10612 16.so.16.12[.0] - * 1.6.12 16 10612 16.so.16.12[.0] - * 1.6.13beta01-04 16 10613 16.so.16.13[.0] - * 1.6.13rc01-02 16 10613 16.so.16.13[.0] - * 1.6.13 16 10613 16.so.16.13[.0] - * 1.6.14beta01-07 16 10614 16.so.16.14[.0] - * 1.6.14rc01-02 16 10614 16.so.16.14[.0] - * 1.6.14 16 10614 16.so.16.14[.0] - * 1.6.15beta01-08 16 10615 16.so.16.15[.0] - * 1.6.15rc01-03 16 10615 16.so.16.15[.0] - * 1.6.15 16 10615 16.so.16.15[.0] - * 1.6.16beta01-03 16 10616 16.so.16.16[.0] - * 1.6.16rc01-02 16 10616 16.so.16.16[.0] - * 1.6.16 16 10616 16.so.16.16[.0] - * 1.6.17beta01-06 16 10617 16.so.16.17[.0] - * 1.6.17rc01-06 16 10617 16.so.16.17[.0] - * 1.6.17 16 10617 16.so.16.17[.0] + * ... + * 1.0.19 10 10019 10.so.0.19[.0] + * ... + * 1.2.59 13 10257 12.so.0.59[.0] + * ... + * 1.5.30 15 10527 15.so.15.30[.0] + * ... + * 1.6.34 16 10633 16.so.16.34[.0] * - * Henceforth the source version will match the shared-library major - * and minor numbers; the shared-library major version number will be - * used for changes in backward compatibility, as it is intended. The - * PNG_LIBPNG_VER macro, which is not used within libpng but is available - * for applications, is an unsigned integer of the form xyyzz corresponding - * to the source version x.y.z (leading zeros in y and z). Beta versions - * were given the previous public release number plus a letter, until - * version 1.0.6j; from then on they were given the upcoming public - * release number plus "betaNN" or "rcNN". + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcNN". * - * Binary incompatibility exists only when applications make direct access - * to the info_ptr or png_ptr members through png.h, and the compiled - * application is loaded with a different version of the library. + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). * - * See libpng-manual.txt or libpng.3 for more information. The PNG - * specification is available as a W3C Recommendation and as an ISO - * Specification, defines should NOT be changed. */ -#define PNG_INFO_gAMA 0x0001 -#define PNG_INFO_sBIT 0x0002 -#define PNG_INFO_cHRM 0x0004 -#define PNG_INFO_PLTE 0x0008 -#define PNG_INFO_tRNS 0x0010 -#define PNG_INFO_bKGD 0x0020 -#define PNG_INFO_hIST 0x0040 -#define PNG_INFO_pHYs 0x0080 -#define PNG_INFO_oFFs 0x0100 -#define PNG_INFO_tIME 0x0200 -#define PNG_INFO_pCAL 0x0400 -#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ -#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ -#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ -#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ -#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ +#define PNG_INFO_gAMA 0x0001U +#define PNG_INFO_sBIT 0x0002U +#define PNG_INFO_cHRM 0x0004U +#define PNG_INFO_PLTE 0x0008U +#define PNG_INFO_tRNS 0x0010U +#define PNG_INFO_bKGD 0x0020U +#define PNG_INFO_hIST 0x0040U +#define PNG_INFO_pHYs 0x0080U +#define PNG_INFO_oFFs 0x0100U +#define PNG_INFO_tIME 0x0200U +#define PNG_INFO_pCAL 0x0400U +#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */ +#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */ /* This is used for the transformation routines, as some of them * change these values for the row. It also should enable using @@ -993,7 +880,9 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); #define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ /* Added to libpng-1.5.4 */ #define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ +#if INT_MAX >= 0x8000 /* else this might break */ #define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ +#endif /* Flags for MNG supported features */ #define PNG_FLAG_MNG_EMPTY_PLTE 0x01 @@ -1010,7 +899,7 @@ typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, png_alloc_size_t)); typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); -/* Section 3: exported functions +/* Section 4: exported functions * Here are the function definitions most commonly used. This is not * the place to find out how to use libpng. See libpng-manual.txt for the * full explanation, see example.c for the summary. This just provides @@ -1383,13 +1272,13 @@ PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); #endif #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, int flags)); /* The values of the PNG_FILLER_ defines should NOT be changed */ # define PNG_FILLER_BEFORE 0 # define PNG_FILLER_AFTER 1 -/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, png_uint_32 filler, int flags)); #endif /* READ_FILLER || WRITE_FILLER */ @@ -1458,7 +1347,7 @@ PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); #endif #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ +#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */ /* Strip the second byte of information from a 16-bit depth file. */ PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); #endif @@ -1609,8 +1498,8 @@ PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, #define PNG_FILTER_UP 0x20 #define PNG_FILTER_AVG 0x40 #define PNG_FILTER_PAETH 0x80 -#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ - PNG_FILTER_AVG | PNG_FILTER_PAETH) +#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP) +#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH) /* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. * These defines should NOT be changed. @@ -1623,35 +1512,7 @@ PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, #define PNG_FILTER_VALUE_LAST 5 #ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ -/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ - * defines, either the default (minimum-sum-of-absolute-differences), or - * the experimental method (weighted-minimum-sum-of-absolute-differences). - * - * Weights are factors >= 1.0, indicating how important it is to keep the - * filter type consistent between rows. Larger numbers mean the current - * filter is that many times as likely to be the same as the "num_weights" - * previous filters. This is cumulative for each previous row with a weight. - * There needs to be "num_weights" values in "filter_weights", or it can be - * NULL if the weights aren't being specified. Weights have no influence on - * the selection of the first row filter. Well chosen weights can (in theory) - * improve the compression for a given image. - * - * Costs are factors >= 1.0 indicating the relative decoding costs of a - * filter type. Higher costs indicate more decoding expense, and are - * therefore less likely to be selected over a filter with lower computational - * costs. There needs to be a value in "filter_costs" for each valid filter - * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't - * setting the costs. Costs try to improve the speed of decompression without - * unduly increasing the compressed image size. - * - * A negative weight or cost indicates the default value is to be used, and - * values in the range [0.0, 1.0) indicate the value is to remain unchanged. - * The default values for both weights and costs are currently 1.0, but may - * change if good general weighting/cost heuristics can be found. If both - * the weights and costs are set to 1.0, this degenerates the WEIGHTED method - * to the UNWEIGHTED method, but with added encoding time/computation. - */ +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, int heuristic_method, int num_weights, png_const_doublep filter_weights, png_const_doublep filter_costs)) @@ -1661,9 +1522,7 @@ PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, png_const_fixed_point_p filter_costs)) #endif /* WRITE_WEIGHTED_FILTER */ -/* Heuristic used for row filter selection. These defines should NOT be - * changed. - */ +/* The following are no longer used and will be removed from libpng-1.7: */ #define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ #define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ #define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ @@ -1917,21 +1776,22 @@ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, #define PNG_SET_WILL_FREE_DATA 1 #define PNG_USER_WILL_FREE_DATA 2 /* Flags for png_ptr->free_me and info_ptr->free_me */ -#define PNG_FREE_HIST 0x0008 -#define PNG_FREE_ICCP 0x0010 -#define PNG_FREE_SPLT 0x0020 -#define PNG_FREE_ROWS 0x0040 -#define PNG_FREE_PCAL 0x0080 -#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_HIST 0x0008U +#define PNG_FREE_ICCP 0x0010U +#define PNG_FREE_SPLT 0x0020U +#define PNG_FREE_ROWS 0x0040U +#define PNG_FREE_PCAL 0x0080U +#define PNG_FREE_SCAL 0x0100U #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -# define PNG_FREE_UNKN 0x0200 +# define PNG_FREE_UNKN 0x0200U #endif -/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */ -#define PNG_FREE_PLTE 0x1000 -#define PNG_FREE_TRNS 0x2000 -#define PNG_FREE_TEXT 0x4000 -#define PNG_FREE_ALL 0x7fff -#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ +/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */ +#define PNG_FREE_PLTE 0x1000U +#define PNG_FREE_TRNS 0x2000U +#define PNG_FREE_TEXT 0x4000U +#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */ +#define PNG_FREE_ALL 0xffffU +#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ #ifdef PNG_USER_MEM_SUPPORTED PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, @@ -2149,6 +2009,18 @@ PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, png_fixed_point int_blue_Z)) #endif +#ifdef PNG_eXIf_SUPPORTED +PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr, + png_inforp info_ptr, png_bytep *exif)); +PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr, + png_inforp info_ptr, const png_bytep exif)); + +PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr, + png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif)); +PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr, + png_inforp info_ptr, const png_uint_32 num_exif, const png_bytep exif)); +#endif + #ifdef PNG_gAMA_SUPPORTED PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, png_const_inforp info_ptr, double *file_gamma)) @@ -2167,9 +2039,6 @@ PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, #ifdef PNG_hIST_SUPPORTED PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, png_inforp info_ptr, png_uint_16p *hist)); -#endif - -#ifdef PNG_hIST_SUPPORTED PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, png_inforp info_ptr, png_const_uint_16p hist)); #endif @@ -2437,8 +2306,10 @@ PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to * be processed by libpng. */ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, int keep, png_const_bytep chunk_list, int num_chunks)); +#endif /* HANDLE_AS_UNKNOWN */ /* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; * the result is therefore true (non-zero) if special handling is required, @@ -2446,7 +2317,7 @@ PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, */ PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, png_const_bytep chunk_name)); -#endif +#endif /* SET_UNKNOWN_CHUNKS */ #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, @@ -2667,33 +2538,37 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ -# define png_composite(composite, fg, alpha, bg) \ - { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ - * (png_uint_16)(alpha) \ - + (png_uint_16)(bg)*(png_uint_16)(255 \ - - (png_uint_16)(alpha)) + 128); \ - (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); } +# define png_composite(composite, fg, alpha, bg) \ + { \ + png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ + * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 \ + - (png_uint_16)(alpha)) + 128); \ + (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \ + } -# define png_composite_16(composite, fg, alpha, bg) \ - { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ - * (png_uint_32)(alpha) \ - + (png_uint_32)(bg)*(65535 \ - - (png_uint_32)(alpha)) + 32768); \ - (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); } +# define png_composite_16(composite, fg, alpha, bg) \ + { \ + png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ + * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(65535 \ + - (png_uint_32)(alpha)) + 32768); \ + (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \ + } #else /* Standard method using integer division */ -# define png_composite(composite, fg, alpha, bg) \ - (composite) = \ - (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ - (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ - 127) / 255)) +# define png_composite(composite, fg, alpha, bg) \ + (composite) = \ + (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + 127) / 255)) -# define png_composite_16(composite, fg, alpha, bg) \ - (composite) = \ - (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ - (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ - 32767) / 65535)) +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = \ + (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ + 32767) / 65535)) #endif /* READ_COMPOSITE_NODIV */ #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED @@ -2729,45 +2604,52 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); * format for negative values, which is almost certainly true. */ # define PNG_get_uint_32(buf) \ - (((png_uint_32)(*(buf)) << 24) + \ - ((png_uint_32)(*((buf) + 1)) << 16) + \ - ((png_uint_32)(*((buf) + 2)) << 8) + \ - ((png_uint_32)(*((buf) + 3)))) + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ + ((png_uint_32)(*((buf) + 3)))) /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the * function) incorrectly returned a value of type png_uint_32. */ # define PNG_get_uint_16(buf) \ - ((png_uint_16) \ - (((unsigned int)(*(buf)) << 8) + \ - ((unsigned int)(*((buf) + 1))))) + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) # define PNG_get_int_32(buf) \ - ((png_int_32)((*(buf) & 0x80) \ - ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ - : (png_int_32)png_get_uint_32(buf))) + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \ + : (png_int_32)png_get_uint_32(buf))) - /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, - * but defining a macro name prefixed with PNG_PREFIX. - */ +/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, + * but defining a macro name prefixed with PNG_PREFIX. + */ # ifndef PNG_PREFIX -# define png_get_uint_32(buf) PNG_get_uint_32(buf) -# define png_get_uint_16(buf) PNG_get_uint_16(buf) -# define png_get_int_32(buf) PNG_get_int_32(buf) +# define png_get_uint_32(buf) PNG_get_uint_32(buf) +# define png_get_uint_16(buf) PNG_get_uint_16(buf) +# define png_get_int_32(buf) PNG_get_int_32(buf) # endif #else # ifdef PNG_PREFIX - /* No macros; revert to the (redefined) function */ -# define PNG_get_uint_32 (png_get_uint_32) -# define PNG_get_uint_16 (png_get_uint_16) -# define PNG_get_int_32 (png_get_int_32) + /* No macros; revert to the (redefined) function */ +# define PNG_get_uint_32 (png_get_uint_32) +# define PNG_get_uint_16 (png_get_uint_16) +# define PNG_get_int_32 (png_get_int_32) # endif #endif -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +PNG_EXPORT(242, void, png_set_check_for_invalid_index, + (png_structrp png_ptr, int allowed)); +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, + png_const_infop info_ptr)); +# endif +#endif /* CHECK_FOR_INVALID_INDEX */ + /******************************************************************************* - * SIMPLIFIED API + * Section 5: SIMPLIFIED API ******************************************************************************* * * Please read the documentation in libpng-manual.txt (TODO: write said @@ -2783,8 +2665,9 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); * * To read a PNG file using the simplified API: * - * 1) Declare a 'png_image' structure (see below) on the stack and set the - * version field to PNG_IMAGE_VERSION. + * 1) Declare a 'png_image' structure (see below) on the stack, set the + * version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL + * (this is REQUIRED, your program may crash if you don't do it.) * 2) Call the appropriate png_image_begin_read... function. * 3) Set the png_image 'format' member to the required sample format. * 4) Allocate a buffer for the image and, if required, the color-map. @@ -2811,6 +2694,9 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); * when it is being read or defines the in-memory format of an image that you * need to write: */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) + #define PNG_IMAGE_VERSION 1 typedef struct png_control *png_controlp; @@ -2878,7 +2764,7 @@ typedef struct * * When the simplified API needs to convert between sRGB and linear colorspaces, * the actual sRGB transfer curve defined in the sRGB specification (see the - * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 + * article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 * approximation used elsewhere in libpng. * * When an alpha channel is present it is expected to denote pixel coverage @@ -2910,7 +2796,7 @@ typedef struct * called to read or write the color-map and set the format correctly for the * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! * - * NOTE: libpng can be built with particular features disabled, if you see + * NOTE: libpng can be built with particular features disabled. If you see * compiler errors because the definition of one of the following flags has been * compiled out it is because libpng does not have the required support. It is * possible, however, for the libpng configuration to enable the format on just @@ -2922,7 +2808,7 @@ typedef struct */ #define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ #define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ -#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ +#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2-byte channels else 1-byte */ #define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ #ifdef PNG_FORMAT_BGR_SUPPORTED @@ -2933,6 +2819,8 @@ typedef struct # define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ #endif +#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */ + /* Commonly used formats have predefined macros. * * First the single byte (sRGB) formats: @@ -3044,12 +2932,19 @@ typedef struct * is the minimum 'row stride', the minimum count of components between each * row. For a color-mapped image this is the minimum number of bytes in a * row. + * + * WARNING: this macro overflows for some images with more than one component + * and very large image widths. libpng will refuse to process an image where + * this macro would overflow. */ #define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) /* Return the size, in bytes, of an image buffer given a png_image and a row * stride - the number of components to leave space for in each row. + * + * WARNING: this macro overflows a 32-bit integer for some large PNG images, + * libpng will refuse to process an image where such an overflow would occur. */ #define PNG_IMAGE_SIZE(image)\ @@ -3170,7 +3065,6 @@ PNG_EXPORT(238, void, png_image_free, (png_imagep image)); #endif /* SIMPLIFIED_READ */ #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -#ifdef PNG_STDIO_SUPPORTED /* WRITE APIS * ---------- * For write you must initialize a png_image structure to describe the image to @@ -3187,6 +3081,7 @@ PNG_EXPORT(238, void, png_image_free, (png_imagep image)); * values do not correspond to the colors in sRGB. * colormap_entries: set to the number of entries in the color-map (0 to 256) */ +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, const char *file, int convert_to_8bit, const void *buffer, png_int_32 row_stride, const void *colormap)); @@ -3196,8 +3091,9 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, int convert_to_8_bit, const void *buffer, png_int_32 row_stride, const void *colormap)); /* Write the image to the given (FILE*). */ +#endif /* SIMPLIFIED_WRITE_STDIO */ -/* With both write APIs if image is in one of the linear formats with 16-bit +/* With all write APIs if image is in one of the linear formats with 16-bit * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG * gamma encoded according to the sRGB specification, otherwise a 16-bit linear * encoded PNG file is written. @@ -3209,28 +3105,111 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, * * With all APIs row_stride is handled as in the read APIs - it is the spacing * from one row to the next in component sized units (1 or 2 bytes) and if - * negative indicates a bottom-up row layout in the buffer. + * negative indicates a bottom-up row layout in the buffer. If row_stride is + * zero, libpng will calculate it for you from the image width and number of + * channels. * - * Note that the write API does not support interlacing or sub-8-bit pixels. + * Note that the write API does not support interlacing, sub-8-bit pixels or + * most ancillary chunks. If you need to write text chunks (e.g. for copyright + * notices) you need to use one of the other APIs. */ -#endif /* STDIO */ + +PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, + png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit, + const void *buffer, png_int_32 row_stride, const void *colormap)); + /* Write the image to the given memory buffer. The function both writes the + * whole PNG data stream to *memory and updates *memory_bytes with the count + * of bytes written. + * + * 'memory' may be NULL. In this case *memory_bytes is not read however on + * success the number of bytes which would have been written will still be + * stored in *memory_bytes. On failure *memory_bytes will contain 0. + * + * If 'memory' is not NULL it must point to memory[*memory_bytes] of + * writeable memory. + * + * If the function returns success memory[*memory_bytes] (if 'memory' is not + * NULL) contains the written PNG data. *memory_bytes will always be less + * than or equal to the original value. + * + * If the function returns false and *memory_bytes was not changed an error + * occured during write. If *memory_bytes was changed, or is not 0 if + * 'memory' was NULL, the write would have succeeded but for the memory + * buffer being too small. *memory_bytes contains the required number of + * bytes and will be bigger that the original value. + */ + +#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\ + row_stride, colormap)\ + png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\ + row_stride, colormap) + /* Return the amount of memory in 'size' required to compress this image. + * The png_image structure 'image' must be filled in as in the above + * function and must not be changed before the actual write call, the buffer + * and all other parameters must also be identical to that in the final + * write call. The 'size' variable need not be initialized. + * + * NOTE: the macro returns true/false, if false is returned 'size' will be + * set to zero and the write failed and probably will fail if tried again. + */ + +/* You can pre-allocate the buffer by making sure it is of sufficient size + * regardless of the amount of compression achieved. The buffer size will + * always be bigger than the original image and it will never be filled. The + * following macros are provided to assist in allocating the buffer. + */ +#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height) + /* The number of uncompressed bytes in the PNG byte encoding of the image; + * uncompressing the PNG IDAT data will give this number of bytes. + * + * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this + * macro can because of the extra bytes used in the PNG byte encoding. You + * need to avoid this macro if your image size approaches 2^30 in width or + * height. The same goes for the remainder of these macros; they all produce + * bigger numbers than the actual in-memory image size. + */ +#ifndef PNG_ZLIB_MAX_SIZE +# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U) + /* An upper bound on the number of compressed bytes given 'b' uncompressed + * bytes. This is based on deflateBounds() in zlib; different + * implementations of zlib compression may conceivably produce more data so + * if your zlib implementation is not zlib itself redefine this macro + * appropriately. + */ +#endif + +#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\ + PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image)) + /* An upper bound on the size of the data in the PNG IDAT chunks. */ + +#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\ + ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\ + (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\ + 12U+3U*(image).colormap_entries/*PLTE data*/+\ + (((image).format&PNG_FORMAT_FLAG_ALPHA)?\ + 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\ + 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size)) + /* A helper for the following macro; if your compiler cannot handle the + * following macro use this one with the result of + * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most + * compilers should handle this just fine.) + */ + +#define PNG_IMAGE_PNG_SIZE_MAX(image)\ + PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image)) + /* An upper bound on the total length of the PNG data stream for 'image'. + * The result is of type png_alloc_size_t, on 32-bit systems this may + * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will + * run out of buffer space but return a corrected size which should work. + */ #endif /* SIMPLIFIED_WRITE */ /******************************************************************************* * END OF SIMPLIFIED API ******************************************************************************/ #endif /* SIMPLIFIED_{READ|WRITE} */ -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -PNG_EXPORT(242, void, png_set_check_for_invalid_index, - (png_structrp png_ptr, int allowed)); -# ifdef PNG_GET_PALETTE_MAX_SUPPORTED -PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, - png_const_infop info_ptr)); -# endif -#endif /* CHECK_FOR_INVALID_INDEX */ - /******************************************************************************* - * IMPLEMENTATION OPTIONS + * Section 6: IMPLEMENTATION OPTIONS ******************************************************************************* * * Support for arbitrary implementation-specific optimizations. The API allows @@ -3256,7 +3235,14 @@ PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, #endif #define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ #define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ -#define PNG_OPTION_NEXT 6 /* Next option - numbers must be even */ +#ifdef PNG_MIPS_MSA_API_SUPPORTED +# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ +#endif +#define PNG_IGNORE_ADLER32 8 +#ifdef PNG_POWERPC_VSX_API_SUPPORTED +# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */ +#endif +#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */ /* Return values: NOTE: there are four values and 'off' is *not* zero */ #define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ @@ -3280,7 +3266,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, * one to use is one more than this.) */ #ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(244); + PNG_EXPORT_LAST_ORDINAL(249); #endif #ifdef __cplusplus diff --git a/src/third-party/libpng/pngconf.h b/src/third-party/libpng/pngconf.h index 3f9493e43..d13b13e57 100644 --- a/src/third-party/libpng/pngconf.h +++ b/src/third-party/libpng/pngconf.h @@ -1,9 +1,9 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.6.17, March 26, 2015 + * libpng version 1.6.34, September 29, 2017 * - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -63,7 +63,7 @@ */ #define PNG_CONST const /* backward compatibility only */ -/* This controls optimization of the reading of 16 and 32 bit values +/* This controls optimization of the reading of 16-bit and 32-bit values * from PNG files. It can be set on a per-app-file basis - it * just changes whether a macro is used when the function is called. * The library builder sets the default; if read functions are not @@ -188,27 +188,27 @@ * compatible with GCC or Visual C because of different calling conventions. */ # if PNG_API_RULE == 2 - /* If this line results in an error, either because __watcall is not - * understood or because of a redefine just below you cannot use *this* - * build of the library with the compiler you are using. *This* build was - * build using Watcom and applications must also be built using Watcom! - */ + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ # define PNGCAPI __watcall # endif # if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) # define PNGCAPI __cdecl # if PNG_API_RULE == 1 - /* If this line results in an error __stdcall is not understood and - * PNG_API_RULE should not have been set to '1'. - */ + /* If this line results in an error __stdcall is not understood and + * PNG_API_RULE should not have been set to '1'. + */ # define PNGAPI __stdcall # endif # else - /* An older compiler, or one not detected (erroneously) above, - * if necessary override on the command line to get the correct - * variants for the compiler. - */ + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ # ifndef PNGCAPI # define PNGCAPI _cdecl # endif @@ -225,10 +225,10 @@ # if (defined(_MSC_VER) && _MSC_VER < 800) ||\ (defined(__BORLANDC__) && __BORLANDC__ < 0x500) - /* older Borland and MSC - * compilers used '__export' and required this to be after - * the type. - */ + /* older Borland and MSC + * compilers used '__export' and required this to be after + * the type. + */ # ifndef PNG_EXPORT_TYPE # define PNG_EXPORT_TYPE(type) type PNG_IMPEXP # endif @@ -244,9 +244,9 @@ # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) # define PNGAPI _System # else /* !Windows/x86 && !OS/2 */ - /* Use the defaults, or define PNG*API on the command line (but - * this will have to be done for every compile!) - */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ # endif /* other system, !OS/2 */ #endif /* !Windows/x86 */ @@ -267,7 +267,7 @@ */ #ifndef PNG_IMPEXP # if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) - /* This forces use of a DLL, disallowing static linking */ + /* This forces use of a DLL, disallowing static linking */ # define PNG_IMPEXP PNG_DLL_IMPORT # endif @@ -295,11 +295,11 @@ * table entries, so we discard it here. See the .dfn files in the * scripts directory. */ -#ifndef PNG_EXPORTA -# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ - PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \ - extern attributes) +#ifndef PNG_EXPORTA +# define PNG_EXPORTA(ordinal, type, name, args, attributes) \ + PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \ + PNG_LINKAGE_API attributes) #endif /* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, @@ -307,7 +307,7 @@ */ #define PNG_EMPTY /*empty list*/ -#define PNG_EXPORT(ordinal, type, name, args)\ +#define PNG_EXPORT(ordinal, type, name, args) \ PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) /* Use PNG_REMOVED to comment out a removed interface. */ @@ -340,7 +340,7 @@ * less efficient code. */ # if defined(__clang__) && defined(__has_attribute) - /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ + /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ # if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) # define PNG_USE_RESULT __attribute__((__warn_unused_result__)) # endif @@ -480,7 +480,7 @@ #if CHAR_BIT == 8 && UCHAR_MAX == 255 typedef unsigned char png_byte; #else -# error "libpng requires 8 bit bytes" +# error "libpng requires 8-bit bytes" #endif #if INT_MIN == -32768 && INT_MAX == 32767 @@ -488,7 +488,7 @@ #elif SHRT_MIN == -32768 && SHRT_MAX == 32767 typedef short png_int_16; #else -# error "libpng requires a signed 16 bit type" +# error "libpng requires a signed 16-bit type" #endif #if UINT_MAX == 65535 @@ -496,7 +496,7 @@ #elif USHRT_MAX == 65535 typedef unsigned short png_uint_16; #else -# error "libpng requires an unsigned 16 bit type" +# error "libpng requires an unsigned 16-bit type" #endif #if INT_MIN < -2147483646 && INT_MAX > 2147483646 @@ -504,15 +504,15 @@ #elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 typedef long int png_int_32; #else -# error "libpng requires a signed 32 bit (or more) type" +# error "libpng requires a signed 32-bit (or more) type" #endif -#if UINT_MAX > 4294967294 +#if UINT_MAX > 4294967294U typedef unsigned int png_uint_32; -#elif ULONG_MAX > 4294967294 +#elif ULONG_MAX > 4294967294U typedef unsigned long int png_uint_32; #else -# error "libpng requires an unsigned 32 bit (or more) type" +# error "libpng requires an unsigned 32-bit (or more) type" #endif /* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, diff --git a/src/third-party/libpng/pngdebug.h b/src/third-party/libpng/pngdebug.h index 6a01b106e..15a7ed0c9 100644 --- a/src/third-party/libpng/pngdebug.h +++ b/src/third-party/libpng/pngdebug.h @@ -2,7 +2,7 @@ /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c * * Last changed in libpng 1.6.8 [December 19, 2013] - * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * diff --git a/src/third-party/libpng/pngerror.c b/src/third-party/libpng/pngerror.c index 0781866a8..ad48bfb98 100644 --- a/src/third-party/libpng/pngerror.c +++ b/src/third-party/libpng/pngerror.c @@ -1,8 +1,8 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.6.15 [November 20, 2014] - * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * Last changed in libpng 1.6.31 [July 27, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -26,7 +26,7 @@ static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr, #ifdef PNG_WARNINGS_SUPPORTED static void /* PRIVATE */ png_default_warning PNGARG((png_const_structrp png_ptr, - png_const_charp warning_message)); + png_const_charp warning_message)); #endif /* WARNINGS */ /* This function is called whenever there is a fatal error. This function @@ -37,14 +37,14 @@ png_default_warning PNGARG((png_const_structrp png_ptr, #ifdef PNG_ERROR_TEXT_SUPPORTED PNG_FUNCTION(void,PNGAPI png_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) + PNG_NORETURN) { #ifdef PNG_ERROR_NUMBERS_SUPPORTED char msg[16]; if (png_ptr != NULL) { if ((png_ptr->flags & - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0 + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) { if (*error_message == PNG_LITERAL_SHARP) { @@ -65,18 +65,18 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message), else error_message += offset; - } - - else - { - if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - msg[0] = '0'; - msg[1] = '\0'; - error_message = msg; } - } - } + + else + { + if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) + { + msg[0] = '0'; + msg[1] = '\0'; + error_message = msg; + } + } + } } #endif if (png_ptr != NULL && png_ptr->error_fn != NULL) @@ -110,7 +110,7 @@ png_err,(png_const_structrp png_ptr),PNG_NORETURN) */ size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos, - png_const_charp string) + png_const_charp string) { if (buffer != NULL && pos < bufsize) { @@ -131,7 +131,7 @@ png_safecat(png_charp buffer, size_t bufsize, size_t pos, */ png_charp png_format_number(png_const_charp start, png_charp end, int format, - png_alloc_size_t number) + png_alloc_size_t number) { int count = 0; /* number of digits output */ int mincount = 1; /* minimum number required */ @@ -163,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format, case PNG_NUMBER_FORMAT_02u: /* Expects at least 2 digits. */ mincount = 2; - /* FALL THROUGH */ + /* FALLTHROUGH */ case PNG_NUMBER_FORMAT_u: *--end = digits[number % 10]; @@ -173,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format, case PNG_NUMBER_FORMAT_02x: /* This format expects at least two digits */ mincount = 2; - /* FALL THROUGH */ + /* FALLTHROUGH */ case PNG_NUMBER_FORMAT_x: *--end = digits[number & 0xf]; @@ -233,7 +233,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message) } if (png_ptr != NULL && png_ptr->warning_fn != NULL) (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), - warning_message + offset); + warning_message + offset); else png_default_warning(png_ptr, warning_message + offset); } @@ -245,7 +245,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message) */ void png_warning_parameter(png_warning_parameters p, int number, - png_const_charp string) + png_const_charp string) { if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); @@ -253,7 +253,7 @@ png_warning_parameter(png_warning_parameters p, int number, void png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, - png_alloc_size_t value) + png_alloc_size_t value) { char buffer[PNG_NUMBER_BUFFER_SIZE]; png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); @@ -261,7 +261,7 @@ png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, void png_warning_parameter_signed(png_warning_parameters p, int number, int format, - png_int_32 value) + png_int_32 value) { png_alloc_size_t u; png_charp str; @@ -282,7 +282,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format, void png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, - png_const_charp message) + png_const_charp message) { /* The internal buffer is just 192 bytes - enough for all our messages, * overflow doesn't happen because this code checks! If someone figures @@ -391,10 +391,10 @@ png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) void /* PRIVATE */ png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) { - if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); + if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); # ifndef PNG_ERROR_TEXT_SUPPORTED PNG_UNUSED(error_message) @@ -404,10 +404,10 @@ png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) void /* PRIVATE */ png_app_error(png_const_structrp png_ptr, png_const_charp error_message) { - if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); + if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); # ifndef PNG_ERROR_TEXT_SUPPORTED PNG_UNUSED(error_message) @@ -478,7 +478,7 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) PNG_FUNCTION(void,PNGAPI png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) + PNG_NORETURN) { char msg[18+PNG_MAX_ERROR_TEXT]; if (png_ptr == NULL) @@ -573,7 +573,7 @@ png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) { # define fixed_message "fixed point overflow in " # define fixed_message_ln ((sizeof fixed_message)-1) - int iin; + unsigned int iin; char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; memcpy(msg, fixed_message, fixed_message_ln); iin = 0; @@ -620,7 +620,7 @@ png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, else { png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, - png_malloc_warn(png_ptr, jmp_buf_size)); + png_malloc_warn(png_ptr, jmp_buf_size)); if (png_ptr->jmp_buf_ptr == NULL) return NULL; /* new NULL return on OOM */ @@ -709,7 +709,7 @@ png_free_jmpbuf(png_structrp png_ptr) */ static PNG_FUNCTION(void /* PRIVATE */, png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) + PNG_NORETURN) { #ifdef PNG_CONSOLE_IO_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED @@ -768,7 +768,7 @@ png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN) /* If control reaches this point, png_longjmp() must not return. The only * choice is to terminate the whole process (or maybe the thread); to do - * this the ANSI-C abort() function is used unless a different method is + * this the ANSI-C abort() function is used unless a different method is * implemented by overriding the default configuration setting for * PNG_ABORT(). */ @@ -883,7 +883,7 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) */ PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), - PNG_NORETURN) + PNG_NORETURN) { const png_const_structrp png_ptr = png_nonconst_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); @@ -906,7 +906,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), /* Missing longjmp buffer, the following is to help debugging: */ { size_t pos = png_safecat(image->message, (sizeof image->message), 0, - "bad longjmp: "); + "bad longjmp: "); png_safecat(image->message, (sizeof image->message), pos, error_message); } diff --git a/src/third-party/libpng/pngget.c b/src/third-party/libpng/pngget.c index 743a6a9bb..26e9fb1c3 100644 --- a/src/third-party/libpng/pngget.c +++ b/src/third-party/libpng/pngget.c @@ -1,8 +1,8 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -338,7 +338,7 @@ ppi_from_ppm(png_uint_32 ppm) png_fixed_point result; if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, 5000) != 0) - return result; + return (png_uint_32)result; /* Overflow. */ return 0; @@ -456,11 +456,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, return (retval); } #endif /* pHYs */ -#endif /* INCH_CONVERSIONS */ +#endif /* INCH_CONVERSIONS */ /* png_get_channels really belongs in here, too, but it's been around longer */ -#endif /* EASY_ACCESS */ +#endif /* EASY_ACCESS */ png_byte PNGAPI @@ -486,7 +486,7 @@ png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) #ifdef PNG_bKGD_SUPPORTED png_uint_32 PNGAPI png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_16p *background) + png_color_16p *background) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0 && @@ -526,28 +526,28 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, if (white_x != NULL) *white_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); + info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); if (white_y != NULL) *white_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); + info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); if (red_x != NULL) *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, - "cHRM red X"); + "cHRM red X"); if (red_y != NULL) *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, - "cHRM red Y"); + "cHRM red Y"); if (green_x != NULL) *green_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); + info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); if (green_y != NULL) *green_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); + info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); if (blue_x != NULL) *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, - "cHRM blue X"); + "cHRM blue X"); if (blue_y != NULL) *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, - "cHRM blue Y"); + "cHRM blue Y"); return (PNG_INFO_cHRM); } @@ -556,42 +556,42 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 PNGAPI png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *red_X, double *red_Y, double *red_Z, double *green_X, - double *green_Y, double *green_Z, double *blue_X, double *blue_Y, - double *blue_Z) + double *red_X, double *red_Y, double *red_Z, double *green_X, + double *green_Y, double *green_Z, double *blue_X, double *blue_Y, + double *blue_Z) { if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); if (red_X != NULL) *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, - "cHRM red X"); + "cHRM red X"); if (red_Y != NULL) *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, - "cHRM red Y"); + "cHRM red Y"); if (red_Z != NULL) *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, - "cHRM red Z"); + "cHRM red Z"); if (green_X != NULL) *green_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); + info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); if (green_Y != NULL) *green_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); + info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); if (green_Z != NULL) *green_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); + info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); if (blue_X != NULL) *blue_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); + info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); if (blue_Y != NULL) *blue_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); + info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); if (blue_Z != NULL) *blue_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); + info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); return (PNG_INFO_cHRM); } @@ -681,8 +681,8 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, png_debug1(1, "in %s retrieval function", "gAMA"); if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) + (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && + file_gamma != NULL) { *file_gamma = info_ptr->colorspace.gamma; return (PNG_INFO_gAMA); @@ -704,7 +704,7 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, file_gamma != NULL) { *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, - "png_get_gAMA"); + "png_get_gAMA"); return (PNG_INFO_gAMA); } @@ -773,6 +773,35 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, } #endif +#ifdef PNG_eXIf_SUPPORTED +png_uint_32 PNGAPI +png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, + png_bytep *exif) +{ + png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1"); + PNG_UNUSED(info_ptr) + PNG_UNUSED(exif) + return 0; +} + +png_uint_32 PNGAPI +png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *num_exif, png_bytep *exif) +{ + png_debug1(1, "in %s retrieval function", "eXIf"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL) + { + *num_exif = info_ptr->num_exif; + *exif = info_ptr->exif; + return (PNG_INFO_eXIf); + } + + return (0); +} +#endif + #ifdef PNG_hIST_SUPPORTED png_uint_32 PNGAPI png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, @@ -901,7 +930,7 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, */ *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), - "sCAL height"); + "sCAL height"); return (PNG_INFO_sCAL); } @@ -1142,19 +1171,19 @@ png_get_compression_buffer_size(png_const_structrp png_ptr) return 0; #ifdef PNG_WRITE_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) #endif { #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - return png_ptr->IDAT_read_size; + return png_ptr->IDAT_read_size; #else - return PNG_IDAT_READ_SIZE; + return PNG_IDAT_READ_SIZE; #endif } #ifdef PNG_WRITE_SUPPORTED - else - return png_ptr->zbuffer_size; + else + return png_ptr->zbuffer_size; #endif } diff --git a/src/third-party/libpng/pnginfo.h b/src/third-party/libpng/pnginfo.h index c8c874dd1..d5f6149db 100644 --- a/src/third-party/libpng/pnginfo.h +++ b/src/third-party/libpng/pnginfo.h @@ -2,7 +2,7 @@ /* pnginfo.h - header file for PNG reference library * * Last changed in libpng 1.6.1 [March 28, 2013] - * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -185,6 +185,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ #endif +#ifdef PNG_eXIf_SUPPORTED + int num_exif; /* Added at libpng-1.6.31 */ + png_bytep exif; +# ifdef PNG_READ_eXIf_SUPPORTED + png_bytep eXIf_buf; /* Added at libpng-1.6.32 */ +# endif +#endif + #ifdef PNG_hIST_SUPPORTED /* The hIST chunk contains the relative frequency or importance of the * various palette entries, so that a viewer can intelligently select a @@ -223,7 +231,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) /* Storage for unknown chunks that the library doesn't recognize. */ png_unknown_chunkp unknown_chunks; - /* The type of this field is limited by the type of + /* The type of this field is limited by the type of * png_struct::user_chunk_cache_max, else overflow can occur. */ int unknown_chunks_num; diff --git a/src/third-party/libpng/pngmem.c b/src/third-party/libpng/pngmem.c index 8b157e54d..ff3ef7e88 100644 --- a/src/third-party/libpng/pngmem.c +++ b/src/third-party/libpng/pngmem.c @@ -1,8 +1,8 @@ /* pngmem.c - stub functions for memory allocation * - * Last changed in libpng 1.6.15 [November 20, 2014] - * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * Last changed in libpng 1.6.26 [October 20, 2016] + * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -66,7 +66,7 @@ png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) */ PNG_FUNCTION(png_voidp /* PRIVATE */, png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) + PNG_ALLOCATED) { /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS * allocators have also been removed in 1.6.0, so any 16-bit system now has @@ -77,6 +77,9 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), PNG_UNUSED(png_ptr) #endif + /* Some compilers complain that this is always true. However, it + * can be false when integer overflow happens. + */ if (size > 0 && size <= PNG_SIZE_MAX # ifdef PNG_MAX_MALLOC_64K && size <= 65536U @@ -104,9 +107,9 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), */ static png_voidp png_malloc_array_checked(png_const_structrp png_ptr, int nelements, - size_t element_size) + size_t element_size) { - png_alloc_size_t req = nelements; /* known to be > 0 */ + png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */ if (req <= PNG_SIZE_MAX/element_size) return png_malloc_base(png_ptr, req * element_size); @@ -117,7 +120,7 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements, PNG_FUNCTION(png_voidp /* PRIVATE */, png_malloc_array,(png_const_structrp png_ptr, int nelements, - size_t element_size),PNG_ALLOCATED) + size_t element_size),PNG_ALLOCATED) { if (nelements <= 0 || element_size == 0) png_error(png_ptr, "internal error: array alloc"); @@ -127,7 +130,7 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements, PNG_FUNCTION(png_voidp /* PRIVATE */, png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, - int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) + int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) { /* These are internal errors: */ if (add_elements <= 0 || element_size == 0 || old_elements < 0 || @@ -140,7 +143,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, if (add_elements <= INT_MAX - old_elements) { png_voidp new_array = png_malloc_array_checked(png_ptr, - old_elements+add_elements, element_size); + old_elements+add_elements, element_size); if (new_array != NULL) { @@ -151,7 +154,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, memcpy(new_array, old_array, element_size*(unsigned)old_elements); memset((char*)new_array + element_size*(unsigned)old_elements, 0, - element_size*(unsigned)add_elements); + element_size*(unsigned)add_elements); return new_array; } @@ -184,7 +187,7 @@ png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) #ifdef PNG_USER_MEM_SUPPORTED PNG_FUNCTION(png_voidp,PNGAPI png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED PNG_DEPRECATED) + PNG_ALLOCATED PNG_DEPRECATED) { png_voidp ret; @@ -207,7 +210,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), */ PNG_FUNCTION(png_voidp,PNGAPI png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) + PNG_ALLOCATED) { if (png_ptr != NULL) { diff --git a/src/third-party/libpng/pngpread.c b/src/third-party/libpng/pngpread.c index 823dcad8c..fbe361dc3 100644 --- a/src/third-party/libpng/pngpread.c +++ b/src/third-party/libpng/pngpread.c @@ -1,8 +1,8 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -19,7 +19,6 @@ #define PNG_READ_SIG_MODE 0 #define PNG_READ_CHUNK_MODE 1 #define PNG_READ_IDAT_MODE 2 -#define PNG_SKIP_MODE 3 #define PNG_READ_tEXt_MODE 4 #define PNG_READ_zTXt_MODE 5 #define PNG_READ_DONE_MODE 6 @@ -78,32 +77,14 @@ png_process_data_pause(png_structrp png_ptr, int save) png_uint_32 PNGAPI png_process_data_skip(png_structrp png_ptr) { - png_uint_32 remaining = 0; - - if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE && - png_ptr->skip_length > 0) - { - /* At the end of png_process_data the buffer size must be 0 (see the loop - * above) so we can detect a broken call here: - */ - if (png_ptr->buffer_size != 0) - png_error(png_ptr, - "png_process_data_skip called inside png_process_data"); - - /* If is impossible for there to be a saved buffer at this point - - * otherwise we could not be in SKIP mode. This will also happen if - * png_process_skip is called inside png_process_data (but only very - * rarely.) - */ - if (png_ptr->save_buffer_size != 0) - png_error(png_ptr, "png_process_data_skip called with saved data"); - - remaining = png_ptr->skip_length; - png_ptr->skip_length = 0; - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } - - return remaining; +/* TODO: Deprecate and remove this API. + * Somewhere the implementation of this seems to have been lost, + * or abandoned. It was only to support some internal back-door access + * to png_struct) in libpng-1.4.x. + */ + png_app_warning(png_ptr, +"png_process_data_skip is not implemented in any current version of libpng"); + return 0; } /* What we do with the incoming data depends on what we were previously @@ -135,12 +116,6 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) break; } - case PNG_SKIP_MODE: - { - png_push_crc_finish(png_ptr); - break; - } - default: { png_ptr->buffer_size = 0; @@ -158,8 +133,8 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) void /* PRIVATE */ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) { - png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ - num_to_check = 8 - num_checked; + png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ + num_to_check = 8 - num_checked; if (png_ptr->buffer_size < num_to_check) { @@ -214,6 +189,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) png_crc_read(png_ptr, chunk_tag, 4); png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); png_check_chunk_name(png_ptr, png_ptr->chunk_name); + png_check_chunk_length(png_ptr, png_ptr->push_length); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } @@ -235,12 +211,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) (png_ptr->mode & PNG_HAVE_PLTE) == 0) png_error(png_ptr, "Missing PLTE before IDAT"); - png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->process_mode = PNG_READ_IDAT_MODE; - if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) - if (png_ptr->push_length == 0) - return; + if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) + if (png_ptr->push_length == 0) + return; + + png_ptr->mode |= PNG_HAVE_IDAT; if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) png_benign_error(png_ptr, "Too many IDATs found"); @@ -433,75 +411,12 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) { PNG_PUSH_SAVE_BUFFER_IF_FULL png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + PNG_HANDLE_CHUNK_AS_DEFAULT); } png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; } -void /* PRIVATE */ -png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip) -{ - png_ptr->process_mode = PNG_SKIP_MODE; - png_ptr->skip_length = skip; -} - -void /* PRIVATE */ -png_push_crc_finish(png_structrp png_ptr) -{ - if (png_ptr->skip_length != 0 && png_ptr->save_buffer_size != 0) - { - png_size_t save_size = png_ptr->save_buffer_size; - png_uint_32 skip_length = png_ptr->skip_length; - - /* We want the smaller of 'skip_length' and 'save_buffer_size', but - * they are of different types and we don't know which variable has the - * fewest bits. Carefully select the smaller and cast it to the type of - * the larger - this cannot overflow. Do not cast in the following test - * - it will break on either 16 or 64 bit platforms. - */ - if (skip_length < save_size) - save_size = (png_size_t)skip_length; - - else - skip_length = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_ptr->skip_length -= skip_length; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - if (png_ptr->skip_length != 0 && png_ptr->current_buffer_size != 0) - { - png_size_t save_size = png_ptr->current_buffer_size; - png_uint_32 skip_length = png_ptr->skip_length; - - /* We want the smaller of 'skip_length' and 'current_buffer_size', here, - * the same problem exists as above and the same solution. - */ - if (skip_length < save_size) - save_size = (png_size_t)skip_length; - - else - skip_length = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_ptr->skip_length -= skip_length; - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } - if (png_ptr->skip_length == 0) - { - PNG_PUSH_SAVE_BUFFER_IF_LT(4) - png_crc_finish(png_ptr, 0); - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } -} - void PNGCBAPI png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) { @@ -584,13 +499,14 @@ png_push_save_buffer(png_structrp png_ptr) if (png_ptr->save_buffer == NULL) { png_free(png_ptr, old_buffer); - old_buffer = NULL; png_error(png_ptr, "Insufficient memory for save_buffer"); } - memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); + if (old_buffer) + memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); + else if (png_ptr->save_buffer_size) + png_error(png_ptr, "save_buffer error"); png_free(png_ptr, old_buffer); - old_buffer = NULL; png_ptr->save_buffer_max = new_max; } if (png_ptr->current_buffer_size) @@ -606,7 +522,7 @@ png_push_save_buffer(png_structrp png_ptr) void /* PRIVATE */ png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, - png_size_t buffer_length) + png_size_t buffer_length) { png_ptr->current_buffer = buffer; png_ptr->current_buffer_size = buffer_length; @@ -653,7 +569,7 @@ png_push_read_IDAT(png_structrp png_ptr) * are of different types and we don't know which variable has the fewest * bits. Carefully select the smaller and cast it to the type of the * larger - this cannot overflow. Do not cast in the following test - it - * will break on either 16 or 64 bit platforms. + * will break on either 16-bit or 64-bit platforms. */ if (idat_size < save_size) save_size = (png_size_t)idat_size; @@ -696,6 +612,7 @@ png_push_read_IDAT(png_structrp png_ptr) png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; } + if (png_ptr->idat_size == 0) { PNG_PUSH_SAVE_BUFFER_IF_LT(4) @@ -708,7 +625,7 @@ png_push_read_IDAT(png_structrp png_ptr) void /* PRIVATE */ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, - png_size_t buffer_length) + png_size_t buffer_length) { /* The caller checks for a non-zero buffer length. */ if (!(buffer_length > 0) || buffer == NULL) @@ -751,7 +668,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, * change the current behavior (see comments in inflate.c * for why this doesn't happen at present with zlib 1.2.5). */ - ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); + ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH); /* Check for any failure before proceeding. */ if (ret != Z_OK && ret != Z_STREAM_END) @@ -768,7 +685,12 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, png_warning(png_ptr, "Truncated compressed data in IDAT"); else - png_error(png_ptr, "Decompression error in IDAT"); + { + if (ret == Z_DATA_ERROR) + png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch"); + else + png_error(png_ptr, "Decompression error in IDAT"); + } /* Skip the check on unprocessed input */ return; @@ -866,7 +788,7 @@ png_push_process_row(png_structrp png_ptr) { if (png_ptr->pass < 6) png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); + png_ptr->transformations); switch (png_ptr->pass) { @@ -1128,7 +1050,7 @@ png_push_have_row(png_structrp png_ptr, png_bytep row) { if (png_ptr->row_fn != NULL) (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, - (int)png_ptr->pass); + (int)png_ptr->pass); } #ifdef PNG_READ_INTERLACING_SUPPORTED diff --git a/src/third-party/libpng/pngpriv.h b/src/third-party/libpng/pngpriv.h index 5980a3fc3..1f2e90f2b 100644 --- a/src/third-party/libpng/pngpriv.h +++ b/src/third-party/libpng/pngpriv.h @@ -1,8 +1,8 @@ /* pngpriv.h - private declarations for use inside libpng * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -35,7 +35,9 @@ * Windows/Visual Studio) there is no effect; the OS specific tests below are * still required (as of 2011-05-02.) */ -#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ +#endif #ifndef PNG_VERSION_INFO_ONLY /* Standard library headers not required by png.h: */ @@ -118,8 +120,12 @@ * to compile with an appropriate #error if ALIGNED_MEMORY has been turned * off. * - * Note that gcc-4.9 defines __ARM_NEON instead of __ARM_NEON__, so we - * check both variants. + * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated + * __ARM_NEON__, so we check both variants. + * + * To disable ARM_NEON optimizations entirely, and skip compiling the + * associated assembler code, pass --enable-arm-neon=no to configure + * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS. */ # if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \ defined(PNG_ALIGNED_MEMORY_SUPPORTED) @@ -178,6 +184,84 @@ # endif #endif /* PNG_ARM_NEON_OPT > 0 */ +#ifndef PNG_MIPS_MSA_OPT +# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_MIPS_MSA_OPT 2 +# else +# define PNG_MIPS_MSA_OPT 0 +# endif +#endif + +#ifndef PNG_POWERPC_VSX_OPT +# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) +# define PNG_POWERPC_VSX_OPT 2 +# else +# define PNG_POWERPC_VSX_OPT 0 +# endif +#endif + +#ifndef PNG_INTEL_SSE_OPT +# ifdef PNG_INTEL_SSE + /* Only check for SSE if the build configuration has been modified to + * enable SSE optimizations. This means that these optimizations will + * be off by default. See contrib/intel for more details. + */ +# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ + defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP >= 2) +# define PNG_INTEL_SSE_OPT 1 +# endif +# endif +#endif + +#if PNG_INTEL_SSE_OPT > 0 +# ifndef PNG_INTEL_SSE_IMPLEMENTATION +# if defined(__SSE4_1__) || defined(__AVX__) + /* We are not actually using AVX, but checking for AVX is the best + way we can detect SSE4.1 and SSSE3 on MSVC. + */ +# define PNG_INTEL_SSE_IMPLEMENTATION 3 +# elif defined(__SSSE3__) +# define PNG_INTEL_SSE_IMPLEMENTATION 2 +# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP >= 2) +# define PNG_INTEL_SSE_IMPLEMENTATION 1 +# else +# define PNG_INTEL_SSE_IMPLEMENTATION 0 +# endif +# endif + +# if PNG_INTEL_SSE_IMPLEMENTATION > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2 +# endif +#endif + +#if PNG_MIPS_MSA_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa +# ifndef PNG_MIPS_MSA_IMPLEMENTATION +# if defined(__mips_msa) +# if defined(__clang__) +# elif defined(__GNUC__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +# define PNG_MIPS_MSA_IMPLEMENTATION 2 +# endif /* no GNUC support */ +# endif /* __GNUC__ */ +# else /* !defined __mips_msa */ +# define PNG_MIPS_MSA_IMPLEMENTATION 2 +# endif /* __mips_msa */ +# endif /* !PNG_MIPS_MSA_IMPLEMENTATION */ + +# ifndef PNG_MIPS_MSA_IMPLEMENTATION +# define PNG_MIPS_MSA_IMPLEMENTATION 1 +# endif +#endif /* PNG_MIPS_MSA_OPT > 0 */ + +#if PNG_POWERPC_VSX_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx +# define PNG_POWERPC_VSX_IMPLEMENTATION 1 +#endif + + /* Is this a build of a DLL where compilation of the object modules requires * different preprocessor settings to those required for a simple library? If * so PNG_BUILD_DLL must be set. @@ -248,17 +332,18 @@ * always be used to declare an extern data or function object in this file. */ #ifndef PNG_INTERNAL_DATA -# define PNG_INTERNAL_DATA(type, name, array) extern type name array +# define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array #endif #ifndef PNG_INTERNAL_FUNCTION # define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ - extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) + PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) #endif #ifndef PNG_INTERNAL_CALLBACK # define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ - extern PNG_FUNCTION(type, (PNGCBAPI name), args, PNG_EMPTY attributes) + PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\ + PNG_EMPTY attributes) #endif /* If floating or fixed point APIs are disabled they may still be compiled @@ -296,6 +381,22 @@ # define PNG_DLL_EXPORT #endif +/* This is a global switch to set the compilation for an installed system + * (a release build). It can be set for testing debug builds to ensure that + * they will compile when the build type is switched to RC or STABLE, the + * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE. Set this in CPPFLAGS + * with either: + * + * -DPNG_RELEASE_BUILD Turns on the release compile path + * -DPNG_RELEASE_BUILD=0 Turns it off + * or in your pngusr.h with + * #define PNG_RELEASE_BUILD=1 Turns on the release compile path + * #define PNG_RELEASE_BUILD=0 Turns it off + */ +#ifndef PNG_RELEASE_BUILD +# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) +#endif + /* SECURITY and SAFETY: * * libpng is built with support for internal limits on image dimensions and @@ -353,25 +454,6 @@ # define png_fixed_error(s1,s2) png_err(s1) #endif -/* C allows up-casts from (void*) to any pointer and (const void*) to any - * pointer to a const object. C++ regards this as a type error and requires an - * explicit, static, cast and provides the static_cast<> rune to ensure that - * const is not cast away. - */ -#ifdef __cplusplus -# define png_voidcast(type, value) static_cast(value) -# define png_constcast(type, value) const_cast(value) -# define png_aligncast(type, value) \ - static_cast(static_cast(value)) -# define png_aligncastconst(type, value) \ - static_cast(static_cast(value)) -#else -# define png_voidcast(type, value) (value) -# define png_constcast(type, value) ((type)(value)) -# define png_aligncast(type, value) ((void*)(value)) -# define png_aligncastconst(type, value) ((const void*)(value)) -#endif /* __cplusplus */ - /* Some fixed point APIs are still required even if not exported because * they get used by the corresponding floating point APIs. This magic * deals with this: @@ -386,6 +468,35 @@ /* Other defines specific to compilers can go here. Try to keep * them inside an appropriate ifdef/endif pair for portability. */ + +/* C allows up-casts from (void*) to any pointer and (const void*) to any + * pointer to a const object. C++ regards this as a type error and requires an + * explicit, static, cast and provides the static_cast<> rune to ensure that + * const is not cast away. + */ +#ifdef __cplusplus +# define png_voidcast(type, value) static_cast(value) +# define png_constcast(type, value) const_cast(value) +# define png_aligncast(type, value) \ + static_cast(static_cast(value)) +# define png_aligncastconst(type, value) \ + static_cast(static_cast(value)) +#else +# define png_voidcast(type, value) (value) +# ifdef _WIN64 +# ifdef __GNUC__ + typedef unsigned long long png_ptruint; +# else + typedef unsigned __int64 png_ptruint; +# endif +# else + typedef unsigned long png_ptruint; +# endif +# define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value)) +# define png_aligncast(type, value) ((void*)(value)) +# define png_aligncastconst(type, value) ((const void*)(value)) +#endif /* __cplusplus */ + #if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) /* png.c requires the following ANSI-C constants if the conversion of @@ -399,10 +510,10 @@ # if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) - /* We need to check that hasn't already been included earlier - * as it seems it doesn't agree with , yet we should really use - * if possible. - */ + /* We need to check that hasn't already been included earlier + * as it seems it doesn't agree with , yet we should really use + * if possible. + */ # if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) # include # endif @@ -410,9 +521,9 @@ # include # endif # if defined(_AMIGA) && defined(__SASC) && defined(_M68881) - /* Amiga SAS/C: We must include builtin FPU functions when compiling using - * MATH=68881 - */ + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ # include # endif #endif @@ -483,7 +594,8 @@ /* This implicitly assumes alignment is always to a power of 2. */ #ifdef png_alignof # define png_isaligned(ptr, type)\ - ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) + (((type)((const char*)ptr-(const char*)0) & \ + (type)(png_alignof(type)-1)) == 0) #else # define png_isaligned(ptr, type) 0 #endif @@ -500,96 +612,92 @@ * are defined in png.h because they need to be visible to applications * that call png_set_unknown_chunk(). */ -/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */ -/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */ -#define PNG_HAVE_IDAT 0x04 -/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */ -#define PNG_HAVE_IEND 0x10 - /* 0x20 (unused) */ - /* 0x40 (unused) */ - /* 0x80 (unused) */ -#define PNG_HAVE_CHUNK_HEADER 0x100 -#define PNG_WROTE_tIME 0x200 -#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 -#define PNG_BACKGROUND_IS_GRAY 0x800 -#define PNG_HAVE_PNG_SIGNATURE 0x1000 -#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ - /* 0x4000 (unused) */ -#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */ +/* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */ +/* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */ +#define PNG_HAVE_IDAT 0x04U +/* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */ +#define PNG_HAVE_IEND 0x10U + /* 0x20U (unused) */ + /* 0x40U (unused) */ + /* 0x80U (unused) */ +#define PNG_HAVE_CHUNK_HEADER 0x100U +#define PNG_WROTE_tIME 0x200U +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U +#define PNG_BACKGROUND_IS_GRAY 0x800U +#define PNG_HAVE_PNG_SIGNATURE 0x1000U +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */ + /* 0x4000U (unused) */ +#define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */ /* Flags for the transformations the PNG library does on the image data */ -#define PNG_BGR 0x0001 -#define PNG_INTERLACE 0x0002 -#define PNG_PACK 0x0004 -#define PNG_SHIFT 0x0008 -#define PNG_SWAP_BYTES 0x0010 -#define PNG_INVERT_MONO 0x0020 -#define PNG_QUANTIZE 0x0040 -#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */ -#define PNG_BACKGROUND_EXPAND 0x0100 -#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */ -#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */ -#define PNG_RGBA 0x0800 -#define PNG_EXPAND 0x1000 -#define PNG_GAMMA 0x2000 -#define PNG_GRAY_TO_RGB 0x4000 -#define PNG_FILLER 0x8000 -#define PNG_PACKSWAP 0x10000 -#define PNG_SWAP_ALPHA 0x20000 -#define PNG_STRIP_ALPHA 0x40000 -#define PNG_INVERT_ALPHA 0x80000 -#define PNG_USER_TRANSFORM 0x100000 -#define PNG_RGB_TO_GRAY_ERR 0x200000 -#define PNG_RGB_TO_GRAY_WARN 0x400000 -#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */ -#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */ -#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */ -#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */ -#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */ - /* 0x8000000 unused */ - /* 0x10000000 unused */ - /* 0x20000000 unused */ - /* 0x40000000 unused */ +#define PNG_BGR 0x0001U +#define PNG_INTERLACE 0x0002U +#define PNG_PACK 0x0004U +#define PNG_SHIFT 0x0008U +#define PNG_SWAP_BYTES 0x0010U +#define PNG_INVERT_MONO 0x0020U +#define PNG_QUANTIZE 0x0040U +#define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */ +#define PNG_BACKGROUND_EXPAND 0x0100U +#define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */ +#define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */ +#define PNG_RGBA 0x0800U +#define PNG_EXPAND 0x1000U +#define PNG_GAMMA 0x2000U +#define PNG_GRAY_TO_RGB 0x4000U +#define PNG_FILLER 0x8000U +#define PNG_PACKSWAP 0x10000U +#define PNG_SWAP_ALPHA 0x20000U +#define PNG_STRIP_ALPHA 0x40000U +#define PNG_INVERT_ALPHA 0x80000U +#define PNG_USER_TRANSFORM 0x100000U +#define PNG_RGB_TO_GRAY_ERR 0x200000U +#define PNG_RGB_TO_GRAY_WARN 0x400000U +#define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */ +#define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */ +#define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */ +#define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */ + /* 0x8000000U unused */ + /* 0x10000000U unused */ + /* 0x20000000U unused */ + /* 0x40000000U unused */ /* Flags for png_create_struct */ -#define PNG_STRUCT_PNG 0x0001 -#define PNG_STRUCT_INFO 0x0002 - -/* Scaling factor for filter heuristic weighting calculations */ -#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) -#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) +#define PNG_STRUCT_PNG 0x0001U +#define PNG_STRUCT_INFO 0x0002U /* Flags for the png_ptr->flags rather than declaring a byte for each one */ -#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 -#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */ - /* 0x0004 unused */ -#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */ - /* 0x0010 unused */ - /* 0x0020 unused */ -#define PNG_FLAG_ROW_INIT 0x0040 -#define PNG_FLAG_FILLER_AFTER 0x0080 -#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 -#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 -#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 -#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 -#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ -#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ -#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ -/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 */ -/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 */ -#define PNG_FLAG_LIBRARY_MISMATCH 0x20000 -#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000 -#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 -#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */ -#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */ -#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */ - /* 0x800000 unused */ - /* 0x1000000 unused */ - /* 0x2000000 unused */ - /* 0x4000000 unused */ - /* 0x8000000 unused */ - /* 0x10000000 unused */ - /* 0x20000000 unused */ - /* 0x40000000 unused */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U +#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */ + /* 0x0004U unused */ +#define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */ + /* 0x0010U unused */ + /* 0x0020U unused */ +#define PNG_FLAG_ROW_INIT 0x0040U +#define PNG_FLAG_FILLER_AFTER 0x0080U +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400U +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U +#define PNG_FLAG_ASSUME_sRGB 0x1000U /* Added to libpng-1.5.4 */ +#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */ +#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */ +/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */ +/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */ +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000U +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000U +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U +#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */ +#define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */ +#define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */ + /* 0x800000U unused */ + /* 0x1000000U unused */ + /* 0x2000000U unused */ + /* 0x4000000U unused */ + /* 0x8000000U unused */ + /* 0x10000000U unused */ + /* 0x20000000U unused */ + /* 0x40000000U unused */ #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ PNG_FLAG_CRC_ANCILLARY_NOWARN) @@ -623,6 +731,24 @@ ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \ (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) ) +/* This returns the number of trailing bits in the last byte of a row, 0 if the + * last byte is completely full of pixels. It is, in principle, (pixel_bits x + * width) % 8, but that would overflow for large 'width'. The second macro is + * the same except that it returns the number of unused bits in the last byte; + * (8-TRAILBITS), but 0 when TRAILBITS is 0. + * + * NOTE: these macros are intended to be self-evidently correct and never + * overflow on the assumption that pixel_bits is in the range 0..255. The + * arguments are evaluated only once and they can be signed (e.g. as a result of + * the integral promotions). The result of the expression always has type + * (png_uint_32), however the compiler always knows it is in the range 0..7. + */ +#define PNG_TRAILBITS(pixel_bits, width) \ + (((pixel_bits) * ((width) % (png_uint_32)8)) % 8) + +#define PNG_PADBITS(pixel_bits, width) \ + ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8) + /* PNG_OUT_OF_RANGE returns true if value is outside the range * ideal-delta..ideal+delta. Each argument is evaluated twice. * "ideal" and "delta" should be constants, normally simple @@ -648,7 +774,7 @@ /* The fixed point conversion performs range checking and evaluates * its argument multiple times, so must be used with care. The * range checking uses the PNG specification values for a signed - * 32 bit fixed point value except that the values are deliberately + * 32-bit fixed point value except that the values are deliberately * rounded-to-zero to an integral value - 21474 (21474.83 is roughly * (2^31-1) * 100000). 's' is a string that describes the value being * converted. @@ -716,6 +842,7 @@ #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) @@ -795,7 +922,7 @@ */ #endif -/* This is used for 16 bit gamma tables -- only the top level pointers are +/* This is used for 16-bit gamma tables -- only the top level pointers are * const; this could be changed: */ typedef const png_uint_16p * png_const_uint_16pp; @@ -1008,7 +1135,7 @@ PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr, #ifdef PNG_WRITE_cHRM_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, const png_xy *xy), PNG_EMPTY); - /* The xy value must have been previously validated */ + /* The xy value must have been previously validated */ #endif #ifdef PNG_WRITE_sRGB_SUPPORTED @@ -1016,6 +1143,11 @@ PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr, int intent),PNG_EMPTY); #endif +#ifdef PNG_WRITE_eXIf_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr, + png_bytep exif, int num_exif),PNG_EMPTY); +#endif + #ifdef PNG_WRITE_iCCP_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, png_const_charp name, png_const_bytep profile), PNG_EMPTY); @@ -1157,6 +1289,7 @@ PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info, PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY); +#if PNG_ARM_NEON_OPT > 0 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop @@ -1171,6 +1304,56 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + +#if PNG_MIPS_MSA_OPT > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + +#if PNG_POWERPC_VSX_OPT > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + +#if PNG_INTEL_SSE_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif /* Choose the best filter to use and filter the row data */ PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, @@ -1198,6 +1381,14 @@ PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr), /* Initialize the row buffers, etc. */ PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); +#if ZLIB_VERNUM >= 0x1240 +PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush), + PNG_EMPTY); +# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush) +#else /* Zlib < 1.2.4 */ +# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush) +#endif /* Zlib < 1.2.4 */ + #ifdef PNG_READ_TRANSFORMS_SUPPORTED /* Optional call to update the users info structure */ PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, @@ -1256,6 +1447,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); #endif +#ifdef PNG_READ_eXIf_SUPPORTED +PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr, + png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); +#endif + #ifdef PNG_READ_gAMA_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); @@ -1331,8 +1527,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); #endif -PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr, - png_uint_32 chunk_name),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr, + const png_uint_32 chunk_name),PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr, + const png_uint_32 chunk_length),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); @@ -1372,10 +1571,6 @@ PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr, png_inforp info_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_crc_skip,(png_structrp png_ptr, - png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_crc_finish,(png_structrp png_ptr), - PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr), PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, @@ -1392,7 +1587,7 @@ PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, png_inforp info_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr, - png_bytep row),PNG_EMPTY); + png_bytep row),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr, png_inforp info_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, @@ -1431,13 +1626,13 @@ PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, png_inforp info_ptr), PNG_EMPTY); - /* Synchronize the info 'valid' flags with the colorspace */ + /* Synchronize the info 'valid' flags with the colorspace */ PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, png_inforp info_ptr), PNG_EMPTY); - /* Copy the png_struct colorspace to the info_struct and call the above to - * synchronize the flags. Checks for NULL info_ptr and does nothing. - */ + /* Copy the png_struct colorspace to the info_struct and call the above to + * synchronize the flags. Checks for NULL info_ptr and does nothing. + */ #endif /* Added at libpng version 1.4.0 */ @@ -1471,9 +1666,11 @@ PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, /* The 'name' is used for information only */ /* Routines for checking parts of an ICC profile. */ +#ifdef PNG_READ_iCCP_SUPPORTED PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, png_colorspacerp colorspace, png_const_charp name, png_uint_32 profile_length), PNG_EMPTY); +#endif /* READ_iCCP */ PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, png_colorspacerp colorspace, png_const_charp name, png_uint_32 profile_length, @@ -1892,10 +2089,25 @@ PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr, * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. */ +# if PNG_ARM_NEON_OPT > 0 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif +#if PNG_MIPS_MSA_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +#endif + +# if PNG_INTEL_SSE_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +# endif +#endif + +PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, + png_const_charp key, png_bytep new_key), PNG_EMPTY); + /* Maintainer: Put new private prototypes here ^ */ #include "pngdebug.h" diff --git a/src/third-party/libpng/pngread.c b/src/third-party/libpng/pngread.c index 6764dbe56..da32e9ad9 100644 --- a/src/third-party/libpng/pngread.c +++ b/src/third-party/libpng/pngread.c @@ -1,8 +1,8 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.33 [September 28, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -28,10 +28,10 @@ png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, { #ifndef PNG_USER_MEM_SUPPORTED png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); + error_fn, warn_fn, NULL, NULL, NULL); #else return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); + warn_fn, NULL, NULL, NULL); } /* Alternate create PNG structure for reading, and allocate any memory @@ -43,7 +43,7 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) { png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); + error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); #endif /* USER_MEM */ if (png_ptr != NULL) @@ -63,7 +63,7 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, /* In stable builds only warn if an application error can be completely * handled. */ -# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC +# if PNG_RELEASE_BUILD png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; # endif # endif @@ -127,7 +127,10 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) } else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; png_ptr->mode |= PNG_AFTER_IDAT; + } /* This should be a binary subdivision search or a hash for * matching the chunk name rather than a linear search. @@ -172,6 +175,11 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) png_handle_cHRM(png_ptr, info_ptr, length); #endif +#ifdef PNG_READ_eXIf_SUPPORTED + else if (chunk_name == png_eXIf) + png_handle_eXIf(png_ptr, info_ptr, length); +#endif + #ifdef PNG_READ_gAMA_SUPPORTED else if (chunk_name == png_gAMA) png_handle_gAMA(png_ptr, info_ptr, length); @@ -249,7 +257,7 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr) else png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + PNG_HANDLE_CHUNK_AS_DEFAULT); } } #endif /* SEQUENTIAL_READ */ @@ -276,7 +284,7 @@ png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) /* New in 1.6.0 this avoids the bug of doing the initializations twice */ else png_app_error(png_ptr, - "png_read_update_info/png_start_read_image: duplicate call"); + "png_read_update_info/png_start_read_image: duplicate call"); } } @@ -299,7 +307,7 @@ png_start_read_image(png_structrp png_ptr) /* New in 1.6.0 this avoids the bug of doing the initializations twice */ else png_app_error(png_ptr, - "png_start_read_image/png_read_update_info: duplicate call"); + "png_start_read_image/png_read_update_info: duplicate call"); } } #endif /* SEQUENTIAL_READ */ @@ -356,9 +364,9 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); + png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); png_uint_32 red = (s0 + s1 + 65536) & 0xffff; png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; *(rp ) = (png_byte)((red >> 8) & 0xff); @@ -531,13 +539,14 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) png_error(png_ptr, "Invalid attempt to read row data"); /* Fill the row with IDAT data: */ + png_ptr->row_buf[0]=255; /* to force error if no data was found */ png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) { if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); + png_ptr->prev_row + 1, png_ptr->row_buf[0]); else png_error(png_ptr, "bad adaptive filter value"); } @@ -581,7 +590,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) { if (png_ptr->pass < 6) png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); + png_ptr->transformations); if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, 1/*display*/); @@ -716,7 +725,7 @@ png_read_image(png_structrp png_ptr, png_bytepp image) * but the caller should do it! */ png_warning(png_ptr, "Interlace handling should be turned on when " - "using png_read_image"); + "using png_read_image"); /* Make sure this is set correctly */ png_ptr->num_rows = png_ptr->height; } @@ -776,8 +785,8 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED /* Report invalid palette index; added at libng-1.5.10 */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max > png_ptr->num_palette) - png_benign_error(png_ptr, "Read palette index exceeding num_palette"); + png_ptr->num_palette_max > png_ptr->num_palette) + png_benign_error(png_ptr, "Read palette index exceeding num_palette"); #endif do @@ -785,6 +794,9 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) png_uint_32 length = png_read_chunk_header(png_ptr); png_uint_32 chunk_name = png_ptr->chunk_name; + if (chunk_name != png_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + if (chunk_name == png_IEND) png_handle_IEND(png_ptr, info_ptr, length); @@ -799,9 +811,9 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) { if (chunk_name == png_IDAT) { - if ((length > 0) || - (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "Too many IDATs found"); + if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) + || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) + png_benign_error(png_ptr, ".Too many IDATs found"); } png_handle_unknown(png_ptr, info_ptr, length, keep); if (chunk_name == png_PLTE) @@ -812,10 +824,14 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) else if (chunk_name == png_IDAT) { /* Zero length IDATs are legal after the last IDAT has been - * read, but not after other chunks have been read. + * read, but not after other chunks have been read. 1.6 does not + * always read all the deflate data; specifically it cannot be relied + * upon to read the Adler32 at the end. If it doesn't ignore IDAT + * chunks which are longer than zero as well: */ - if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "Too many IDATs found"); + if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) + || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) + png_benign_error(png_ptr, "..Too many IDATs found"); png_crc_finish(png_ptr, length); } @@ -832,6 +848,11 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) png_handle_cHRM(png_ptr, info_ptr, length); #endif +#ifdef PNG_READ_eXIf_SUPPORTED + else if (chunk_name == png_eXIf) + png_handle_eXIf(png_ptr, info_ptr, length); +#endif + #ifdef PNG_READ_gAMA_SUPPORTED else if (chunk_name == png_gAMA) png_handle_gAMA(png_ptr, info_ptr, length); @@ -909,7 +930,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) else png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); + PNG_HANDLE_CHUNK_AS_DEFAULT); } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); } #endif /* SEQUENTIAL_READ */ @@ -1020,8 +1041,7 @@ png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) #ifdef PNG_INFO_IMAGE_SUPPORTED void PNGAPI png_read_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, - voidp params) + int transforms, voidp params) { if (png_ptr == NULL || info_ptr == NULL) return; @@ -1043,9 +1063,9 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr, /* Tell libpng to strip 16-bit/color files down to 8 bits per color. */ if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) - /* Added at libpng-1.5.4. "strip_16" produces the same result that it - * did in earlier versions, while "scale_16" is now more accurate. - */ + /* Added at libpng-1.5.4. "strip_16" produces the same result that it + * did in earlier versions, while "scale_16" is now more accurate. + */ #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED png_set_scale_16(png_ptr); #else @@ -1209,7 +1229,7 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr, for (iptr = 0; iptr < info_ptr->height; iptr++) info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, - png_malloc(png_ptr, info_ptr->rowbytes)); + png_malloc(png_ptr, info_ptr->rowbytes)); } png_read_image(png_ptr, info_ptr->row_pointers); @@ -1297,7 +1317,7 @@ png_image_read_init(png_imagep image) if (info_ptr != NULL) { png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); + png_malloc_warn(png_ptr, (sizeof *control))); if (control != NULL) { @@ -1384,7 +1404,9 @@ png_image_read_header(png_voidp argument) png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; +#ifdef PNG_BENIGN_ERRORS_SUPPORTED png_set_benign_errors(png_ptr, 1/*warn*/); +#endif png_read_info(png_ptr, info_ptr); /* Do this the fast way; just read directly out of png_struct. */ @@ -1422,7 +1444,7 @@ png_image_read_header(png_voidp argument) break; case PNG_COLOR_TYPE_PALETTE: - cmap_entries = png_ptr->num_palette; + cmap_entries = (png_uint_32)png_ptr->num_palette; break; default: @@ -1460,12 +1482,12 @@ png_image_begin_read_from_stdio(png_imagep image, FILE* file) else return png_image_error(image, - "png_image_begin_read_from_stdio: invalid argument"); + "png_image_begin_read_from_stdio: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); + "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); return 0; } @@ -1498,12 +1520,12 @@ png_image_begin_read_from_file(png_imagep image, const char *file_name) else return png_image_error(image, - "png_image_begin_read_from_file: invalid argument"); + "png_image_begin_read_from_file: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); + "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); return 0; } @@ -1540,7 +1562,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) } int PNGAPI png_image_begin_read_from_memory(png_imagep image, - png_const_voidp memory, png_size_t size) + png_const_voidp memory, png_size_t size) { if (image != NULL && image->version == PNG_IMAGE_VERSION) { @@ -1563,12 +1585,12 @@ int PNGAPI png_image_begin_read_from_memory(png_imagep image, else return png_image_error(image, - "png_image_begin_read_from_memory: invalid argument"); + "png_image_begin_read_from_memory: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); + "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); return 0; } @@ -1614,12 +1636,12 @@ png_image_skip_unused_chunks(png_structrp png_ptr) * IHDR, PLTE, tRNS, IDAT, and IEND chunks. */ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, - NULL, -1); + NULL, -1); /* But do not ignore image data handling chunks */ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, - chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); - } + chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); + } } # define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) @@ -1683,10 +1705,11 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) value *= 257; break; +#ifdef __GNUC__ default: png_error(display->image->opaque->png_ptr, - "unexpected encoding (internal error)"); - break; + "unexpected encoding (internal error)"); +#endif } return value; @@ -1694,8 +1717,8 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) static png_uint_32 png_colormap_compose(png_image_read_control *display, - png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, - png_uint_32 background, int encoding) + png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, + png_uint_32 background, int encoding) { /* The file value is composed on the background, the background has the given * encoding and so does the result, the file is encoded with P_FILE and the @@ -1731,14 +1754,14 @@ png_colormap_compose(png_image_read_control *display, */ static void png_create_colormap_entry(png_image_read_control *display, - png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, - png_uint_32 alpha, int encoding) + png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, + png_uint_32 alpha, int encoding) { png_imagep image = display->image; const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; + P_LINEAR : P_sRGB; const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && - (red != green || green != blue); + (red != green || green != blue); if (ip > 255) png_error(image->opaque->png_ptr, "color-map index out of range"); @@ -1871,7 +1894,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_uint_16)alpha; - /* FALL THROUGH */ + /* FALLTHROUGH */ case 3: if (alpha < 65535) @@ -1893,7 +1916,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_uint_16)alpha; - /* FALL THROUGH */ + /* FALLTHROUGH */ case 1: if (alpha < 65535) @@ -1922,6 +1945,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_byte)alpha; + /* FALLTHROUGH */ case 3: entry[afirst + (2 ^ bgr)] = (png_byte)blue; entry[afirst + 1] = (png_byte)green; @@ -1930,6 +1954,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_byte)alpha; + /* FALLTHROUGH */ case 1: entry[afirst] = (png_byte)green; break; @@ -1956,7 +1981,7 @@ make_gray_file_colormap(png_image_read_control *display) for (i=0; i<256; ++i) png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); - return i; + return (int)i; } static int @@ -1967,7 +1992,7 @@ make_gray_colormap(png_image_read_control *display) for (i=0; i<256; ++i) png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); - return i; + return (int)i; } #define PNG_GRAY_COLORMAP_ENTRIES 256 @@ -2018,10 +2043,10 @@ make_ga_colormap(png_image_read_control *display) for (g=0; g<6; ++g) png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, - P_sRGB); + P_sRGB); } - return i; + return (int)i; } #define PNG_GA_COLORMAP_ENTRIES 256 @@ -2042,11 +2067,11 @@ make_rgb_colormap(png_image_read_control *display) for (b=0; b<6; ++b) png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, - P_sRGB); + P_sRGB); } } - return i; + return (int)i; } #define PNG_RGB_COLORMAP_ENTRIES 216 @@ -2094,7 +2119,7 @@ png_image_read_colormap(png_voidp argument) else if (display->background == NULL /* no way to remove it */) png_error(png_ptr, - "a background color must be supplied to remove alpha/transparency"); + "background color must be supplied to remove alpha/transparency"); /* Get a copy of the background color (this avoids repeating the checks * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the @@ -2189,7 +2214,7 @@ png_image_read_colormap(png_voidp argument) */ if (i != trans) png_create_colormap_entry(display, i, val, val, val, 255, - P_FILE/*8-bit with file gamma*/); + P_FILE/*8-bit with file gamma*/); /* Else this entry is transparent. The colors don't matter if * there is an alpha channel (back_alpha == 0), but it does no @@ -2201,7 +2226,7 @@ png_image_read_colormap(png_voidp argument) */ else png_create_colormap_entry(display, i, back_r, back_g, back_b, - back_alpha, output_encoding); + back_alpha, output_encoding); } /* We need libpng to preserve the original encoding. */ @@ -2239,7 +2264,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "gray[16] color-map: too few entries"); - cmap_entries = make_gray_colormap(display); + cmap_entries = (unsigned int)make_gray_colormap(display); if (png_ptr->num_trans > 0) { @@ -2266,7 +2291,7 @@ png_image_read_colormap(png_voidp argument) * matches. */ png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); + back_g, 65535, P_LINEAR); } /* The background passed to libpng, however, must be the @@ -2280,8 +2305,8 @@ png_image_read_colormap(png_voidp argument) * doesn't. */ png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); output_processing = PNG_CMAP_NONE; break; @@ -2311,7 +2336,7 @@ png_image_read_colormap(png_voidp argument) * background color at full precision. */ png_create_colormap_entry(display, 254, back_r, back_g, back_b, - back_alpha, output_encoding); + back_alpha, output_encoding); } else @@ -2337,7 +2362,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "gray+alpha color-map: too few entries"); - cmap_entries = make_ga_colormap(display); + cmap_entries = (unsigned int)make_ga_colormap(display); background_index = PNG_CMAP_GA_BACKGROUND; output_processing = PNG_CMAP_GA; @@ -2371,7 +2396,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "gray-alpha color-map: too few entries"); - cmap_entries = make_gray_colormap(display); + cmap_entries = (unsigned int)make_gray_colormap(display); if (output_encoding == P_LINEAR) { @@ -2379,7 +2404,7 @@ png_image_read_colormap(png_voidp argument) /* And make sure the corresponding palette entry matches. */ png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); + back_g, 65535, P_LINEAR); } /* The background passed to libpng, however, must be the sRGB @@ -2389,8 +2414,8 @@ png_image_read_colormap(png_voidp argument) c.gray = c.red = c.green = c.blue = (png_uint_16)gray; png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); output_processing = PNG_CMAP_NONE; } @@ -2410,7 +2435,7 @@ png_image_read_colormap(png_voidp argument) { png_uint_32 gray = (i * 256 + 115) / 231; png_create_colormap_entry(display, i++, gray, gray, gray, - 255, P_sRGB); + 255, P_sRGB); } /* NOTE: this preserves the full precision of the application @@ -2419,13 +2444,13 @@ png_image_read_colormap(png_voidp argument) background_index = i; png_create_colormap_entry(display, i++, back_r, back_g, back_b, #ifdef __COVERITY__ - /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) - * here. - */ 255U, + /* Coverity claims that output_encoding + * cannot be 2 (P_LINEAR) here. + */ 255U, #else - output_encoding == P_LINEAR ? 65535U : 255U, + output_encoding == P_LINEAR ? 65535U : 255U, #endif - output_encoding); + output_encoding); /* For non-opaque input composite on the sRGB background - this * requires inverting the encoding for each component. The input @@ -2463,9 +2488,9 @@ png_image_read_colormap(png_voidp argument) png_uint_32 gray = png_sRGB_table[g*51] * alpha; png_create_colormap_entry(display, i++, - PNG_sRGB_FROM_LINEAR(gray + back_rx), - PNG_sRGB_FROM_LINEAR(gray + back_gx), - PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); + PNG_sRGB_FROM_LINEAR(gray + back_rx), + PNG_sRGB_FROM_LINEAR(gray + back_gx), + PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); } } @@ -2491,7 +2516,7 @@ png_image_read_colormap(png_voidp argument) * png_set_tRNS_to_alpha before png_set_background_fixed. */ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, - -1); + -1); data_encoding = P_sRGB; /* The output will now be one or two 8-bit gray or gray+alpha @@ -2510,7 +2535,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "rgb[ga] color-map: too few entries"); - cmap_entries = make_ga_colormap(display); + cmap_entries = (unsigned int)make_ga_colormap(display); background_index = PNG_CMAP_GA_BACKGROUND; output_processing = PNG_CMAP_GA; } @@ -2536,12 +2561,12 @@ png_image_read_colormap(png_voidp argument) png_ptr->num_trans > 0) && png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) { - cmap_entries = make_gray_file_colormap(display); + cmap_entries = (unsigned int)make_gray_file_colormap(display); data_encoding = P_FILE; } else - cmap_entries = make_gray_colormap(display); + cmap_entries = (unsigned int)make_gray_colormap(display); /* But if the input has alpha or transparency it must be removed */ @@ -2567,13 +2592,13 @@ png_image_read_colormap(png_voidp argument) gray = png_sRGB_table[gray]; /* now P_LINEAR */ gray = PNG_DIV257(png_gamma_16bit_correct(gray, - png_ptr->colorspace.gamma)); /* now P_FILE */ + png_ptr->colorspace.gamma)); /* now P_FILE */ /* And make sure the corresponding palette entry contains * exactly the required sRGB value. */ png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, output_encoding); + back_g, 0/*unused*/, output_encoding); } else if (output_encoding == P_LINEAR) @@ -2598,8 +2623,8 @@ png_image_read_colormap(png_voidp argument) */ expand_tRNS = 1; png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); } output_processing = PNG_CMAP_NONE; @@ -2629,11 +2654,11 @@ png_image_read_colormap(png_voidp argument) if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) png_error(png_ptr, "rgb+alpha color-map: too few entries"); - cmap_entries = make_rgb_colormap(display); + cmap_entries = (unsigned int)make_rgb_colormap(display); /* Add a transparent entry. */ png_create_colormap_entry(display, cmap_entries, 255, 255, - 255, 0, P_sRGB); + 255, 0, P_sRGB); /* This is stored as the background index for the processing * algorithm. @@ -2654,7 +2679,7 @@ png_image_read_colormap(png_voidp argument) */ for (b=0; b<256; b = (b << 1) | 0x7f) png_create_colormap_entry(display, cmap_entries++, - r, g, b, 128, P_sRGB); + r, g, b, 128, P_sRGB); } } @@ -2678,10 +2703,10 @@ png_image_read_colormap(png_voidp argument) if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) png_error(png_ptr, "rgb-alpha color-map: too few entries"); - cmap_entries = make_rgb_colormap(display); + cmap_entries = (unsigned int)make_rgb_colormap(display); png_create_colormap_entry(display, cmap_entries, back_r, - back_g, back_b, 0/*unused*/, output_encoding); + back_g, back_b, 0/*unused*/, output_encoding); if (output_encoding == P_LINEAR) { @@ -2703,9 +2728,9 @@ png_image_read_colormap(png_voidp argument) * index. */ if (memcmp((png_const_bytep)display->colormap + - sample_size * cmap_entries, - (png_const_bytep)display->colormap + - sample_size * PNG_RGB_INDEX(r,g,b), + sample_size * cmap_entries, + (png_const_bytep)display->colormap + + sample_size * PNG_RGB_INDEX(r,g,b), sample_size) != 0) { /* The background color must be added. */ @@ -2723,13 +2748,13 @@ png_image_read_colormap(png_voidp argument) */ for (b=0; b<256; b = (b << 1) | 0x7f) png_create_colormap_entry(display, cmap_entries++, - png_colormap_compose(display, r, P_sRGB, 128, - back_r, output_encoding), - png_colormap_compose(display, g, P_sRGB, 128, - back_g, output_encoding), - png_colormap_compose(display, b, P_sRGB, 128, - back_b, output_encoding), - 0/*unused*/, output_encoding); + png_colormap_compose(display, r, P_sRGB, 128, + back_r, output_encoding), + png_colormap_compose(display, g, P_sRGB, 128, + back_g, output_encoding), + png_colormap_compose(display, b, P_sRGB, 128, + back_b, output_encoding), + 0/*unused*/, output_encoding); } } @@ -2747,8 +2772,8 @@ png_image_read_colormap(png_voidp argument) c.blue = (png_uint_16)back_b; png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); output_processing = PNG_CMAP_RGB; } @@ -2763,7 +2788,7 @@ png_image_read_colormap(png_voidp argument) if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) png_error(png_ptr, "rgb color-map: too few entries"); - cmap_entries = make_rgb_colormap(display); + cmap_entries = (unsigned int)make_rgb_colormap(display); output_processing = PNG_CMAP_RGB; } } @@ -2787,11 +2812,11 @@ png_image_read_colormap(png_voidp argument) output_processing = PNG_CMAP_NONE; data_encoding = P_FILE; /* Don't change from color-map indices */ - cmap_entries = png_ptr->num_palette; + cmap_entries = (unsigned int)png_ptr->num_palette; if (cmap_entries > 256) cmap_entries = 256; - if (cmap_entries > image->colormap_entries) + if (cmap_entries > (unsigned int)image->colormap_entries) png_error(png_ptr, "palette color-map: too few entries"); for (i=0; i < cmap_entries; ++i) @@ -2800,7 +2825,7 @@ png_image_read_colormap(png_voidp argument) { if (trans[i] == 0) png_create_colormap_entry(display, i, back_r, back_g, - back_b, 0, output_encoding); + back_b, 0, output_encoding); else { @@ -2808,22 +2833,22 @@ png_image_read_colormap(png_voidp argument) * on the sRGB color in 'back'. */ png_create_colormap_entry(display, i, - png_colormap_compose(display, colormap[i].red, P_FILE, - trans[i], back_r, output_encoding), - png_colormap_compose(display, colormap[i].green, P_FILE, - trans[i], back_g, output_encoding), - png_colormap_compose(display, colormap[i].blue, P_FILE, - trans[i], back_b, output_encoding), - output_encoding == P_LINEAR ? trans[i] * 257U : - trans[i], - output_encoding); + png_colormap_compose(display, colormap[i].red, + P_FILE, trans[i], back_r, output_encoding), + png_colormap_compose(display, colormap[i].green, + P_FILE, trans[i], back_g, output_encoding), + png_colormap_compose(display, colormap[i].blue, + P_FILE, trans[i], back_b, output_encoding), + output_encoding == P_LINEAR ? trans[i] * 257U : + trans[i], + output_encoding); } } else png_create_colormap_entry(display, i, colormap[i].red, - colormap[i].green, colormap[i].blue, - i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); + colormap[i].green, colormap[i].blue, + i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); } /* The PNG data may have indices packed in fewer than 8 bits, it @@ -2837,7 +2862,6 @@ png_image_read_colormap(png_voidp argument) default: png_error(png_ptr, "invalid PNG color type"); /*NOT REACHED*/ - break; } /* Now deal with the output processing */ @@ -2847,19 +2871,20 @@ png_image_read_colormap(png_voidp argument) switch (data_encoding) { - default: - png_error(png_ptr, "bad data option (internal error)"); - break; - case P_sRGB: /* Change to 8-bit sRGB */ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); - /* FALL THROUGH */ + /* FALLTHROUGH */ case P_FILE: if (png_ptr->bit_depth > 8) png_set_scale_16(png_ptr); break; + +#ifdef __GNUC__ + default: + png_error(png_ptr, "bad data option (internal error)"); +#endif } if (cmap_entries > 256 || cmap_entries > image->colormap_entries) @@ -2903,7 +2928,7 @@ png_image_read_colormap(png_voidp argument) png_error(png_ptr, "bad background index (internal error)"); } - display->colormap_processing = output_processing; + display->colormap_processing = (int)output_processing; return 1/*ok*/; } @@ -2913,7 +2938,7 @@ static int png_image_read_and_map(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; int passes; @@ -3050,7 +3075,7 @@ png_image_read_and_map(png_voidp argument) if (alpha >= 196) *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], - inrow[2]); + inrow[2]); else if (alpha < 64) *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; @@ -3102,7 +3127,7 @@ static int png_image_read_colormapped(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_controlp control = image->opaque; png_structrp png_ptr = control->png_ptr; @@ -3167,8 +3192,7 @@ png_image_read_colormapped(png_voidp argument) image->colormap_entries == 244 /* 216 + 1 + 27 */) break; - /* goto bad_output; */ - /* FALL THROUGH */ + goto bad_output; default: bad_output: @@ -3212,14 +3236,14 @@ png_image_read_colormapped(png_voidp argument) else { - png_alloc_size_t row_bytes = display->row_bytes; + png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; while (--passes >= 0) { png_uint_32 y = image->height; png_bytep row = png_voidcast(png_bytep, display->first_row); - while (y-- > 0) + for (; y > 0; --y) { png_read_row(png_ptr, row, NULL); row += row_bytes; @@ -3235,7 +3259,7 @@ static int png_image_read_composite(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; int passes; @@ -3362,7 +3386,7 @@ static int png_image_read_background(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; @@ -3410,10 +3434,6 @@ png_image_read_background(png_voidp argument) */ switch (info_ptr->bit_depth) { - default: - png_error(png_ptr, "unexpected bit depth"); - break; - case 8: /* 8-bit sRGB gray values with an alpha channel; the alpha channel is * to be removed by composing on a background: either the row if @@ -3426,8 +3446,7 @@ png_image_read_background(png_voidp argument) for (pass = 0; pass < passes; ++pass) { - png_bytep row = png_voidcast(png_bytep, - display->first_row); + png_bytep row = png_voidcast(png_bytep, display->first_row); unsigned int startx, stepx, stepy; png_uint_32 y; @@ -3455,7 +3474,7 @@ png_image_read_background(png_voidp argument) for (; ylocal_row); + display->local_row); png_bytep outrow = first_row + y * step_row; png_const_bytep end_row = outrow + width; @@ -3500,7 +3519,7 @@ png_image_read_background(png_voidp argument) for (; ylocal_row); + display->local_row); png_bytep outrow = first_row + y * step_row; png_const_bytep end_row = outrow + width; @@ -3547,13 +3566,14 @@ png_image_read_background(png_voidp argument) */ { png_uint_16p first_row = png_voidcast(png_uint_16p, - display->first_row); + display->first_row); /* The division by two is safe because the caller passed in a * stride which was multiplied by 2 (below) to get row_bytes. */ ptrdiff_t step_row = display->row_bytes / 2; - int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; - unsigned int outchannels = 1+preserve_alpha; + unsigned int preserve_alpha = (image->format & + PNG_FORMAT_FLAG_ALPHA) != 0; + unsigned int outchannels = 1U+preserve_alpha; int swap_alpha = 0; # ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED @@ -3597,7 +3617,7 @@ png_image_read_background(png_voidp argument) /* Read the row, which is packed: */ png_read_row(png_ptr, png_voidcast(png_bytep, - display->local_row), NULL); + display->local_row), NULL); inrow = png_voidcast(png_const_uint_16p, display->local_row); /* Now do the pre-multiplication on each pixel in this row. @@ -3631,6 +3651,11 @@ png_image_read_background(png_voidp argument) } } break; + +#ifdef __GNUC__ + default: + png_error(png_ptr, "unexpected bit depth"); +#endif } return 1; @@ -3641,7 +3666,7 @@ static int png_image_read_direct(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; @@ -3692,7 +3717,7 @@ png_image_read_direct(png_voidp argument) do_local_background = 1/*maybe*/; png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, - PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); + PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); } change &= ~PNG_FORMAT_FLAG_COLOR; @@ -3734,7 +3759,13 @@ png_image_read_direct(png_voidp argument) mode = PNG_ALPHA_PNG; output_gamma = PNG_DEFAULT_sRGB; } - + + if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) + { + mode = PNG_ALPHA_OPTIMIZED; + change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + /* If 'do_local_background' is set check for the presence of gamma * correction; this is part of the work-round for the libpng bug * described above. @@ -3751,7 +3782,7 @@ png_image_read_direct(png_voidp argument) * final value. */ if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, - PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) + PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) do_local_background = 0; else if (mode == PNG_ALPHA_STANDARD) @@ -3814,8 +3845,8 @@ png_image_read_direct(png_voidp argument) * pixels. */ png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); } else /* compose on row: implemented below. */ @@ -3846,16 +3877,16 @@ png_image_read_direct(png_voidp argument) else filler = 255; -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - where = PNG_FILLER_BEFORE; - change &= ~PNG_FORMAT_FLAG_AFIRST; - } +#ifdef PNG_FORMAT_AFIRST_SUPPORTED + if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + where = PNG_FILLER_BEFORE; + change &= ~PNG_FORMAT_FLAG_AFIRST; + } - else -# endif - where = PNG_FILLER_AFTER; + else +#endif + where = PNG_FILLER_AFTER; png_set_add_alpha(png_ptr, filler, where); } @@ -3960,15 +3991,19 @@ png_image_read_direct(png_voidp argument) else if (do_local_compose != 0) /* internal error */ png_error(png_ptr, "png_image_read: alpha channel lost"); + if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { + info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + if (info_ptr->bit_depth == 16) info_format |= PNG_FORMAT_FLAG_LINEAR; -# ifdef PNG_FORMAT_BGR_SUPPORTED - if ((png_ptr->transformations & PNG_BGR) != 0) - info_format |= PNG_FORMAT_FLAG_BGR; -# endif +#ifdef PNG_FORMAT_BGR_SUPPORTED + if ((png_ptr->transformations & PNG_BGR) != 0) + info_format |= PNG_FORMAT_FLAG_BGR; +#endif -# ifdef PNG_FORMAT_AFIRST_SUPPORTED +#ifdef PNG_FORMAT_AFIRST_SUPPORTED if (do_local_background == 2) { if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) @@ -4045,14 +4080,14 @@ png_image_read_direct(png_voidp argument) else { - png_alloc_size_t row_bytes = display->row_bytes; + png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; while (--passes >= 0) { png_uint_32 y = image->height; png_bytep row = png_voidcast(png_bytep, display->first_row); - while (y-- > 0) + for (; y > 0; --y) { png_read_row(png_ptr, row, NULL); row += row_bytes; @@ -4065,67 +4100,117 @@ png_image_read_direct(png_voidp argument) int PNGAPI png_image_finish_read(png_imagep image, png_const_colorp background, - void *buffer, png_int_32 row_stride, void *colormap) + void *buffer, png_int_32 row_stride, void *colormap) { if (image != NULL && image->version == PNG_IMAGE_VERSION) { - png_uint_32 check; + /* Check for row_stride overflow. This check is not performed on the + * original PNG format because it may not occur in the output PNG format + * and libpng deals with the issues of reading the original. + */ + const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - if (row_stride == 0) - row_stride = PNG_IMAGE_ROW_STRIDE(*image); - - if (row_stride < 0) - check = -row_stride; - - else - check = row_stride; - - if (image->opaque != NULL && buffer != NULL && - check >= PNG_IMAGE_ROW_STRIDE(*image)) + /* The following checks just the 'row_stride' calculation to ensure it + * fits in a signed 32-bit value. Because channels/components can be + * either 1 or 2 bytes in size the length of a row can still overflow 32 + * bits; this is just to verify that the 'row_stride' argument can be + * represented. + */ + if (image->width <= 0x7fffffffU/channels) /* no overflow */ { - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || - (image->colormap_entries > 0 && colormap != NULL)) + png_uint_32 check; + const png_uint_32 png_row_stride = image->width * channels; + + if (row_stride == 0) + row_stride = (png_int_32)/*SAFE*/png_row_stride; + + if (row_stride < 0) + check = (png_uint_32)(-row_stride); + + else + check = (png_uint_32)row_stride; + + /* This verifies 'check', the absolute value of the actual stride + * passed in and detects overflow in the application calculation (i.e. + * if the app did actually pass in a non-zero 'row_stride'. + */ + if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) { - int result; - png_image_read_control display; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.background = background; - display.local_row = NULL; - - /* Choose the correct 'end' routine; for the color-map case all the - * setup has already been done. + /* Now check for overflow of the image buffer calculation; this + * limits the whole image size to 32 bits for API compatibility with + * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. + * + * The PNG_IMAGE_BUFFER_SIZE macro is: + * + * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride)) + * + * And the component size is always 1 or 2, so make sure that the + * number of *bytes* that the application is saying are available + * does actually fit into a 32-bit number. + * + * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE + * will be changed to use png_alloc_size_t; bigger images can be + * accomodated on 64-bit systems. */ - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - result = - png_safe_execute(image, png_image_read_colormap, &display) && - png_safe_execute(image, png_image_read_colormapped, &display); + if (image->height <= + 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check) + { + if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || + (image->colormap_entries > 0 && colormap != NULL)) + { + int result; + png_image_read_control display; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.background = background; + display.local_row = NULL; + + /* Choose the correct 'end' routine; for the color-map case + * all the setup has already been done. + */ + if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) + result = + png_safe_execute(image, + png_image_read_colormap, &display) && + png_safe_execute(image, + png_image_read_colormapped, &display); + + else + result = + png_safe_execute(image, + png_image_read_direct, &display); + + png_image_free(image); + return result; + } + + else + return png_image_error(image, + "png_image_finish_read[color-map]: no color-map"); + } else - result = - png_safe_execute(image, png_image_read_direct, &display); - - png_image_free(image); - return result; + return png_image_error(image, + "png_image_finish_read: image too large"); } else return png_image_error(image, - "png_image_finish_read[color-map]: no color-map"); + "png_image_finish_read: invalid argument"); } else return png_image_error(image, - "png_image_finish_read: invalid argument"); + "png_image_finish_read: row_stride too large"); } else if (image != NULL) return png_image_error(image, - "png_image_finish_read: damaged PNG_IMAGE_VERSION"); + "png_image_finish_read: damaged PNG_IMAGE_VERSION"); return 0; } diff --git a/src/third-party/libpng/pngrio.c b/src/third-party/libpng/pngrio.c index bb5c82510..7e26e855c 100644 --- a/src/third-party/libpng/pngrio.c +++ b/src/third-party/libpng/pngrio.c @@ -1,8 +1,8 @@ /* pngrio.c - functions for data input * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.24 [August 4, 2016] + * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -26,7 +26,7 @@ * reads from a file pointer. Note that this routine sometimes gets called * with very small lengths, so you should implement some kind of simple * buffering if you are using unbuffered reads. This should never be asked - * to read more than 64K on a 16 bit machine. + * to read more than 64K on a 16-bit machine. */ void /* PRIVATE */ png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length) @@ -85,7 +85,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) */ void PNGAPI png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn) + png_rw_ptr read_data_fn) { if (png_ptr == NULL) return; diff --git a/src/third-party/libpng/pngrtran.c b/src/third-party/libpng/pngrtran.c index cad7a8daa..c18965031 100644 --- a/src/third-party/libpng/pngrtran.c +++ b/src/third-party/libpng/pngrtran.c @@ -1,8 +1,8 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.33 [September 28, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -48,7 +48,8 @@ png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ png_warning(png_ptr, - "Can't discard critical data on CRC error"); + "Can't discard critical data on CRC error"); + /* FALLTHROUGH */ case PNG_CRC_ERROR_QUIT: /* Error/quit */ case PNG_CRC_DEFAULT: @@ -101,7 +102,7 @@ png_rtran_ok(png_structrp png_ptr, int need_IHDR) { if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) png_app_error(png_ptr, - "invalid after png_start_read_image or png_read_update_info"); + "invalid after png_start_read_image or png_read_update_info"); else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) png_app_error(png_ptr, "invalid before the PNG header has been read"); @@ -159,7 +160,7 @@ png_set_background(png_structrp png_ptr, png_set_background_fixed(png_ptr, background_color, background_gamma_code, need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); } -# endif /* FLOATING_POINT */ +# endif /* FLOATING_POINT */ #endif /* READ_BACKGROUND */ /* Scale 16-bit depth files to 8-bit depth. If both of these are set then the @@ -209,7 +210,7 @@ png_set_strip_alpha(png_structrp png_ptr) #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) static png_fixed_point translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, - int is_screen) + int is_screen) { /* Check for flag values. The main reason for having the old Mac value as a * flag is that it is pretty near impossible to work out what the correct @@ -273,7 +274,7 @@ convert_gamma_value(png_structrp png_ptr, double output_gamma) #ifdef PNG_READ_ALPHA_MODE_SUPPORTED void PNGFAPI png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, - png_fixed_point output_gamma) + png_fixed_point output_gamma) { int compose = 0; png_fixed_point file_gamma; @@ -289,9 +290,12 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, * is expected to be 1 or greater, but this range test allows for some * viewing correction values. The intent is to weed out users of this API * who use the inverse of the gamma value accidentally! Since some of these - * values are reasonable this may have to be changed. + * values are reasonable this may have to be changed: + * + * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit + * gamma of 36, and its reciprocal.) */ - if (output_gamma < 70000 || output_gamma > 300000) + if (output_gamma < 1000 || output_gamma > 10000000) png_error(png_ptr, "output gamma out of expected range"); /* The default file gamma is the inverse of the output gamma; the output @@ -374,7 +378,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, if ((png_ptr->transformations & PNG_COMPOSE) != 0) png_error(png_ptr, - "conflicting calls to set alpha mode and background"); + "conflicting calls to set alpha mode and background"); png_ptr->transformations |= PNG_COMPOSE; } @@ -385,7 +389,7 @@ void PNGAPI png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) { png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, - output_gamma)); + output_gamma)); } # endif #endif @@ -426,7 +430,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, int i; png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); for (i = 0; i < num_palette; i++) png_ptr->quantize_index[i] = (png_byte)i; } @@ -443,7 +447,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize an array to sort colors */ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) @@ -577,9 +581,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * + (sizeof (png_byte)))); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)((png_uint_32)num_palette * + (sizeof (png_byte)))); /* Initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -588,7 +594,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, png_ptr->palette_to_index[i] = (png_byte)i; } - hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * + hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 * (sizeof (png_dsortp)))); num_new_palette = num_palette; @@ -619,7 +625,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, { t = (png_dsortp)png_malloc_warn(png_ptr, - (png_uint_32)(sizeof (png_dsort))); + (png_alloc_size_t)(sizeof (png_dsort))); if (t == NULL) break; @@ -744,9 +750,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, png_size_t num_entries = ((png_size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_uint_32)(num_entries * (sizeof (png_byte)))); + (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); - distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * + distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); memset(distance, 0xff, num_entries * (sizeof (png_byte))); @@ -799,7 +805,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, #ifdef PNG_READ_GAMMA_SUPPORTED void PNGFAPI png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, - png_fixed_point file_gamma) + png_fixed_point file_gamma) { png_debug(1, "in png_set_gamma_fixed"); @@ -841,7 +847,7 @@ void PNGAPI png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) { png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), - convert_gamma_value(png_ptr, file_gamma)); + convert_gamma_value(png_ptr, file_gamma)); } # endif /* FLOATING_POINT */ #endif /* READ_GAMMA */ @@ -976,7 +982,6 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, default: png_error(png_ptr, "invalid error action to rgb_to_gray"); - break; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) @@ -988,7 +993,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, * that it just worked and get a memory overwrite. */ png_error(png_ptr, - "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); + "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ } @@ -1015,7 +1020,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, { if (red >= 0 && green >= 0) png_app_warning(png_ptr, - "ignoring out of range rgb_to_gray coefficients"); + "ignoring out of range rgb_to_gray coefficients"); /* Use the defaults, from the cHRM chunk if set, else the historical * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See @@ -1024,7 +1029,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, * something has already provided a default. */ if (png_ptr->rgb_to_gray_red_coeff == 0 && - png_ptr->rgb_to_gray_green_coeff == 0) + png_ptr->rgb_to_gray_green_coeff == 0) { png_ptr->rgb_to_gray_red_coeff = 6968; png_ptr->rgb_to_gray_green_coeff = 23434; @@ -1041,10 +1046,10 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, void PNGAPI png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, - double green) + double green) { png_set_rgb_to_gray_fixed(png_ptr, error_action, - png_fixed(png_ptr, red, "rgb to gray red coefficient"), + png_fixed(png_ptr, red, "rgb to gray red coefficient"), png_fixed(png_ptr, green, "rgb to gray green coefficient")); } #endif /* FLOATING POINT */ @@ -1251,7 +1256,7 @@ png_init_rgb_transformations(png_structrp png_ptr) default: case 8: - /* FALL THROUGH (Already 8 bits) */ + /* FALLTHROUGH */ /* (Already 8 bits) */ case 16: /* Already a full 16 bits */ @@ -1301,7 +1306,7 @@ png_init_read_transformations(png_structrp png_ptr) { if (png_ptr->screen_gamma != 0) /* screen set too */ gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); + png_ptr->screen_gamma); else /* Assume the output matches the input; a long time default behavior @@ -1582,7 +1587,7 @@ png_init_read_transformations(png_structrp png_ptr) */ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) png_warning(png_ptr, - "libpng does not support gamma+background+rgb_to_gray"); + "libpng does not support gamma+background+rgb_to_gray"); if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) { @@ -1618,13 +1623,13 @@ png_init_read_transformations(png_structrp png_ptr) case PNG_BACKGROUND_GAMMA_FILE: g = png_reciprocal(png_ptr->colorspace.gamma); gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); + png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: g = png_reciprocal(png_ptr->background_gamma); gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); + png_ptr->screen_gamma); break; default: g = PNG_FP_1; /* back_1 */ @@ -1652,11 +1657,11 @@ png_init_read_transformations(png_structrp png_ptr) if (png_gamma_significant(g) != 0) { back_1.red = png_gamma_8bit_correct(png_ptr->background.red, - g); + g); back_1.green = png_gamma_8bit_correct( - png_ptr->background.green, g); + png_ptr->background.green, g); back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, - g); + g); } else @@ -1727,7 +1732,7 @@ png_init_read_transformations(png_structrp png_ptr) case PNG_BACKGROUND_GAMMA_FILE: g = png_reciprocal(png_ptr->colorspace.gamma); gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); + png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: @@ -1913,7 +1918,7 @@ png_init_read_transformations(png_structrp png_ptr) png_ptr->palette[i].blue = (png_byte)component; } } -#endif /* READ_SHIFT */ +#endif /* READ_SHIFT */ } /* Modify the info structure to reflect the transformations. The @@ -1997,7 +2002,7 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) # endif # else - /* No 16 bit support: force chopping 16-bit input down to 8, in this case + /* No 16-bit support: force chopping 16-bit input down to 8, in this case * the app program can chose if both APIs are available by setting the * correct scaling to use. */ @@ -2098,10 +2103,10 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) defined(PNG_READ_USER_TRANSFORM_SUPPORTED) if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) { - if (info_ptr->bit_depth < png_ptr->user_transform_depth) + if (png_ptr->user_transform_depth != 0) info_ptr->bit_depth = png_ptr->user_transform_depth; - if (info_ptr->channels < png_ptr->user_transform_channels) + if (png_ptr->user_transform_channels != 0) info_ptr->channels = png_ptr->user_transform_channels; } #endif @@ -2148,7 +2153,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row) { png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); + png_uint_32 shift = 7U - ((row_width + 7U) & 0x07); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x01); @@ -2172,7 +2177,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row) png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x03); @@ -2195,7 +2200,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row) { png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2); for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x0f); @@ -2382,8 +2387,8 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) while (sp < ep) { - /* The input is an array of 16 bit components, these must be scaled to - * 8 bits each. For a 16 bit value V the required value (from the PNG + /* The input is an array of 16-bit components, these must be scaled to + * 8 bits each. For a 16-bit value V the required value (from the PNG * specification) is: * * (V * 255) / 65535 @@ -2404,7 +2409,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) * * The approximate differs from the exact answer only when (vlo-vhi) is * 128; it then gives a correction of +1 when the exact correction is - * 0. This gives 128 errors. The exact answer (correct for all 16 bit + * 0. This gives 128 errors. The exact answer (correct for all 16-bit * input values) is: * * error = (vlo-vhi+128)*65535 >> 24; @@ -2932,7 +2937,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) * using the equation given in Poynton's ColorFAQ of 1998-01-04 at * (THIS LINK IS DEAD June 2008 but * versions dated 1998 through November 2002 have been archived at - * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ + * https://web.archive.org/web/20000816232553/www.inforamp.net/ * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) * Charles Poynton poynton at poynton.com * @@ -3148,9 +3153,9 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) if (red != green || red != blue) rgb_error |= 1; - /* From 1.5.5 in the 16 bit case do the accurate conversion even + /* From 1.5.5 in the 16-bit case do the accurate conversion even * in the 'fast' case - this is because this is where the code - * ends up when handling linear 16 bit data. + * ends up when handling linear 16-bit data. */ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> 15); @@ -3221,7 +3226,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) == png_ptr->trans_color.gray) { unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); - tmp |= png_ptr->background.gray << shift; + tmp |= + (unsigned int)(png_ptr->background.gray << shift); *sp = (png_byte)(tmp & 0xff); } @@ -3250,7 +3256,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) == png_ptr->trans_color.gray) { unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= png_ptr->background.gray << shift; + tmp |= + (unsigned int)png_ptr->background.gray << shift; *sp = (png_byte)(tmp & 0xff); } @@ -3260,7 +3267,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) unsigned int g = (gamma_table [p | (p << 2) | (p << 4) | (p << 6)] >> 6) & 0x03; unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= g << shift; + tmp |= (unsigned int)(g << shift); *sp = (png_byte)(tmp & 0xff); } @@ -3286,7 +3293,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) == png_ptr->trans_color.gray) { unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= png_ptr->background.gray << shift; + tmp |= + (unsigned int)png_ptr->background.gray << shift; *sp = (png_byte)(tmp & 0xff); } @@ -3315,8 +3323,9 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x0f) == png_ptr->trans_color.gray) { - unsigned int tmp = *sp & (0xf0f >> (4 - shift)); - tmp |= png_ptr->background.gray << shift; + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); *sp = (png_byte)(tmp & 0xff); } @@ -3325,8 +3334,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) unsigned int p = (*sp >> shift) & 0x0f; unsigned int g = (gamma_table[p | (p << 4)] >> 4) & 0x0f; - unsigned int tmp = *sp & (0xf0f >> (4 - shift)); - tmp |= g << shift; + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= (unsigned int)(g << shift); *sp = (png_byte)(tmp & 0xff); } @@ -3351,8 +3360,9 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x0f) == png_ptr->trans_color.gray) { - unsigned int tmp = *sp & (0xf0f >> (4 - shift)); - tmp |= png_ptr->background.gray << shift; + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); *sp = (png_byte)(tmp & 0xff); } @@ -4193,7 +4203,7 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) */ static void png_do_expand_palette(png_row_infop row_info, png_bytep row, - png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) + png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) { int shift, value; png_bytep sp, dp; @@ -4295,7 +4305,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, if (num_trans > 0) { sp = row + (png_size_t)row_width - 1; - dp = row + (png_size_t)(row_width << 2) - 1; + dp = row + ((png_size_t)row_width << 2) - 1; for (i = 0; i < row_width; i++) { @@ -4456,11 +4466,11 @@ png_do_expand(png_row_infop row_info, png_bytep row, { gray = gray & 0xff; sp = row + (png_size_t)row_width - 1; - dp = row + (png_size_t)(row_width << 1) - 1; + dp = row + ((png_size_t)row_width << 1) - 1; for (i = 0; i < row_width; i++) { - if (*sp == gray) + if ((*sp & 0xffU) == gray) *dp-- = 0; else @@ -4478,7 +4488,8 @@ png_do_expand(png_row_infop row_info, png_bytep row, dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) { - if (*(sp - 1) == gray_high && *(sp) == gray_low) + if ((*(sp - 1) & 0xffU) == gray_high && + (*(sp) & 0xffU) == gray_low) { *dp-- = 0; *dp-- = 0; @@ -4499,7 +4510,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, row_info->channels = 2; row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_width); + row_width); } } else if (row_info->color_type == PNG_COLOR_TYPE_RGB && @@ -4511,7 +4522,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, png_byte green = (png_byte)(trans_color->green & 0xff); png_byte blue = (png_byte)(trans_color->blue & 0xff); sp = row + (png_size_t)row_info->rowbytes - 1; - dp = row + (png_size_t)(row_width << 2) - 1; + dp = row + ((png_size_t)row_width << 2) - 1; for (i = 0; i < row_width; i++) { if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) @@ -4534,7 +4545,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, png_byte green_low = (png_byte)(trans_color->green & 0xff); png_byte blue_low = (png_byte)(trans_color->blue & 0xff); sp = row + row_info->rowbytes - 1; - dp = row + (png_size_t)(row_width << 3) - 1; + dp = row + ((png_size_t)row_width << 3) - 1; for (i = 0; i < row_width; i++) { if (*(sp - 5) == red_high && @@ -4593,7 +4604,9 @@ png_do_expand_16(png_row_infop row_info, png_bytep row) png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ while (dp > sp) - dp[-2] = dp[-1] = *--sp, dp -= 2; + { + dp[-2] = dp[-1] = *--sp; dp -= 2; + } row_info->rowbytes *= 2; row_info->bit_depth = 16; @@ -4759,7 +4772,7 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); + 0 /* at_start == false, because SWAP_ALPHA happens later */); #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED diff --git a/src/third-party/libpng/pngrutil.c b/src/third-party/libpng/pngrutil.c index 6c5c37526..8692933bd 100644 --- a/src/third-party/libpng/pngrutil.c +++ b/src/third-party/libpng/pngrutil.c @@ -1,8 +1,8 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.33 [September 28, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -86,10 +86,16 @@ png_get_int_32)(png_const_bytep buf) { png_uint_32 uval = png_get_uint_32(buf); if ((uval & 0x80000000) == 0) /* non-negative */ - return uval; + return (png_int_32)uval; uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ - return -(png_int_32)uval; + if ((uval & 0x80000000) == 0) /* no overflow */ + return -(png_int_32)uval; + /* The following has to be safe; this function only gets called on PNG data + * and if we get here that data is invalid. 0 is the most safe value and + * if not then an attacker would surely just generate a PNG with 0 instead. + */ + return 0; } /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ @@ -98,7 +104,7 @@ png_get_uint_16)(png_const_bytep buf) { /* ANSI-C requires an int value to accomodate at least 16 bits so this * works and allows the compiler not to worry about possible narrowing - * on 32 bit systems. (Pre-ANSI systems did not make integers smaller + * on 32-bit systems. (Pre-ANSI systems did not make integers smaller * than 16 bits either.) */ unsigned int val = @@ -175,6 +181,9 @@ png_read_chunk_header(png_structrp png_ptr) /* Check to see if chunk name is valid. */ png_check_chunk_name(png_ptr, png_ptr->chunk_name); + /* Check for too-large chunk length */ + png_check_chunk_length(png_ptr, length); + #ifdef PNG_IO_STATE_SUPPORTED png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; #endif @@ -305,6 +314,7 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) if (buffer != NULL) { + memset(buffer, 0, new_size); /* just in case */ png_ptr->read_buffer = buffer; png_ptr->read_buffer_size = new_size; } @@ -341,7 +351,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) * are minimal. */ (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); -#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC +#if PNG_RELEASE_BUILD png_chunk_warning(png_ptr, msg); png_ptr->zowner = 0; #else @@ -364,21 +374,24 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) */ { int ret; /* zlib return code */ -#if PNG_ZLIB_VERNUM >= 0x1240 +#if ZLIB_VERNUM >= 0x1240 + int window_bits = 0; # if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) - int window_bits; - if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == PNG_OPTION_ON) + { window_bits = 15; + png_ptr->zstream_start = 0; /* fixed window size */ + } else - window_bits = 0; -# else -# define window_bits 0 + { + png_ptr->zstream_start = 1; + } # endif -#endif + +#endif /* ZLIB_VERNUM >= 0x1240 */ /* Set this for safety, just in case the previous owner left pointers to * memory allocations. @@ -390,25 +403,32 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) { -#if PNG_ZLIB_VERNUM < 0x1240 - ret = inflateReset(&png_ptr->zstream); -#else +#if ZLIB_VERNUM >= 0x1240 ret = inflateReset2(&png_ptr->zstream, window_bits); +#else + ret = inflateReset(&png_ptr->zstream); #endif } else { -#if PNG_ZLIB_VERNUM < 0x1240 - ret = inflateInit(&png_ptr->zstream); -#else +#if ZLIB_VERNUM >= 0x1240 ret = inflateInit2(&png_ptr->zstream, window_bits); +#else + ret = inflateInit(&png_ptr->zstream); #endif if (ret == Z_OK) png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; } +#if ZLIB_VERNUM >= 0x1290 && \ + defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) + if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) + /* Turn off validation of the ADLER32 checksum in IDAT chunks */ + ret = inflateValidate(&png_ptr->zstream, 0); +#endif + if (ret == Z_OK) png_ptr->zowner = owner; @@ -423,7 +443,33 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) #endif } +#if ZLIB_VERNUM >= 0x1240 +/* Handle the start of the inflate stream if we called inflateInit2(strm,0); + * in this case some zlib versions skip validation of the CINFO field and, in + * certain circumstances, libpng may end up displaying an invalid image, in + * contrast to implementations that call zlib in the normal way (e.g. libpng + * 1.5). + */ +int /* PRIVATE */ +png_zlib_inflate(png_structrp png_ptr, int flush) +{ + if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0) + { + if ((*png_ptr->zstream.next_in >> 4) > 7) + { + png_ptr->zstream.msg = "invalid window size (libpng)"; + return Z_DATA_ERROR; + } + + png_ptr->zstream_start = 0; + } + + return inflate(&png_ptr->zstream, flush); +} +#endif /* Zlib >= 1.2.4 */ + #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED +#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED) /* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to * allow the caller to do multiple calls if required. If the 'finish' flag is * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must @@ -516,7 +562,7 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, * the previous chunk of input data. Tell zlib if we have reached the * end of the output buffer. */ - ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : + ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); } while (ret == Z_OK); @@ -562,9 +608,9 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, */ static int png_decompress_chunk(png_structrp png_ptr, - png_uint_32 chunklength, png_uint_32 prefix_size, - png_alloc_size_t *newlength /* must be initialized to the maximum! */, - int terminate /*add a '\0' to the end of the uncompressed data*/) + png_uint_32 chunklength, png_uint_32 prefix_size, + png_alloc_size_t *newlength /* must be initialized to the maximum! */, + int terminate /*add a '\0' to the end of the uncompressed data*/) { /* TODO: implement different limits for different types of chunk. * @@ -575,7 +621,7 @@ png_decompress_chunk(png_structrp png_ptr, */ png_alloc_size_t limit = PNG_SIZE_MAX; -# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +# ifdef PNG_SET_USER_LIMITS_SUPPORTED if (png_ptr->user_chunk_malloc_max > 0 && png_ptr->user_chunk_malloc_max < limit) limit = png_ptr->user_chunk_malloc_max; @@ -601,8 +647,8 @@ png_decompress_chunk(png_structrp png_ptr, png_uint_32 lzsize = chunklength - prefix_size; ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, - /* output: */ NULL, newlength); + /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, + /* output: */ NULL, newlength); if (ret == Z_STREAM_END) { @@ -622,15 +668,17 @@ png_decompress_chunk(png_structrp png_ptr, */ png_alloc_size_t new_size = *newlength; png_alloc_size_t buffer_size = prefix_size + new_size + - (terminate != 0); + (terminate != 0); png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, - buffer_size)); + buffer_size)); if (text != NULL) { + memset(text, 0, buffer_size); + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - png_ptr->read_buffer + prefix_size, &lzsize, - text + prefix_size, newlength); + png_ptr->read_buffer + prefix_size, &lzsize, + text + prefix_size, newlength); if (ret == Z_STREAM_END) { @@ -670,13 +718,12 @@ png_decompress_chunk(png_structrp png_ptr, * success) */ png_free(png_ptr, text); - text = NULL; /* This really is very benign, but it's still an error because * the extra space may otherwise be used as a Trojan Horse. */ if (ret == Z_STREAM_END && - chunklength - prefix_size != lzsize) + chunklength - prefix_size != lzsize) png_chunk_benign_error(png_ptr, "extra compressed data"); } @@ -692,9 +739,7 @@ png_decompress_chunk(png_structrp png_ptr, { /* inflateReset failed, store the error message */ png_zstream_error(png_ptr, ret); - - if (ret == Z_STREAM_END) - ret = PNG_UNEXPECTED_ZLIB_RETURN; + ret = PNG_UNEXPECTED_ZLIB_RETURN; } } @@ -718,6 +763,7 @@ png_decompress_chunk(png_structrp png_ptr, return Z_MEM_ERROR; } } +#endif /* READ_zTXt || READ_iTXt */ #endif /* READ_COMPRESSED_TEXT */ #ifdef PNG_READ_iCCP_SUPPORTED @@ -726,8 +772,8 @@ png_decompress_chunk(png_structrp png_ptr, */ static int png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, - png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, - int finish) + png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, + int finish) { if (png_ptr->zowner == png_ptr->chunk_name) { @@ -766,8 +812,8 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, * the available output is produced; this allows reading of truncated * streams. */ - ret = inflate(&png_ptr->zstream, - *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); + ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ? + Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); } while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); @@ -785,7 +831,7 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, return Z_STREAM_ERROR; } } -#endif +#endif /* READ_iCCP */ /* Read and check the IDHR chunk */ @@ -867,7 +913,7 @@ void /* PRIVATE */ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_color palette[PNG_MAX_PALETTE_LENGTH]; - int num, i; + int max_palette_length, num, i; #ifdef PNG_POINTER_INDEXING_SUPPORTED png_colorp pal_ptr; #endif @@ -928,6 +974,19 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ num = (int)length / 3; + /* If the palette has 256 or fewer entries but is too large for the bit + * depth, we don't issue an error, to preserve the behavior of previous + * libpng versions. We silently truncate the unused extra palette entries + * here. + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + max_palette_length = (1 << png_ptr->bit_depth); + else + max_palette_length = PNG_MAX_PALETTE_LENGTH; + + if (num > max_palette_length) + num = max_palette_length; + #ifdef PNG_POINTER_INDEXING_SUPPORTED for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) { @@ -960,7 +1019,7 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) #endif { - png_crc_finish(png_ptr, 0); + png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3)); } #ifndef PNG_READ_OPT_PLTE_SUPPORTED @@ -1147,11 +1206,13 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) return; for (i=0; i sample_depth) { png_chunk_benign_error(png_ptr, "invalid"); return; } + } if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) { @@ -1241,7 +1302,7 @@ png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, - 1/*prefer cHRM values*/); + 1/*prefer cHRM values*/); png_colorspace_sync(png_ptr, info_ptr); } #endif @@ -1320,11 +1381,13 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * chunk is just ignored, so does not invalidate the color space. An * alternative is to set the 'invalid' flags at the start of this routine * and only clear them in they were not set before and all the tests pass. - * The minimum 'deflate' stream is assumed to be just the 2 byte header and - * 4 byte checksum. The keyword must be at least one character and there is - * a terminator (0) byte and the compression method. */ - if (length < 9) + + /* The keyword must be at least one character and there is a + * terminator (0) byte and the compression method byte, and the + * 'zlib' datastream is at least 11 bytes. + */ + if (length < 14) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "too short"); @@ -1356,6 +1419,16 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_crc_read(png_ptr, (png_bytep)keyword, read_length); length -= read_length; + /* The minimum 'zlib' stream is assumed to be just the 2 byte header, + * 5 bytes minimum 'deflate' stream, and the 4 byte checksum. + */ + if (length < 11) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too short"); + return; + } + keyword_length = 0; while (keyword_length < 80 && keyword_length < read_length && keyword[keyword_length] != 0) @@ -1374,15 +1447,15 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) { - Byte profile_header[132]; + Byte profile_header[132]={0}; Byte local_buffer[PNG_INFLATE_BUF_SIZE]; png_alloc_size_t size = (sizeof profile_header); png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); png_ptr->zstream.avail_in = read_length; (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, profile_header, &size, - 0/*finish: don't, because the output is too small*/); + (sizeof local_buffer), &length, profile_header, &size, + 0/*finish: don't, because the output is too small*/); if (size == 0) { @@ -1392,35 +1465,35 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_get_uint_32(profile_header); if (png_icc_check_length(png_ptr, &png_ptr->colorspace, - keyword, profile_length) != 0) + keyword, profile_length) != 0) { /* The length is apparently ok, so we can check the 132 * byte header. */ if (png_icc_check_header(png_ptr, &png_ptr->colorspace, - keyword, profile_length, profile_header, - png_ptr->color_type) != 0) + keyword, profile_length, profile_header, + png_ptr->color_type) != 0) { /* Now read the tag table; a variable size buffer is * needed at this point, allocate one for the whole * profile. The header check has already validated - * that none of these stuff will overflow. + * that none of this stuff will overflow. */ const png_uint_32 tag_count = png_get_uint_32( - profile_header+128); + profile_header+128); png_bytep profile = png_read_buffer(png_ptr, - profile_length, 2/*silent*/); + profile_length, 2/*silent*/); if (profile != NULL) { memcpy(profile, profile_header, - (sizeof profile_header)); + (sizeof profile_header)); size = 12 * tag_count; (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header), &size, 0); + (sizeof local_buffer), &length, + profile + (sizeof profile_header), &size, 0); /* Still expect a buffer error because we expect * there to be some tag data! @@ -1428,22 +1501,22 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (size == 0) { if (png_icc_check_tag_table(png_ptr, - &png_ptr->colorspace, keyword, profile_length, - profile) != 0) + &png_ptr->colorspace, keyword, profile_length, + profile) != 0) { /* The profile has been validated for basic * security issues, so read the whole thing in. */ size = profile_length - (sizeof profile_header) - - 12 * tag_count; + - 12 * tag_count; (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header) + - 12 * tag_count, &size, 1/*finish*/); + (sizeof local_buffer), &length, + profile + (sizeof profile_header) + + 12 * tag_count, &size, 1/*finish*/); if (length > 0 && !(png_ptr->flags & - PNG_FLAG_BENIGN_ERRORS_WARN)) + PNG_FLAG_BENIGN_ERRORS_WARN)) errmsg = "extra compressed data"; /* But otherwise allow extra data: */ @@ -1455,34 +1528,34 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * keep going. */ png_chunk_warning(png_ptr, - "extra compressed data"); + "extra compressed data"); } png_crc_finish(png_ptr, length); finished = 1; -# ifdef PNG_sRGB_SUPPORTED - /* Check for a match against sRGB */ - png_icc_set_sRGB(png_ptr, - &png_ptr->colorspace, profile, - png_ptr->zstream.adler); -# endif +# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 + /* Check for a match against sRGB */ + png_icc_set_sRGB(png_ptr, + &png_ptr->colorspace, profile, + png_ptr->zstream.adler); +# endif /* Steal the profile for info_ptr. */ if (info_ptr != NULL) { png_free_data(png_ptr, info_ptr, - PNG_FREE_ICCP, 0); + PNG_FREE_ICCP, 0); info_ptr->iccp_name = png_voidcast(char*, - png_malloc_base(png_ptr, - keyword_length+1)); + png_malloc_base(png_ptr, + keyword_length+1)); if (info_ptr->iccp_name != NULL) { memcpy(info_ptr->iccp_name, keyword, - keyword_length+1); + keyword_length+1); info_ptr->iccp_proflen = - profile_length; + profile_length; info_ptr->iccp_profile = profile; png_ptr->read_buffer = NULL; /*steal*/ info_ptr->free_me |= PNG_FREE_ICCP; @@ -1511,19 +1584,11 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) return; } } - - else if (size > 0) - errmsg = "truncated"; - -#ifndef __COVERITY__ - else + if (errmsg == NULL) errmsg = png_ptr->zstream.msg; -#endif } - /* else png_icc_check_tag_table output an error */ } - else /* profile truncated */ errmsg = png_ptr->zstream.msg; } @@ -1650,7 +1715,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) ++entry_start; /* A sample depth should follow the separator, and we should be on it */ - if (entry_start > buffer + length - 2) + if (length < 2U || entry_start > buffer + (length - 2U)) { png_warning(png_ptr, "malformed sPLT chunk"); return; @@ -1664,30 +1729,30 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) data_length = length - (png_uint_32)(entry_start - buffer); /* Integrity-check the data length */ - if ((data_length % entry_size) != 0) + if ((data_length % (unsigned int)entry_size) != 0) { png_warning(png_ptr, "sPLT chunk has bad length"); return; } - dl = (png_int_32)(data_length / entry_size); + dl = (png_uint_32)(data_length / (unsigned int)entry_size); max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); if (dl > max_dl) { - png_warning(png_ptr, "sPLT chunk too long"); - return; + png_warning(png_ptr, "sPLT chunk too long"); + return; } - new_palette.nentries = (png_int_32)(data_length / entry_size); + new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size); - new_palette.entries = (png_sPLT_entryp)png_malloc_warn( - png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry))); + new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, + (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry))); if (new_palette.entries == NULL) { - png_warning(png_ptr, "sPLT chunk requires too much memory"); - return; + png_warning(png_ptr, "sPLT chunk requires too much memory"); + return; } #ifdef PNG_POINTER_INDEXING_SUPPORTED @@ -1817,7 +1882,8 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) return; } - if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH || + if (length > (unsigned int) png_ptr->num_palette || + length > (unsigned int) PNG_MAX_PALETTE_LENGTH || length == 0) { png_crc_finish(png_ptr, length); @@ -1951,6 +2017,69 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } #endif +#ifdef PNG_READ_eXIf_SUPPORTED +void /* PRIVATE */ +png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + unsigned int i; + + png_debug(1, "in png_handle_eXIf"); + + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); + + if (length < 2) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too short"); + return; + } + + else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + info_ptr->free_me |= PNG_FREE_EXIF; + + info_ptr->eXIf_buf = png_voidcast(png_bytep, + png_malloc_warn(png_ptr, length)); + + if (info_ptr->eXIf_buf == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + for (i = 0; i < length; i++) + { + png_byte buf[1]; + png_crc_read(png_ptr, buf, 1); + info_ptr->eXIf_buf[i] = buf[0]; + if (i == 1 && buf[0] != 'M' && buf[0] != 'I' + && info_ptr->eXIf_buf[0] != buf[0]) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "incorrect byte-order specifier"); + png_free(png_ptr, info_ptr->eXIf_buf); + info_ptr->eXIf_buf = NULL; + return; + } + } + + if (png_crc_finish(png_ptr, 0) != 0) + return; + + png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf); + + png_free(png_ptr, info_ptr->eXIf_buf); + info_ptr->eXIf_buf = NULL; +} +#endif + #ifdef PNG_READ_hIST_SUPPORTED void /* PRIVATE */ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) @@ -1980,7 +2109,8 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) num = length / 2 ; - if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH) + if (num != (unsigned int) png_ptr->num_palette || + num > (unsigned int) PNG_MAX_PALETTE_LENGTH) { png_crc_finish(png_ptr, length); png_chunk_benign_error(png_ptr, "invalid"); @@ -2152,7 +2282,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) /* We need to have at least 12 bytes after the purpose string * in order to get the parameter information. */ - if (endptr <= buf + 12) + if (endptr - buf <= 12) { png_chunk_benign_error(png_ptr, "invalid"); return; @@ -2217,7 +2347,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, - (png_charp)units, params); + (png_charp)units, params); png_free(png_ptr, params); } @@ -2260,7 +2390,7 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) } png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", - length + 1); + length + 1); buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); @@ -2312,7 +2442,7 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) else /* This is the (only) success case. */ png_set_sCAL_s(png_ptr, info_ptr, buffer[0], - (png_charp)buffer+1, (png_charp)buffer+heighti); + (png_charp)buffer+1, (png_charp)buffer+heighti); } } #endif @@ -2412,8 +2542,8 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if (buffer == NULL) { - png_chunk_benign_error(png_ptr, "out of memory"); - return; + png_chunk_benign_error(png_ptr, "out of memory"); + return; } png_crc_read(png_ptr, buffer, length); @@ -2478,6 +2608,9 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) png_ptr->mode |= PNG_AFTER_IDAT; + /* Note, "length" is sufficient here; we won't be adding + * a null terminator later. + */ buffer = png_read_buffer(png_ptr, length, 2/*silent*/); if (buffer == NULL) @@ -2520,27 +2653,32 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * and text chunks. */ if (png_decompress_chunk(png_ptr, length, keyword_length+2, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) { png_text text; - /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except - * for the extra compression type byte and the fact that it isn't - * necessarily '\0' terminated. - */ - buffer = png_ptr->read_buffer; - buffer[uncompressed_length+(keyword_length+2)] = 0; + if (png_ptr->read_buffer == NULL) + errmsg="Read failure in png_handle_zTXt"; + else + { + /* It worked; png_ptr->read_buffer now looks like a tEXt chunk + * except for the extra compression type byte and the fact that + * it isn't necessarily '\0' terminated. + */ + buffer = png_ptr->read_buffer; + buffer[uncompressed_length+(keyword_length+2)] = 0; - text.compression = PNG_TEXT_COMPRESSION_zTXt; - text.key = (png_charp)buffer; - text.text = (png_charp)(buffer + keyword_length+2); - text.text_length = uncompressed_length; - text.itxt_length = 0; - text.lang = NULL; - text.lang_key = NULL; + text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.key = (png_charp)buffer; + text.text = (png_charp)(buffer + keyword_length+2); + text.text_length = uncompressed_length; + text.itxt_length = 0; + text.lang = NULL; + text.lang_key = NULL; - if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) - errmsg = "insufficient memory"; + if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) + errmsg = "insufficient memory"; + } } else @@ -2660,7 +2798,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * iCCP and text chunks. */ if (png_decompress_chunk(png_ptr, length, prefix_length, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) buffer = png_ptr->read_buffer; else @@ -2715,14 +2853,14 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) png_ptr->unknown_chunk.data = NULL; } -# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; # elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; # endif if (length <= limit) @@ -2740,7 +2878,7 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) { /* Do a 'warn' here - it is handled below. */ png_ptr->unknown_chunk.data = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, length)); + png_malloc_warn(png_ptr, length)); } } @@ -2765,7 +2903,7 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) /* Handle an unknown, or known but disabled, chunk */ void /* PRIVATE */ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, - png_uint_32 length, int keep) + png_uint_32 length, int keep) { int handled = 0; /* the chunk was handled */ @@ -2785,7 +2923,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, */ # ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED # ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); + keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); # endif # endif @@ -2794,153 +2932,153 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) */ # ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* The user callback takes precedence over the chunk keep value, but the - * keep value is still required to validate a save of a critical chunk. - */ - if (png_ptr->read_user_chunk_fn != NULL) + /* The user callback takes precedence over the chunk keep value, but the + * keep value is still required to validate a save of a critical chunk. + */ + if (png_ptr->read_user_chunk_fn != NULL) + { + if (png_cache_unknown_chunk(png_ptr, length) != 0) { - if (png_cache_unknown_chunk(png_ptr, length) != 0) + /* Callback to user unknown chunk handler */ + int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, + &png_ptr->unknown_chunk); + + /* ret is: + * negative: An error occurred; png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be discarded + * unless png_set_keep_unknown_chunks has been used to set + * a 'keep' behavior for this particular chunk, in which + * case that will be used. A critical chunk will cause an + * error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + */ + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + + else if (ret == 0) { - /* Callback to user unknown chunk handler */ - int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, - &png_ptr->unknown_chunk); - - /* ret is: - * negative: An error occurred; png_chunk_error will be called. - * zero: The chunk was not handled, the chunk will be discarded - * unless png_set_keep_unknown_chunks has been used to set - * a 'keep' behavior for this particular chunk, in which - * case that will be used. A critical chunk will cause an - * error at this point unless it is to be saved. - * positive: The chunk was handled, libpng will ignore/discard it. + /* If the keep value is 'default' or 'never' override it, but + * still error out on critical chunks unless the keep value is + * 'always' While this is weird it is the behavior in 1.4.12. + * A possible improvement would be to obey the value set for the + * chunk, but this would be an API change that would probably + * damage some applications. + * + * The png_app_warning below catches the case that matters, where + * the application has not set specific save or ignore for this + * chunk or global save or ignore. */ - if (ret < 0) - png_chunk_error(png_ptr, "error in user chunk"); - - else if (ret == 0) + if (keep < PNG_HANDLE_CHUNK_IF_SAFE) { - /* If the keep value is 'default' or 'never' override it, but - * still error out on critical chunks unless the keep value is - * 'always' While this is weird it is the behavior in 1.4.12. - * A possible improvement would be to obey the value set for the - * chunk, but this would be an API change that would probably - * damage some applications. - * - * The png_app_warning below catches the case that matters, where - * the application has not set specific save or ignore for this - * chunk or global save or ignore. - */ - if (keep < PNG_HANDLE_CHUNK_IF_SAFE) +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) { -# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) - { - png_chunk_warning(png_ptr, "Saving unknown chunk:"); - png_app_warning(png_ptr, - "forcing save of an unhandled chunk;" - " please call png_set_keep_unknown_chunks"); - /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ - } -# endif - keep = PNG_HANDLE_CHUNK_IF_SAFE; + png_chunk_warning(png_ptr, "Saving unknown chunk:"); + png_app_warning(png_ptr, + "forcing save of an unhandled chunk;" + " please call png_set_keep_unknown_chunks"); + /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ } - } - - else /* chunk was handled */ - { - handled = 1; - /* Critical chunks can be safely discarded at this point. */ - keep = PNG_HANDLE_CHUNK_NEVER; +# endif + keep = PNG_HANDLE_CHUNK_IF_SAFE; } } - else - keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ + else /* chunk was handled */ + { + handled = 1; + /* Critical chunks can be safely discarded at this point. */ + keep = PNG_HANDLE_CHUNK_NEVER; + } } else - /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ + keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ + } + + else + /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ # endif /* READ_USER_CHUNKS */ # ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED + { + /* keep is currently just the per-chunk setting, if there was no + * setting change it to the global default now (not that this may + * still be AS_DEFAULT) then obtain the cache of the chunk if required, + * if not simply skip the chunk. + */ + if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) + keep = png_ptr->unknown_default; + + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) { - /* keep is currently just the per-chunk setting, if there was no - * setting change it to the global default now (not that this may - * still be AS_DEFAULT) then obtain the cache of the chunk if required, - * if not simply skip the chunk. - */ - if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) - keep = png_ptr->unknown_default; - - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) - { - if (png_cache_unknown_chunk(png_ptr, length) == 0) - keep = PNG_HANDLE_CHUNK_NEVER; - } - - else - png_crc_finish(png_ptr, length); + if (png_cache_unknown_chunk(png_ptr, length) == 0) + keep = PNG_HANDLE_CHUNK_NEVER; } + + else + png_crc_finish(png_ptr, length); + } # else # ifndef PNG_READ_USER_CHUNKS_SUPPORTED # error no method to support READ_UNKNOWN_CHUNKS # endif - { - /* If here there is no read callback pointer set and no support is - * compiled in to just save the unknown chunks, so simply skip this - * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then - * the app has erroneously asked for unknown chunk saving when there - * is no support. - */ - if (keep > PNG_HANDLE_CHUNK_NEVER) - png_app_error(png_ptr, "no unknown chunk support available"); + { + /* If here there is no read callback pointer set and no support is + * compiled in to just save the unknown chunks, so simply skip this + * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then + * the app has erroneously asked for unknown chunk saving when there + * is no support. + */ + if (keep > PNG_HANDLE_CHUNK_NEVER) + png_app_error(png_ptr, "no unknown chunk support available"); - png_crc_finish(png_ptr, length); - } + png_crc_finish(png_ptr, length); + } # endif # ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - /* Now store the chunk in the chunk list if appropriate, and if the limits - * permit it. - */ - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + /* Now store the chunk in the chunk list if appropriate, and if the limits + * permit it. + */ + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + { +# ifdef PNG_USER_LIMITS_SUPPORTED + switch (png_ptr->user_chunk_cache_max) { -# ifdef PNG_USER_LIMITS_SUPPORTED - switch (png_ptr->user_chunk_cache_max) - { - case 2: - png_ptr->user_chunk_cache_max = 1; - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - /* FALL THROUGH */ - case 1: - /* NOTE: prior to 1.6.0 this case resulted in an unknown critical - * chunk being skipped, now there will be a hard error below. - */ - break; + case 2: + png_ptr->user_chunk_cache_max = 1; + png_chunk_benign_error(png_ptr, "no space in chunk cache"); + /* FALLTHROUGH */ + case 1: + /* NOTE: prior to 1.6.0 this case resulted in an unknown critical + * chunk being skipped, now there will be a hard error below. + */ + break; - default: /* not at limit */ - --(png_ptr->user_chunk_cache_max); - /* FALL THROUGH */ - case 0: /* no limit */ -# endif /* USER_LIMITS */ - /* Here when the limit isn't reached or when limits are compiled - * out; store the chunk. - */ - png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); - handled = 1; -# ifdef PNG_USER_LIMITS_SUPPORTED - break; - } -# endif + default: /* not at limit */ + --(png_ptr->user_chunk_cache_max); + /* FALLTHROUGH */ + case 0: /* no limit */ +# endif /* USER_LIMITS */ + /* Here when the limit isn't reached or when limits are compiled + * out; store the chunk. + */ + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + handled = 1; +# ifdef PNG_USER_LIMITS_SUPPORTED + break; } +# endif + } # else /* no store support: the chunk must be handled by the user callback */ - PNG_UNUSED(info_ptr) + PNG_UNUSED(info_ptr) # endif /* Regardless of the error handling below the cached data (if any) can be @@ -2976,20 +3114,58 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, */ void /* PRIVATE */ -png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name) +png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name) { int i; + png_uint_32 cn=chunk_name; png_debug(1, "in png_check_chunk_name"); for (i=1; i<=4; ++i) { - int c = chunk_name & 0xff; + int c = cn & 0xff; if (c < 65 || c > 122 || (c > 90 && c < 97)) png_chunk_error(png_ptr, "invalid chunk type"); - chunk_name >>= 8; + cn >>= 8; + } +} + +void /* PRIVATE */ +png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length) +{ + png_alloc_size_t limit = PNG_UINT_31_MAX; + +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; +# endif + if (png_ptr->chunk_name == png_IDAT) + { + png_alloc_size_t idat_limit = PNG_UINT_31_MAX; + size_t row_factor = + (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1) + + 1 + (png_ptr->interlaced? 6: 0)); + if (png_ptr->height > PNG_UINT_32_MAX/row_factor) + idat_limit=PNG_UINT_31_MAX; + else + idat_limit = png_ptr->height * row_factor; + row_factor = row_factor > 32566? 32566 : row_factor; + idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */ + idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX; + limit = limit < idat_limit? idat_limit : limit; + } + + if (length > limit) + { + png_debug2(0," length = %lu, limit = %lu", + (unsigned long)length,(unsigned long)limit); + png_chunk_error(png_ptr, "chunk data is too large"); } } @@ -3042,13 +3218,13 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; end_byte = *end_ptr; # ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - /* little-endian byte */ - end_mask = 0xff << end_mask; + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + /* little-endian byte */ + end_mask = (unsigned int)(0xff << end_mask); - else /* big-endian byte */ + else /* big-endian byte */ # endif - end_mask = 0xff >> end_mask; + end_mask = 0xff >> end_mask; /* end_mask is now the bits to *keep* from the destination row */ } @@ -3206,12 +3382,12 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) png_uint_32 mask; # ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - mask = MASK(pass, pixel_depth, display, 0); + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + mask = MASK(pass, pixel_depth, display, 0); - else + else # endif - mask = MASK(pass, pixel_depth, display, 1); + mask = MASK(pass, pixel_depth, display, 1); for (;;) { @@ -3318,7 +3494,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) */ do { - dp[0] = sp[0], dp[1] = sp[1]; + dp[0] = sp[0]; dp[1] = sp[1]; if (row_width <= bytes_to_jump) return; @@ -3339,7 +3515,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) */ for (;;) { - dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; + dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2]; if (row_width <= bytes_to_jump) return; @@ -3365,8 +3541,8 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) /* Everything is aligned for png_uint_16 copies, but try for * png_uint_32 first. */ - if (png_isaligned(dp, png_uint_32) != 0 && - png_isaligned(sp, png_uint_32) != 0 && + if (png_isaligned(dp, png_uint_32) && + png_isaligned(sp, png_uint_32) && bytes_to_copy % (sizeof (png_uint_32)) == 0 && bytes_to_jump % (sizeof (png_uint_32)) == 0) { @@ -3486,11 +3662,11 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) #ifdef PNG_READ_INTERLACING_SUPPORTED void /* PRIVATE */ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, - png_uint_32 transformations /* Because these may affect the byte layout */) + png_uint_32 transformations /* Because these may affect the byte layout */) { /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Offset to next interlace block */ - static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static PNG_CONST unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_read_interlace"); if (row != NULL && row_info != NULL) @@ -3505,9 +3681,10 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, { png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); - int sshift, dshift; - int s_start, s_end, s_inc; - int jstop = png_pass_inc[pass]; + unsigned int sshift, dshift; + unsigned int s_start, s_end; + int s_inc; + int jstop = (int)png_pass_inc[pass]; png_byte v; png_uint_32 i; int j; @@ -3515,8 +3692,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, #ifdef PNG_READ_PACKSWAP_SUPPORTED if ((transformations & PNG_PACKSWAP) != 0) { - sshift = (int)((row_info->width + 7) & 0x07); - dshift = (int)((final_width + 7) & 0x07); + sshift = ((row_info->width + 7) & 0x07); + dshift = ((final_width + 7) & 0x07); s_start = 7; s_end = 0; s_inc = -1; @@ -3525,8 +3702,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, else #endif { - sshift = 7 - (int)((row_info->width + 7) & 0x07); - dshift = 7 - (int)((final_width + 7) & 0x07); + sshift = 7 - ((row_info->width + 7) & 0x07); + dshift = 7 - ((final_width + 7) & 0x07); s_start = 0; s_end = 7; s_inc = 1; @@ -3538,7 +3715,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, for (j = 0; j < jstop; j++) { unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); - tmp |= v << dshift; + tmp |= (unsigned int)(v << dshift); *dp = (png_byte)(tmp & 0xff); if (dshift == s_end) @@ -3548,7 +3725,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, } else - dshift += s_inc; + dshift = (unsigned int)((int)dshift + s_inc); } if (sshift == s_end) @@ -3558,7 +3735,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, } else - sshift += s_inc; + sshift = (unsigned int)((int)sshift + s_inc); } break; } @@ -3567,16 +3744,17 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, { png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); - int sshift, dshift; - int s_start, s_end, s_inc; - int jstop = png_pass_inc[pass]; + unsigned int sshift, dshift; + unsigned int s_start, s_end; + int s_inc; + int jstop = (int)png_pass_inc[pass]; png_uint_32 i; #ifdef PNG_READ_PACKSWAP_SUPPORTED if ((transformations & PNG_PACKSWAP) != 0) { - sshift = (int)(((row_info->width + 3) & 0x03) << 1); - dshift = (int)(((final_width + 3) & 0x03) << 1); + sshift = (((row_info->width + 3) & 0x03) << 1); + dshift = (((final_width + 3) & 0x03) << 1); s_start = 6; s_end = 0; s_inc = -2; @@ -3585,8 +3763,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, else #endif { - sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); - dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); + sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1); + dshift = ((3 - ((final_width + 3) & 0x03)) << 1); s_start = 0; s_end = 6; s_inc = 2; @@ -3601,7 +3779,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, for (j = 0; j < jstop; j++) { unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); - tmp |= v << dshift; + tmp |= (unsigned int)(v << dshift); *dp = (png_byte)(tmp & 0xff); if (dshift == s_end) @@ -3611,7 +3789,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, } else - dshift += s_inc; + dshift = (unsigned int)((int)dshift + s_inc); } if (sshift == s_end) @@ -3621,7 +3799,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, } else - sshift += s_inc; + sshift = (unsigned int)((int)sshift + s_inc); } break; } @@ -3630,16 +3808,17 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, { png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); - int sshift, dshift; - int s_start, s_end, s_inc; + unsigned int sshift, dshift; + unsigned int s_start, s_end; + int s_inc; png_uint_32 i; - int jstop = png_pass_inc[pass]; + int jstop = (int)png_pass_inc[pass]; #ifdef PNG_READ_PACKSWAP_SUPPORTED if ((transformations & PNG_PACKSWAP) != 0) { - sshift = (int)(((row_info->width + 1) & 0x01) << 2); - dshift = (int)(((final_width + 1) & 0x01) << 2); + sshift = (((row_info->width + 1) & 0x01) << 2); + dshift = (((final_width + 1) & 0x01) << 2); s_start = 4; s_end = 0; s_inc = -4; @@ -3648,8 +3827,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, else #endif { - sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); - dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); + sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2); + dshift = ((1 - ((final_width + 1) & 0x01)) << 2); s_start = 0; s_end = 4; s_inc = 4; @@ -3663,7 +3842,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, for (j = 0; j < jstop; j++) { unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); - tmp |= v << dshift; + tmp |= (unsigned int)(v << dshift); *dp = (png_byte)(tmp & 0xff); if (dshift == s_end) @@ -3673,7 +3852,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, } else - dshift += s_inc; + dshift = (unsigned int)((int)dshift + s_inc); } if (sshift == s_end) @@ -3683,7 +3862,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, } else - sshift += s_inc; + sshift = (unsigned int)((int)sshift + s_inc); } break; } @@ -3697,7 +3876,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; - int jstop = png_pass_inc[pass]; + int jstop = (int)png_pass_inc[pass]; png_uint_32 i; for (i = 0; i < row_info->width; i++) @@ -3730,7 +3909,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, static void png_read_filter_row_sub(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) + png_const_bytep prev_row) { png_size_t i; png_size_t istop = row_info->rowbytes; @@ -3748,7 +3927,7 @@ png_read_filter_row_sub(png_row_infop row_info, png_bytep row, static void png_read_filter_row_up(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) + png_const_bytep prev_row) { png_size_t i; png_size_t istop = row_info->rowbytes; @@ -3764,7 +3943,7 @@ png_read_filter_row_up(png_row_infop row_info, png_bytep row, static void png_read_filter_row_avg(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) + png_const_bytep prev_row) { png_size_t i; png_bytep rp = row; @@ -3791,7 +3970,7 @@ png_read_filter_row_avg(png_row_infop row_info, png_bytep row, static void png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) + png_const_bytep prev_row) { png_bytep rp_end = row + row_info->rowbytes; int a, c; @@ -3812,20 +3991,23 @@ png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, p = b - c; pc = a - c; -# ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -# else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -# endif +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif /* Find the best predictor, the least of pa, pb, pc favoring the earlier * ones in the case of a tie. */ - if (pb < pa) pa = pb, a = b; + if (pb < pa) + { + pa = pb; a = b; + } if (pc < pa) a = c; /* Calculate the current pixel in a, and move the previous row pixel to c @@ -3839,9 +4021,9 @@ png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, static void png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) + png_const_bytep prev_row) { - int bpp = (row_info->pixel_depth + 7) >> 3; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; png_bytep rp_end = row + bpp; /* Process the first pixel in the row completely (this is the same as 'up' @@ -3854,7 +4036,7 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, } /* Remainder */ - rp_end += row_info->rowbytes - bpp; + rp_end = rp_end + (row_info->rowbytes - bpp); while (row < rp_end) { @@ -3867,17 +4049,20 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, p = b - c; pc = a - c; -# ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -# else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -# endif +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif - if (pb < pa) pa = pb, a = b; + if (pb < pa) + { + pa = pb; a = b; + } if (pc < pa) a = c; a += *row; @@ -3924,7 +4109,7 @@ png_init_filter_functions(png_structrp pp) void /* PRIVATE */ png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, - png_const_bytep prev_row, int filter) + png_const_bytep prev_row, int filter) { /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic @@ -3942,7 +4127,7 @@ png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, #ifdef PNG_SEQUENTIAL_READ_SUPPORTED void /* PRIVATE */ png_read_IDAT_data(png_structrp png_ptr, png_bytep output, - png_alloc_size_t avail_out) + png_alloc_size_t avail_out) { /* Loop reading IDATs and decompressing the result into output[avail_out] */ png_ptr->zstream.next_out = output; @@ -4017,7 +4202,7 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output, * * TODO: deal more elegantly with truncated IDAT lists. */ - ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); + ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH); /* Take the unconsumed output back. */ if (output != NULL) @@ -4199,7 +4384,7 @@ png_read_start_row(png_structrp png_ptr) /* Offset to next interlace block in the y direction */ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - int max_pixel_depth; + unsigned int max_pixel_depth; png_size_t row_bytes; png_debug(1, "in png_read_start_row"); @@ -4228,7 +4413,7 @@ png_read_start_row(png_structrp png_ptr) png_ptr->iwidth = png_ptr->width; } - max_pixel_depth = png_ptr->pixel_depth; + max_pixel_depth = (unsigned int)png_ptr->pixel_depth; /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of * calculations to calculate the final pixel depth, then @@ -4280,18 +4465,18 @@ png_read_start_row(png_structrp png_ptr) #ifdef PNG_READ_EXPAND_16_SUPPORTED if ((png_ptr->transformations & PNG_EXPAND_16) != 0) { -# ifdef PNG_READ_EXPAND_SUPPORTED - /* In fact it is an error if it isn't supported, but checking is - * the safe way. - */ - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (png_ptr->bit_depth < 16) - max_pixel_depth *= 2; - } - else -# endif - png_ptr->transformations &= ~PNG_EXPAND_16; +# ifdef PNG_READ_EXPAND_SUPPORTED + /* In fact it is an error if it isn't supported, but checking is + * the safe way. + */ + if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (png_ptr->bit_depth < 16) + max_pixel_depth *= 2; + } + else +# endif + png_ptr->transformations &= ~PNG_EXPAND_16; } #endif @@ -4363,7 +4548,7 @@ png_read_start_row(png_structrp png_ptr) defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) { - int user_pixel_depth = png_ptr->user_transform_depth * + unsigned int user_pixel_depth = png_ptr->user_transform_depth * png_ptr->user_transform_channels; if (user_pixel_depth > max_pixel_depth) @@ -4385,7 +4570,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) * for safety's sake */ row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + - 1 + ((max_pixel_depth + 7) >> 3); + 1 + ((max_pixel_depth + 7) >> 3U); #ifdef PNG_MAX_MALLOC_64K if (row_bytes > (png_uint_32)65536L) @@ -4394,42 +4579,42 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if (row_bytes + 48 > png_ptr->old_big_row_buf_size) { - png_free(png_ptr, png_ptr->big_row_buf); - png_free(png_ptr, png_ptr->big_prev_row); + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); - if (png_ptr->interlaced != 0) - png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, - row_bytes + 48); + if (png_ptr->interlaced != 0) + png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, + row_bytes + 48); - else - png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + else + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); #ifdef PNG_ALIGNED_MEMORY_SUPPORTED - /* Use 16-byte aligned memory for row_buf with at least 16 bytes - * of padding before and after row_buf; treat prev_row similarly. - * NOTE: the alignment is to the start of the pixels, one beyond the start - * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this - * was incorrect; the filter byte was aligned, which had the exact - * opposite effect of that intended. - */ - { - png_bytep temp = png_ptr->big_row_buf + 32; - int extra = (int)((temp - (png_bytep)0) & 0x0f); - png_ptr->row_buf = temp - extra - 1/*filter byte*/; + /* Use 16-byte aligned memory for row_buf with at least 16 bytes + * of padding before and after row_buf; treat prev_row similarly. + * NOTE: the alignment is to the start of the pixels, one beyond the start + * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this + * was incorrect; the filter byte was aligned, which had the exact + * opposite effect of that intended. + */ + { + png_bytep temp = png_ptr->big_row_buf + 32; + int extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->row_buf = temp - extra - 1/*filter byte*/; - temp = png_ptr->big_prev_row + 32; - extra = (int)((temp - (png_bytep)0) & 0x0f); - png_ptr->prev_row = temp - extra - 1/*filter byte*/; - } + temp = png_ptr->big_prev_row + 32; + extra = (int)((temp - (png_bytep)0) & 0x0f); + png_ptr->prev_row = temp - extra - 1/*filter byte*/; + } #else - /* Use 31 bytes of padding before and 17 bytes after row_buf. */ - png_ptr->row_buf = png_ptr->big_row_buf + 31; - png_ptr->prev_row = png_ptr->big_prev_row + 31; + /* Use 31 bytes of padding before and 17 bytes after row_buf. */ + png_ptr->row_buf = png_ptr->big_row_buf + 31; + png_ptr->prev_row = png_ptr->big_prev_row + 31; #endif - png_ptr->old_big_row_buf_size = row_bytes + 48; + png_ptr->old_big_row_buf_size = row_bytes + 48; } #ifdef PNG_MAX_MALLOC_64K @@ -4454,7 +4639,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) * does not, so free the read buffer now regardless; the sequential reader * reallocates it on demand. */ - if (png_ptr->read_buffer != 0) + if (png_ptr->read_buffer != NULL) { png_bytep buffer = png_ptr->read_buffer; diff --git a/src/third-party/libpng/pngset.c b/src/third-party/libpng/pngset.c index fce303916..6f3a1ee11 100644 --- a/src/third-party/libpng/pngset.c +++ b/src/third-party/libpng/pngset.c @@ -1,8 +1,8 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -104,14 +104,14 @@ png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, double green_x, double green_y, double blue_x, double blue_y) { png_set_cHRM_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, white_x, "cHRM White X"), - png_fixed(png_ptr, white_y, "cHRM White Y"), - png_fixed(png_ptr, red_x, "cHRM Red X"), - png_fixed(png_ptr, red_y, "cHRM Red Y"), - png_fixed(png_ptr, green_x, "cHRM Green X"), - png_fixed(png_ptr, green_y, "cHRM Green Y"), - png_fixed(png_ptr, blue_x, "cHRM Blue X"), - png_fixed(png_ptr, blue_y, "cHRM Blue Y")); + png_fixed(png_ptr, white_x, "cHRM White X"), + png_fixed(png_ptr, white_y, "cHRM White Y"), + png_fixed(png_ptr, red_x, "cHRM Red X"), + png_fixed(png_ptr, red_y, "cHRM Red Y"), + png_fixed(png_ptr, green_x, "cHRM Green X"), + png_fixed(png_ptr, green_y, "cHRM Green Y"), + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); } void PNGAPI @@ -120,20 +120,67 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, double blue_X, double blue_Y, double blue_Z) { png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, red_X, "cHRM Red X"), - png_fixed(png_ptr, red_Y, "cHRM Red Y"), - png_fixed(png_ptr, red_Z, "cHRM Red Z"), - png_fixed(png_ptr, green_X, "cHRM Red X"), - png_fixed(png_ptr, green_Y, "cHRM Red Y"), - png_fixed(png_ptr, green_Z, "cHRM Red Z"), - png_fixed(png_ptr, blue_X, "cHRM Red X"), - png_fixed(png_ptr, blue_Y, "cHRM Red Y"), - png_fixed(png_ptr, blue_Z, "cHRM Red Z")); + png_fixed(png_ptr, red_X, "cHRM Red X"), + png_fixed(png_ptr, red_Y, "cHRM Red Y"), + png_fixed(png_ptr, red_Z, "cHRM Red Z"), + png_fixed(png_ptr, green_X, "cHRM Green X"), + png_fixed(png_ptr, green_Y, "cHRM Green Y"), + png_fixed(png_ptr, green_Z, "cHRM Green Z"), + png_fixed(png_ptr, blue_X, "cHRM Blue X"), + png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), + png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); } # endif /* FLOATING_POINT */ #endif /* cHRM */ +#ifdef PNG_eXIf_SUPPORTED +void PNGAPI +png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, + const png_bytep eXIf_buf) +{ + png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1"); + PNG_UNUSED(info_ptr) + PNG_UNUSED(eXIf_buf) +} + +void PNGAPI +png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr, + const png_uint_32 num_exif, const png_bytep eXIf_buf) +{ + int i; + + png_debug1(1, "in %s storage function", "eXIf"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (info_ptr->exif) + { + png_free(png_ptr, info_ptr->exif); + info_ptr->exif = NULL; + } + + info_ptr->num_exif = num_exif; + + info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, + info_ptr->num_exif)); + + if (info_ptr->exif == NULL) + { + png_warning(png_ptr, "Insufficient memory for eXIf chunk data"); + return; + } + + info_ptr->free_me |= PNG_FREE_EXIF; + + for (i = 0; i < (int) info_ptr->num_exif; i++) + info_ptr->exif[i] = eXIf_buf[i]; + + info_ptr->valid |= PNG_INFO_eXIf; +} +#endif /* eXIf */ + #ifdef PNG_gAMA_SUPPORTED void PNGFAPI png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, @@ -283,17 +330,29 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, /* Check that the type matches the specification. */ if (type < 0 || type > 3) - png_error(png_ptr, "Invalid pCAL equation type"); + { + png_chunk_report(png_ptr, "Invalid pCAL equation type", + PNG_CHUNK_WRITE_ERROR); + return; + } if (nparams < 0 || nparams > 255) - png_error(png_ptr, "Invalid pCAL parameter count"); + { + png_chunk_report(png_ptr, "Invalid pCAL parameter count", + PNG_CHUNK_WRITE_ERROR); + return; + } /* Validate params[nparams] */ for (i=0; ipcal_purpose = png_voidcast(png_charp, @@ -301,8 +360,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, if (info_ptr->pcal_purpose == NULL) { - png_warning(png_ptr, "Insufficient memory for pCAL purpose"); - + png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose", + PNG_CHUNK_WRITE_ERROR); return; } @@ -316,10 +375,10 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, length = strlen(units) + 1; png_debug1(3, "allocating units for info (%lu bytes)", - (unsigned long)length); + (unsigned long)length); info_ptr->pcal_units = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); + png_malloc_warn(png_ptr, length)); if (info_ptr->pcal_units == NULL) { @@ -331,7 +390,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, memcpy(info_ptr->pcal_units, units, length); info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - (png_size_t)((nparams + 1) * (sizeof (png_charp))))); + (png_size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp))))); if (info_ptr->pcal_params == NULL) { @@ -340,7 +399,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, return; } - memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); + memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) * + (sizeof (png_charp))); for (i = 0; i < nparams; i++) { @@ -398,7 +458,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); info_ptr->scal_s_width = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthw)); + png_malloc_warn(png_ptr, lengthw)); if (info_ptr->scal_s_width == NULL) { @@ -414,7 +474,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); info_ptr->scal_s_height = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthh)); + png_malloc_warn(png_ptr, lengthh)); if (info_ptr->scal_s_height == NULL) { @@ -453,9 +513,9 @@ png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, char sheight[PNG_sCAL_MAX_DIGITS+1]; png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, - PNG_sCAL_PRECISION); + PNG_sCAL_PRECISION); png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, - PNG_sCAL_PRECISION); + PNG_sCAL_PRECISION); png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); } @@ -513,12 +573,17 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_const_colorp palette, int num_palette) { + png_uint_32 max_palette_length; + png_debug1(1, "in %s storage function", "PLTE"); if (png_ptr == NULL || info_ptr == NULL) return; - if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) + max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; + + if (num_palette < 0 || num_palette > (int) max_palette_length) { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_error(png_ptr, "Invalid palette length"); @@ -551,14 +616,15 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead - * of num_palette entries, in case of an invalid PNG file that has - * too-large sample values. + * of num_palette entries, in case of an invalid PNG file or incorrect + * call to png_set_PLTE() with too-large sample values. */ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); if (num_palette > 0) - memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color))); + memcpy(png_ptr->palette, palette, (unsigned int)num_palette * + (sizeof (png_color))); info_ptr->palette = png_ptr->palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; @@ -643,7 +709,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, */ { int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, - proflen, profile, info_ptr->color_type); + proflen, profile, info_ptr->color_type); png_colorspace_sync_info(png_ptr, info_ptr); @@ -668,12 +734,11 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, memcpy(new_iccp_name, name, length); new_iccp_profile = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, proflen)); + png_malloc_warn(png_ptr, proflen)); if (new_iccp_profile == NULL) { png_free(png_ptr, new_iccp_name); - new_iccp_name = NULL; png_benign_error(png_ptr, "Insufficient memory to process iCCP profile"); @@ -710,7 +775,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, { int i; - png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : + png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U : (unsigned long)png_ptr->chunk_name); if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) @@ -744,14 +809,14 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, * the overflow checks. */ new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, - info_ptr->text, old_num_text, max_text-old_num_text, - sizeof *new_text)); + info_ptr->text, old_num_text, max_text-old_num_text, + sizeof *new_text)); } if (new_text == NULL) { png_chunk_report(png_ptr, "too many text chunks", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); return 1; } @@ -779,7 +844,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) { png_chunk_report(png_ptr, "text compression mode is out of range", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); continue; } @@ -811,7 +876,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, # else /* iTXt */ { png_chunk_report(png_ptr, "iTXt chunk not supported", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); continue; } # endif @@ -840,7 +905,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, if (textp->key == NULL) { png_chunk_report(png_ptr, "text chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); return 1; } @@ -948,12 +1013,14 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep, - png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); - if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) + { + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ + info_ptr->trans_alpha = png_voidcast(png_bytep, + png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + } + png_ptr->trans_alpha = info_ptr->trans_alpha; } if (trans_color != NULL) @@ -970,7 +1037,7 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, trans_color->green > sample_max || trans_color->blue > sample_max))) png_warning(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth"); + "tRNS chunk has out-of-range samples for bit_depth"); } #endif @@ -1012,8 +1079,8 @@ png_set_sPLT(png_const_structrp png_ptr, * overflows. Notice that the parameters are (int) and (size_t) */ np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, - info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, - sizeof *np)); + info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, + sizeof *np)); if (np == NULL) { @@ -1074,7 +1141,7 @@ png_set_sPLT(png_const_structrp png_ptr, * checked it when doing the allocation. */ memcpy(np->entries, entries->entries, - entries->nentries * sizeof (png_sPLT_entry)); + (unsigned int)entries->nentries * sizeof (png_sPLT_entry)); /* Note that 'continue' skips the advance of the out pointer and out * count, so an invalid entry is not added. @@ -1082,8 +1149,9 @@ png_set_sPLT(png_const_structrp png_ptr, info_ptr->valid |= PNG_INFO_sPLT; ++(info_ptr->splt_palettes_num); ++np; + ++entries; } - while (++entries, --nentries); + while (--nentries); if (nentries > 0) png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); @@ -1104,10 +1172,10 @@ check_location(png_const_structrp png_ptr, int location) { /* Write struct, so unknown chunks come from the app */ png_app_warning(png_ptr, - "png_set_unknown_chunks now expects a valid location"); + "png_set_unknown_chunks now expects a valid location"); /* Use the old behavior */ location = (png_byte)(png_ptr->mode & - (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); + (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); } /* This need not be an internal error - if the app calls @@ -1130,7 +1198,7 @@ check_location(png_const_structrp png_ptr, int location) void PNGAPI png_set_unknown_chunks(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) + png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) { png_unknown_chunkp np; @@ -1169,13 +1237,13 @@ png_set_unknown_chunks(png_const_structrp png_ptr, * appropriate to read or write. */ np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, - info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, - sizeof *np)); + info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, + sizeof *np)); if (np == NULL) { png_chunk_report(png_ptr, "too many unknown chunks", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); return; } @@ -1204,12 +1272,12 @@ png_set_unknown_chunks(png_const_structrp png_ptr, else { np->data = png_voidcast(png_bytep, - png_malloc_base(png_ptr, unknowns->size)); + png_malloc_base(png_ptr, unknowns->size)); if (np->data == NULL) { png_chunk_report(png_ptr, "unknown chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); + PNG_CHUNK_WRITE_ERROR); /* But just skip storing the unknown chunk */ continue; } @@ -1243,7 +1311,7 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, { png_app_error(png_ptr, "invalid unknown chunk location"); /* Fake out the pre 1.6.0 behavior: */ - if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */ + if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */ location = PNG_AFTER_IDAT; else @@ -1334,6 +1402,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, static PNG_CONST png_byte chunks_to_ignore[] = { 98, 75, 71, 68, '\0', /* bKGD */ 99, 72, 82, 77, '\0', /* cHRM */ + 101, 88, 73, 102, '\0', /* eXIf */ 103, 65, 77, 65, '\0', /* gAMA */ 104, 73, 83, 84, '\0', /* hIST */ 105, 67, 67, 80, '\0', /* iCCP */ @@ -1367,7 +1436,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, return; } - num_chunks = num_chunks_in; + num_chunks = (unsigned int)num_chunks_in; } old_num_chunks = png_ptr->num_chunk_list; @@ -1416,7 +1485,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, for (i=0; i PNG_UINT_31_MAX) - png_error(png_ptr, "invalid compression buffer size"); + if (size == 0 || size > PNG_UINT_31_MAX) + png_error(png_ptr, "invalid compression buffer size"); # ifdef PNG_SEQUENTIAL_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { - png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ - return; - } + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { + png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ + return; + } # endif # ifdef PNG_WRITE_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + if (png_ptr->zowner != 0) { - if (png_ptr->zowner != 0) - { - png_warning(png_ptr, - "Compression buffer size cannot be changed because it is in use"); + png_warning(png_ptr, + "Compression buffer size cannot be changed because it is in use"); - return; - } + return; + } #ifndef __COVERITY__ - if (size > ZLIB_IO_MAX) - { - png_warning(png_ptr, - "Compression buffer size limited to system maximum"); - size = ZLIB_IO_MAX; /* must fit */ - } + /* Some compilers complain that this is always false. However, it + * can be true when integer overflow happens. + */ + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, + "Compression buffer size limited to system maximum"); + size = ZLIB_IO_MAX; /* must fit */ + } #endif - if (size < 6) - { - /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH - * if this is permitted. - */ - png_warning(png_ptr, - "Compression buffer size cannot be reduced below 6"); + if (size < 6) + { + /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH + * if this is permitted. + */ + png_warning(png_ptr, + "Compression buffer size cannot be reduced below 6"); - return; - } - - if (png_ptr->zbuffer_size != size) - { - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_ptr->zbuffer_size = (uInt)size; - } + return; } + + if (png_ptr->zbuffer_size != size) + { + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + png_ptr->zbuffer_size = (uInt)size; + } + } # endif } @@ -1554,7 +1626,7 @@ void PNGAPI png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) { if (png_ptr != NULL && info_ptr != NULL) - info_ptr->valid &= ~mask; + info_ptr->valid &= (unsigned int)(~mask); } @@ -1566,7 +1638,7 @@ png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, { /* Images with dimensions larger than these limits will be * rejected by png_set_IHDR(). To accept any PNG datastream - * regardless of dimensions, set both limits to 0x7ffffffL. + * regardless of dimensions, set both limits to 0x7fffffff. */ if (png_ptr == NULL) return; @@ -1637,4 +1709,94 @@ png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) png_ptr->num_palette_max = -1; } #endif + +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, + * and if invalid, correct the keyword rather than discarding the entire + * chunk. The PNG 1.0 specification requires keywords 1-79 characters in + * length, forbids leading or trailing whitespace, multiple internal spaces, + * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. + * + * The 'new_key' buffer must be 80 characters in size (for the keyword plus a + * trailing '\0'). If this routine returns 0 then there was no keyword, or a + * valid one could not be generated, and the caller must png_error. + */ +png_uint_32 /* PRIVATE */ +png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) +{ +#ifdef PNG_WARNINGS_SUPPORTED + png_const_charp orig_key = key; +#endif + png_uint_32 key_len = 0; + int bad_character = 0; + int space = 1; + + png_debug(1, "in png_check_keyword"); + + if (key == NULL) + { + *new_key = 0; + return 0; + } + + while (*key && key_len < 79) + { + png_byte ch = (png_byte)*key++; + + if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) + { + *new_key++ = ch; ++key_len; space = 0; + } + + else if (space == 0) + { + /* A space or an invalid character when one wasn't seen immediately + * before; output just a space. + */ + *new_key++ = 32; ++key_len; space = 1; + + /* If the character was not a space then it is invalid. */ + if (ch != 32) + bad_character = ch; + } + + else if (bad_character == 0) + bad_character = ch; /* just skip it, record the first error */ + } + + if (key_len > 0 && space != 0) /* trailing space */ + { + --key_len; --new_key; + if (bad_character == 0) + bad_character = 32; + } + + /* Terminate the keyword */ + *new_key = 0; + + if (key_len == 0) + return 0; + +#ifdef PNG_WARNINGS_SUPPORTED + /* Try to only output one warning per keyword: */ + if (*key != 0) /* keyword too long */ + png_warning(png_ptr, "keyword truncated"); + + else if (bad_character != 0) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter(p, 1, orig_key); + png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); + + png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); + } +#else /* !WARNINGS */ + PNG_UNUSED(png_ptr) +#endif /* !WARNINGS */ + + return key_len; +} +#endif /* TEXT || pCAL || iCCP || sPLT */ #endif /* READ || WRITE */ diff --git a/src/third-party/libpng/pngstruct.h b/src/third-party/libpng/pngstruct.h index 8420d0997..d83f97125 100644 --- a/src/third-party/libpng/pngstruct.h +++ b/src/third-party/libpng/pngstruct.h @@ -1,8 +1,8 @@ /* pngstruct.h - header file for PNG reference library * - * Last changed in libpng 1.6.1 [March 28, 2013] - * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -219,16 +219,18 @@ struct png_struct_def png_uint_32 row_number; /* current row in interlace pass */ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ png_bytep prev_row; /* buffer to save previous (unfiltered) row. - * This is a pointer into big_prev_row + * While reading this is a pointer into + * big_prev_row; while writing it is separately + * allocated if needed. */ png_bytep row_buf; /* buffer to save current (unfiltered) row. - * This is a pointer into big_row_buf + * While reading, this is a pointer into + * big_row_buf; while writing it is separately + * allocated. */ -#ifdef PNG_WRITE_SUPPORTED - png_bytep sub_row; /* buffer to save "sub" row when filtering */ - png_bytep up_row; /* buffer to save "up" row when filtering */ - png_bytep avg_row; /* buffer to save "avg" row when filtering */ - png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_bytep try_row; /* buffer to save trial row when filtering */ + png_bytep tst_row; /* buffer to save best trial row when filtering */ #endif png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ @@ -247,7 +249,7 @@ struct png_struct_def png_byte filter; /* file filter type (always 0) */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ png_byte pass; /* current interlace pass (0 - 6) */ - png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */ png_byte color_type; /* color type of file */ png_byte bit_depth; /* bit depth of file */ png_byte usr_bit_depth; /* bit depth of users row: write only */ @@ -261,6 +263,9 @@ struct png_struct_def /* pixel depth used for the row buffers */ png_byte transformed_pixel_depth; /* pixel depth after read/write transforms */ +#if ZLIB_VERNUM >= 0x1240 + png_byte zstream_start; /* at start of an input zlib stream */ +#endif /* Zlib >= 1.2.4 */ #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) png_uint_16 filler; /* filler bytes for pixel expansion */ #endif @@ -346,19 +351,9 @@ struct png_struct_def png_bytep quantize_index; /* index translation for palette files */ #endif -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_byte heuristic_method; /* heuristic for row filter selection */ - png_byte num_prev_filters; /* number of weights for previous rows */ - png_bytep prev_filters; /* filter type(s) of previous row(s) */ - png_uint_16p filter_weights; /* weight(s) for previous line(s) */ - png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ - png_uint_16p filter_costs; /* relative filter calculation cost */ - png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ -#endif - - /* Options */ +/* Options */ #ifdef PNG_SET_OPTION_SUPPORTED - png_byte options; /* On/off state (up to 4 options) */ + png_uint_32 options; /* On/off state (up to 16 options) */ #endif #if PNG_LIBPNG_VER < 10700 diff --git a/src/third-party/libpng/pngtest.c b/src/third-party/libpng/pngtest.c index 2c3e04d2d..9d5075791 100644 --- a/src/third-party/libpng/pngtest.c +++ b/src/third-party/libpng/pngtest.c @@ -1,8 +1,8 @@ /* pngtest.c - a simple test program to test libpng * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -61,10 +61,11 @@ defined PNG_READ_sBIT_SUPPORTED &&\ defined PNG_READ_sCAL_SUPPORTED &&\ defined PNG_READ_sRGB_SUPPORTED &&\ + defined PNG_READ_sPLT_SUPPORTED &&\ defined PNG_READ_tEXt_SUPPORTED &&\ defined PNG_READ_tIME_SUPPORTED &&\ defined PNG_READ_zTXt_SUPPORTED &&\ - defined PNG_WRITE_INTERLACING_SUPPORTED + (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700) #ifdef PNG_ZLIB_HEADER # include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ @@ -101,6 +102,10 @@ typedef FILE * png_FILE_p; # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ #endif +#ifndef PNG_UNUSED +# define PNG_UNUSED(param) (void)param; +#endif + /* Turn on CPU timing #define PNGTEST_TIMING */ @@ -118,11 +123,28 @@ static float t_start, t_stop, t_decode, t_encode, t_misc; #define PNG_tIME_STRING_LENGTH 29 static int tIME_chunk_present = 0; static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; + +#if PNG_LIBPNG_VER < 10619 +#define png_convert_to_rfc1123_buffer(ts, t) tIME_to_str(read_ptr, ts, t) + +static int +tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t) +{ + png_const_charp str = png_convert_to_rfc1123(png_ptr, t); + + if (str == NULL) + return 0; + + strcpy(ts, str); + return 1; +} +#endif /* older libpng */ #endif static int verbose = 0; static int strict = 0; static int relaxed = 0; +static int xfail = 0; static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ static int error_count = 0; /* count calls to png_error */ static int warning_count = 0; /* count calls to png_warning */ @@ -185,16 +207,14 @@ write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -/* Example of using user transform callback (we don't transform anything, - * but merely examine the row filters. We set this to 256 rather than - * 5 in case illegal filter values are present.) +/* Example of using a user transform callback (doesn't do anything at present). */ -static png_uint_32 filters_used[256]; static void PNGCBAPI -count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) +read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data) { - if (png_ptr != NULL && row_info != NULL) - ++filters_used[*(data - 1)]; + PNG_UNUSED(png_ptr) + PNG_UNUSED(row_info) + PNG_UNUSED(data) } #endif @@ -221,95 +241,95 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) * png_byte pixel_depth bits per pixel (depth*channels) */ - /* Counts the number of zero samples (or zero pixels if color_type is 3 */ + /* Counts the number of zero samples (or zero pixels if color_type is 3 */ - if (row_info->color_type == 0 || row_info->color_type == 3) - { - int pos = 0; - png_uint_32 n, nstop; + if (row_info->color_type == 0 || row_info->color_type == 3) + { + int pos = 0; + png_uint_32 n, nstop; - for (n = 0, nstop=row_info->width; nbit_depth == 1) - { - if (((*dp << pos++ ) & 0x80) == 0) - zero_samples++; + for (n = 0, nstop=row_info->width; nbit_depth == 1) + { + if (((*dp << pos++ ) & 0x80) == 0) + zero_samples++; - if (pos == 8) - { - pos = 0; - dp++; - } - } + if (pos == 8) + { + pos = 0; + dp++; + } + } - if (row_info->bit_depth == 2) - { - if (((*dp << (pos+=2)) & 0xc0) == 0) - zero_samples++; + if (row_info->bit_depth == 2) + { + if (((*dp << (pos+=2)) & 0xc0) == 0) + zero_samples++; - if (pos == 8) - { - pos = 0; - dp++; - } - } + if (pos == 8) + { + pos = 0; + dp++; + } + } - if (row_info->bit_depth == 4) - { - if (((*dp << (pos+=4)) & 0xf0) == 0) - zero_samples++; + if (row_info->bit_depth == 4) + { + if (((*dp << (pos+=4)) & 0xf0) == 0) + zero_samples++; - if (pos == 8) - { - pos = 0; - dp++; - } - } + if (pos == 8) + { + pos = 0; + dp++; + } + } - if (row_info->bit_depth == 8) - if (*dp++ == 0) - zero_samples++; + if (row_info->bit_depth == 8) + if (*dp++ == 0) + zero_samples++; - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - dp+=2; - } - } - } - else /* Other color types */ - { - png_uint_32 n, nstop; - int channel; - int color_channels = row_info->channels; - if (row_info->color_type > 3) - color_channels--; + if (row_info->bit_depth == 16) + { + if ((*dp | *(dp+1)) == 0) + zero_samples++; + dp+=2; + } + } + } + else /* Other color types */ + { + png_uint_32 n, nstop; + int channel; + int color_channels = row_info->channels; + if (row_info->color_type > 3) + color_channels--; - for (n = 0, nstop=row_info->width; nbit_depth == 8) - if (*dp++ == 0) - zero_samples++; + for (n = 0, nstop=row_info->width; nbit_depth == 8) + if (*dp++ == 0) + zero_samples++; - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; + if (row_info->bit_depth == 16) + { + if ((*dp | *(dp+1)) == 0) + zero_samples++; - dp+=2; - } - } - if (row_info->color_type > 3) - { - dp++; - if (row_info->bit_depth == 16) - dp++; - } - } - } + dp+=2; + } + } + if (row_info->color_type > 3) + { + dp++; + if (row_info->bit_depth == 16) + dp++; + } + } + } } #endif /* WRITE_USER_TRANSFORM */ @@ -326,10 +346,10 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) #ifdef PNG_IO_STATE_SUPPORTED void pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, - png_uint_32 io_op); + png_uint_32 io_op); void pngtest_check_io_state(png_structp png_ptr, png_size_t data_length, - png_uint_32 io_op) + png_uint_32 io_op) { png_uint_32 io_state = png_get_io_state(png_ptr); int err = 0; @@ -444,7 +464,7 @@ pngtest_warning(png_structp png_ptr, png_const_charp message) if (test != NULL && test->file_name != NULL) name = test->file_name; - fprintf(STDERR, "%s: libpng warning: %s\n", name, message); + fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message); } /* This is the default error handling function. Note that replacements for @@ -513,7 +533,7 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) memory_infop pinfo; png_set_mem_fn(png_ptr, NULL, NULL, NULL); pinfo = (memory_infop)png_malloc(png_ptr, - (sizeof *pinfo)); + (sizeof *pinfo)); pinfo->size = size; current_allocation += size; total_allocation += size; @@ -543,7 +563,7 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) if (verbose != 0) printf("png_malloc %lu bytes at %p\n", (unsigned long)size, - pinfo->pointer); + pinfo->pointer); return (png_voidp)(pinfo->pointer); } @@ -565,6 +585,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) } /* Unlink the element from the list. */ + if (pinformation != NULL) { memory_infop *ppinfo = &pinformation; @@ -581,8 +602,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) /* We must free the list element too, but first kill the memory that is to be freed. */ memset(ptr, 0x55, pinfo->size); - if (pinfo != NULL) - free(pinfo); + free(pinfo); pinfo = NULL; break; } @@ -750,9 +770,9 @@ write_vpAg_chunk(png_structp write_ptr) if (verbose != 0) fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", - (unsigned long)user_chunk_data.vpAg_width, - (unsigned long)user_chunk_data.vpAg_height, - user_chunk_data.vpAg_units); + (unsigned long)user_chunk_data.vpAg_width, + (unsigned long)user_chunk_data.vpAg_height, + user_chunk_data.vpAg_units); png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); @@ -792,8 +812,8 @@ write_chunks(png_structp write_ptr, int location) */ #ifdef PNG_TEXT_SUPPORTED static void -pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr, - int num_text) +pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr, + int num_text) { while (num_text > 0) { @@ -805,6 +825,8 @@ pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr, case PNG_TEXT_COMPRESSION_zTXt: # ifndef PNG_WRITE_zTXt_SUPPORTED ++unsupported_chunks; + /* In libpng 1.7 this now does an app-error, so stop it: */ + text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; # endif break; @@ -812,6 +834,7 @@ pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr, case PNG_ITXT_COMPRESSION_zTXt: # ifndef PNG_WRITE_iTXt_SUPPORTED ++unsupported_chunks; + text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; # endif break; @@ -838,16 +861,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_structp write_ptr; png_infop write_info_ptr; png_infop write_end_info_ptr; +#ifdef PNG_WRITE_FILTER_SUPPORTED int interlace_preserved = 1; -#else +#endif /* WRITE_FILTER */ +#else /* !WRITE */ png_structp write_ptr = NULL; png_infop write_info_ptr = NULL; png_infop write_end_info_ptr = NULL; -#endif +#endif /* !WRITE */ png_bytep row_buf; png_uint_32 y; png_uint_32 width, height; - int num_pass = 1, pass; + volatile int num_passes; + int pass; int bit_depth, color_type; row_buf = NULL; @@ -869,26 +895,26 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) pngtest_debug("Allocating read and write structures"); #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG read_ptr = - png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); + png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, + NULL, NULL, NULL, png_debug_malloc, png_debug_free); #else read_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif png_set_error_fn(read_ptr, &error_parameters, pngtest_error, - pngtest_warning); + pngtest_warning); #ifdef PNG_WRITE_SUPPORTED #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG write_ptr = - png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); + png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, + NULL, NULL, NULL, png_debug_malloc, png_debug_free); #else write_ptr = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif png_set_error_fn(write_ptr, &error_parameters, pngtest_error, - pngtest_warning); + pngtest_warning); #endif pngtest_debug("Allocating read_info, write_info and end_info structures"); read_info_ptr = png_create_info_struct(read_ptr); @@ -901,7 +927,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #ifdef PNG_READ_USER_CHUNKS_SUPPORTED init_callback_info(read_info_ptr); png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, - read_user_chunk_callback); + read_user_chunk_callback); #endif #ifdef PNG_SETJMP_SUPPORTED @@ -911,8 +937,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); png_free(read_ptr, row_buf); row_buf = NULL; + if (verbose != 0) + fprintf(STDERR, " destroy read structs\n"); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); #ifdef PNG_WRITE_SUPPORTED + if (verbose != 0) + fprintf(STDERR, " destroy write structs\n"); png_destroy_info_struct(write_ptr, &write_end_info_ptr); png_destroy_write_struct(&write_ptr, &write_info_ptr); #endif @@ -927,11 +957,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (setjmp(png_jmpbuf(write_ptr))) { fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); + if (verbose != 0) + fprintf(STDERR, " destroying read structs\n"); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); + if (verbose != 0) + fprintf(STDERR, " destroying write structs\n"); png_destroy_info_struct(write_ptr, &write_end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif FCLOSE(fpin); FCLOSE(fpout); return (1); @@ -939,15 +971,16 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif #endif +#ifdef PNG_BENIGN_ERRORS_SUPPORTED if (strict != 0) { /* Treat png_benign_error() as errors on read */ png_set_benign_errors(read_ptr, 0); -#ifdef PNG_WRITE_SUPPORTED +# ifdef PNG_WRITE_SUPPORTED /* Treat them as errors on write */ png_set_benign_errors(write_ptr, 0); -#endif +# endif /* if strict is not set, then app warnings and errors are treated as * warnings in release builds, but not in unstable builds; this can be @@ -960,10 +993,20 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) /* Allow application (pngtest) errors and warnings to pass */ png_set_benign_errors(read_ptr, 1); -#ifdef PNG_WRITE_SUPPORTED - png_set_benign_errors(write_ptr, 1); + /* Turn off CRC checking while reading */ + png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); + +#ifdef PNG_IGNORE_ADLER32 + /* Turn off ADLER32 checking while reading */ + png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON); #endif + +# ifdef PNG_WRITE_SUPPORTED + png_set_benign_errors(write_ptr, 1); +# endif + } +#endif /* BENIGN_ERRORS */ pngtest_debug("Initializing input and output streams"); #ifdef PNG_STDIO_SUPPORTED @@ -976,9 +1019,9 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) # ifdef PNG_WRITE_SUPPORTED png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, # ifdef PNG_WRITE_FLUSH_SUPPORTED - pngtest_flush); + pngtest_flush); # else - NULL); + NULL); # endif # endif #endif @@ -1000,14 +1043,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) } #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - { - int i; - - for (i = 0; i<256; i++) - filters_used[i] = 0; - - png_set_read_user_transform_fn(read_ptr, count_filters); - } + png_set_read_user_transform_fn(read_ptr, read_user_callback); #endif #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED zero_samples = 0; @@ -1025,11 +1061,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) */ #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); + NULL, 0); #endif #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); + NULL, 0); #endif #endif @@ -1053,40 +1089,40 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) &color_type, &interlace_type, &compression_type, &filter_type) != 0) { png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); -#ifndef PNG_READ_INTERLACING_SUPPORTED - /* num_pass will not be set below, set it here if the image is - * interlaced: what happens is that write interlacing is *not* turned - * on an the partial interlaced rows are written directly. + color_type, interlace_type, compression_type, filter_type); + /* num_passes may not be available below if interlace support is not + * provided by libpng for both read and write. */ switch (interlace_type) { case PNG_INTERLACE_NONE: - num_pass = 1; + num_passes = 1; break; case PNG_INTERLACE_ADAM7: - num_pass = 7; - break; + num_passes = 7; + break; default: - png_error(read_ptr, "invalid interlace type"); - /*NOT REACHED*/ + png_error(read_ptr, "invalid interlace type"); + /*NOT REACHED*/ } -#endif } + + else + png_error(read_ptr, "png_get_IHDR failed"); } #ifdef PNG_FIXED_POINT_SUPPORTED #ifdef PNG_cHRM_SUPPORTED { png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; + blue_y; if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, - &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) + &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) { png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); + red_y, green_x, green_y, blue_x, blue_y); } } #endif @@ -1103,13 +1139,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #ifdef PNG_cHRM_SUPPORTED { double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; + blue_y; if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, - &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) + &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) { png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); + red_y, green_x, green_y, blue_x, blue_y); } } #endif @@ -1131,10 +1167,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int compression_type; if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, - &profile, &proflen) != 0) + &profile, &proflen) != 0) { png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, - profile, proflen); + profile, proflen); } } #endif @@ -1163,6 +1199,22 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) } } #endif +#ifdef PNG_READ_eXIf_SUPPORTED + { + png_bytep exif=NULL; + png_uint_32 exif_length; + + if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0) + { + if (exif_length > 1) + fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1], + (unsigned long)exif_length); +# ifdef PNG_WRITE_eXIf_SUPPORTED + png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif); +# endif + } + } +#endif #ifdef PNG_hIST_SUPPORTED { png_uint_16p hist; @@ -1191,10 +1243,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int type, nparams; if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, - &nparams, &units, ¶ms) != 0) + &nparams, &units, ¶ms) != 0) { png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, - nparams, units, params); + nparams, units, params); } } #endif @@ -1224,7 +1276,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) double scal_width, scal_height; if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) + &scal_height) != 0) { png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); } @@ -1236,7 +1288,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_charp scal_width, scal_height; if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) + &scal_height) != 0) { png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height); @@ -1245,6 +1297,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif #endif #endif + +#ifdef PNG_sPLT_SUPPORTED + { + png_sPLT_tp entries; + + int num_entries = (int) png_get_sPLT(read_ptr, read_info_ptr, &entries); + if (num_entries) + { + png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries); + } + } +#endif + #ifdef PNG_TEXT_SUPPORTED { png_textp text_ptr; @@ -1260,11 +1325,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { int i; - printf("\n"); + fprintf(STDERR,"\n"); for (i=0; i 0) + pass_height = PNG_PASS_ROWS(height, pass); + + else + pass_height = 0; + } + + else /* not interlaced */ + pass_height = height; +# else +# define pass_height height +# endif + pngtest_debug1("Writing row data for pass %d", pass); - for (y = 0; y < height; y++) + for (y = 0; y < pass_height; y++) { #ifndef SINGLE_ROWBUF_ALLOC pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); + png_get_rowbytes(read_ptr, read_info_ptr)); pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf, - (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); + (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); #endif /* !SINGLE_ROWBUF_ALLOC */ png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); @@ -1443,11 +1545,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { int i; - printf("\n"); + fprintf(STDERR,"\n"); for (i=0; i 1) + fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1], + (unsigned long)exif_length); +# ifdef PNG_WRITE_eXIf_SUPPORTED + png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif); +# endif + } + } +#endif #ifdef PNG_tIME_SUPPORTED { png_timep mod_time; @@ -1481,12 +1599,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_unknown_chunkp unknowns; int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, - &unknowns); + &unknowns); if (num_unknowns != 0) { png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, - num_unknowns); + num_unknowns); #if PNG_LIBPNG_VER < 10600 /* Copy the locations from the read_info_ptr. The automatically * generated locations in write_end_info_ptr are wrong prior to 1.6.0 @@ -1496,7 +1614,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int i; for (i = 0; i < num_unknowns; i++) png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, - unknowns[i].location); + unknowns[i].location); } #endif } @@ -1530,7 +1648,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) iwidth = png_get_image_width(write_ptr, write_info_ptr); iheight = png_get_image_height(write_ptr, write_info_ptr); fprintf(STDERR, "\n Image width = %lu, height = %lu\n", - (unsigned long)iwidth, (unsigned long)iheight); + (unsigned long)iwidth, (unsigned long)iheight); } #endif @@ -1563,25 +1681,25 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) * above, but this is safe. */ fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", - inname, error_count, warning_count); + inname, error_count, warning_count); if (strict != 0) return (1); } # ifdef PNG_WRITE_SUPPORTED - /* If there we no write support nothing was written! */ + /* If there is no write support nothing was written! */ else if (unsupported_chunks > 0) { fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", - inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); + inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); } # endif else if (warning_count > 0) { fprintf(STDERR, "\n %s: %d libpng warnings found", - inname, warning_count); + inname, warning_count); if (strict != 0) return (1); @@ -1601,7 +1719,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) return (1); } -#ifdef PNG_WRITE_SUPPORTED /* else nothing was written */ +#if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\ + defined (PNG_WRITE_FILTER_SUPPORTED) if (interlace_preserved != 0) /* else the files will be changed */ { for (;;) @@ -1616,18 +1735,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (num_in != num_out) { fprintf(STDERR, "\nFiles %s and %s are of a different size\n", - inname, outname); + inname, outname); if (wrote_question == 0 && unsupported_chunks == 0) { fprintf(STDERR, - " Was %s written with the same maximum IDAT chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); + " Was %s written with the same maximum IDAT" + " chunk size (%d bytes),", + inname, PNG_ZBUF_SIZE); fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); + "\n filtering heuristic (libpng default), compression"); fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); + " level (zlib default),\n and zlib version (%s)?\n\n", + ZLIB_VERSION); wrote_question = 1; } @@ -1647,17 +1767,18 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (memcmp(inbuf, outbuf, num_in)) { fprintf(STDERR, "\nFiles %s and %s are different\n", inname, - outname); + outname); if (wrote_question == 0 && unsupported_chunks == 0) { fprintf(STDERR, - " Was %s written with the same maximum IDAT chunk size (%d bytes),", + " Was %s written with the same maximum" + " IDAT chunk size (%d bytes),", inname, PNG_ZBUF_SIZE); fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); + "\n filtering heuristic (libpng default), compression"); fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", + " level (zlib default),\n and zlib version (%s)?\n\n", ZLIB_VERSION); wrote_question = 1; } @@ -1678,7 +1799,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) } } } -#endif /* WRITE */ +#endif /* WRITE && WRITE_FILTER */ FCLOSE(fpin); FCLOSE(fpout); @@ -1708,12 +1829,12 @@ main(int argc, char *argv[]) fprintf(STDERR, "%s", png_get_copyright(NULL)); /* Show the version of libpng used in building the library */ fprintf(STDERR, " library (%lu):%s", - (unsigned long)png_access_version_number(), - png_get_header_version(NULL)); + (unsigned long)png_access_version_number(), + png_get_header_version(NULL)); /* Show the version of libpng used in building the application */ fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, - PNG_HEADER_VERSION_STRING); + PNG_HEADER_VERSION_STRING); /* Do some consistency checking on the memory allocation settings, I'm * not sure this matters, but it is nice to know, the first of these @@ -1731,7 +1852,7 @@ main(int argc, char *argv[]) if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) { fprintf(STDERR, - "Warning: versions are different between png.h and png.c\n"); + "Warning: versions are different between png.h and png.c\n"); fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); ++ierror; @@ -1767,6 +1888,7 @@ main(int argc, char *argv[]) inname = argv[2]; strict++; relaxed = 0; + multiple=1; } else if (strcmp(argv[1], "--relaxed") == 0) @@ -1776,6 +1898,17 @@ main(int argc, char *argv[]) inname = argv[2]; strict = 0; relaxed++; + multiple=1; + } + else if (strcmp(argv[1], "--xfail") == 0) + { + status_dots_requested = 0; + verbose = 1; + inname = argv[2]; + strict = 0; + xfail++; + relaxed++; + multiple=1; } else @@ -1786,19 +1919,19 @@ main(int argc, char *argv[]) } if (multiple == 0 && argc == 3 + verbose) - outname = argv[2 + verbose]; + outname = argv[2 + verbose]; if ((multiple == 0 && argc > 3 + verbose) || (multiple != 0 && argc < 2)) { - fprintf(STDERR, - "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", - argv[0], argv[0]); - fprintf(STDERR, - " reads/writes one PNG file (without -m) or multiple files (-m)\n"); - fprintf(STDERR, - " with -m %s is used as a temporary file\n", outname); - exit(1); + fprintf(STDERR, + "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", + argv[0], argv[0]); + fprintf(STDERR, + " reads/writes one PNG file (without -m) or multiple files (-m)\n"); + fprintf(STDERR, + " with -m %s is used as a temporary file\n", outname); + exit(1); } if (multiple != 0) @@ -1817,51 +1950,47 @@ main(int argc, char *argv[]) kerror = test_one_file(argv[i], outname); if (kerror == 0) { -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - int k; -#endif #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); + (unsigned long)zero_samples); #else fprintf(STDERR, " PASS\n"); #endif -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - for (k = 0; k<256; k++) - if (filters_used[k] != 0) - fprintf(STDERR, " Filter %d was used %lu times\n", - k, (unsigned long)filters_used[k]); -#endif #ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); + if (tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n", tIME_string); - tIME_chunk_present = 0; + tIME_chunk_present = 0; #endif /* TIME_RFC1123 */ } else { - fprintf(STDERR, " FAIL\n"); - ierror += kerror; + if (xfail) + fprintf(STDERR, " XFAIL\n"); + else + { + fprintf(STDERR, " FAIL\n"); + ierror += kerror; + } } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG if (allocation_now != current_allocation) fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); + current_allocation - allocation_now); if (current_allocation != 0) { memory_infop pinfo = pinformation; fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); + current_allocation); while (pinfo != NULL) { fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, - pinfo->pointer); + (unsigned long)pinfo->size, + pinfo->pointer); pinfo = pinfo->next; } } @@ -1869,13 +1998,13 @@ main(int argc, char *argv[]) } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); + current_allocation); fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); + maximum_allocation); fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); + total_allocation); fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); + num_allocations); #endif } @@ -1908,21 +2037,12 @@ main(int argc, char *argv[]) { if (verbose == 1 || i == 2) { -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - int k; -#endif #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); + (unsigned long)zero_samples); #else fprintf(STDERR, " PASS\n"); #endif -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - for (k = 0; k<256; k++) - if (filters_used[k] != 0) - fprintf(STDERR, " Filter %d was used %lu times\n", - k, (unsigned long)filters_used[k]); -#endif #ifdef PNG_TIME_RFC1123_SUPPORTED if (tIME_chunk_present != 0) fprintf(STDERR, " tIME = %s\n", tIME_string); @@ -1940,25 +2060,30 @@ main(int argc, char *argv[]) #endif } - fprintf(STDERR, " FAIL\n"); - ierror += kerror; + if (xfail) + fprintf(STDERR, " XFAIL\n"); + else + { + fprintf(STDERR, " FAIL\n"); + ierror += kerror; + } } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG if (allocation_now != current_allocation) fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); + current_allocation - allocation_now); if (current_allocation != 0) { memory_infop pinfo = pinformation; fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); + current_allocation); while (pinfo != NULL) { fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, pinfo->pointer); + (unsigned long)pinfo->size, pinfo->pointer); pinfo = pinfo->next; } } @@ -1966,13 +2091,13 @@ main(int argc, char *argv[]) } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); + current_allocation); fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); + maximum_allocation); fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); + total_allocation); fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); + num_allocations); #endif } @@ -1981,13 +2106,13 @@ main(int argc, char *argv[]) t_misc += (t_stop - t_start); t_start = t_stop; fprintf(STDERR, " CPU time used = %.3f seconds", - (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); + (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); fprintf(STDERR, " (decoding %.3f,\n", - t_decode/(float)CLOCKS_PER_SEC); + t_decode/(float)CLOCKS_PER_SEC); fprintf(STDERR, " encoding %.3f ,", - t_encode/(float)CLOCKS_PER_SEC); + t_encode/(float)CLOCKS_PER_SEC); fprintf(STDERR, " other %.3f seconds)\n\n", - t_misc/(float)CLOCKS_PER_SEC); + t_misc/(float)CLOCKS_PER_SEC); #endif if (ierror == 0) @@ -1999,19 +2124,19 @@ main(int argc, char *argv[]) dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); fprintf(STDERR, " Default limits:\n"); fprintf(STDERR, " width_max = %lu\n", - (unsigned long) png_get_user_width_max(dummy_ptr)); + (unsigned long) png_get_user_width_max(dummy_ptr)); fprintf(STDERR, " height_max = %lu\n", - (unsigned long) png_get_user_height_max(dummy_ptr)); + (unsigned long) png_get_user_height_max(dummy_ptr)); if (png_get_chunk_cache_max(dummy_ptr) == 0) fprintf(STDERR, " cache_max = unlimited\n"); else fprintf(STDERR, " cache_max = %lu\n", - (unsigned long) png_get_chunk_cache_max(dummy_ptr)); + (unsigned long) png_get_chunk_cache_max(dummy_ptr)); if (png_get_chunk_malloc_max(dummy_ptr) == 0) fprintf(STDERR, " malloc_max = unlimited\n"); else fprintf(STDERR, " malloc_max = %lu\n", - (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); + (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); png_destroy_read_struct(&dummy_ptr, NULL, NULL); return (int)(ierror != 0); @@ -2021,11 +2146,11 @@ int main(void) { fprintf(STDERR, - " test ignored because libpng was not built with read support\n"); + " test ignored because libpng was not built with read support\n"); /* And skip this test */ return PNG_LIBPNG_VER < 10600 ? 0 : 77; } #endif /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_17 Your_png_h_is_not_version_1_6_17; +typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34; diff --git a/src/third-party/libpng/pngtest.png b/src/third-party/libpng/pngtest.png index cb3fef4cf844324953cc45f21b479a338cb9c288..66df0c4e6f6d13981148bf2fbb85df2b797028a7 100644 GIT binary patch delta 81 zcmezFyxnEPJ4H{E)CkWsUtb0-1_lNW1|~)!24*0Ok%5(gp*@p<1pixel_depth = 8; } @@ -527,10 +532,14 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) if (at_start != 0) /* Skip initial filler */ sp += 2; else /* Skip initial channel and, for sp, the filler */ - sp += 4, dp += 2; + { + sp += 4; dp += 2; + } while (sp < ep) - *dp++ = *sp++, *dp++ = *sp, sp += 3; + { + *dp++ = *sp++; *dp++ = *sp; sp += 3; + } row_info->pixel_depth = 16; } @@ -553,11 +562,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) if (at_start != 0) /* Skip initial filler */ ++sp; else /* Skip initial channels and, for sp, the filler */ - sp += 4, dp += 3; + { + sp += 4; dp += 3; + } /* Note that the loop adds 3 to dp and 4 to sp each time. */ while (sp < ep) - *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; + { + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2; + } row_info->pixel_depth = 24; } @@ -567,14 +580,16 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) if (at_start != 0) /* Skip initial filler */ sp += 2; else /* Skip initial channels and, for sp, the filler */ - sp += 8, dp += 6; + { + sp += 8; dp += 6; + } while (sp < ep) { /* Copy 6 bytes, skip 2 */ - *dp++ = *sp++, *dp++ = *sp++; - *dp++ = *sp++, *dp++ = *sp++; - *dp++ = *sp++, *dp++ = *sp, sp += 3; + *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp; sp += 3; } row_info->pixel_depth = 48; @@ -594,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) return; /* The filler channel has gone already */ /* Fix the rowbytes value. */ - row_info->rowbytes = dp-row; + row_info->rowbytes = (png_size_t)(dp-row); } #endif @@ -692,8 +707,8 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) * and this calculation is used because it avoids warnings that other * forms produced on either GCC or MSVC. */ - int padding = (-row_info->pixel_depth * row_info->width) & 7; - png_bytep rp = png_ptr->row_buf + row_info->rowbytes; + int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); + png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1; switch (row_info->bit_depth) { @@ -704,7 +719,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) */ for (; rp > png_ptr->row_buf; rp--) { - if (*rp >> padding != 0) + if ((*rp >> padding) != 0) png_ptr->num_palette_max = 1; padding = 0; } @@ -797,7 +812,7 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) { png_app_error(png_ptr, - "info change after png_start_read_image or png_read_update_info"); + "info change after png_start_read_image or png_read_update_info"); return; } #endif diff --git a/src/third-party/libpng/pngwio.c b/src/third-party/libpng/pngwio.c index 0a40948aa..37c7c3a7f 100644 --- a/src/third-party/libpng/pngwio.c +++ b/src/third-party/libpng/pngwio.c @@ -1,8 +1,8 @@ /* pngwio.c - functions for data output * - * Last changed in libpng 1.6.15 [November 20, 2014] - * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * Last changed in libpng 1.6.24 [August 4, 2016] + * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -26,7 +26,7 @@ * writes to a file pointer. Note that this routine sometimes gets called * with very small lengths, so you should implement some kind of simple * buffering if you are using unbuffered writes. This should never be asked - * to write more than 64K on a 16 bit machine. + * to write more than 64K on a 16-bit machine. */ void /* PRIVATE */ @@ -35,7 +35,7 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) /* NOTE: write_data_fn must not change the buffer! */ if (png_ptr->write_data_fn != NULL ) (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), - length); + length); else png_error(png_ptr, "Call to NULL write function"); diff --git a/src/third-party/libpng/pngwrite.c b/src/third-party/libpng/pngwrite.c index e3c203496..a16d77ce0 100644 --- a/src/third-party/libpng/pngwrite.c +++ b/src/third-party/libpng/pngwrite.c @@ -1,8 +1,8 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -12,9 +12,9 @@ */ #include "pngpriv.h" -#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED # include -#endif +#endif /* SIMPLIFIED_WRITE_STDIO */ #ifdef PNG_WRITE_SUPPORTED @@ -22,7 +22,7 @@ /* Write out all the unknown chunks for the current given location */ static void write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, - unsigned int where) + unsigned int where) { if (info_ptr->unknown_chunks_num != 0) { @@ -90,43 +90,44 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) { - /* Write PNG signature */ - png_write_sig(png_ptr); + /* Write PNG signature */ + png_write_sig(png_ptr); #ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ - png_ptr->mng_features_permitted != 0) - { - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - png_ptr->mng_features_permitted = 0; - } + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ + png_ptr->mng_features_permitted != 0) + { + png_warning(png_ptr, + "MNG features are not allowed in a PNG datastream"); + png_ptr->mng_features_permitted = 0; + } #endif - /* Write IHDR information. */ - png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, - info_ptr->filter_type, + /* Write IHDR information. */ + png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, + info_ptr->filter_type, #ifdef PNG_WRITE_INTERLACING_SUPPORTED - info_ptr->interlace_type + info_ptr->interlace_type #else - 0 + 0 #endif - ); + ); - /* The rest of these check to see if the valid field has the appropriate - * flag set, and if it does, writes the chunk. - * - * 1.6.0: COLORSPACE support controls the writing of these chunks too, and - * the chunks will be written if the WRITE routine is there and information - * is available in the COLORSPACE. (See png_colorspace_sync_info in png.c - * for where the valid flags get set.) - * - * Under certain circumstances the colorspace can be invalidated without - * syncing the info_struct 'valid' flags; this happens if libpng detects and - * error and calls png_error while the color space is being set, yet the - * application continues writing the PNG. So check the 'invalid' flag here - * too. - */ + /* The rest of these check to see if the valid field has the appropriate + * flag set, and if it does, writes the chunk. + * + * 1.6.0: COLORSPACE support controls the writing of these chunks too, and + * the chunks will be written if the WRITE routine is there and + * information * is available in the COLORSPACE. (See + * png_colorspace_sync_info in png.c for where the valid flags get set.) + * + * Under certain circumstances the colorspace can be invalidated without + * syncing the info_struct 'valid' flags; this happens if libpng detects + * an error and calls png_error while the color space is being set, yet + * the application continues writing the PNG. So check the 'invalid' + * flag here too. + */ #ifdef PNG_GAMMA_SUPPORTED # ifdef PNG_WRITE_gAMA_SUPPORTED if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && @@ -137,50 +138,50 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) #endif #ifdef PNG_COLORSPACE_SUPPORTED - /* Write only one of sRGB or an ICC profile. If a profile was supplied - * and it matches one of the known sRGB ones issue a warning. - */ + /* Write only one of sRGB or an ICC profile. If a profile was supplied + * and it matches one of the known sRGB ones issue a warning. + */ # ifdef PNG_WRITE_iCCP_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_iCCP) != 0) - { -# ifdef PNG_WRITE_sRGB_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sRGB) != 0) - png_app_warning(png_ptr, - "profile matches sRGB but writing iCCP instead"); -# endif + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && + (info_ptr->valid & PNG_INFO_iCCP) != 0) + { +# ifdef PNG_WRITE_sRGB_SUPPORTED + if ((info_ptr->valid & PNG_INFO_sRGB) != 0) + png_app_warning(png_ptr, + "profile matches sRGB but writing iCCP instead"); +# endif - png_write_iCCP(png_ptr, info_ptr->iccp_name, - info_ptr->iccp_profile); - } + png_write_iCCP(png_ptr, info_ptr->iccp_name, + info_ptr->iccp_profile); + } # ifdef PNG_WRITE_sRGB_SUPPORTED else # endif # endif # ifdef PNG_WRITE_sRGB_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_sRGB) != 0) - png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && + (info_ptr->valid & PNG_INFO_sRGB) != 0) + png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); # endif /* WRITE_sRGB */ #endif /* COLORSPACE */ #ifdef PNG_WRITE_sBIT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); + if ((info_ptr->valid & PNG_INFO_sBIT) != 0) + png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); #endif #ifdef PNG_COLORSPACE_SUPPORTED # ifdef PNG_WRITE_cHRM_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && - (info_ptr->valid & PNG_INFO_cHRM) != 0) - png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); + if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && + (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && + (info_ptr->valid & PNG_INFO_cHRM) != 0) + png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); # endif #endif #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); + write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); #endif png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; @@ -205,7 +206,7 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) png_write_PLTE(png_ptr, info_ptr->palette, (png_uint_32)info_ptr->num_palette); - else if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) !=0) + else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_error(png_ptr, "Valid palette required for paletted images"); #ifdef PNG_WRITE_tRNS_SUPPORTED @@ -216,8 +217,13 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 && info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - int j; - for (j = 0; j<(int)info_ptr->num_trans; j++) + int j, jend; + + jend = info_ptr->num_trans; + if (jend > PNG_MAX_PALETTE_LENGTH) + jend = PNG_MAX_PALETTE_LENGTH; + + for (j = 0; jtrans_alpha[j] = (png_byte)(255 - info_ptr->trans_alpha[j]); } @@ -231,6 +237,11 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); #endif +#ifdef PNG_WRITE_eXIf_SUPPORTED + if ((info_ptr->valid & PNG_INFO_eXIf) != 0) + png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); +#endif + #ifdef PNG_WRITE_hIST_SUPPORTED if ((info_ptr->valid & PNG_INFO_hIST) != 0) png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); @@ -377,7 +388,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr) for (i = 0; i < info_ptr->num_text; i++) { png_debug2(2, "Writing trailer text chunk %d, type %d", i, - info_ptr->text[i].compression); + info_ptr->text[i].compression); /* An internationalized chunk? */ if (info_ptr->text[i].compression > 0) { @@ -426,6 +437,12 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr) } } #endif + +#ifdef PNG_WRITE_eXIf_SUPPORTED + if ((info_ptr->valid & PNG_INFO_eXIf) != 0) + png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); +#endif + #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); #endif @@ -538,7 +555,7 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, /* App warnings are warnings in release (or release candidate) builds but * are errors during development. */ -#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC +#if PNG_RELEASE_BUILD png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; #endif @@ -660,9 +677,9 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); + png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); *(rp ) = (png_byte)(red >> 8); @@ -687,7 +704,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row) return; png_debug2(1, "in png_write_row (row %u, pass %d)", - png_ptr->row_number, png_ptr->pass); + png_ptr->row_number, png_ptr->pass); /* Initialize transformations and other stuff if first time */ if (png_ptr->row_number == 0 && png_ptr->pass == 0) @@ -849,7 +866,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row) * which is also the output depth. */ if (row_info.pixel_depth != png_ptr->pixel_depth || - row_info.pixel_depth != png_ptr->transformed_pixel_depth) + row_info.pixel_depth != png_ptr->transformed_pixel_depth) png_error(png_ptr, "internal write transform logic error"); #ifdef PNG_MNG_FEATURES_SUPPORTED @@ -895,7 +912,7 @@ png_set_flush(png_structrp png_ptr, int nrows) if (png_ptr == NULL) return; - png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); + png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows); } /* Flush the current output buffers now */ @@ -917,10 +934,6 @@ png_write_flush(png_structrp png_ptr) } #endif /* WRITE_FLUSH */ -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */ -#endif - /* Free any memory used in png_ptr struct without freeing the struct itself. */ static void png_write_destroy(png_structrp png_ptr) @@ -937,24 +950,11 @@ png_write_destroy(png_structrp png_ptr) png_ptr->row_buf = NULL; #ifdef PNG_WRITE_FILTER_SUPPORTED png_free(png_ptr, png_ptr->prev_row); - png_free(png_ptr, png_ptr->sub_row); - png_free(png_ptr, png_ptr->up_row); - png_free(png_ptr, png_ptr->avg_row); - png_free(png_ptr, png_ptr->paeth_row); + png_free(png_ptr, png_ptr->try_row); + png_free(png_ptr, png_ptr->tst_row); png_ptr->prev_row = NULL; - png_ptr->sub_row = NULL; - png_ptr->up_row = NULL; - png_ptr->avg_row = NULL; - png_ptr->paeth_row = NULL; -#endif - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - /* Use this to save a little code space, it doesn't free the filter_costs */ - png_reset_filter_heuristics(png_ptr); - png_free(png_ptr, png_ptr->filter_costs); - png_free(png_ptr, png_ptr->inv_filter_costs); - png_ptr->filter_costs = NULL; - png_ptr->inv_filter_costs = NULL; + png_ptr->try_row = NULL; + png_ptr->tst_row = NULL; #endif #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED @@ -1018,8 +1018,8 @@ png_set_filter(png_structrp png_ptr, int method, int filters) case 5: case 6: case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); - /* FALL THROUGH */ #endif /* WRITE_FILTER */ + /* FALLTHROUGH */ case PNG_FILTER_VALUE_NONE: png_ptr->do_filter = PNG_FILTER_NONE; break; @@ -1044,6 +1044,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters) #endif /* WRITE_FILTER */ } +#ifdef PNG_WRITE_FILTER_SUPPORTED /* If we have allocated the row_buf, this means we have already started * with the image and we should have allocated all of the filter buffers * that have been selected. If prev_row isn't already allocated, then @@ -1052,203 +1053,76 @@ png_set_filter(png_structrp png_ptr, int method, int filters) * wants to start and stop using particular filters during compression, * it should start out with all of the filters, and then remove them * or add them back after the start of compression. + * + * NOTE: this is a nasty constraint on the code, because it means that the + * prev_row buffer must be maintained even if there are currently no + * 'prev_row' requiring filters active. */ if (png_ptr->row_buf != NULL) { -#ifdef PNG_WRITE_FILTER_SUPPORTED - if ((png_ptr->do_filter & PNG_FILTER_SUB) != 0 && - png_ptr->sub_row == NULL) + int num_filters; + png_alloc_size_t buf_size; + + /* Repeat the checks in png_write_start_row; 1 pixel high or wide + * images cannot benefit from certain filters. If this isn't done here + * the check below will fire on 1 pixel high images. + */ + if (png_ptr->height == 1) + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (png_ptr->width == 1) + filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0 + && png_ptr->prev_row == NULL) { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + /* This is the error case, however it is benign - the previous row + * is not available so the filter can't be used. Just warn here. + */ + png_app_warning(png_ptr, + "png_set_filter: UP/AVG/PAETH cannot be added after start"); + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); } - if ((png_ptr->do_filter & PNG_FILTER_UP) != 0 && - png_ptr->up_row == NULL) + num_filters = 0; + + if (filters & PNG_FILTER_SUB) + num_filters++; + + if (filters & PNG_FILTER_UP) + num_filters++; + + if (filters & PNG_FILTER_AVG) + num_filters++; + + if (filters & PNG_FILTER_PAETH) + num_filters++; + + /* Allocate needed row buffers if they have not already been + * allocated. + */ + buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth, + png_ptr->width) + 1; + + if (png_ptr->try_row == NULL) + png_ptr->try_row = png_voidcast(png_bytep, + png_malloc(png_ptr, buf_size)); + + if (num_filters > 1) { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Up filter after starting"); - png_ptr->do_filter = (png_byte)(png_ptr->do_filter & - ~PNG_FILTER_UP); - } - - else - { - png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; - } + if (png_ptr->tst_row == NULL) + png_ptr->tst_row = png_voidcast(png_bytep, + png_malloc(png_ptr, buf_size)); } - - if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0 && - png_ptr->avg_row == NULL) - { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Average filter after starting"); - png_ptr->do_filter = (png_byte)(png_ptr->do_filter & - ~PNG_FILTER_AVG); - } - - else - { - png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; - } - } - - if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0 && - png_ptr->paeth_row == NULL) - { - if (png_ptr->prev_row == NULL) - { - png_warning(png_ptr, "Can't add Paeth filter after starting"); - png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); - } - - else - { - png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; - } - } - - if (png_ptr->do_filter == PNG_NO_FILTERS) -#endif /* WRITE_FILTER */ - png_ptr->do_filter = PNG_FILTER_NONE; } + png_ptr->do_filter = (png_byte)filters; +#endif } else png_error(png_ptr, "Unknown custom filter method"); } -/* This allows us to influence the way in which libpng chooses the "best" - * filter for the current scanline. While the "minimum-sum-of-absolute- - * differences metric is relatively fast and effective, there is some - * question as to whether it can be improved upon by trying to keep the - * filtered data going to zlib more consistent, hopefully resulting in - * better compression. - */ -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ -/* Convenience reset API. */ -static void -png_reset_filter_heuristics(png_structrp png_ptr) -{ - /* Clear out any old values in the 'weights' - this must be done because if - * the app calls set_filter_heuristics multiple times with different - * 'num_weights' values we would otherwise potentially have wrong sized - * arrays. - */ - png_ptr->num_prev_filters = 0; - png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; - if (png_ptr->prev_filters != NULL) - { - png_bytep old = png_ptr->prev_filters; - png_ptr->prev_filters = NULL; - png_free(png_ptr, old); - } - if (png_ptr->filter_weights != NULL) - { - png_uint_16p old = png_ptr->filter_weights; - png_ptr->filter_weights = NULL; - png_free(png_ptr, old); - } - - if (png_ptr->inv_filter_weights != NULL) - { - png_uint_16p old = png_ptr->inv_filter_weights; - png_ptr->inv_filter_weights = NULL; - png_free(png_ptr, old); - } - - /* Leave the filter_costs - this array is fixed size. */ -} - -static int -png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method, - int num_weights) -{ - if (png_ptr == NULL) - return 0; - - /* Clear out the arrays */ - png_reset_filter_heuristics(png_ptr); - - /* Check arguments; the 'reset' function makes the correct settings for the - * unweighted case, but we must handle the weight case by initializing the - * arrays for the caller. - */ - if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int i; - - if (num_weights > 0) - { - png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, - (png_uint_32)((sizeof (png_byte)) * num_weights)); - - /* To make sure that the weighting starts out fairly */ - for (i = 0; i < num_weights; i++) - { - png_ptr->prev_filters[i] = 255; - } - - png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)((sizeof (png_uint_16)) * num_weights)); - - png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)((sizeof (png_uint_16)) * num_weights)); - - for (i = 0; i < num_weights; i++) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - - /* Safe to set this now */ - png_ptr->num_prev_filters = (png_byte)num_weights; - } - - /* If, in the future, there are other filter methods, this would - * need to be based on png_ptr->filter. - */ - if (png_ptr->filter_costs == NULL) - { - png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); - - png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); - } - - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) - { - png_ptr->inv_filter_costs[i] = - png_ptr->filter_costs[i] = PNG_COST_FACTOR; - } - - /* All the arrays are inited, safe to set this: */ - png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; - - /* Return the 'ok' code. */ - return 1; - } - else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || - heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) - { - return 1; - } - else - { - png_warning(png_ptr, "Unknown filter heuristic method"); - return 0; - } -} - +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ /* Provide floating and fixed point APIs */ #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI @@ -1256,52 +1130,11 @@ png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, int num_weights, png_const_doublep filter_weights, png_const_doublep filter_costs) { - png_debug(1, "in png_set_filter_heuristics"); - - /* The internal API allocates all the arrays and ensures that the elements of - * those arrays are set to the default value. - */ - if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) - return; - - /* If using the weighted method copy in the weights. */ - if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int i; - for (i = 0; i < num_weights; i++) - { - if (filter_weights[i] <= 0.0) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - - else - { - png_ptr->inv_filter_weights[i] = - (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); - - png_ptr->filter_weights[i] = - (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); - } - } - - /* Here is where we set the relative costs of the different filters. We - * should take the desired compression level into account when setting - * the costs, so that Paeth, for instance, has a high relative cost at low - * compression levels, while it has a lower relative cost at higher - * compression settings. The filter types are in order of increasing - * relative cost, so it would be possible to do this with an algorithm. - */ - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) - { - png_ptr->inv_filter_costs[i] = - (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); - - png_ptr->filter_costs[i] = - (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); - } - } + PNG_UNUSED(png_ptr) + PNG_UNUSED(heuristic_method) + PNG_UNUSED(num_weights) + PNG_UNUSED(filter_weights) + PNG_UNUSED(filter_costs) } #endif /* FLOATING_POINT */ @@ -1311,63 +1144,11 @@ png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, int num_weights, png_const_fixed_point_p filter_weights, png_const_fixed_point_p filter_costs) { - png_debug(1, "in png_set_filter_heuristics_fixed"); - - /* The internal API allocates all the arrays and ensures that the elements of - * those arrays are set to the default value. - */ - if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) - return; - - /* If using the weighted method copy in the weights. */ - if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int i; - for (i = 0; i < num_weights; i++) - { - if (filter_weights[i] <= 0) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - - else - { - png_ptr->inv_filter_weights[i] = (png_uint_16) - ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); - - png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* - PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); - } - } - - /* Here is where we set the relative costs of the different filters. We - * should take the desired compression level into account when setting - * the costs, so that Paeth, for instance, has a high relative cost at low - * compression levels, while it has a lower relative cost at higher - * compression settings. The filter types are in order of increasing - * relative cost, so it would be possible to do this with an algorithm. - */ - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) - if (filter_costs[i] >= PNG_FP_1) - { - png_uint_32 tmp; - - /* Use a 32 bit unsigned temporary here because otherwise the - * intermediate value will be a 32 bit *signed* integer (ANSI rules) - * and this will get the wrong answer on division. - */ - tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); - tmp /= filter_costs[i]; - - png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; - - tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; - tmp /= PNG_FP_1; - - png_ptr->filter_costs[i] = (png_uint_16)tmp; - } - } + PNG_UNUSED(png_ptr) + PNG_UNUSED(heuristic_method) + PNG_UNUSED(num_weights) + PNG_UNUSED(filter_weights) + PNG_UNUSED(filter_costs) } #endif /* FIXED_POINT */ #endif /* WRITE_WEIGHTED_FILTER */ @@ -1616,14 +1397,14 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr, * alpha channel. */ if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| - PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) + PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) { #ifdef PNG_WRITE_FILLER_SUPPORTED if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) { if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) png_app_error(png_ptr, - "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); + "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); /* Continue if ignored - this is the pre-1.6.10 behavior */ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); @@ -1652,7 +1433,7 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr, png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); #endif - /* Swap bits of 1, 2, 4 bit packed pixel formats */ + /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */ if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) #ifdef PNG_WRITE_PACKSWAP_SUPPORTED png_set_packswap(png_ptr); @@ -1682,13 +1463,12 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr, #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */ /* Initialize the write structure - general purpose utility. */ static int png_image_write_init(png_imagep image) { png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, - png_safe_error, png_safe_warning); + png_safe_error, png_safe_warning); if (png_ptr != NULL) { @@ -1697,7 +1477,7 @@ png_image_write_init(png_imagep image) if (info_ptr != NULL) { png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); + png_malloc_warn(png_ptr, (sizeof *control))); if (control != NULL) { @@ -1734,6 +1514,10 @@ typedef struct png_const_voidp first_row; ptrdiff_t row_bytes; png_voidp local_row; + /* Byte count for memory writing */ + png_bytep memory; + png_alloc_size_t memory_bytes; /* not used for STDIO */ + png_alloc_size_t output_bytes; /* running total */ } png_image_write_control; /* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to @@ -1744,31 +1528,33 @@ static int png_write_image_16bit(png_voidp argument) { png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); + display->first_row); png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); png_uint_16p row_end; - const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; + const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + 3 : 1; int aindex = 0; png_uint_32 y = image->height; if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) { -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } - +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } else + aindex = (int)channels; +# else + aindex = (int)channels; # endif - aindex = channels; } else @@ -1780,7 +1566,7 @@ png_write_image_16bit(png_voidp argument) */ row_end = output_row + image->width * (channels+1); - while (y-- > 0) + for (; y > 0; --y) { png_const_uint_16p in_ptr = input_row; png_uint_16p out_ptr = output_row; @@ -1801,7 +1587,7 @@ png_write_image_16bit(png_voidp argument) if (alpha > 0 && alpha < 65535) reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; - c = channels; + c = (int)channels; do /* always at least one channel */ { png_uint_16 component = *in_ptr++; @@ -1836,7 +1622,7 @@ png_write_image_16bit(png_voidp argument) } png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); - input_row += display->row_bytes/(sizeof (png_uint_16)); + input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); } return 1; @@ -1850,11 +1636,11 @@ png_write_image_16bit(png_voidp argument) * calculation can be done to 15 bits of accuracy; however, the output needs to * be scaled in the range 0..255*65535, so include that scaling here. */ -#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) +# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) static png_byte png_unpremultiply(png_uint_32 component, png_uint_32 alpha, - png_uint_32 reciprocal/*from the above macro*/) + png_uint_32 reciprocal/*from the above macro*/) { /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 * is represented as some other value there is more likely to be a @@ -1901,37 +1687,38 @@ static int png_write_image_8bit(png_voidp argument) { png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); + display->first_row); png_bytep output_row = png_voidcast(png_bytep, display->local_row); png_uint_32 y = image->height; - const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; + const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + 3 : 1; if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) { png_bytep row_end; int aindex; -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } - else -# endif - aindex = channels; + else +# endif + aindex = (int)channels; /* Use row_end in place of a loop counter: */ row_end = output_row + image->width * (channels+1); - while (y-- > 0) + for (; y > 0; --y) { png_const_uint_16p in_ptr = input_row; png_bytep out_ptr = output_row; @@ -1949,7 +1736,7 @@ png_write_image_8bit(png_voidp argument) if (alphabyte > 0 && alphabyte < 255) reciprocal = UNP_RECIPROCAL(alpha); - c = channels; + c = (int)channels; do /* always at least one channel */ *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); while (--c > 0); @@ -1960,8 +1747,8 @@ png_write_image_8bit(png_voidp argument) } /* while out_ptr < row_end */ png_write_row(png_ptr, png_voidcast(png_const_bytep, - display->local_row)); - input_row += display->row_bytes/(sizeof (png_uint_16)); + display->local_row)); + input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); } /* while y */ } @@ -1972,7 +1759,7 @@ png_write_image_8bit(png_voidp argument) */ png_bytep row_end = output_row + image->width * channels; - while (y-- > 0) + for (; y > 0; --y) { png_const_uint_16p in_ptr = input_row; png_bytep out_ptr = output_row; @@ -1986,7 +1773,7 @@ png_write_image_8bit(png_voidp argument) } png_write_row(png_ptr, output_row); - input_row += display->row_bytes/(sizeof (png_uint_16)); + input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); } } @@ -1999,25 +1786,25 @@ png_image_set_PLTE(png_image_write_control *display) const png_imagep image = display->image; const void *cmap = display->colormap; const int entries = image->colormap_entries > 256 ? 256 : - (int)image->colormap_entries; + (int)image->colormap_entries; /* NOTE: the caller must check for cmap != NULL and entries != 0 */ const png_uint_32 format = image->format; - const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); + const unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); -# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ +# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && - (format & PNG_FORMAT_FLAG_ALPHA) != 0; -# else + (format & PNG_FORMAT_FLAG_ALPHA) != 0; +# else # define afirst 0 -# endif +# endif -# ifdef PNG_FORMAT_BGR_SUPPORTED +# ifdef PNG_FORMAT_BGR_SUPPORTED const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -# else +# else # define bgr 0 -# endif +# endif int i, num_trans; png_color palette[256]; @@ -2035,18 +1822,18 @@ png_image_set_PLTE(png_image_write_control *display) { png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap); - entry += i * channels; + entry += (unsigned int)i * channels; if ((channels & 1) != 0) /* no alpha */ { if (channels >= 3) /* RGB */ { palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[(2 ^ bgr)]); + entry[(2 ^ bgr)]); palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[1]); + entry[1]); palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[bgr]); + entry[bgr]); } else /* Gray */ @@ -2074,16 +1861,16 @@ png_image_set_PLTE(png_image_write_control *display) if (channels >= 3) /* RGB */ { palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], - alpha, reciprocal); + alpha, reciprocal); palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, - reciprocal); + reciprocal); palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, - reciprocal); + reciprocal); } else /* gray */ palette[i].blue = palette[i].red = palette[i].green = - png_unpremultiply(entry[afirst], alpha, reciprocal); + png_unpremultiply(entry[afirst], alpha, reciprocal); } } @@ -2091,7 +1878,7 @@ png_image_set_PLTE(png_image_write_control *display) { png_const_bytep entry = png_voidcast(png_const_bytep, cmap); - entry += i * channels; + entry += (unsigned int)i * channels; switch (channels) { @@ -2099,7 +1886,7 @@ png_image_set_PLTE(png_image_write_control *display) tRNS[i] = entry[afirst ? 0 : 3]; if (tRNS[i] < 255) num_trans = i+1; - /* FALL THROUGH */ + /* FALLTHROUGH */ case 3: palette[i].blue = entry[afirst + (2 ^ bgr)]; palette[i].green = entry[afirst + 1]; @@ -2110,7 +1897,7 @@ png_image_set_PLTE(png_image_write_control *display) tRNS[i] = entry[1 ^ afirst]; if (tRNS[i] < 255) num_trans = i+1; - /* FALL THROUGH */ + /* FALLTHROUGH */ case 1: palette[i].blue = palette[i].red = palette[i].green = entry[afirst]; @@ -2122,28 +1909,28 @@ png_image_set_PLTE(png_image_write_control *display) } } -# ifdef afirst +# ifdef afirst # undef afirst -# endif -# ifdef bgr +# endif +# ifdef bgr # undef bgr -# endif +# endif png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, - entries); + entries); if (num_trans > 0) png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, - num_trans, NULL); + num_trans, NULL); - image->colormap_entries = entries; + image->colormap_entries = (png_uint_32)entries; } static int png_image_write_main(png_voidp argument) { png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); + argument); png_imagep image = display->image; png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; @@ -2153,16 +1940,50 @@ png_image_write_main(png_voidp argument) int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); - int write_16bit = linear && !colormap && (display->convert_to_8bit == 0); + int write_16bit = linear && (display->convert_to_8bit == 0); -# ifdef PNG_BENIGN_ERRORS_SUPPORTED +# ifdef PNG_BENIGN_ERRORS_SUPPORTED /* Make sure we error out on any bad situation */ png_set_benign_errors(png_ptr, 0/*error*/); -# endif +# endif - /* Default the 'row_stride' parameter if required. */ - if (display->row_stride == 0) - display->row_stride = PNG_IMAGE_ROW_STRIDE(*image); + /* Default the 'row_stride' parameter if required, also check the row stride + * and total image size to ensure that they are within the system limits. + */ + { + const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + + if (image->width <= 0x7fffffffU/channels) /* no overflow */ + { + png_uint_32 check; + const png_uint_32 png_row_stride = image->width * channels; + + if (display->row_stride == 0) + display->row_stride = (png_int_32)/*SAFE*/png_row_stride; + + if (display->row_stride < 0) + check = (png_uint_32)(-display->row_stride); + + else + check = (png_uint_32)display->row_stride; + + if (check >= png_row_stride) + { + /* Now check for overflow of the image buffer calculation; this + * limits the whole image size to 32 bits for API compatibility with + * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. + */ + if (image->height > 0xffffffffU/png_row_stride) + png_error(image->opaque->png_ptr, "memory image too large"); + } + + else + png_error(image->opaque->png_ptr, "supplied row stride too small"); + } + + else + png_error(image->opaque->png_ptr, "image row stride too large"); + } /* Set the required transforms then write the rows in the correct order. */ if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) @@ -2172,24 +1993,24 @@ png_image_write_main(png_voidp argument) png_uint_32 entries = image->colormap_entries; png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), - PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), + PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_image_set_PLTE(display); } else png_error(image->opaque->png_ptr, - "no color-map for color-mapped image"); + "no color-map for color-mapped image"); } else png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - write_16bit ? 16 : 8, - ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + - ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + write_16bit ? 16 : 8, + ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + + ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* Counter-intuitively the data transformations must be called *after* * png_write_info, not before as in the read code, but the 'set' functions @@ -2204,11 +2025,11 @@ png_image_write_main(png_voidp argument) if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) png_set_cHRM_fixed(png_ptr, info_ptr, - /* color x y */ - /* white */ 31270, 32900, - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000 + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000 ); } @@ -2227,7 +2048,7 @@ png_image_write_main(png_voidp argument) /* Now set up the data transformations (*after* the header is written), * remove the handled transformations from the 'format' flags for checking. * - * First check for a little endian system if writing 16 bit files. + * First check for a little endian system if writing 16-bit files. */ if (write_16bit != 0) { @@ -2237,23 +2058,23 @@ png_image_write_main(png_voidp argument) png_set_swap(png_ptr); } -# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED +# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED if ((format & PNG_FORMAT_FLAG_BGR) != 0) { if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) png_set_bgr(png_ptr); format &= ~PNG_FORMAT_FLAG_BGR; } -# endif +# endif -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) { if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) png_set_swap_alpha(png_ptr); format &= ~PNG_FORMAT_FLAG_AFIRST; } -# endif +# endif /* If there are 16 or fewer color-map entries we wrote a lower bit depth * above, but the application data is still byte packed. @@ -2289,9 +2110,9 @@ png_image_write_main(png_voidp argument) * it about 50 times. The speed-up in pngstest was about 10-20% of the * total (user) time on a heavily loaded system. */ -#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED +# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED png_set_compression_level(png_ptr, 3); -#endif +# endif } /* Check for the cases that currently require a pre-transform on the row @@ -2302,7 +2123,7 @@ png_image_write_main(png_voidp argument) (colormap == 0 && display->convert_to_8bit != 0)) { png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, - png_get_rowbytes(png_ptr, info_ptr))); + png_get_rowbytes(png_ptr, info_ptr))); int result; display->local_row = row; @@ -2328,7 +2149,7 @@ png_image_write_main(png_voidp argument) ptrdiff_t row_bytes = display->row_bytes; png_uint_32 y = image->height; - while (y-- > 0) + for (; y > 0; --y) { png_write_row(png_ptr, row); row += row_bytes; @@ -2339,14 +2160,130 @@ png_image_write_main(png_voidp argument) return 1; } + +static void (PNGCBAPI +image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, + png_size_t size) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); + const png_alloc_size_t ob = display->output_bytes; + + /* Check for overflow; this should never happen: */ + if (size <= ((png_alloc_size_t)-1) - ob) + { + /* I don't think libpng ever does this, but just in case: */ + if (size > 0) + { + if (display->memory_bytes >= ob+size) /* writing */ + memcpy(display->memory+ob, data, size); + + /* Always update the size: */ + display->output_bytes = ob+size; + } + } + + else + png_error(png_ptr, "png_image_write_to_memory: PNG too big"); +} + +static void (PNGCBAPI +image_memory_flush)(png_structp png_ptr) +{ + PNG_UNUSED(png_ptr) +} + +static int +png_image_write_memory(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + + /* The rest of the memory-specific init and write_main in an error protected + * environment. This case needs to use callbacks for the write operations + * since libpng has no built in support for writing to memory. + */ + png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/, + image_memory_write, image_memory_flush); + + return png_image_write_main(display); +} + +int PNGAPI +png_image_write_to_memory(png_imagep image, void *memory, + png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit, + const void *buffer, png_int_32 row_stride, const void *colormap) +{ + /* Write the image to the given buffer, or count the bytes if it is NULL */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (memory_bytes != NULL && buffer != NULL) + { + /* This is to give the caller an easier error detection in the NULL + * case and guard against uninitialized variable problems: + */ + if (memory == NULL) + *memory_bytes = 0; + + if (png_image_write_init(image) != 0) + { + png_image_write_control display; + int result; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.convert_to_8bit = convert_to_8bit; + display.memory = png_voidcast(png_bytep, memory); + display.memory_bytes = *memory_bytes; + display.output_bytes = 0; + + result = png_safe_execute(image, png_image_write_memory, &display); + png_image_free(image); + + /* write_memory returns true even if we ran out of buffer. */ + if (result) + { + /* On out-of-buffer this function returns '0' but still updates + * memory_bytes: + */ + if (memory != NULL && display.output_bytes > *memory_bytes) + result = 0; + + *memory_bytes = display.output_bytes; + } + + return result; + } + + else + return 0; + } + + else + return png_image_error(image, + "png_image_write_to_memory: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} + +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED int PNGAPI png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, - const void *buffer, png_int_32 row_stride, const void *colormap) + const void *buffer, png_int_32 row_stride, const void *colormap) { /* Write the image to the given (FILE*). */ if (image != NULL && image->version == PNG_IMAGE_VERSION) { - if (file != NULL) + if (file != NULL && buffer != NULL) { if (png_image_write_init(image) != 0) { @@ -2377,12 +2314,12 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, else return png_image_error(image, - "png_image_write_to_stdio: invalid argument"); + "png_image_write_to_stdio: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); + "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); else return 0; @@ -2390,20 +2327,20 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, int PNGAPI png_image_write_to_file(png_imagep image, const char *file_name, - int convert_to_8bit, const void *buffer, png_int_32 row_stride, - const void *colormap) + int convert_to_8bit, const void *buffer, png_int_32 row_stride, + const void *colormap) { /* Write the image to the named file. */ if (image != NULL && image->version == PNG_IMAGE_VERSION) { - if (file_name != NULL) + if (file_name != NULL && buffer != NULL) { FILE *fp = fopen(file_name, "wb"); if (fp != NULL) { if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, - row_stride, colormap) != 0) + row_stride, colormap) != 0) { int error; /* from fflush/fclose */ @@ -2444,16 +2381,16 @@ png_image_write_to_file(png_imagep image, const char *file_name, else return png_image_error(image, - "png_image_write_to_file: invalid argument"); + "png_image_write_to_file: invalid argument"); } else if (image != NULL) return png_image_error(image, - "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); + "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); else return 0; } -#endif /* STDIO */ +#endif /* SIMPLIFIED_WRITE_STDIO */ #endif /* SIMPLIFIED_WRITE */ #endif /* WRITE */ diff --git a/src/third-party/libpng/pngwtran.c b/src/third-party/libpng/pngwtran.c index db82e27bc..377b43e5c 100644 --- a/src/third-party/libpng/pngwtran.c +++ b/src/third-party/libpng/pngwtran.c @@ -1,8 +1,8 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.26 [October 20, 2016] + * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -71,7 +71,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) case 2: { png_bytep sp, dp; - int shift, v; + unsigned int shift; + int v; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -110,7 +111,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) case 4: { png_bytep sp, dp; - int shift, v; + unsigned int shift; + int v; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -175,7 +177,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) { int shift_start[4], shift_dec[4]; - int channels = 0; + unsigned int channels = 0; if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) { @@ -422,7 +424,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) *(dp++) = *(sp++); */ sp+=3; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); + *dp = (png_byte)(255 - *(sp++)); } } @@ -446,7 +448,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) */ sp+=6; dp = sp; *(dp++) = (png_byte)(255 - *(sp++)); - *(dp++) = (png_byte)(255 - *(sp++)); + *dp = (png_byte)(255 - *(sp++)); } } #endif /* WRITE_16BIT */ @@ -484,7 +486,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) */ sp+=2; dp = sp; *(dp++) = (png_byte)(255 - *(sp++)); - *(dp++) = (png_byte)(255 - *(sp++)); + *dp = (png_byte)(255 - *(sp++)); } } #endif /* WRITE_16BIT */ @@ -523,7 +525,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) #ifdef PNG_WRITE_FILLER_SUPPORTED if ((png_ptr->transformations & PNG_FILLER) != 0) png_do_strip_channel(row_info, png_ptr->row_buf + 1, - !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); + !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); #endif #ifdef PNG_WRITE_PACKSWAP_SUPPORTED @@ -547,7 +549,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) #ifdef PNG_WRITE_SHIFT_SUPPORTED if ((png_ptr->transformations & PNG_SHIFT) != 0) png_do_shift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); + &(png_ptr->shift)); #endif #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED diff --git a/src/third-party/libpng/pngwutil.c b/src/third-party/libpng/pngwutil.c index b289671d1..0d4fb1336 100644 --- a/src/third-party/libpng/pngwutil.c +++ b/src/third-party/libpng/pngwutil.c @@ -1,8 +1,8 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.6.17 [March 26, 2015] - * Copyright (c) 1998-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [August 24, 2017] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -23,10 +23,10 @@ void PNGAPI png_save_uint_32(png_bytep buf, png_uint_32 i) { - buf[0] = (png_byte)(i >> 24); - buf[1] = (png_byte)(i >> 16); - buf[2] = (png_byte)(i >> 8); - buf[3] = (png_byte)(i ); + buf[0] = (png_byte)((i >> 24) & 0xffU); + buf[1] = (png_byte)((i >> 16) & 0xffU); + buf[2] = (png_byte)((i >> 8) & 0xffU); + buf[3] = (png_byte)( i & 0xffU); } /* Place a 16-bit number into a buffer in PNG byte order. @@ -36,8 +36,8 @@ png_save_uint_32(png_bytep buf, png_uint_32 i) void PNGAPI png_save_uint_16(png_bytep buf, unsigned int i) { - buf[0] = (png_byte)(i >> 8); - buf[1] = (png_byte)(i ); + buf[0] = (png_byte)((i >> 8) & 0xffU); + buf[1] = (png_byte)( i & 0xffU); } #endif @@ -59,7 +59,7 @@ png_write_sig(png_structrp png_ptr) /* Write the rest of the 8 byte signature */ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], - (png_size_t)(8 - png_ptr->sig_bytes)); + (png_size_t)(8 - png_ptr->sig_bytes)); if (png_ptr->sig_bytes < 3) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; @@ -174,12 +174,12 @@ png_write_chunk_end(png_structrp png_ptr) */ static void png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, - png_const_bytep data, png_size_t length) + png_const_bytep data, png_size_t length) { if (png_ptr == NULL) return; - /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ + /* On 64-bit architectures 'length' may not fit in a png_uint_32. */ if (length > PNG_UINT_31_MAX) png_error(png_ptr, "length exceeds PNG maximum"); @@ -191,10 +191,10 @@ png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, /* This is the API that calls the internal function above. */ void PNGAPI png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, - png_const_bytep data, png_size_t length) + png_const_bytep data, png_size_t length) { png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, - length); + length); } /* This is used below to find the size of an image to pass to png_deflate_claim, @@ -291,7 +291,7 @@ optimize_cmf(png_bytep data, png_alloc_size_t data_size) /* Initialize the compressor for the appropriate type of compression. */ static int png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, - png_alloc_size_t data_size) + png_alloc_size_t data_size) { if (png_ptr->zowner != 0) { @@ -308,7 +308,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, */ (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); #endif -#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC +#if PNG_RELEASE_BUILD png_warning(png_ptr, msg); /* Attempt sane error recovery */ @@ -408,7 +408,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, png_ptr->zstream.avail_out = 0; /* Now initialize if required, setting the new parameters, otherwise just - * to a simple reset to the previous parameters. + * do a simple reset to the previous parameters. */ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) ret = deflateReset(&png_ptr->zstream); @@ -416,7 +416,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, else { ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, - memLevel, strategy); + memLevel, strategy); if (ret == Z_OK) png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; @@ -477,7 +477,7 @@ typedef struct static void png_text_compress_init(compression_state *comp, png_const_bytep input, - png_alloc_size_t input_len) + png_alloc_size_t input_len) { comp->input = input; comp->input_len = input_len; @@ -487,7 +487,7 @@ png_text_compress_init(compression_state *comp, png_const_bytep input, /* Compress the data in the compression state input */ static int png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, - compression_state *comp, png_uint_32 prefix_len) + compression_state *comp, png_uint_32 prefix_len) { int ret; @@ -579,7 +579,7 @@ png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, /* Compress the data */ ret = deflate(&png_ptr->zstream, - input_len > 0 ? Z_NO_FLUSH : Z_FINISH); + input_len > 0 ? Z_NO_FLUSH : Z_FINISH); /* Claw back input data that was not consumed (because avail_in is * reset above every time round the loop). @@ -665,90 +665,6 @@ png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) } #endif /* WRITE_COMPRESSED_TEXT */ -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ - defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) -/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, - * and if invalid, correct the keyword rather than discarding the entire - * chunk. The PNG 1.0 specification requires keywords 1-79 characters in - * length, forbids leading or trailing whitespace, multiple internal spaces, - * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. - * - * The 'new_key' buffer must be 80 characters in size (for the keyword plus a - * trailing '\0'). If this routine returns 0 then there was no keyword, or a - * valid one could not be generated, and the caller must png_error. - */ -static png_uint_32 -png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) -{ - png_const_charp orig_key = key; - png_uint_32 key_len = 0; - int bad_character = 0; - int space = 1; - - png_debug(1, "in png_check_keyword"); - - if (key == NULL) - { - *new_key = 0; - return 0; - } - - while (*key && key_len < 79) - { - png_byte ch = (png_byte)*key++; - - if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) - *new_key++ = ch, ++key_len, space = 0; - - else if (space == 0) - { - /* A space or an invalid character when one wasn't seen immediately - * before; output just a space. - */ - *new_key++ = 32, ++key_len, space = 1; - - /* If the character was not a space then it is invalid. */ - if (ch != 32) - bad_character = ch; - } - - else if (bad_character == 0) - bad_character = ch; /* just skip it, record the first error */ - } - - if (key_len > 0 && space != 0) /* trailing space */ - { - --key_len, --new_key; - if (bad_character == 0) - bad_character = 32; - } - - /* Terminate the keyword */ - *new_key = 0; - - if (key_len == 0) - return 0; - -#ifdef PNG_WARNINGS_SUPPORTED - /* Try to only output one warning per keyword: */ - if (*key != 0) /* keyword too long */ - png_warning(png_ptr, "keyword truncated"); - - else if (bad_character != 0) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter(p, 1, orig_key); - png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); - - png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); - } -#endif /* WARNINGS */ - - return key_len; -} -#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */ - /* Write the IHDR chunk, and update the png_struct with the necessary * information. Note that the rest of this code depends upon this * information being correct. @@ -759,6 +675,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, int interlace_type) { png_byte buf[13]; /* Buffer to store the IHDR info */ + int is_invalid_depth; png_debug(1, "in png_write_IHDR"); @@ -784,11 +701,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, break; case PNG_COLOR_TYPE_RGB: + is_invalid_depth = (bit_depth != 8); #ifdef PNG_WRITE_16BIT_SUPPORTED - if (bit_depth != 8 && bit_depth != 16) -#else - if (bit_depth != 8) + is_invalid_depth = (is_invalid_depth && bit_depth != 16); #endif + if (is_invalid_depth) png_error(png_ptr, "Invalid bit depth for RGB image"); png_ptr->channels = 3; @@ -810,18 +727,22 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, break; case PNG_COLOR_TYPE_GRAY_ALPHA: - if (bit_depth != 8 && bit_depth != 16) + is_invalid_depth = (bit_depth != 8); +#ifdef PNG_WRITE_16BIT_SUPPORTED + is_invalid_depth = (is_invalid_depth && bit_depth != 16); +#endif + if (is_invalid_depth) png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); png_ptr->channels = 2; break; case PNG_COLOR_TYPE_RGB_ALPHA: + is_invalid_depth = (bit_depth != 8); #ifdef PNG_WRITE_16BIT_SUPPORTED - if (bit_depth != 8 && bit_depth != 16) -#else - if (bit_depth != 8) + is_invalid_depth = (is_invalid_depth && bit_depth != 16); #endif + if (is_invalid_depth) png_error(png_ptr, "Invalid bit depth for RGBA image"); png_ptr->channels = 4; @@ -922,17 +843,20 @@ void /* PRIVATE */ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, png_uint_32 num_pal) { - png_uint_32 i; + png_uint_32 max_palette_length, i; png_const_colorp pal_ptr; png_byte buf[3]; png_debug(1, "in png_write_PLTE"); + max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; + if (( #ifdef PNG_MNG_FEATURES_SUPPORTED (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && #endif - num_pal == 0) || num_pal > 256) + num_pal == 0) || num_pal > max_palette_length) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { @@ -1006,7 +930,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, */ void /* PRIVATE */ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, - png_alloc_size_t input_len, int flush) + png_alloc_size_t input_len, int flush) { if (png_ptr->zowner != png_IDAT) { @@ -1018,7 +942,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, if (png_ptr->zbuffer_list == NULL) { png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, - png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); + png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); png_ptr->zbuffer_list->next = NULL; } @@ -1079,7 +1003,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, optimize_cmf(data, png_image_size(png_ptr)); #endif - png_write_complete_chunk(png_ptr, png_IDAT, data, size); + if (size > 0) + png_write_complete_chunk(png_ptr, png_IDAT, data, size); png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->zstream.next_out = data; @@ -1125,7 +1050,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, optimize_cmf(data, png_image_size(png_ptr)); #endif - png_write_complete_chunk(png_ptr, png_IDAT, data, size); + if (size > 0) + png_write_complete_chunk(png_ptr, png_IDAT, data, size); png_ptr->zstream.avail_out = 0; png_ptr->zstream.next_out = NULL; png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; @@ -1257,7 +1183,7 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) png_byte new_name[80]; png_byte entrybuf[10]; png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); - png_size_t palette_size = entry_size * spalette->nentries; + png_size_t palette_size = entry_size * (png_size_t)spalette->nentries; png_sPLT_entryp ep; #ifndef PNG_POINTER_INDEXING_SUPPORTED int i; @@ -1439,12 +1365,12 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, /* Write the chunk out as it is */ png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, - (png_size_t)num_trans); + (png_size_t)num_trans); } else if (color_type == PNG_COLOR_TYPE_GRAY) { - /* One 16 bit value */ + /* One 16-bit value */ if (tran->gray >= (1 << png_ptr->bit_depth)) { png_app_warning(png_ptr, @@ -1459,7 +1385,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, else if (color_type == PNG_COLOR_TYPE_RGB) { - /* Three 16 bit values */ + /* Three 16-bit values */ png_save_uint_16(buf, tran->red); png_save_uint_16(buf + 2, tran->green); png_save_uint_16(buf + 4, tran->blue); @@ -1470,7 +1396,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, #endif { png_app_warning(png_ptr, - "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); + "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); return; } @@ -1522,7 +1448,8 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) #endif { png_warning(png_ptr, - "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); + "Ignoring attempt to write 16-bit bKGD chunk " + "when bit_depth is 8"); return; } @@ -1546,6 +1473,28 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) } #endif +#ifdef PNG_WRITE_eXIf_SUPPORTED +/* Write the Exif data */ +void /* PRIVATE */ +png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif) +{ + int i; + png_byte buf[1]; + + png_debug(1, "in png_write_eXIf"); + + png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif)); + + for (i = 0; i < num_exif; i++) + { + buf[0] = exif[i]; + png_write_chunk_data(png_ptr, buf, (png_size_t)1); + } + + png_write_chunk_end(png_ptr); +} +#endif + #ifdef PNG_WRITE_hIST_SUPPORTED /* Write the histogram */ void /* PRIVATE */ @@ -1652,7 +1601,7 @@ png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, /* Compute the compressed data; do it now for the length */ png_text_compress_init(&comp, (png_const_bytep)text, - text == NULL ? 0 : strlen(text)); + text == NULL ? 0 : strlen(text)); if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) png_error(png_ptr, png_ptr->zstream.msg); @@ -1823,7 +1772,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, total_len = purpose_len + units_len + 10; params_len = (png_size_tp)png_malloc(png_ptr, - (png_alloc_size_t)(nparams * (sizeof (png_size_t)))); + (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (png_size_t)))); /* Find the length of each parameter, making sure we don't count the * null terminator for the last parameter. @@ -1961,6 +1910,10 @@ png_write_start_row(png_structrp png_ptr) png_alloc_size_t buf_size; int usr_pixel_depth; +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_byte filters; +#endif + png_debug(1, "in png_write_start_row"); usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; @@ -1971,50 +1924,54 @@ png_write_start_row(png_structrp png_ptr) png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; /* Set up row buffer */ - png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); + png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; #ifdef PNG_WRITE_FILTER_SUPPORTED - /* Set up filtering buffer, if using this filter */ - if (png_ptr->do_filter & PNG_FILTER_SUB) - { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); + filters = png_ptr->do_filter; - png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + if (png_ptr->height == 1) + filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (png_ptr->width == 1) + filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (filters == 0) + filters = PNG_FILTER_NONE; + + png_ptr->do_filter = filters; + + if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | + PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL) + { + int num_filters = 0; + + png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + + if (filters & PNG_FILTER_SUB) + num_filters++; + + if (filters & PNG_FILTER_UP) + num_filters++; + + if (filters & PNG_FILTER_AVG) + num_filters++; + + if (filters & PNG_FILTER_PAETH) + num_filters++; + + if (num_filters > 1) + png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr, + buf_size)); } - /* We only need to keep the previous row if we are using one of these. */ - if ((png_ptr->do_filter & - (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) - { - /* Set up previous row buffer */ - png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); - - if ((png_ptr->do_filter & PNG_FILTER_UP) != 0) - { - png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); - - png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; - } - - if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0) - { - png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); - - png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; - } - - if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0) - { - png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); - - png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; - } - } + /* We only need to keep the previous row if we are using one of the following + * filters. + */ + if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) + png_ptr->prev_row = png_voidcast(png_bytep, + png_calloc(png_ptr, buf_size)); #endif /* WRITE_FILTER */ #ifdef PNG_WRITE_INTERLACING_SUPPORTED @@ -2160,7 +2117,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) { png_bytep sp; png_bytep dp; - int shift; + unsigned int shift; int d; int value; png_uint_32 i; @@ -2198,7 +2155,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) { png_bytep sp; png_bytep dp; - int shift; + unsigned int shift; int d; int value; png_uint_32 i; @@ -2235,7 +2192,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) { png_bytep sp; png_bytep dp; - int shift; + unsigned int shift; int d; int value; png_uint_32 i; @@ -2310,50 +2267,309 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) } #endif + /* This filters the row, chooses which filter to use, if it has not already * been specified by the application, and then writes the row out with the * chosen filter. */ static void /* PRIVATE */ png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - png_size_t row_bytes); + png_size_t row_bytes); + +#ifdef PNG_WRITE_FILTER_SUPPORTED +static png_size_t /* PRIVATE */ +png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, + const png_size_t row_bytes, const png_size_t lmins) +{ + png_bytep rp, dp, lp; + png_size_t i; + png_size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; + i++, rp++, dp++) + { + v = *dp = *rp; +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return (sum); +} + +static void /* PRIVATE */ +png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp, + const png_size_t row_bytes) +{ + png_bytep rp, dp, lp; + png_size_t i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; + i++, rp++, dp++) + { + *dp = *rp; + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + } +} + +static png_size_t /* PRIVATE */ +png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, + const png_size_t lmins) +{ + png_bytep rp, dp, pp; + png_size_t i; + png_size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) + { + v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return (sum); +} +static void /* PRIVATE */ +png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes) +{ + png_bytep rp, dp, pp; + png_size_t i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); + } +} + +static png_size_t /* PRIVATE */ +png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, + const png_size_t row_bytes, const png_size_t lmins) +{ + png_bytep rp, dp, pp, lp; + png_uint_32 i; + png_size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) + & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return (sum); +} +static void /* PRIVATE */ +png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp, + const png_size_t row_bytes) +{ + png_bytep rp, dp, pp, lp; + png_uint_32 i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) + & 0xff); + } +} + +static png_size_t /* PRIVATE */ +png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, + const png_size_t row_bytes, const png_size_t lmins) +{ + png_bytep rp, dp, pp, cp, lp; + png_size_t i; + png_size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + } + + for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; + i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return (sum); +} +static void /* PRIVATE */ +png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp, + const png_size_t row_bytes) +{ + png_bytep rp, dp, pp, cp, lp; + png_size_t i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + } + + for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; + i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + } +} +#endif /* WRITE_FILTER */ -#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) -#define PNG_HISHIFT 10 -#define PNG_LOMASK ((png_uint_32)0xffffL) -#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) void /* PRIVATE */ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) { +#ifndef PNG_WRITE_FILTER_SUPPORTED + png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1); +#else + unsigned int filter_to_do = png_ptr->do_filter; + png_bytep row_buf; png_bytep best_row; -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_bytep prev_row, row_buf; - png_uint_32 mins, bpp; - png_byte filter_to_do = png_ptr->do_filter; + png_uint_32 bpp; + png_size_t mins; png_size_t row_bytes = row_info->rowbytes; -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - int num_p_filters = png_ptr->num_prev_filters; -#endif png_debug(1, "in png_write_find_filter"); -#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) - { - /* These will never be selected so we need not test them. */ - filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); - } -#endif - /* Find out how many bytes offset each pixel is */ bpp = (row_info->pixel_depth + 7) >> 3; - prev_row = png_ptr->prev_row; -#endif - best_row = png_ptr->row_buf; -#ifdef PNG_WRITE_FILTER_SUPPORTED - row_buf = best_row; - mins = PNG_MAXSUM; + row_buf = png_ptr->row_buf; + mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the + running sum */; /* The prediction method we use is to find which method provides the * smallest value when summing the absolute values of the distances @@ -2383,57 +2599,38 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) /* We don't need to test the 'no filter' case if this is the only filter * that has been chosen, as it doesn't actually do anything to the data. */ - if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE) + best_row = png_ptr->row_buf; + + if (PNG_SIZE_MAX/128 <= row_bytes) { + /* Overflow can occur in the calculation, just select the lowest set + * filter. + */ + filter_to_do &= 0U-filter_to_do; + } + else if ((filter_to_do & PNG_FILTER_NONE) != 0 && + filter_to_do != PNG_FILTER_NONE) + { + /* Overflow not possible and multiple filters in the list, including the + * 'none' filter. + */ png_bytep rp; - png_uint_32 sum = 0; + png_size_t sum = 0; png_size_t i; - int v; + unsigned int v; - for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) { - v = *rp; - sum += (v < 128) ? v : 256 - v; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - png_uint_32 sumhi, sumlo; - int j; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ - - /* Reduce the sum if we match any of the previous rows */ - for (j = 0; j < num_p_filters; j++) + for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - /* Factor in the cost of this filter (this is here for completeness, - * but it makes no sense to have a "cost" for the NONE filter, as - * it has the minimum possible computational cost - none). - */ - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } + v = *rp; +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; #endif + } + } + mins = sum; } @@ -2441,553 +2638,109 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) if (filter_to_do == PNG_FILTER_SUB) /* It's the only filter so no testing is needed */ { - png_bytep rp, lp, dp; - png_size_t i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; - i++, rp++, dp++) - { - *dp = *rp; - } - - for (lp = row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - *dp = (png_byte)((int)*rp - (int)*lp); - } - - best_row = png_ptr->sub_row; + png_setup_sub_row_only(png_ptr, bpp, row_bytes); + best_row = png_ptr->try_row; } else if ((filter_to_do & PNG_FILTER_SUB) != 0) { - png_bytep rp, dp, lp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; + png_size_t sum; + png_size_t lmins = mins; -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - /* We temporarily increase the "minimum sum" by the factor we - * would reduce the sum of this filter, so that we can do the - * early exit comparison without scaling the sum each time. - */ - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; - i++, rp++, dp++) - { - v = *dp = *rp; - - sum += (v < 128) ? v : 256 - v; - } - - for (lp = row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - v = *dp = (png_byte)((int)*rp - (int)*lp); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) - { - sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif + sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); if (sum < mins) { mins = sum; - best_row = png_ptr->sub_row; + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } } } /* Up filter */ if (filter_to_do == PNG_FILTER_UP) { - png_bytep rp, dp, pp; - png_size_t i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, - pp = prev_row + 1; i < row_bytes; - i++, rp++, pp++, dp++) - { - *dp = (png_byte)((int)*rp - (int)*pp); - } - - best_row = png_ptr->up_row; + png_setup_up_row_only(png_ptr, row_bytes); + best_row = png_ptr->try_row; } else if ((filter_to_do & PNG_FILTER_UP) != 0) { - png_bytep rp, dp, pp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; + png_size_t sum; + png_size_t lmins = mins; - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, - pp = prev_row + 1; i < row_bytes; i++) - { - v = *dp++ = (png_byte)((int)*rp++ - (int)*pp++); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif + sum = png_setup_up_row(png_ptr, row_bytes, lmins); if (sum < mins) { mins = sum; - best_row = png_ptr->up_row; + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } } } /* Avg filter */ if (filter_to_do == PNG_FILTER_AVG) { - png_bytep rp, dp, pp, lp; - png_uint_32 i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)((int)*rp++ - ((int)*pp++ / 2)); - } - - for (lp = row_buf + 1; i < row_bytes; i++) - { - *dp++ = - (png_byte)((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)); - } - best_row = png_ptr->avg_row; + png_setup_avg_row_only(png_ptr, bpp, row_bytes); + best_row = png_ptr->try_row; } else if ((filter_to_do & PNG_FILTER_AVG) != 0) { - png_bytep rp, dp, pp, lp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; + png_size_t sum; + png_size_t lmins = mins; -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)((int)*rp++ - ((int)*pp++ / 2)); - - sum += (v < 128) ? v : 256 - v; - } - - for (lp = row_buf + 1; i < row_bytes; i++) - { - v = *dp++ = - (png_byte)(((int)*rp++ - ((int)*pp++ + (int)*lp++) / 2)); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif + sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); if (sum < mins) { mins = sum; - best_row = png_ptr->avg_row; + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } } } /* Paeth filter */ - if ((filter_to_do == PNG_FILTER_PAETH) != 0) + if (filter_to_do == PNG_FILTER_PAETH) { - png_bytep rp, dp, pp, cp, lp; - png_size_t i; - - for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)((int)*rp++ - (int)*pp++); - } - - for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; - - *dp++ = (png_byte)((int)*rp++ - p); - } - best_row = png_ptr->paeth_row; + png_setup_paeth_row_only(png_ptr, bpp, row_bytes); + best_row = png_ptr->try_row; } else if ((filter_to_do & PNG_FILTER_PAETH) != 0) { - png_bytep rp, dp, pp, cp, lp; - png_uint_32 sum = 0, lmins = mins; - png_size_t i; - int v; + png_size_t sum; + png_size_t lmins = mins; -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 lmhi, lmlo; - lmlo = lmins & PNG_LOMASK; - lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) - { - lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - if (lmhi > PNG_HIMASK) - lmins = PNG_MAXSUM; - - else - lmins = (lmhi << PNG_HISHIFT) + lmlo; - } -#endif - - for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, - pp = prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)((int)*rp++ - (int)*pp++); - - sum += (v < 128) ? v : 256 - v; - } - - for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - -#ifndef PNG_SLOW_PAETH - p = b - c; - pc = a - c; -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; -#else /* SLOW_PAETH */ - p = a + b - c; - pa = abs(p - a); - pb = abs(p - b); - pc = abs(p - c); - - if (pa <= pb && pa <= pc) - p = a; - - else if (pb <= pc) - p = b; - - else - p = c; -#endif /* SLOW_PAETH */ - - v = *dp++ = (png_byte)((int)*rp++ - p); - - sum += (v < 128) ? v : 256 - v; - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) - { - int j; - png_uint_32 sumhi, sumlo; - sumlo = sum & PNG_LOMASK; - sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; - - for (j = 0; j < num_p_filters; j++) - { - if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) - { - sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - - sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; - } - } - - sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; - - if (sumhi > PNG_HIMASK) - sum = PNG_MAXSUM; - - else - sum = (sumhi << PNG_HISHIFT) + sumlo; - } -#endif + sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); if (sum < mins) { - best_row = png_ptr->paeth_row; + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } } } -#endif /* WRITE_FILTER */ /* Do the actual writing of the filtered row data from the chosen filter. */ png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); -#ifdef PNG_WRITE_FILTER_SUPPORTED -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - /* Save the type of filter we picked this time for future calculations */ - if (png_ptr->num_prev_filters > 0) - { - int j; - - for (j = 1; j < num_p_filters; j++) - { - png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; - } - - png_ptr->prev_filters[j] = best_row[0]; - } -#endif #endif /* WRITE_FILTER */ } @@ -2995,7 +2748,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) /* Do the actual writing of a previously filtered row. */ static void png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - png_size_t full_row_length/*includes filter byte*/) + png_size_t full_row_length/*includes filter byte*/) { png_debug(1, "in png_write_filtered_row"); diff --git a/src/third-party/libpng/powerpc/filter_vsx_intrinsics.c b/src/third-party/libpng/powerpc/filter_vsx_intrinsics.c new file mode 100644 index 000000000..e3de496bd --- /dev/null +++ b/src/third-party/libpng/powerpc/filter_vsx_intrinsics.c @@ -0,0 +1,767 @@ +/* filter_vsx_intrinsics.c - PowerPC optimised filter functions + * + * 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 + */ +#include +#include +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* This code requires -maltivec and -mvsx on the command line: */ +#if PNG_POWERPC_VSX_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ + +#include + +#if PNG_POWERPC_VSX_OPT > 0 + +#ifndef __VSX__ +# error "This code requires VSX support (POWER7 and later). Please provide -mvsx compiler flag." +#endif + +#define vec_ld_unaligned(vec,data) vec = vec_vsx_ld(0,data) +#define vec_st_unaligned(vec,data) vec_vsx_st(vec,0,data) + + +/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d). + * They're positioned like this: + * prev: c b + * row: a d + * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be + * whichever of a, b, or c is closest to p=a+b-c. + * ( this is taken from ../intel/filter_sse2_intrinsics.c ) + */ + +#define vsx_declare_common_vars(row_info,row,prev_row,offset) \ + png_byte i;\ + png_bytep rp = row + offset;\ + png_const_bytep pp = prev_row;\ + png_size_t unaligned_top = 16 - (((png_size_t)rp % 16));\ + png_size_t istop;\ + if(unaligned_top == 16)\ + unaligned_top = 0;\ + istop = row_info->rowbytes;\ + if((unaligned_top < istop))\ + istop -= unaligned_top;\ + else{\ + unaligned_top = istop;\ + istop = 0;\ + } + +void png_read_filter_row_up_vsx(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + vector unsigned char rp_vec; + vector unsigned char pp_vec; + vsx_declare_common_vars(row_info,row,prev_row,0) + + /* Altivec operations require 16-byte aligned data + * but input can be unaligned. So we calculate + * unaligned part as usual. + */ + for (i = 0; i < unaligned_top; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } + + /* Using SIMD while we can */ + while( istop >= 16 ) + { + rp_vec = vec_ld(0,rp); + vec_ld_unaligned(pp_vec,pp); + + rp_vec = vec_add(rp_vec,pp_vec); + + vec_st(rp_vec,0,rp); + + pp += 16; + rp += 16; + istop -= 16; + } + + if(istop > 0) + { + /* If byte count of row is not divisible by 16 + * we will process remaining part as usual + */ + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } +} + +} + +static const vector unsigned char VSX_LEFTSHIFTED1_4 = {16,16,16,16, 0, 1, 2, 3,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_LEFTSHIFTED2_4 = {16,16,16,16,16,16,16,16, 4, 5, 6, 7,16,16,16,16}; +static const vector unsigned char VSX_LEFTSHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 8, 9,10,11}; + +static const vector unsigned char VSX_LEFTSHIFTED1_3 = {16,16,16, 0, 1, 2,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_LEFTSHIFTED2_3 = {16,16,16,16,16,16, 3, 4, 5,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_LEFTSHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 6, 7, 8,16,16,16,16}; +static const vector unsigned char VSX_LEFTSHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 9,10,11,16}; + +static const vector unsigned char VSX_NOT_SHIFTED1_4 = {16,16,16,16, 4, 5, 6, 7,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_NOT_SHIFTED2_4 = {16,16,16,16,16,16,16,16, 8, 9,10,11,16,16,16,16}; +static const vector unsigned char VSX_NOT_SHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,15}; + +static const vector unsigned char VSX_NOT_SHIFTED1_3 = {16,16,16, 3, 4, 5,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_NOT_SHIFTED2_3 = {16,16,16,16,16,16, 6, 7, 8,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_NOT_SHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 9,10,11,16,16,16,16}; +static const vector unsigned char VSX_NOT_SHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,16}; + +static const vector unsigned char VSX_CHAR_ZERO = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +#ifdef __LITTLE_ENDIAN__ + +static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = { 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = { 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {12,16,13,16,14,16,15,16,16,16,16,16,16,16,16,16}; + +static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 0, 2, 4, 6,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 0, 2, 4, 6,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4, 6}; + +static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = { 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = { 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = { 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {12,16,13,16,14,16,16,16,16,16,16,16,16,16,16,16}; + +static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 0, 2, 4,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 0, 2, 4,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 0, 2, 4,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4,16}; + +#elif defined(__BIG_ENDIAN__) + +static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = {16, 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = {16, 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {16,12,16,13,16,14,16,15,16,16,16,16,16,16,16,16}; + +static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 1, 3, 5, 7,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 1, 3, 5, 7,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5, 7}; + +static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = {16, 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = {16, 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = {16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {16,12,16,13,16,14,16,16,16,16,16,16,16,16,16,16}; + +static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 1, 3, 5,16,16,16,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 1, 3, 5,16,16,16,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 1, 3, 5,16,16,16,16}; +static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5,16}; + +#endif + +#define vsx_char_to_short(vec,offset,bpp) (vector unsigned short)vec_perm((vec),VSX_CHAR_ZERO,VSX_CHAR_TO_SHORT##offset##_##bpp) +#define vsx_short_to_char(vec,offset,bpp) vec_perm(((vector unsigned char)(vec)),VSX_CHAR_ZERO,VSX_SHORT_TO_CHAR##offset##_##bpp) + +#ifdef PNG_USE_ABS +# define vsx_abs(number) abs(number) +#else +# define vsx_abs(number) (number > 0) ? (number) : -(number) +#endif + +void png_read_filter_row_sub4_vsx(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + const png_byte bpp = 4; + + vector unsigned char rp_vec; + vector unsigned char part_vec; + + vsx_declare_common_vars(row_info,row,prev_row,bpp) + + PNG_UNUSED(pp) + + /* Altivec operations require 16-byte aligned data + * but input can be unaligned. So we calculate + * unaligned part as usual. + */ + for (i = 0; i < unaligned_top; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } + + /* Using SIMD while we can */ + while( istop >= 16 ) + { + for(i=0;i < bpp ; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } + rp -= bpp; + + rp_vec = vec_ld(0,rp); + part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4); + rp_vec = vec_add(rp_vec,part_vec); + + part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4); + rp_vec = vec_add(rp_vec,part_vec); + + part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4); + rp_vec = vec_add(rp_vec,part_vec); + + vec_st(rp_vec,0,rp); + + rp += 16; + istop -= 16; + } + + if(istop > 0) + for (i = 0; i < istop % 16; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp - bpp))) & 0xff); + rp++; + } + +} + +void png_read_filter_row_sub3_vsx(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + const png_byte bpp = 3; + + vector unsigned char rp_vec; + vector unsigned char part_vec; + + vsx_declare_common_vars(row_info,row,prev_row,bpp) + + PNG_UNUSED(pp) + + /* Altivec operations require 16-byte aligned data + * but input can be unaligned. So we calculate + * unaligned part as usual. + */ + for (i = 0; i < unaligned_top; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } + + /* Using SIMD while we can */ + while( istop >= 16 ) + { + for(i=0;i < bpp ; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } + rp -= bpp; + + rp_vec = vec_ld(0,rp); + part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3); + rp_vec = vec_add(rp_vec,part_vec); + + part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3); + rp_vec = vec_add(rp_vec,part_vec); + + part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3); + rp_vec = vec_add(rp_vec,part_vec); + + part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3); + rp_vec = vec_add(rp_vec,part_vec); + + vec_st(rp_vec,0,rp); + rp += 15; + istop -= 16; + + /* Since 16 % bpp = 16 % 3 = 1, last element of array must + * be proceeded manually + */ + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } + + if(istop > 0) + for (i = 0; i < istop % 16; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } +} + +void png_read_filter_row_avg4_vsx(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + const png_byte bpp = 4; + + vector unsigned char rp_vec; + vector unsigned char pp_vec; + vector unsigned char pp_part_vec; + vector unsigned char rp_part_vec; + vector unsigned char avg_vec; + + vsx_declare_common_vars(row_info,row,prev_row,bpp) + rp -= bpp; + if(istop >= bpp) + istop -= bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) / 2 )) & 0xff); + + rp++; + } + + /* Altivec operations require 16-byte aligned data + * but input can be unaligned. So we calculate + * unaligned part as usual. + */ + for (i = 0; i < unaligned_top; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } + + /* Using SIMD while we can */ + while( istop >= 16 ) + { + for(i=0;i < bpp ; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } + rp -= bpp; + pp -= bpp; + + vec_ld_unaligned(pp_vec,pp); + rp_vec = vec_ld(0,rp); + + rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4); + pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_4); + avg_vec = vec_avg(rp_part_vec,pp_part_vec); + avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1))); + rp_vec = vec_add(rp_vec,avg_vec); + + rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4); + pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_4); + avg_vec = vec_avg(rp_part_vec,pp_part_vec); + avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1))); + rp_vec = vec_add(rp_vec,avg_vec); + + rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4); + pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_4); + avg_vec = vec_avg(rp_part_vec,pp_part_vec); + avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1))); + rp_vec = vec_add(rp_vec,avg_vec); + + vec_st(rp_vec,0,rp); + + rp += 16; + pp += 16; + istop -= 16; + } + + if(istop > 0) + for (i = 0; i < istop % 16; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } +} + +void png_read_filter_row_avg3_vsx(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + const png_byte bpp = 3; + + vector unsigned char rp_vec; + vector unsigned char pp_vec; + vector unsigned char pp_part_vec; + vector unsigned char rp_part_vec; + vector unsigned char avg_vec; + + vsx_declare_common_vars(row_info,row,prev_row,bpp) + rp -= bpp; + if(istop >= bpp) + istop -= bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) / 2 )) & 0xff); + + rp++; + } + + /* Altivec operations require 16-byte aligned data + * but input can be unaligned. So we calculate + * unaligned part as usual. + */ + for (i = 0; i < unaligned_top; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } + + /* Using SIMD while we can */ + while( istop >= 16 ) + { + for(i=0;i < bpp ; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } + rp -= bpp; + pp -= bpp; + + vec_ld_unaligned(pp_vec,pp); + rp_vec = vec_ld(0,rp); + + rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3); + pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_3); + avg_vec = vec_avg(rp_part_vec,pp_part_vec); + avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1))); + rp_vec = vec_add(rp_vec,avg_vec); + + rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3); + pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_3); + avg_vec = vec_avg(rp_part_vec,pp_part_vec); + avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1))); + rp_vec = vec_add(rp_vec,avg_vec); + + rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3); + pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_3); + avg_vec = vec_avg(rp_part_vec,pp_part_vec); + avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1))); + rp_vec = vec_add(rp_vec,avg_vec); + + rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3); + pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED4_3); + avg_vec = vec_avg(rp_part_vec,pp_part_vec); + avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1))); + rp_vec = vec_add(rp_vec,avg_vec); + + vec_st(rp_vec,0,rp); + + rp += 15; + pp += 15; + istop -= 16; + + /* Since 16 % bpp = 16 % 3 = 1, last element of array must + * be proceeded manually + */ + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + rp++; + } + + if(istop > 0) + for (i = 0; i < istop % 16; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } +} + +/* Bytewise c ? t : e. */ +#define if_then_else(c,t,e) vec_sel(e,t,c) + +#define vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) {\ + c = *(pp - bpp);\ + a = *(rp - bpp);\ + b = *pp++;\ + p = b - c;\ + pc = a - c;\ + pa = vsx_abs(p);\ + pb = vsx_abs(pc);\ + pc = vsx_abs(p + pc);\ + if (pb < pa) pa = pb, a = b;\ + if (pc < pa) a = c;\ + a += *rp;\ + *rp++ = (png_byte)a;\ + } + +void png_read_filter_row_paeth4_vsx(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + const png_byte bpp = 4; + + int a, b, c, pa, pb, pc, p; + vector unsigned char rp_vec; + vector unsigned char pp_vec; + vector unsigned short a_vec,b_vec,c_vec,nearest_vec; + vector signed short pa_vec,pb_vec,pc_vec,smallest_vec; + + vsx_declare_common_vars(row_info,row,prev_row,bpp) + rp -= bpp; + if(istop >= bpp) + istop -= bpp; + + /* Process the first pixel in the row completely (this is the same as 'up' + * because there is only one candidate predictor for the first row). + */ + for(i = 0; i < bpp ; i++) + { + *rp = (png_byte)( *rp + *pp); + rp++; + pp++; + } + + for(i = 0; i < unaligned_top ; i++) + { + vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) + } + + while( istop >= 16) + { + for(i = 0; i < bpp ; i++) + { + vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) + } + + rp -= bpp; + pp -= bpp; + rp_vec = vec_ld(0,rp); + vec_ld_unaligned(pp_vec,pp); + + a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4); + b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_4),1,4); + c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4); + pa_vec = (vector signed short) vec_sub(b_vec,c_vec); + pb_vec = (vector signed short) vec_sub(a_vec , c_vec); + pc_vec = vec_add(pa_vec,pb_vec); + pa_vec = vec_abs(pa_vec); + pb_vec = vec_abs(pb_vec); + pc_vec = vec_abs(pc_vec); + smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec)); + nearest_vec = if_then_else( + vec_cmpeq(pa_vec,smallest_vec), + a_vec, + if_then_else( + vec_cmpeq(pb_vec,smallest_vec), + b_vec, + c_vec + ) + ); + rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,4))); + + a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4); + b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_4),2,4); + c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4); + pa_vec = (vector signed short) vec_sub(b_vec,c_vec); + pb_vec = (vector signed short) vec_sub(a_vec , c_vec); + pc_vec = vec_add(pa_vec,pb_vec); + pa_vec = vec_abs(pa_vec); + pb_vec = vec_abs(pb_vec); + pc_vec = vec_abs(pc_vec); + smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec)); + nearest_vec = if_then_else( + vec_cmpeq(pa_vec,smallest_vec), + a_vec, + if_then_else( + vec_cmpeq(pb_vec,smallest_vec), + b_vec, + c_vec + ) + ); + rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,4))); + + a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4); + b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_4),3,4); + c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4); + pa_vec = (vector signed short) vec_sub(b_vec,c_vec); + pb_vec = (vector signed short) vec_sub(a_vec , c_vec); + pc_vec = vec_add(pa_vec,pb_vec); + pa_vec = vec_abs(pa_vec); + pb_vec = vec_abs(pb_vec); + pc_vec = vec_abs(pc_vec); + smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec)); + nearest_vec = if_then_else( + vec_cmpeq(pa_vec,smallest_vec), + a_vec, + if_then_else( + vec_cmpeq(pb_vec,smallest_vec), + b_vec, + c_vec + ) + ); + rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,4))); + + vec_st(rp_vec,0,rp); + + rp += 16; + pp += 16; + istop -= 16; + } + + if(istop > 0) + for (i = 0; i < istop % 16; i++) + { + vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) + } +} + +void png_read_filter_row_paeth3_vsx(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + const png_byte bpp = 3; + + int a, b, c, pa, pb, pc, p; + vector unsigned char rp_vec; + vector unsigned char pp_vec; + vector unsigned short a_vec,b_vec,c_vec,nearest_vec; + vector signed short pa_vec,pb_vec,pc_vec,smallest_vec; + + vsx_declare_common_vars(row_info,row,prev_row,bpp) + rp -= bpp; + if(istop >= bpp) + istop -= bpp; + + /* Process the first pixel in the row completely (this is the same as 'up' + * because there is only one candidate predictor for the first row). + */ + for(i = 0; i < bpp ; i++) + { + *rp = (png_byte)( *rp + *pp); + rp++; + pp++; + } + + for(i = 0; i < unaligned_top ; i++) + { + vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) + } + + while( istop >= 16) + { + for(i = 0; i < bpp ; i++) + { + vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) + } + + rp -= bpp; + pp -= bpp; + rp_vec = vec_ld(0,rp); + vec_ld_unaligned(pp_vec,pp); + + a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3); + b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_3),1,3); + c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3); + pa_vec = (vector signed short) vec_sub(b_vec,c_vec); + pb_vec = (vector signed short) vec_sub(a_vec , c_vec); + pc_vec = vec_add(pa_vec,pb_vec); + pa_vec = vec_abs(pa_vec); + pb_vec = vec_abs(pb_vec); + pc_vec = vec_abs(pc_vec); + smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec)); + nearest_vec = if_then_else( + vec_cmpeq(pa_vec,smallest_vec), + a_vec, + if_then_else( + vec_cmpeq(pb_vec,smallest_vec), + b_vec, + c_vec + ) + ); + rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,3))); + + a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3); + b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_3),2,3); + c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3); + pa_vec = (vector signed short) vec_sub(b_vec,c_vec); + pb_vec = (vector signed short) vec_sub(a_vec , c_vec); + pc_vec = vec_add(pa_vec,pb_vec); + pa_vec = vec_abs(pa_vec); + pb_vec = vec_abs(pb_vec); + pc_vec = vec_abs(pc_vec); + smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec)); + nearest_vec = if_then_else( + vec_cmpeq(pa_vec,smallest_vec), + a_vec, + if_then_else( + vec_cmpeq(pb_vec,smallest_vec), + b_vec, + c_vec + ) + ); + rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,3))); + + a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3); + b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_3),3,3); + c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3); + pa_vec = (vector signed short) vec_sub(b_vec,c_vec); + pb_vec = (vector signed short) vec_sub(a_vec , c_vec); + pc_vec = vec_add(pa_vec,pb_vec); + pa_vec = vec_abs(pa_vec); + pb_vec = vec_abs(pb_vec); + pc_vec = vec_abs(pc_vec); + smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec)); + nearest_vec = if_then_else( + vec_cmpeq(pa_vec,smallest_vec), + a_vec, + if_then_else( + vec_cmpeq(pb_vec,smallest_vec), + b_vec, + c_vec + ) + ); + rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,3))); + + a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3); + b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED4_3),4,3); + c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3); + pa_vec = (vector signed short) vec_sub(b_vec,c_vec); + pb_vec = (vector signed short) vec_sub(a_vec , c_vec); + pc_vec = vec_add(pa_vec,pb_vec); + pa_vec = vec_abs(pa_vec); + pb_vec = vec_abs(pb_vec); + pc_vec = vec_abs(pc_vec); + smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec)); + nearest_vec = if_then_else( + vec_cmpeq(pa_vec,smallest_vec), + a_vec, + if_then_else( + vec_cmpeq(pb_vec,smallest_vec), + b_vec, + c_vec + ) + ); + rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,4,3))); + + vec_st(rp_vec,0,rp); + + rp += 15; + pp += 15; + istop -= 16; + + /* Since 16 % bpp = 16 % 3 = 1, last element of array must + * be proceeded manually + */ + vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) + } + + if(istop > 0) + for (i = 0; i < istop % 16; i++) + { + vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) + } +} + +#endif /* PNG_POWERPC_VSX_OPT > 0 */ +#endif /* PNG_POWERPC_VSX_IMPLEMENTATION == 1 (intrinsics) */ +#endif /* READ */ diff --git a/src/third-party/libpng/powerpc/powerpc_init.c b/src/third-party/libpng/powerpc/powerpc_init.c new file mode 100644 index 000000000..07016177c --- /dev/null +++ b/src/third-party/libpng/powerpc/powerpc_init.c @@ -0,0 +1,125 @@ + +/* powerpc_init.c - POWERPC optimised filter functions + * + * 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 + */ +/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are + * called. + */ +#define _POSIX_SOURCE 1 + +#include +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#if PNG_POWERPC_VSX_OPT > 0 +#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED /* Do run-time checks */ +/* WARNING: it is strongly recommended that you do not build libpng with + * run-time checks for CPU features if at all possible. In the case of the PowerPC + * VSX instructions there is no processor-specific way of detecting the + * presence of the required support, therefore run-time detection is extremely + * OS specific. + * + * You may set the macro PNG_POWERPC_VSX_FILE to the file name of file containing + * a fragment of C source code which defines the png_have_vsx function. There + * are a number of implementations in contrib/powerpc-vsx, but the only one that + * has partial support is contrib/powerpc-vsx/linux.c - a generic Linux + * implementation which reads /proc/cpufino. + */ +#ifndef PNG_POWERPC_VSX_FILE +# ifdef __linux__ +# define PNG_POWERPC_VSX_FILE "contrib/powerpc-vsx/linux_aux.c" +# endif +#endif + +#ifdef PNG_POWERPC_VSX_FILE + +#include /* for sig_atomic_t */ +static int png_have_vsx(png_structp png_ptr); +#include PNG_POWERPC_VSX_FILE + +#else /* PNG_POWERPC_VSX_FILE */ +# error "PNG_POWERPC_VSX_FILE undefined: no support for run-time POWERPC VSX checks" +#endif /* PNG_POWERPC_VSX_FILE */ +#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */ + +void +png_init_filter_functions_vsx(png_structp pp, unsigned int bpp) +{ + /* The switch statement is compiled in for POWERPC_VSX_API, the call to + * png_have_vsx is compiled in for POWERPC_VSX_CHECK. If both are defined + * the check is only performed if the API has not set the PowerPC option on + * or off explicitly. In this case the check controls what happens. + */ + +#ifdef PNG_POWERPC_VSX_API_SUPPORTED + switch ((pp->options >> PNG_POWERPC_VSX) & 3) + { + case PNG_OPTION_UNSET: + /* Allow the run-time check to execute if it has been enabled - + * thus both API and CHECK can be turned on. If it isn't supported + * this case will fall through to the 'default' below, which just + * returns. + */ +#endif /* PNG_POWERPC_VSX_API_SUPPORTED */ +#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED + { + static volatile sig_atomic_t no_vsx = -1; /* not checked */ + + if (no_vsx < 0) + no_vsx = !png_have_vsx(pp); + + if (no_vsx) + return; + } +#ifdef PNG_POWERPC_VSX_API_SUPPORTED + break; +#endif +#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */ + +#ifdef PNG_POWERPC_VSX_API_SUPPORTED + default: /* OFF or INVALID */ + return; + + case PNG_OPTION_ON: + /* Option turned on */ + break; + } +#endif + + /* IMPORTANT: any new internal functions used here must be declared using + * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the + * 'prefix' option to configure works: + * + * ./configure --with-libpng-prefix=foobar_ + * + * Verify you have got this right by running the above command, doing a build + * and examining pngprefix.h; it must contain a #define for every external + * function you add. (Notice that this happens automatically for the + * initialization function.) + */ + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_vsx; + + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_vsx; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_vsx; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_vsx; + } + + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_vsx; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_vsx; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_vsx; + } +} +#endif /* PNG_POWERPC_VSX_OPT > 0 */ +#endif /* READ */ diff --git a/src/third-party/libpng/projects/owatcom/pngconfig.mak b/src/third-party/libpng/projects/owatcom/pngconfig.mak index 054a3fc20..3ef2948ca 100644 --- a/src/third-party/libpng/projects/owatcom/pngconfig.mak +++ b/src/third-party/libpng/projects/owatcom/pngconfig.mak @@ -126,7 +126,7 @@ $# to work, download Brian Kernighan's awk (Brian Kernighan is the author of $# awk.) You can find source code and a built executable (called awk95.exe) $# here: $# -$# http://www.cs.princeton.edu/~bwk/btl.mirror/ +$# https://www.cs.princeton.edu/~bwk/btl.mirror/ $# $# The executable works just fine. $# diff --git a/src/third-party/libpng/projects/vstudio/WARNING b/src/third-party/libpng/projects/vstudio/WARNING deleted file mode 100644 index da002c937..000000000 --- a/src/third-party/libpng/projects/vstudio/WARNING +++ /dev/null @@ -1,27 +0,0 @@ -WARNING -======= -Libpng 1.6 does not use the default run-time library when building static -library builds of libpng; instead of the shared DLL runtime it uses a static -runtime. If you need to change this make sure to change the setting on all the -relevant projects: - -libpng -zlib -all the test programs - -The runtime library settings for each build are as follows: - - Release Debug -DLL /MD /MDd -Library /MT /MTd - -NOTICE that libpng 1.5 erroneously used /MD for Debug DLL builds; if you used -the debug builds in your app and you changed your app to use /MD you will need -to change it to /MDd for libpng 1.6. - -The Visual Studio 2010 defaults for a Win32 DLL or Static Library project are -as follows: - - Release Debug -DLL /MD /MDd -Static Library /MD /MDd diff --git a/src/third-party/libpng/projects/vstudio/libpng/libpng.vcxproj b/src/third-party/libpng/projects/vstudio/libpng/libpng.vcxproj index de7fc3c41..9bfb718a4 100644 --- a/src/third-party/libpng/projects/vstudio/libpng/libpng.vcxproj +++ b/src/third-party/libpng/projects/vstudio/libpng/libpng.vcxproj @@ -84,7 +84,7 @@ Use - Level4 + $(WarningLevel) false ProgramDatabase EnableFastChecks @@ -97,9 +97,9 @@ true CompileAsC true - 4996;4127 + $(DisableSpecificWarnings) $(ZLibSrcDir);%(AdditionalIncludeDirectories) - true + $(TreatWarningAsError) Disabled MultiThreadedDebugDLL @@ -114,7 +114,7 @@ Use - Level4 + $(WarningLevel) false ProgramDatabase Disabled @@ -128,9 +128,9 @@ true CompileAsC true - 4996;4127 + $(DisableSpecificWarnings) $(ZLibSrcDir);%(AdditionalIncludeDirectories) - true + $(TreatWarningAsError) MultiThreadedDebug @@ -140,7 +140,7 @@ - Level4 + $(WarningLevel) Use ProgramDatabase true @@ -153,9 +153,9 @@ CompileAsC true false - 4996;4127 + $(DisableSpecificWarnings) $(ZLibSrcDir);%(AdditionalIncludeDirectories) - true + $(TreatWarningAsError) Full @@ -170,7 +170,7 @@ - Level4 + $(WarningLevel) Use ProgramDatabase MultiThreaded @@ -184,9 +184,9 @@ CompileAsC true false - 4996;4127 + $(DisableSpecificWarnings) $(ZLibSrcDir);%(AdditionalIncludeDirectories) - true + $(TreatWarningAsError) Full true diff --git a/src/third-party/libpng/projects/vstudio/pnglibconf/pnglibconf.vcxproj b/src/third-party/libpng/projects/vstudio/pnglibconf/pnglibconf.vcxproj index e2a232cb6..efcc440ba 100644 --- a/src/third-party/libpng/projects/vstudio/pnglibconf/pnglibconf.vcxproj +++ b/src/third-party/libpng/projects/vstudio/pnglibconf/pnglibconf.vcxproj @@ -30,7 +30,7 @@ - Level3 + $(WarningLevel) MaxSpeed true true diff --git a/src/third-party/libpng/projects/vstudio/pngstest/pngstest.vcxproj b/src/third-party/libpng/projects/vstudio/pngstest/pngstest.vcxproj index 0d2980dd8..21810e32a 100644 --- a/src/third-party/libpng/projects/vstudio/pngstest/pngstest.vcxproj +++ b/src/third-party/libpng/projects/vstudio/pngstest/pngstest.vcxproj @@ -76,16 +76,16 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled EnableFastChecks WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -109,7 +109,7 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled @@ -117,9 +117,9 @@ MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -141,7 +141,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -149,9 +149,9 @@ true WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true @@ -176,7 +176,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -185,9 +185,9 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true diff --git a/src/third-party/libpng/projects/vstudio/pngtest/pngtest.vcxproj b/src/third-party/libpng/projects/vstudio/pngtest/pngtest.vcxproj index bf9266f75..f1df07d5c 100644 --- a/src/third-party/libpng/projects/vstudio/pngtest/pngtest.vcxproj +++ b/src/third-party/libpng/projects/vstudio/pngtest/pngtest.vcxproj @@ -76,16 +76,16 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled EnableFastChecks WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -109,7 +109,7 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled @@ -117,9 +117,9 @@ MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -141,7 +141,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -149,9 +149,9 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true @@ -176,7 +176,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -185,9 +185,9 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true diff --git a/src/third-party/libpng/projects/vstudio/pngunknown/pngunknown.vcxproj b/src/third-party/libpng/projects/vstudio/pngunknown/pngunknown.vcxproj index a30cc7a21..409d6621d 100644 --- a/src/third-party/libpng/projects/vstudio/pngunknown/pngunknown.vcxproj +++ b/src/third-party/libpng/projects/vstudio/pngunknown/pngunknown.vcxproj @@ -76,16 +76,16 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled EnableFastChecks WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -109,7 +109,7 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled @@ -117,9 +117,9 @@ MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -141,7 +141,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -149,9 +149,9 @@ true WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true @@ -176,7 +176,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -185,9 +185,9 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true diff --git a/src/third-party/libpng/projects/vstudio/pngvalid/pngvalid.vcxproj b/src/third-party/libpng/projects/vstudio/pngvalid/pngvalid.vcxproj index 07cf24119..c117d2910 100644 --- a/src/third-party/libpng/projects/vstudio/pngvalid/pngvalid.vcxproj +++ b/src/third-party/libpng/projects/vstudio/pngvalid/pngvalid.vcxproj @@ -76,16 +76,16 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled EnableFastChecks WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -109,7 +109,7 @@ NotUsing - Level4 + $(WarningLevel) false ProgramDatabase Disabled @@ -117,9 +117,9 @@ MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true true false @@ -141,7 +141,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -149,9 +149,9 @@ true WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true @@ -176,7 +176,7 @@ - Level4 + $(WarningLevel) NotUsing ProgramDatabase Full @@ -185,9 +185,9 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories) - 4996;4127 + $(DisableSpecificWarnings) false - true + $(TreatWarningAsError) true false true diff --git a/src/third-party/libpng/projects/vstudio/readme.txt b/src/third-party/libpng/projects/vstudio/readme.txt index a2521f205..71d3ba239 100644 --- a/src/third-party/libpng/projects/vstudio/readme.txt +++ b/src/third-party/libpng/projects/vstudio/readme.txt @@ -1,9 +1,9 @@ VisualStudio instructions -libpng version 1.6.17 - March 26, 2015 +libpng version 1.6.34 - September 29, 2017 -Copyright (c) 1998-2010 Glenn Randers-Pehrson +Copyright (c) 2010,2013,2015 Glenn Randers-Pehrson This code is released under the libpng license. For conditions of distribution and use, see the disclaimer @@ -38,16 +38,17 @@ In particular the runtime library is the "MultiThreaded DLL" version. If you use Visual Studio defaults to build your application you will have no problems. -If you don't use the Visual Studio defaults your application must still be built -with the default runtime option (/MD). If, for some reason, it is not then your -application will crash inside libpng16.dll as soon as libpng tries to read -from a file handle you pass in. +If you don't use the Visual Studio defaults your application must still be +built with the default runtime option (/MD). If, for some reason, it is not +then your application will crash inside libpng16.dll as soon as libpng +tries to read from a file handle you pass in. If you do not want to use the DLL, for example for a very small application, the 'release library' configuration may be more appropriate. This is built with a non-standard runtime library - the "MultiThreaded" version. When you build your application it must be compiled with this option (/MT), otherwise -it will not build (if you are lucky) or crash (if you are not.) +it will not build (if you are lucky) or crash (if you are not.) See the +WARNING file that is distributed along with this readme.txt. Stop reading here ================= @@ -63,3 +64,34 @@ track down.) The debug build of libpng is minimally supported. Support for debug builds of zlib is also minimal. You really don't want to do this. + +WARNING +======= +Libpng 1.6.x does not use the default run-time library when building static +library builds of libpng; instead of the shared DLL runtime it uses a static +runtime. If you need to change this make sure to change the setting on all the +relevant projects: + + libpng + zlib + all the test programs + +The runtime library settings for each build are as follows: + + Release Debug + DLL /MD /MDd + Library /MT /MTd + +NOTICE that libpng 1.5.x erroneously used /MD for Debug DLL builds; if you used +the debug builds in your app and you changed your app to use /MD you will need +to change it back to /MDd for libpng 1.6.0 and later. + +The Visual Studio 2010 defaults for a Win32 DLL or Static Library project are +as follows: + + Release Debug + DLL /MD /MDd + Static Library /MD /MDd + +Also, be sure to build libpng, zlib, and your project all for the same +platform (e.g., 32-bit or 64-bit). diff --git a/src/third-party/libpng/projects/vstudio/zlib.props b/src/third-party/libpng/projects/vstudio/zlib.props index 5d6d69b72..8e3682a26 100644 --- a/src/third-party/libpng/projects/vstudio/zlib.props +++ b/src/third-party/libpng/projects/vstudio/zlib.props @@ -2,7 +2,7 @@ true + + + EnableAllWarnings + true + 4255;4668;4710;4711;4746;4820;4996 diff --git a/src/third-party/libpng/projects/vstudio/zlib/zlib.vcxproj b/src/third-party/libpng/projects/vstudio/zlib/zlib.vcxproj index 6e5b94a61..0df16db34 100644 --- a/src/third-party/libpng/projects/vstudio/zlib/zlib.vcxproj +++ b/src/third-party/libpng/projects/vstudio/zlib/zlib.vcxproj @@ -88,11 +88,13 @@ WIN32;_DEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions) MultiThreadedDebug - TurnOffAllWarnings + $(WarningLevel) ProgramDatabase Disabled true true + $(DisableSpecificWarnings);4127;4131;4242;4244 + $(TreatWarningAsError) MachineX86 @@ -103,11 +105,13 @@ WIN32;_DEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions) - TurnOffAllWarnings + $(WarningLevel) ProgramDatabase Disabled true true + $(DisableSpecificWarnings);4127;4131;4242;4244 + $(TreatWarningAsError) MultiThreadedDebugDLL @@ -118,7 +122,7 @@ - Level3 + $(WarningLevel) ProgramDatabase Full true @@ -126,7 +130,8 @@ false true true - true + $(DisableSpecificWarnings);4127;4131;4242;4244 + $(TreatWarningAsError) MultiThreaded WIN32;NDEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions) @@ -141,7 +146,7 @@ - Level3 + $(WarningLevel) ProgramDatabase Full true @@ -149,7 +154,8 @@ false true true - true + $(DisableSpecificWarnings);4127;4131;4242;4244 + $(TreatWarningAsError) WIN32;NDEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions) diff --git a/src/third-party/libpng/scripts/README.txt b/src/third-party/libpng/scripts/README.txt index f6a9cf38c..793506e41 100644 --- a/src/third-party/libpng/scripts/README.txt +++ b/src/third-party/libpng/scripts/README.txt @@ -1,9 +1,11 @@ -Makefiles for libpng version 1.6.17 - March 26, 2015 +Makefiles for libpng version 1.6.34 - September 29, 2017 pnglibconf.h.prebuilt => Stores configuration settings makefile.linux => Linux/ELF makefile - (gcc, creates libpng16.so.16.1.6.17) + (gcc, creates libpng16.so.16.1.6.34) + makefile.linux-opt=> Linux/ELF makefile with hardware optimizations on + (gcc, creates libpng16.so.16.1.6.34) makefile.gcc => Generic makefile (gcc, creates static libpng.a) makefile.knr => Archaic UNIX Makefile that converts files with ansi2knr (Requires ansi2knr.c from @@ -33,12 +35,12 @@ pnglibconf.h.prebuilt => Stores configuration settings makefile.os2 => OS/2 Makefile (gcc and emx, requires libpng.def) makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc makefile.sggcc => Silicon Graphics (gcc, - creates libpng16.so.16.1.6.17) + creates libpng16.so.16.1.6.34) makefile.sgi => Silicon Graphics IRIX makefile (cc, creates static lib) makefile.solaris => Solaris 2.X makefile (gcc, - creates libpng16.so.16.1.6.17) + creates libpng16.so.16.1.6.34) makefile.so9 => Solaris 9 makefile (gcc, - creates libpng16.so.16.1.6.17) + creates libpng16.so.16.1.6.34) makefile.std => Generic UNIX makefile (cc, creates static libpng.a) makefile.sunos => Sun makefile makefile.32sunu => Sun Ultra 32-bit makefile diff --git a/src/third-party/libpng/scripts/def.c b/src/third-party/libpng/scripts/def.c index 9c88f7743..23bdbad4e 100644 --- a/src/third-party/libpng/scripts/def.c +++ b/src/third-party/libpng/scripts/def.c @@ -21,7 +21,7 @@ PNG_DFN "OS2 DESCRIPTION "PNG image compression library"" PNG_DFN "OS2 CODE PRELOAD MOVEABLE DISCARDABLE" PNG_DFN "" PNG_DFN "EXPORTS" -PNG_DFN ";Version 1.6.17" +PNG_DFN ";Version 1.6.34" #define PNG_EXPORTA(ordinal, type, name, args, attributes)\ PNG_DFN "@" SYMBOL_PREFIX "@@" name "@" diff --git a/src/third-party/libpng/scripts/genchk.cmake.in b/src/third-party/libpng/scripts/genchk.cmake.in new file mode 100644 index 000000000..ab3b9d746 --- /dev/null +++ b/src/third-party/libpng/scripts/genchk.cmake.in @@ -0,0 +1,37 @@ +# genchk.cmake.in +# Generate .chk from .out with awk (generic), based upon the automake logic. + +# Copyright (C) 2016 Glenn Randers-Pehrson +# Written by Roger Leigh, 2016 + +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h + +# Variables substituted from CMakeLists.txt +set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@") + +set(AWK "@AWK@") + +get_filename_component(INPUTEXT "${INPUT}" EXT) +get_filename_component(OUTPUTEXT "${OUTPUT}" EXT) +get_filename_component(INPUTBASE "${INPUT}" NAME_WE) +get_filename_component(OUTPUTBASE "${OUTPUT}" NAME_WE) +get_filename_component(INPUTDIR "${INPUT}" PATH) +get_filename_component(OUTPUTDIR "${OUTPUT}" PATH) + +if("${INPUTEXT}" STREQUAL ".out" AND "${OUTPUTEXT}" STREQUAL ".chk") + # Generate .chk from .out with awk (generic) + file(REMOVE "${OUTPUT}" "${OUTPUTDIR}/${OUTPUTBASE}.new") + execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/checksym.awk" + "${SRCDIR}/scripts/${INPUTBASE}.def" + "of=${OUTPUTDIR}/${OUTPUTBASE}.new" + "${INPUT}" + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate ${OUTPUTDIR}/${OUTPUTBASE}.new") + endif() + file(RENAME "${OUTPUTDIR}/${OUTPUTBASE}.new" "${OUTPUT}") +else() + message(FATAL_ERROR "Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}") +endif() diff --git a/src/third-party/libpng/scripts/genout.cmake.in b/src/third-party/libpng/scripts/genout.cmake.in new file mode 100644 index 000000000..01f12de2f --- /dev/null +++ b/src/third-party/libpng/scripts/genout.cmake.in @@ -0,0 +1,93 @@ +# genout.cmake.in +# Generate .out from .c with awk (generic), based upon the automake logic. + +# Copyright (C) 2016 Glenn Randers-Pehrson +# Written by Roger Leigh, 2016 + +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h + +# Variables substituted from CMakeLists.txt +set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@") +set(BINDIR "@CMAKE_CURRENT_BINARY_DIR@") + +set(AWK "@AWK@") +set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@") +set(CMAKE_C_FLAGS @CMAKE_C_FLAGS@) +set(INCDIR "@CMAKE_CURRENT_BINARY_DIR@") +set(PNG_PREFIX "@PNG_PREFIX@") +set(PNGLIB_MAJOR "@PNGLIB_MAJOR@") +set(PNGLIB_MINOR "@PNGLIB_MINOR@") +set(PNGLIB_VERSION "@PNGLIB_VERSION@") +set(ZLIBINCDIR "@ZLIB_INCLUDE_DIR@") + +set(PLATFORM_C_FLAGS) +if(APPLE) + set(CMAKE_OSX_ARCHITECTURES "@CMAKE_OSX_ARCHITECTURES@") + set(CMAKE_OSX_SYSROOT "@CMAKE_OSX_SYSROOT@") + if(CMAKE_OSX_ARCHITECTURES) + set(PLATFORM_C_FLAGS ${PLATFORM_C_FLAGS} -arch ${CMAKE_OSX_ARCHITECTURES}) + endif() + if(CMAKE_OSX_SYSROOT) + set(PLATFORM_C_FLAGS ${PLATFORM_C_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT}) + endif() +endif() + +get_filename_component(INPUTEXT "${INPUT}" EXT) +get_filename_component(OUTPUTEXT "${OUTPUT}" EXT) +get_filename_component(INPUTBASE "${INPUT}" NAME_WE) +get_filename_component(OUTPUTBASE "${OUTPUT}" NAME_WE) +get_filename_component(INPUTDIR "${INPUT}" PATH) +get_filename_component(OUTPUTDIR "${OUTPUT}" PATH) + +if ("${INPUTEXT}" STREQUAL ".c" AND "${OUTPUTEXT}" STREQUAL ".out") + get_filename_component(GENDIR "${OUTPUT}" PATH) + file(MAKE_DIRECTORY "${GENDIR}") + + file(REMOVE "${OUTPUT}.tf1" "${OUTPUT}.tf2") + + set(INCLUDES "-I${INCDIR}") + if(ZLIBINCDIR) + foreach(dir ${ZLIBINCDIR}) + list(APPEND INCLUDES "-I${dir}") + endforeach() + endif() + + if(PNG_PREFIX) + set(PNG_PREFIX_DEF "-DPNG_PREFIX=${PNG_PREFIX}") + endif() + + execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E" + ${CMAKE_C_FLAGS} + ${PLATFORM_C_FLAGS} + "-I${SRCDIR}" + "-I${BINDIR}" + ${INCLUDES} + "-DPNGLIB_LIBNAME=PNG${PNGLIB_MAJOR}${PNGLIB_MINOR}_0" + "-DPNGLIB_VERSION=${PNGLIB_VERSION}" + "-DSYMBOL_PREFIX=${SYMBOL_PREFIX}" + "-DPNG_NO_USE_READ_MACROS" + "-DPNG_BUILDING_SYMBOL_TABLE" + ${PNG_PREFIX_DEF} + "${INPUT}" + OUTPUT_FILE "${OUTPUT}.tf1" + WORKING_DIRECTORY "${BINDIR}" + RESULT_VARIABLE CPP_FAIL) + if(CPP_FAIL) + message(FATAL_ERROR "Failed to generate ${OUTPUT}.tf1") + endif() + + execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/dfn.awk" + "out=${OUTPUT}.tf2" "${OUTPUT}.tf1" + WORKING_DIRECTORY "${BINDIR}" + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate ${OUTPUT}.tf2") + endif() + + file(REMOVE "${OUTPUT}.tf1") + file(RENAME "${OUTPUT}.tf2" "${OUTPUT}") +else() + message(FATAL_ERROR "Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}") +endif() diff --git a/src/third-party/libpng/scripts/gensrc.cmake.in b/src/third-party/libpng/scripts/gensrc.cmake.in new file mode 100644 index 000000000..f28a62266 --- /dev/null +++ b/src/third-party/libpng/scripts/gensrc.cmake.in @@ -0,0 +1,138 @@ +# gensrc.cmake.in +# Generate source files with awk, based upon the automake logic. + +# Copyright (C) 2016 Glenn Randers-Pehrson +# Written by Roger Leigh, 2016 + +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h + +# Variables substituted from CMakeLists.txt +set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@") +set(BINDIR "@CMAKE_CURRENT_BINARY_DIR@") + +set(AWK "@AWK@") +set(DFA_XTRA "@DFA_XTRA@") +set(PNG_PREFIX "@PNG_PREFIX@") +set(PNGLIB_VERSION "@PNGLIB_VERSION@") + +if("${OUTPUT}" STREQUAL "scripts/pnglibconf.c") + # Generate scripts/pnglibconf.c + + file(REMOVE "${BINDIR}/pnglibconf.tf6" "${BINDIR}/pnglibconf.tf7") + + execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "com ${PNGLIB_VERSION} STANDARD API DEFINITION" + COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk" + "out=pnglibconf.tf6" "logunsupported=1" "version=search" + "${SRCDIR}/pngconf.h" "-" + "${SRCDIR}/scripts/pnglibconf.dfa" + WORKING_DIRECTORY "${BINDIR}" + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate pnglibconf.tf6") + endif() + + execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk" + "out=pnglibconf.tf7" "pnglibconf.tf6" + WORKING_DIRECTORY "${BINDIR}" + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate pnglibconf.tf7") + endif() + + file(REMOVE "pnglibconf.tf6") + file(MAKE_DIRECTORY "${BINDIR}/scripts") + file(RENAME "pnglibconf.tf7" "${BINDIR}/scripts/pnglibconf.c") + +elseif ("${OUTPUT}" STREQUAL "pnglibconf.c") + # Generate pnglibconf.c + + file(REMOVE "${BINDIR}/pnglibconf.tf4" "${BINDIR}/pnglibconf.tf5") + + execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk" + out=pnglibconf.tf4 version=search + ${SRCDIR}/pngconf.h ${SRCDIR}/scripts/pnglibconf.dfa + ${SRCDIR}/pngusr.dfa ${DFA_XTRA} + WORKING_DIRECTORY "${BINDIR}" + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate pnglibconf.tf4") + endif() + + execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk" + out=pnglibconf.tf5 pnglibconf.tf4 + WORKING_DIRECTORY "${BINDIR}" + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate pnglibconf.tf5") + endif() + + file(REMOVE "pnglibconf.tf4") + file(MAKE_DIRECTORY "${BINDIR}/scripts") + file(RENAME "pnglibconf.tf5" "${BINDIR}/pnglibconf.c") + +elseif ("${OUTPUT}" STREQUAL "pnglibconf.h") + # Generate pnglibconf.h + + file(REMOVE "${BINDIR}/${OUTPUT}") + if(PNG_PREFIX) + file(REMOVE "pnglibconf.tf8") + + execute_process(COMMAND "${AWK}" "s==0 && NR>1{print prev} + s==0{prev=\$0} + s==1{print \"#define\", \$1, \"${PNG_PREFIX}\" \$1} + s==2{print \"#define ${PNG_PREFIX}png_\" \$1, \"PNG_\" \$1} + END{print prev}" s=0 pnglibconf.out s=1 "${BINDIR}/scripts/prefix.out" + s=2 "${SRCDIR}/scripts/macro.lst" + OUTPUT_FILE pnglibconf.tf8 + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate pnglibconf.tf8") + endif() + + file(RENAME "pnglibconf.tf8" "${BINDIR}/${OUTPUT}") + else() + execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${BINDIR}/pnglibconf.out" + "${BINDIR}/${OUTPUT}" + RESULT_VARIABLE COPY_FAIL) + if(COPY_FAIL) + message(FATAL_ERROR "Failed to create pnglibconf.h") + endif() + endif() + +elseif ("${OUTPUT}" STREQUAL "pngprefix.h") + # Generate pngprefix.h + + file(REMOVE "${BINDIR}/${OUTPUT}") + + if(PNG_PREFIX) + file(REMOVE "pngprefix.tf1") + + execute_process(COMMAND "${AWK}" + "{print \"#define\", \$1, \"${PNG_PREFIX}\" \$1}" + "${BINDIR}/scripts/intprefix.out" + OUTPUT_FILE "pngprefix.tf1" + RESULT_VARIABLE AWK_FAIL) + if(AWK_FAIL) + message(FATAL_ERROR "Failed to generate pngprefix.tf1") + endif() + + file(RENAME "pngprefix.tf1" "${BINDIR}/${OUTPUT}") + else() + file(WRITE "${BINDIR}/${OUTPUT}" "/* No libpng symbol prefix configured. */") + endif() + +elseif("${OUTPUT}" STREQUAL "scripts/pnglibconf.h.prebuilt") + # Generate scripts/pnglibconf.h.prebuilt (fails build) + + message(STATUS "Attempting to build scripts/pnglibconf.h.prebuilt") + message(STATUS "This is a machine generated file, but if you want to make") + message(STATUS "a new one simply build the 'genfiles' target, and copy") + message(STATUS "scripts/pnglibconf.out to scripts/pnglibconf.h.prebuilt") + message(STATUS "AND set PNG_ZLIB_VERNUM to 0 (you MUST do this)") + message(FATAL_ERROR "Stopping build") + +else() + message(FATAL_ERROR "Unsupported output: ${OUTPUT}") +endif() diff --git a/src/third-party/libpng/scripts/libpng-config-head.in b/src/third-party/libpng/scripts/libpng-config-head.in index d19010df4..64dd3987d 100644 --- a/src/third-party/libpng/scripts/libpng-config-head.in +++ b/src/third-party/libpng/scripts/libpng-config-head.in @@ -11,7 +11,7 @@ # Modeled after libxml-config. -version=1.6.17 +version=1.6.34 prefix="" libdir="" libs="" diff --git a/src/third-party/libpng/scripts/libpng.pc.in b/src/third-party/libpng/scripts/libpng.pc.in index ce61a3e98..33c65767b 100644 --- a/src/third-party/libpng/scripts/libpng.pc.in +++ b/src/third-party/libpng/scripts/libpng.pc.in @@ -5,6 +5,6 @@ includedir=@includedir@/libpng16 Name: libpng Description: Loads and saves PNG files -Version: 1.6.17 +Version: 1.6.34 Libs: -L${libdir} -lpng16 Cflags: -I${includedir} diff --git a/src/third-party/libpng/scripts/makefile.cegcc b/src/third-party/libpng/scripts/makefile.cegcc index cc56297cd..d85bed9ad 100644 --- a/src/third-party/libpng/scripts/makefile.cegcc +++ b/src/third-party/libpng/scripts/makefile.cegcc @@ -23,7 +23,7 @@ VERMAJ = 1 VERMIN = 6 -VERMIC = 17 +VERMIC = 34 VER = $(VERMAJ).$(VERMIN).$(VERMIC) NAME = libpng PACKAGE = $(NAME)-$(VER) diff --git a/src/third-party/libpng/scripts/makefile.linux b/src/third-party/libpng/scripts/makefile.linux index 86a397f4c..f61087ccf 100644 --- a/src/third-party/libpng/scripts/makefile.linux +++ b/src/third-party/libpng/scripts/makefile.linux @@ -10,7 +10,7 @@ # Library name: LIBNAME = libpng16 PNGMAJ = 16 -RELEASE = 17 +RELEASE = 34 # Shared library names: LIBSO=$(LIBNAME).so @@ -92,7 +92,7 @@ OBJSDLL = $(OBJS:.o=.pic.o) $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< .c.pic.o: - $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $*.c all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config diff --git a/src/third-party/libpng/scripts/makefile.linux-opt b/src/third-party/libpng/scripts/makefile.linux-opt new file mode 100644 index 000000000..017656c6e --- /dev/null +++ b/src/third-party/libpng/scripts/makefile.linux-opt @@ -0,0 +1,265 @@ +# makefile for libpng.a and libpng16.so on Linux ELF with gcc +# Copyright (C) 1998,1999,2002,2006,2008,2010-2014,2017 Greg Roelofs and +# Glenn Randers-Pehrson +# Copyright (C) 1996,1997 Andreas Dilger +# +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h + +# Library name: +LIBNAME = libpng16 +PNGMAJ = 16 +RELEASE = 34 + +# Shared library names: +LIBSO=$(LIBNAME).so +LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ) +LIBSOREL=$(LIBSOMAJ).$(RELEASE) +OLDSO=libpng.so + +# Utilities: +AR_RC=ar rc +CC=gcc +MKDIR_P=mkdir -p +LN_SF=ln -sf +RANLIB=ranlib +CP=cp +RM_F=/bin/rm -f + +# where "make install" puts libpng16.a, libpng16.so*, +# libpng16/png.h, libpng16/pngconf.h, and libpng16/pnglibconf.h +# Prefix must be a full pathname. +prefix=/usr/local +exec_prefix=$(prefix) + +# Where the zlib library and include files are located. +#ZLIBLIB=/usr/local/lib +#ZLIBINC=/usr/local/include +ZLIBLIB=../zlib +ZLIBINC=../zlib + +ALIGN= +# for i386: +#ALIGN=-malign-loops=2 -malign-functions=2 + +#WARNMORE=-Wwrite-strings -Wpointer-arith \ +# -Wmissing-declarations -Wtraditional -Wcast-align \ +# -Wstrict-prototypes -Wmissing-prototypes + +# for pgcc version 2.95.1, -O3 is buggy; don't use it. + +CPPFLAGS=-I$(ZLIBINC) +CPPFLAGS += -DPNG_ARM_NEON +CPPFLAGS += -DPNG_MIPS_MSA +CPPFLAGS += -DPNG_INTEL_SSE +CPPFLAGS += -DPNG_POWERPC_VSX +CPPFLAGS+=-ansi -pedantic -Wextra -Wall -Wshadow -Wno-sign-conversion +CPPFLAGS+=-W -Wall -Wconversion $(ALIGN) +# CPPFLAGS+=$(WARNMORE) +CFLAGS= -O3 -funroll-loops + +LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng16 -lz -lm +LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm + +INCPATH=$(prefix)/include +LIBPATH=$(exec_prefix)/lib +MANPATH=$(prefix)/man +BINPATH=$(exec_prefix)/bin + +# override DESTDIR= on the make install command line to easily support +# installing into a temporary location. Example: +# +# make install DESTDIR=/tmp/build/libpng +# +# If you're going to install into a temporary location +# via DESTDIR, $(DESTDIR)$(prefix) must already exist before +# you execute make install. +DESTDIR= + +DB=$(DESTDIR)$(BINPATH) +DI=$(DESTDIR)$(INCPATH) +DL=$(DESTDIR)$(LIBPATH) +DM=$(DESTDIR)$(MANPATH) + +# Pre-built configuration +# See scripts/pnglibconf.mak for more options +PNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt + +OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \ + pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \ + pngwtran.o pngmem.o pngerror.o pngpread.o \ + arm/arm_init.o arm/filter_neon_intrinsics.o \ + mips/mips_init.o mips/filter_msa_intrinsics.o \ + intel/intel_init.o intel/filter_sse2_intrinsics.o\ + powerpc/powerpc_init.o powerpc/filter_vsx_intrinsics.o + +OBJSDLL = $(OBJS:.o=.pic.o) + +.SUFFIXES: .c .o .pic.o + +.c.o: + $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< + +.c.pic.o: + $(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $*.c + +all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config + +pnglibconf.h: $(PNGLIBCONF_H_PREBUILT) + $(CP) $(PNGLIBCONF_H_PREBUILT) $@ + +libpng.a: $(OBJS) + $(AR_RC) $@ $(OBJS) + $(RANLIB) $@ + +libpng.pc: + cat scripts/libpng.pc.in | sed -e s!@prefix@!$(prefix)! \ + -e s!@exec_prefix@!$(exec_prefix)! \ + -e s!@libdir@!$(LIBPATH)! \ + -e s!@includedir@!$(INCPATH)! \ + -e s!-lpng16!-lpng16\ -lz\ -lm! > libpng.pc + +libpng-config: + ( cat scripts/libpng-config-head.in; \ + echo prefix=\"$(prefix)\"; \ + echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \ + echo L_opts=\"-L$(LIBPATH)\"; \ + echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \ + echo libs=\"-lpng16 -lz -lm\"; \ + cat scripts/libpng-config-body.in ) > libpng-config + chmod +x libpng-config + +$(LIBSO): $(LIBSOMAJ) + $(LN_SF) $(LIBSOMAJ) $(LIBSO) + +$(LIBSOMAJ): $(OBJSDLL) + $(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSOMAJ) $(OBJSDLL) + +pngtest: pngtest.o $(LIBSO) + $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS) + +pngtest-static: pngtest.o libpng.a + $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A) + +test: pngtest pngtest-static + @echo "" + @echo " Running pngtest dynamically linked with $(LIBSO):" + @echo "" + ./pngtest + @echo "" + @echo " Running pngtest statically linked with libpng.a:" + @echo "" + ./pngtest-static + +install-headers: png.h pngconf.h pnglibconf.h + -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi + -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR_P) $(DI)/$(LIBNAME); fi + cp png.h pngconf.h pnglibconf.h $(DI)/$(LIBNAME) + chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h $(DI)/$(LIBNAME)/pnglibconf.h + -@$(RM_F) $(DI)/png.h $(DI)/pngconf.h $(DI)/pnglibconf.h + -@$(RM_F) $(DI)/libpng + (cd $(DI); $(LN_SF) $(LIBNAME) libpng; $(LN_SF) $(LIBNAME)/* .) + +install-static: install-headers libpng.a + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + cp libpng.a $(DL)/$(LIBNAME).a + chmod 644 $(DL)/$(LIBNAME).a + -@$(RM_F) $(DL)/libpng.a + (cd $(DL); $(LN_SF) $(LIBNAME).a libpng.a) + +install-shared: install-headers $(LIBSOMAJ) libpng.pc + -@if [ ! -d $(DL) ]; then $(MKDIR_P) $(DL); fi + -@$(RM_F) $(DL)/$(LIBSO) + -@$(RM_F) $(DL)/$(LIBSOREL) + -@$(RM_F) $(DL)/$(OLDSO) + cp $(LIBSOMAJ) $(DL)/$(LIBSOREL) + chmod 755 $(DL)/$(LIBSOREL) + (cd $(DL); \ + $(LN_SF) $(LIBSOREL) $(LIBSO); \ + $(LN_SF) $(LIBSO) $(OLDSO)) + + -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi + -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc + -@$(RM_F) $(DL)/pkgconfig/libpng.pc + cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc + chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc + (cd $(DL)/pkgconfig; $(LN_SF) $(LIBNAME).pc libpng.pc) + +install-man: libpng.3 libpngpf.3 png.5 + -@if [ ! -d $(DM) ]; then $(MKDIR_P) $(DM); fi + -@if [ ! -d $(DM)/man3 ]; then $(MKDIR_P) $(DM)/man3; fi + -@$(RM_F) $(DM)/man3/libpng.3 + -@$(RM_F) $(DM)/man3/libpngpf.3 + cp libpng.3 $(DM)/man3 + cp libpngpf.3 $(DM)/man3 + -@if [ ! -d $(DM)/man5 ]; then $(MKDIR_P) $(DM)/man5; fi + -@$(RM_F) $(DM)/man5/png.5 + cp png.5 $(DM)/man5 + +install-config: libpng-config + -@if [ ! -d $(DB) ]; then $(MKDIR_P) $(DB); fi + -@$(RM_F) $(DB)/libpng-config + -@$(RM_F) $(DB)/$(LIBNAME)-config + cp libpng-config $(DB)/$(LIBNAME)-config + chmod 755 $(DB)/$(LIBNAME)-config + (cd $(DB); $(LN_SF) $(LIBNAME)-config libpng-config) + +install: install-static install-shared install-man install-config + +# If you installed in $(DESTDIR), test-installed won't work until you +# move the library to its final location. Use test-dd to test it +# before then. + +test-dd: + echo + echo Testing installed dynamic shared library in $(DL). + $(CC) -I$(DI) $(CPPFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(DL) -L$(ZLIBLIB) -Wl, -rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtestd pngtest.png + +test-installed: + $(CC) $(CPPFLAGS) \ + `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \ + -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \ + -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` + ./pngtesti pngtest.png + +clean: + $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \ + $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \ + libpng.pc pnglibconf.h + +DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO +writelock: + chmod a-w *.[ch35] $(DOCS) scripts/* + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +png.o png.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngerror.o pngerror.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngrio.o pngrio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngwio.o pngwio.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngmem.o pngmem.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngset.o pngset.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngget.o pngget.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngread.o pngread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngrtran.o pngrtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngrutil.o pngrutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngtrans.o pngtrans.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +pngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h +arm/arm_init.o arm/arm_init.o: pngpriv.h +arm/filter_neon_intrinsics.o arm/filter_neon_intrinsics.pic.o: pngpriv.h +mips/mips_init.o mips/mips_init.pic.o: pngpriv.h +mips/filter_msa_intrinsics.o mips/filter_msa_intrinsics.pic.: pngpriv.h +intel/intel_init.o intel/intel_init.pic.: pngpriv.h +intel/filter_sse2_intrinsics.o intel/filter_sse2_intrinsics.pic.: pngpriv.h +powerpc/powerpc_init.o powerpc/powerpc_init.pic.: pngpriv.h +powerpc/filter_vsx_intrinsics.o powerpc/filter_vsx_intrinsics.pic.: pngpriv.h + +pngtest.o: png.h pngconf.h pnglibconf.h diff --git a/src/third-party/libpng/scripts/makefile.msys b/src/third-party/libpng/scripts/makefile.msys index 30595a083..33b7721d4 100644 --- a/src/third-party/libpng/scripts/makefile.msys +++ b/src/third-party/libpng/scripts/makefile.msys @@ -18,7 +18,7 @@ exec_prefix=$(prefix) # Library name: LIBNAME = libpng16 PNGMAJ = 16 -RELEASE = 17 +RELEASE = 34 # Shared library names: LIBSO=$(LIBNAME).dll diff --git a/src/third-party/libpng/scripts/makefile.ne12bsd b/src/third-party/libpng/scripts/makefile.ne12bsd index d5be81cb7..bc8dd8ba4 100644 --- a/src/third-party/libpng/scripts/makefile.ne12bsd +++ b/src/third-party/libpng/scripts/makefile.ne12bsd @@ -17,7 +17,7 @@ INCSDIR=${LOCALBASE}/include/libpng16 LIB= png16 SHLIB_MAJOR= 0 -SHLIB_MINOR= 1.6.17 +SHLIB_MINOR= 1.6.34 SRCS= png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \ pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \ pngwtran.c pngmem.c pngerror.c pngpread.c diff --git a/src/third-party/libpng/scripts/makefile.netbsd b/src/third-party/libpng/scripts/makefile.netbsd index 58c48844d..ab1cedda7 100644 --- a/src/third-party/libpng/scripts/makefile.netbsd +++ b/src/third-party/libpng/scripts/makefile.netbsd @@ -17,7 +17,7 @@ INCSDIR=${LOCALBASE}/include LIB= png SHLIB_MAJOR= 16 -SHLIB_MINOR= 1.6.17 +SHLIB_MINOR= 1.6.34 SRCS= png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \ pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \ pngwtran.c pngmem.c pngerror.c pngpread.c diff --git a/src/third-party/libpng/scripts/makefile.openbsd b/src/third-party/libpng/scripts/makefile.openbsd index 0ef62a4e4..b32ea61a2 100644 --- a/src/third-party/libpng/scripts/makefile.openbsd +++ b/src/third-party/libpng/scripts/makefile.openbsd @@ -11,7 +11,7 @@ LIBDIR= ${PREFIX}/lib MANDIR= ${PREFIX}/man/cat SHLIB_MAJOR= 16 -SHLIB_MINOR= 1.6.17 +SHLIB_MINOR= 1.6.34 LIB= png SRCS= png.c pngerror.c pngget.c pngmem.c pngpread.c \ diff --git a/src/third-party/libpng/scripts/makefile.sco b/src/third-party/libpng/scripts/makefile.sco index b9c7c402b..67d84aaac 100644 --- a/src/third-party/libpng/scripts/makefile.sco +++ b/src/third-party/libpng/scripts/makefile.sco @@ -1,5 +1,5 @@ # makefile for SCO OSr5 ELF and Unixware 7 with Native cc -# Contributed by Mike Hopkirk (hops@sco.com) modified from Makefile.lnx +# Contributed by Mike Hopkirk (hops at sco.com) modified from Makefile.lnx # force ELF build dynamic linking, SONAME setting in lib and RPATH in app # Copyright (C) 2002, 2006, 2010-2014 Glenn Randers-Pehrson # Copyright (C) 1998 Greg Roelofs diff --git a/src/third-party/libpng/scripts/makefile.solaris-x86 b/src/third-party/libpng/scripts/makefile.solaris-x86 index b6d24375d..2ee3c14a5 100644 --- a/src/third-party/libpng/scripts/makefile.solaris-x86 +++ b/src/third-party/libpng/scripts/makefile.solaris-x86 @@ -83,7 +83,7 @@ OBJSDLL = $(OBJS:.o=.pic.o) $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< .c.pic.o: - $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c + $(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $*.c all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config diff --git a/src/third-party/libpng/scripts/pnglibconf.dfa b/src/third-party/libpng/scripts/pnglibconf.dfa index e9a82f303..52c0c742e 100644 --- a/src/third-party/libpng/scripts/pnglibconf.dfa +++ b/src/third-party/libpng/scripts/pnglibconf.dfa @@ -8,7 +8,7 @@ com pnglibconf.h - library build configuration com version com -com Copyright (c) 1998-2014 Glenn Randers-Pehrson +com Copyright (c) 1998-2017 Glenn Randers-Pehrson com com This code is released under the libpng license. com For conditions of distribution and use, see the disclaimer @@ -222,13 +222,40 @@ option SET_OPTION disabled # with png_set_option # ARM_NEON_CHECK: (PNG_ARM_NEON == 1) compile a run-time check to see if Neon # extensions are supported. This is poorly supported and -# deprectated - use the png_set_option API. +# deprecated - use the png_set_option API. setting ARM_NEON_OPT option ARM_NEON_API disabled requires ALIGNED_MEMORY enables SET_OPTION, sets ARM_NEON_OPT 1 option ARM_NEON_CHECK disabled requires ALIGNED_MEMORY, sets ARM_NEON_OPT 1 +# These options are specific to the PowerPC VSX hardware optimizations. +# +# POWERPC_VSX_OPT: unset: check at compile time (__PPC64__,__ALTIVEC__,__VSX__ +# must be defined by the compiler, typically as a result +# of specifying +# "-mvsx -maltivec" compiler flags) +# 0: disable (even if the CPU supports VSX.) +# 1: check at run time (via POWERPC_VSX_{API,CHECK}) +# 2: switch on unconditionally (inadvisable - instead pass +# -mvsx -maltivec to compiler options) +# When building libpng avoid using any setting other than '0'; '1' is +# set automatically when either 'API' or 'CHECK' are configured in, +# '2' should not be necessary as "-mvsx -maltivec" will achieve the same +# effect as well as applying VSX optimizations to the rest of the +# libpng code. +# POWERPC_VSX_API: (PNG_POWERPC_VSX == 1) allow the optimization to be switched on +# with png_set_option +# POWERPC_VSX_CHECK: (PNG_POWERPC_VSX == 1) compile a run-time check to see if VSX +# extensions are supported. This is supported not for all OSes +# (see contrib/powerpc/README) +setting POWERPC_VSX_OPT +option POWERPC_VSX_API disabled enables SET_OPTION, + sets POWERPC_VSX_OPT 1 +option POWERPC_VSX_CHECK disabled, + sets POWERPC_VSX_OPT 1 + + # These settings configure the default compression level (0-9) and 'strategy'; # strategy is as defined by the implementors of zlib. It describes the input # data and modifies the zlib parameters in an attempt to optimize the balance @@ -249,6 +276,17 @@ setting Z_DEFAULT_STRATEGY default @Z_FILTERED setting Z_DEFAULT_NOFILTER_STRATEGY default @Z_DEFAULT_STRATEGY setting ZLIB_VERNUM default @ZLIB_VERNUM +# Linkage of: +# +# API: libpng API functions +# CALLBACK: internal non-file-local callbacks +# FUNCTION: internal non-file-local functions +# DATA: internal non-file-local (const) data +setting LINKAGE_API default extern +setting LINKAGE_CALLBACK default extern +setting LINKAGE_FUNCTION default extern +setting LINKAGE_DATA default extern + setting TEXT_Z_DEFAULT_COMPRESSION default @Z_DEFAULT_COMPRESSION setting TEXT_Z_DEFAULT_STRATEGY default @Z_DEFAULT_STRATEGY @@ -263,12 +301,12 @@ setting DEFAULT_READ_MACROS default 1 option READ_INT_FUNCTIONS requires READ -# The same for write, but these can only be switched off if -# no writing is required at all - hence the use of an 'enables' -# not a 'requires' below: +# The same for write but these can only be switched off if no writing +# is required at all - hence the use of a 'disabled', not a 'requires'. +# If these are needed, they are enabled in the 'WRITE options' section +# below. option WRITE_INT_FUNCTIONS disabled -option WRITE enables WRITE_INT_FUNCTIONS # Error controls # @@ -479,7 +517,7 @@ option BUILD_GRAYSCALE_PALETTE # WRITE options -option WRITE +option WRITE enables WRITE_INT_FUNCTIONS # Disabling WRITE_16BIT prevents 16-bit PNG files from being # generated. @@ -504,9 +542,7 @@ option WRITE_USER_TRANSFORM requires WRITE_TRANSFORMS option WRITE_INTERLACING requires WRITE -# The following depends, internally, on WEIGHT_SHIFT and COST_SHIFT -# where are set below. - +# Deprecated, will be removed. option WRITE_WEIGHTED_FILTER requires WRITE option WRITE_FLUSH requires WRITE @@ -543,6 +579,7 @@ option WRITE_ANCILLARY_CHUNKS requires WRITE # These options disable *all* the text chunks if turned off +option TEXT disabled option READ_TEXT requires READ_ANCILLARY_CHUNKS enables TEXT option WRITE_TEXT requires WRITE_ANCILLARY_CHUNKS enables TEXT @@ -657,11 +694,6 @@ setting MAX_GAMMA_8 default 11 setting GAMMA_THRESHOLD_FIXED default 5000 -# Scaling factor for filter heuristic weighting calculations - -setting WEIGHT_SHIFT default 8 -setting COST_SHIFT default 3 - # Precision to use when converting a floating point value to a PNG # extension format string in an sCAL chunk (only relevant if the # floating point API is enabled) @@ -709,6 +741,7 @@ setting IDAT_READ_SIZE default PNG_ZBUF_SIZE # Ancillary chunks chunk bKGD chunk cHRM enables COLORSPACE +chunk eXIf chunk gAMA enables GAMMA chunk hIST chunk iCCP enables COLORSPACE, GAMMA @@ -869,9 +902,12 @@ option SIMPLIFIED_READ_BGR enables FORMAT_BGR, # Write: option SIMPLIFIED_WRITE, - requires WRITE STDIO, SETJMP, WRITE_SWAP, WRITE_PACK, + requires WRITE, SETJMP, WRITE_SWAP, WRITE_PACK, WRITE_tRNS, WRITE_gAMA, WRITE_sRGB, WRITE_cHRM +# 1.6.22: allow simplified write without stdio support: +option SIMPLIFIED_WRITE_STDIO requires SIMPLIFIED_WRITE STDIO + option SIMPLIFIED_WRITE_AFIRST enables FORMAT_AFIRST, requires SIMPLIFIED_WRITE WRITE_SWAP_ALPHA diff --git a/src/third-party/libpng/scripts/pnglibconf.h.prebuilt b/src/third-party/libpng/scripts/pnglibconf.h.prebuilt index b4ec3c31e..53b5e442c 100644 --- a/src/third-party/libpng/scripts/pnglibconf.h.prebuilt +++ b/src/third-party/libpng/scripts/pnglibconf.h.prebuilt @@ -1,10 +1,10 @@ -/* libpng 1.6.17 STANDARD API DEFINITION */ +/* libpng 1.6.34 STANDARD API DEFINITION */ /* pnglibconf.h - library build configuration */ -/* Libpng version 1.6.17 - March 26, 2015 */ +/* Libpng version 1.6.34 - September 29, 2017 */ -/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ +/* Copyright (c) 1998-2017 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ /* For conditions of distribution and use, see the disclaimer */ @@ -20,6 +20,8 @@ #define PNG_ALIGNED_MEMORY_SUPPORTED /*#undef PNG_ARM_NEON_API_SUPPORTED*/ /*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ +/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ +/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/ #define PNG_BENIGN_ERRORS_SUPPORTED #define PNG_BENIGN_READ_ERRORS_SUPPORTED /*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ @@ -82,6 +84,7 @@ #define PNG_READ_USER_TRANSFORM_SUPPORTED #define PNG_READ_bKGD_SUPPORTED #define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_eXIf_SUPPORTED #define PNG_READ_gAMA_SUPPORTED #define PNG_READ_hIST_SUPPORTED #define PNG_READ_iCCP_SUPPORTED @@ -101,8 +104,6 @@ #define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SEQUENTIAL_READ_SUPPORTED #define PNG_SETJMP_SUPPORTED -#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED -#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED #define PNG_SET_OPTION_SUPPORTED #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SET_USER_LIMITS_SUPPORTED @@ -111,6 +112,7 @@ #define PNG_SIMPLIFIED_READ_SUPPORTED #define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED #define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED #define PNG_SIMPLIFIED_WRITE_SUPPORTED #define PNG_STDIO_SUPPORTED #define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED @@ -152,6 +154,7 @@ #define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #define PNG_WRITE_bKGD_SUPPORTED #define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_eXIf_SUPPORTED #define PNG_WRITE_gAMA_SUPPORTED #define PNG_WRITE_hIST_SUPPORTED #define PNG_WRITE_iCCP_SUPPORTED @@ -169,6 +172,7 @@ #define PNG_WRITE_zTXt_SUPPORTED #define PNG_bKGD_SUPPORTED #define PNG_cHRM_SUPPORTED +#define PNG_eXIf_SUPPORTED #define PNG_gAMA_SUPPORTED #define PNG_hIST_SUPPORTED #define PNG_iCCP_SUPPORTED @@ -187,11 +191,14 @@ /* end of options */ /* settings */ #define PNG_API_RULE 0 -#define PNG_COST_SHIFT 3 #define PNG_DEFAULT_READ_MACROS 1 #define PNG_GAMMA_THRESHOLD_FIXED 5000 #define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE #define PNG_INFLATE_BUF_SIZE 1024 +#define PNG_LINKAGE_API extern +#define PNG_LINKAGE_CALLBACK extern +#define PNG_LINKAGE_DATA extern +#define PNG_LINKAGE_FUNCTION extern #define PNG_MAX_GAMMA_8 11 #define PNG_QUANTIZE_BLUE_BITS 5 #define PNG_QUANTIZE_GREEN_BITS 5 @@ -202,7 +209,6 @@ #define PNG_USER_CHUNK_MALLOC_MAX 8000000 #define PNG_USER_HEIGHT_MAX 1000000 #define PNG_USER_WIDTH_MAX 1000000 -#define PNG_WEIGHT_SHIFT 8 #define PNG_ZBUF_SIZE 8192 #define PNG_ZLIB_VERNUM 0 /* unknown */ #define PNG_Z_DEFAULT_COMPRESSION (-1) diff --git a/src/third-party/libpng/scripts/symbols.def b/src/third-party/libpng/scripts/symbols.def index 5bdcef20f..519019014 100644 --- a/src/third-party/libpng/scripts/symbols.def +++ b/src/third-party/libpng/scripts/symbols.def @@ -1,4 +1,4 @@ -;Version 1.6.17 +;Version 1.6.34 ;-------------------------------------------------------------- ; LIBPNG symbol list as a Win32 DEF file ; Contains all the symbols that can be exported from libpng @@ -249,3 +249,8 @@ EXPORTS png_set_check_for_invalid_index @242 png_get_palette_max @243 png_set_option @244 + png_image_write_to_memory @245 + png_get_eXIf @246 + png_set_eXIf @247 + png_get_eXIf_1 @248 + png_set_eXIf_1 @249 diff --git a/src/third-party/libpng/scripts/test.cmake.in b/src/third-party/libpng/scripts/test.cmake.in new file mode 100644 index 000000000..fa6a889bb --- /dev/null +++ b/src/third-party/libpng/scripts/test.cmake.in @@ -0,0 +1,31 @@ +# test.cmake.in + +# Copyright (C) 2016 Glenn Randers-Pehrson +# Written by Roger Leigh, 2016 + +# This code is released under the libpng license. +# For conditions of distribution and use, see the disclaimer +# and license in png.h + +set(TEST_OPTIONS "@TEST_OPTIONS@") +set(TEST_FILES "@TEST_FILES@") + +foreach(file ${TEST_FILES}) + file(TO_NATIVE_PATH "${file}" native_file) + list(APPEND NATIVE_TEST_FILES "${native_file}") +endforeach() + +# Add the directory containing libpng to the PATH (Windows only) +if(WIN32) + get_filename_component(LIBPNG_DIR "${LIBPNG}" PATH) + file(TO_NATIVE_PATH "${LIBPNG_DIR}" LIBPNG_DIR) + set(ENV{PATH} "${LIBPNG_DIR};$ENV{PATH}") +endif() + +execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "Running ${TEST_COMMAND}" ${TEST_OPTIONS} ${NATIVE_TEST_FILES}) + +execute_process(COMMAND "${TEST_COMMAND}" ${TEST_OPTIONS} ${NATIVE_TEST_FILES} + RESULT_VARIABLE TEST_STATUS) +if(TEST_STATUS) + message(FATAL_ERROR "Returned failed status ${TEST_STATUS}!") +endif() diff --git a/src/third-party/libpng/tests/pngimage-full b/src/third-party/libpng/tests/pngimage-full index f5eb9895e..1198ed05c 100755 --- a/src/third-party/libpng/tests/pngimage-full +++ b/src/third-party/libpng/tests/pngimage-full @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngimage --exhaustive --log "${srcdir}/contrib/pngsuite/"*.png +exec ./pngimage --exhaustive --list-combos --log "${srcdir}/contrib/pngsuite/"*.png diff --git a/src/third-party/libpng/tests/pngimage-quick b/src/third-party/libpng/tests/pngimage-quick index 2d4b5db22..328dc27b5 100755 --- a/src/third-party/libpng/tests/pngimage-quick +++ b/src/third-party/libpng/tests/pngimage-quick @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngimage --log "${srcdir}/contrib/pngsuite/"*.png +exec ./pngimage --list-combos --log "${srcdir}/contrib/pngsuite/"*.png diff --git a/src/third-party/libpng/tests/pngstest b/src/third-party/libpng/tests/pngstest index f5cbdbcae..9d1b7764e 100755 --- a/src/third-party/libpng/tests/pngstest +++ b/src/third-party/libpng/tests/pngstest @@ -2,12 +2,53 @@ # # Usage: # -# tests/pngstest pattern +# tests/pngstest gamma alpha # -# Runs pngstest on all the contrib/pngsuite/[^x]*${pattern}.png files -# NOTE: pattern is used to name the temporary files pngstest generates +# Run ./pngstest on the PNG files in $srcdir/contrib/testpngs which have the +# given gamma and opacity: # -pattern="$1" +# gamma: one of; linear, 1.8, sRGB, none. +# alpha: one of; opaque, tRNS, alpha, none. 'none' is equivalent to !alpha +# +# NOTE: the temporary files pngstest generates have the base name gamma-alpha to +# avoid issues with make -j +# +gamma="$1" shift -exec ./pngstest --strict --tmpfile "${pattern}" --log ${1+"$@"}\ - "${srcdir}/contrib/pngsuite/"[a-wyz]*${pattern}".png" +alpha="$1" +shift +args= +LC_ALL="C" # fix glob sort order to ASCII: +for f in "${srcdir}/contrib/testpngs/"*.png +do + g= + case "$f" in + *-linear[.-]*) + test "$gamma" = "linear" && g="$f";; + + *-sRGB[.-]*) + test "$gamma" = "sRGB" && g="$f";; + + *-1.8[.-]*) + test "$gamma" = "1.8" && g="$f";; + + *) + test "$gamma" = "none" && g="$f";; + esac + + case "$g" in + "") + :;; + + *-alpha[-.]*) + test "$alpha" = "alpha" && args="$args $g";; + + *-tRNS[-.]*) + test "$alpha" = "tRNS" -o "$alpha" = "none" && args="$args $g";; + + *) + test "$alpha" = "opaque" -o "$alpha" = "none" && args="$args $g";; + esac +done +# This only works if the arguments don't contain spaces; they don't. +exec ./pngstest --tmpfile "${gamma}-${alpha}-" --log ${1+"$@"} $args diff --git a/src/third-party/libpng/tests/pngstest-0g01 b/src/third-party/libpng/tests/pngstest-0g01 deleted file mode 100755 index 4a495ccb8..000000000 --- a/src/third-party/libpng/tests/pngstest-0g01 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 0g01 diff --git a/src/third-party/libpng/tests/pngstest-0g02 b/src/third-party/libpng/tests/pngstest-0g02 deleted file mode 100755 index 1a607c8e1..000000000 --- a/src/third-party/libpng/tests/pngstest-0g02 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 0g02 diff --git a/src/third-party/libpng/tests/pngstest-0g04 b/src/third-party/libpng/tests/pngstest-0g04 deleted file mode 100755 index 595ba01e3..000000000 --- a/src/third-party/libpng/tests/pngstest-0g04 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 0g04 diff --git a/src/third-party/libpng/tests/pngstest-0g08 b/src/third-party/libpng/tests/pngstest-0g08 deleted file mode 100755 index 21a8b4bb4..000000000 --- a/src/third-party/libpng/tests/pngstest-0g08 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 0g08 diff --git a/src/third-party/libpng/tests/pngstest-0g16 b/src/third-party/libpng/tests/pngstest-0g16 deleted file mode 100755 index 0104c37bd..000000000 --- a/src/third-party/libpng/tests/pngstest-0g16 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 0g16 diff --git a/src/third-party/libpng/tests/pngstest-1.8 b/src/third-party/libpng/tests/pngstest-1.8 new file mode 100755 index 000000000..b2ec21bf6 --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-1.8 @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" 1.8 none diff --git a/src/third-party/libpng/tests/pngstest-1.8-alpha b/src/third-party/libpng/tests/pngstest-1.8-alpha new file mode 100755 index 000000000..d00596d55 --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-1.8-alpha @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" 1.8 alpha diff --git a/src/third-party/libpng/tests/pngstest-2c08 b/src/third-party/libpng/tests/pngstest-2c08 deleted file mode 100755 index 9e0de6f1e..000000000 --- a/src/third-party/libpng/tests/pngstest-2c08 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 2c08 diff --git a/src/third-party/libpng/tests/pngstest-2c16 b/src/third-party/libpng/tests/pngstest-2c16 deleted file mode 100755 index c1b88b04e..000000000 --- a/src/third-party/libpng/tests/pngstest-2c16 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 2c16 diff --git a/src/third-party/libpng/tests/pngstest-3p01 b/src/third-party/libpng/tests/pngstest-3p01 deleted file mode 100755 index 6aeb8d06c..000000000 --- a/src/third-party/libpng/tests/pngstest-3p01 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 3p01 diff --git a/src/third-party/libpng/tests/pngstest-3p02 b/src/third-party/libpng/tests/pngstest-3p02 deleted file mode 100755 index 770a75c0b..000000000 --- a/src/third-party/libpng/tests/pngstest-3p02 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 3p02 diff --git a/src/third-party/libpng/tests/pngstest-3p04 b/src/third-party/libpng/tests/pngstest-3p04 deleted file mode 100755 index 957d6ae34..000000000 --- a/src/third-party/libpng/tests/pngstest-3p04 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 3p04 diff --git a/src/third-party/libpng/tests/pngstest-3p08 b/src/third-party/libpng/tests/pngstest-3p08 deleted file mode 100755 index d0947afde..000000000 --- a/src/third-party/libpng/tests/pngstest-3p08 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 3p08 diff --git a/src/third-party/libpng/tests/pngstest-4a08 b/src/third-party/libpng/tests/pngstest-4a08 deleted file mode 100755 index 2fab57f01..000000000 --- a/src/third-party/libpng/tests/pngstest-4a08 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 4a08 diff --git a/src/third-party/libpng/tests/pngstest-4a16 b/src/third-party/libpng/tests/pngstest-4a16 deleted file mode 100755 index e4ad5aa9a..000000000 --- a/src/third-party/libpng/tests/pngstest-4a16 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 4a16 diff --git a/src/third-party/libpng/tests/pngstest-6a08 b/src/third-party/libpng/tests/pngstest-6a08 deleted file mode 100755 index aa6c03c3d..000000000 --- a/src/third-party/libpng/tests/pngstest-6a08 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 6a08 diff --git a/src/third-party/libpng/tests/pngstest-6a16 b/src/third-party/libpng/tests/pngstest-6a16 deleted file mode 100755 index 545b1b394..000000000 --- a/src/third-party/libpng/tests/pngstest-6a16 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec "${srcdir}/tests/pngstest" 6a16 diff --git a/src/third-party/libpng/tests/pngstest-error b/src/third-party/libpng/tests/pngstest-error deleted file mode 100755 index ebf3a7b59..000000000 --- a/src/third-party/libpng/tests/pngstest-error +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -code=77 # skipped -for t in "${srcdir}/contrib/pngsuite/"x*".png" -do - if test "$t" != "${srcdir}/contrib/pngsuite/x*.png" - then - # not skipped, test it - if ./pngstest --strict --tmpfile "error" --log "$@" "$t" - then - code=0 # oops, success: should not happen! - fi - fi -done -exit $code diff --git a/src/third-party/libpng/tests/pngstest-linear b/src/third-party/libpng/tests/pngstest-linear new file mode 100755 index 000000000..4a5b3fe8c --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-linear @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" linear none diff --git a/src/third-party/libpng/tests/pngstest-linear-alpha b/src/third-party/libpng/tests/pngstest-linear-alpha new file mode 100755 index 000000000..411421036 --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-linear-alpha @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" linear alpha diff --git a/src/third-party/libpng/tests/pngstest-none b/src/third-party/libpng/tests/pngstest-none new file mode 100755 index 000000000..09ad740b5 --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-none @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" none none diff --git a/src/third-party/libpng/tests/pngstest-none-alpha b/src/third-party/libpng/tests/pngstest-none-alpha new file mode 100755 index 000000000..af6083ff8 --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-none-alpha @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" none alpha diff --git a/src/third-party/libpng/tests/pngstest-sRGB b/src/third-party/libpng/tests/pngstest-sRGB new file mode 100755 index 000000000..d8460812c --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-sRGB @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" sRGB none diff --git a/src/third-party/libpng/tests/pngstest-sRGB-alpha b/src/third-party/libpng/tests/pngstest-sRGB-alpha new file mode 100755 index 000000000..f1e57d339 --- /dev/null +++ b/src/third-party/libpng/tests/pngstest-sRGB-alpha @@ -0,0 +1,2 @@ +#!/bin/sh +exec "${srcdir}/tests/pngstest" sRGB alpha diff --git a/src/third-party/libpng/tests/pngtest-badpngs b/src/third-party/libpng/tests/pngtest-badpngs new file mode 100755 index 000000000..77775232b --- /dev/null +++ b/src/third-party/libpng/tests/pngtest-badpngs @@ -0,0 +1,13 @@ +#!/bin/sh + +# various crashers +# using --relaxed because some come from fuzzers that don't maintain CRC's + +./pngtest --relaxed ${srcdir}/contrib/testpngs/crashers/badcrc.png +./pngtest --relaxed ${srcdir}/contrib/testpngs/crashers/badadler.png +./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/bad_iCCP.png +./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/empty_ancillary_chunks.png +./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/huge_*_chunk.png \ + ${srcdir}/contrib/testpngs/crashers/huge_*safe_to_copy.png + +exec ./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/huge_IDAT.png diff --git a/src/third-party/libpng/tests/pngunknown-IDAT b/src/third-party/libpng/tests/pngunknown-IDAT index 71d915a9c..8e7281aa8 100755 --- a/src/third-party/libpng/tests/pngunknown-IDAT +++ b/src/third-party/libpng/tests/pngunknown-IDAT @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngunknown default=discard IDAT=save "${srcdir}/pngtest.png" +exec ./pngunknown --strict default=discard IDAT=save "${srcdir}/pngtest.png" diff --git a/src/third-party/libpng/tests/pngunknown-discard b/src/third-party/libpng/tests/pngunknown-discard index f1f02d4c7..c96dab370 100755 --- a/src/third-party/libpng/tests/pngunknown-discard +++ b/src/third-party/libpng/tests/pngunknown-discard @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngunknown default=discard "${srcdir}/pngtest.png" +exec ./pngunknown --strict default=discard "${srcdir}/pngtest.png" diff --git a/src/third-party/libpng/tests/pngunknown-if-safe b/src/third-party/libpng/tests/pngunknown-if-safe index 7c52824f8..31a4954fb 100755 --- a/src/third-party/libpng/tests/pngunknown-if-safe +++ b/src/third-party/libpng/tests/pngunknown-if-safe @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngunknown default=if-safe "${srcdir}/pngtest.png" +exec ./pngunknown --strict default=if-safe "${srcdir}/pngtest.png" diff --git a/src/third-party/libpng/tests/pngunknown-sAPI b/src/third-party/libpng/tests/pngunknown-sAPI index e087ef25a..88a1f6be2 100755 --- a/src/third-party/libpng/tests/pngunknown-sAPI +++ b/src/third-party/libpng/tests/pngunknown-sAPI @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngunknown bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save "${srcdir}/pngtest.png" +exec ./pngunknown --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save eXIf=save "${srcdir}/pngtest.png" diff --git a/src/third-party/libpng/tests/pngunknown-sTER b/src/third-party/libpng/tests/pngunknown-sTER index 1b945dc34..59c5ecd54 100755 --- a/src/third-party/libpng/tests/pngunknown-sTER +++ b/src/third-party/libpng/tests/pngunknown-sTER @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngunknown sTER=if-safe "${srcdir}/pngtest.png" +exec ./pngunknown --strict sTER=if-safe "${srcdir}/pngtest.png" diff --git a/src/third-party/libpng/tests/pngunknown-save b/src/third-party/libpng/tests/pngunknown-save index ae849308c..21412c42a 100755 --- a/src/third-party/libpng/tests/pngunknown-save +++ b/src/third-party/libpng/tests/pngunknown-save @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngunknown default=save "${srcdir}/pngtest.png" +exec ./pngunknown --strict default=save "${srcdir}/pngtest.png" diff --git a/src/third-party/libpng/tests/pngunknown-vpAg b/src/third-party/libpng/tests/pngunknown-vpAg index 396c6e40d..04f07b69a 100755 --- a/src/third-party/libpng/tests/pngunknown-vpAg +++ b/src/third-party/libpng/tests/pngunknown-vpAg @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngunknown vpAg=if-safe "${srcdir}/pngtest.png" +exec ./pngunknown --strict vpAg=if-safe "${srcdir}/pngtest.png" diff --git a/src/third-party/libpng/tests/pngvalid-gamma-16-to-8 b/src/third-party/libpng/tests/pngvalid-gamma-16-to-8 index b32233829..074945d31 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-16-to-8 +++ b/src/third-party/libpng/tests/pngvalid-gamma-16-to-8 @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-16-to-8 +exec ./pngvalid --strict --gamma-16-to-8 diff --git a/src/third-party/libpng/tests/pngvalid-gamma-alpha-mode b/src/third-party/libpng/tests/pngvalid-gamma-alpha-mode index ed04fa511..b16e8abc4 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-alpha-mode +++ b/src/third-party/libpng/tests/pngvalid-gamma-alpha-mode @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-alpha-mode +exec ./pngvalid --strict --gamma-alpha-mode diff --git a/src/third-party/libpng/tests/pngvalid-gamma-background b/src/third-party/libpng/tests/pngvalid-gamma-background index 658e5fe4d..3dbf58d8a 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-background +++ b/src/third-party/libpng/tests/pngvalid-gamma-background @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-background +exec ./pngvalid --strict --gamma-background diff --git a/src/third-party/libpng/tests/pngvalid-gamma-expand16-alpha-mode b/src/third-party/libpng/tests/pngvalid-gamma-expand16-alpha-mode index bdda566a0..4fa10bde2 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-expand16-alpha-mode +++ b/src/third-party/libpng/tests/pngvalid-gamma-expand16-alpha-mode @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-alpha-mode --expand16 +exec ./pngvalid --strict --gamma-alpha-mode --expand16 diff --git a/src/third-party/libpng/tests/pngvalid-gamma-expand16-background b/src/third-party/libpng/tests/pngvalid-gamma-expand16-background index f993c21ae..ad9a91762 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-expand16-background +++ b/src/third-party/libpng/tests/pngvalid-gamma-expand16-background @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-background --expand16 +exec ./pngvalid --strict --gamma-background --expand16 diff --git a/src/third-party/libpng/tests/pngvalid-gamma-expand16-transform b/src/third-party/libpng/tests/pngvalid-gamma-expand16-transform index f462534e8..5fd1f280b 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-expand16-transform +++ b/src/third-party/libpng/tests/pngvalid-gamma-expand16-transform @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-transform --expand16 +exec ./pngvalid --strict --gamma-transform --expand16 diff --git a/src/third-party/libpng/tests/pngvalid-gamma-sbit b/src/third-party/libpng/tests/pngvalid-gamma-sbit index aa82fe04f..6ca08e9e3 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-sbit +++ b/src/third-party/libpng/tests/pngvalid-gamma-sbit @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-sbit +exec ./pngvalid --strict --gamma-sbit diff --git a/src/third-party/libpng/tests/pngvalid-gamma-threshold b/src/third-party/libpng/tests/pngvalid-gamma-threshold index 2cfca9146..3fe4edf77 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-threshold +++ b/src/third-party/libpng/tests/pngvalid-gamma-threshold @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-threshold +exec ./pngvalid --strict --gamma-threshold diff --git a/src/third-party/libpng/tests/pngvalid-gamma-transform b/src/third-party/libpng/tests/pngvalid-gamma-transform index a71ab4d5e..3fa62c688 100755 --- a/src/third-party/libpng/tests/pngvalid-gamma-transform +++ b/src/third-party/libpng/tests/pngvalid-gamma-transform @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --gamma-transform +exec ./pngvalid --strict --gamma-transform diff --git a/src/third-party/libpng/tests/pngvalid-progressive-interlace-size b/src/third-party/libpng/tests/pngvalid-progressive-interlace-size deleted file mode 100755 index a31b28355..000000000 --- a/src/third-party/libpng/tests/pngvalid-progressive-interlace-size +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec ./pngvalid --size --progressive-read diff --git a/src/third-party/libpng/tests/pngvalid-progressive-interlace-standard b/src/third-party/libpng/tests/pngvalid-progressive-interlace-standard index 59042eb17..a8cdf9e1a 100755 --- a/src/third-party/libpng/tests/pngvalid-progressive-interlace-standard +++ b/src/third-party/libpng/tests/pngvalid-progressive-interlace-standard @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --standard --progressive-read --interlace +exec ./pngvalid --strict --standard --progressive-read --interlace diff --git a/src/third-party/libpng/tests/pngvalid-progressive-interlace-transform b/src/third-party/libpng/tests/pngvalid-progressive-interlace-transform deleted file mode 100755 index edf9a8a79..000000000 --- a/src/third-party/libpng/tests/pngvalid-progressive-interlace-transform +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec ./pngvalid --transform diff --git a/src/third-party/libpng/tests/pngvalid-progressive-size b/src/third-party/libpng/tests/pngvalid-progressive-size new file mode 100755 index 000000000..868d6dcc3 --- /dev/null +++ b/src/third-party/libpng/tests/pngvalid-progressive-size @@ -0,0 +1,2 @@ +#!/bin/sh +exec ./pngvalid --strict --size --progressive-read diff --git a/src/third-party/libpng/tests/pngvalid-progressive-standard b/src/third-party/libpng/tests/pngvalid-progressive-standard index aa1b4b4db..bf7e5c1c2 100755 --- a/src/third-party/libpng/tests/pngvalid-progressive-standard +++ b/src/third-party/libpng/tests/pngvalid-progressive-standard @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --standard --progressive-read +exec ./pngvalid --strict --standard --progressive-read diff --git a/src/third-party/libpng/tests/pngvalid-standard b/src/third-party/libpng/tests/pngvalid-standard index aa1b4b4db..a89b88424 100755 --- a/src/third-party/libpng/tests/pngvalid-standard +++ b/src/third-party/libpng/tests/pngvalid-standard @@ -1,2 +1,2 @@ #!/bin/sh -exec ./pngvalid --standard --progressive-read +exec ./pngvalid --strict --standard diff --git a/src/third-party/libpng/tests/pngvalid-transform b/src/third-party/libpng/tests/pngvalid-transform new file mode 100755 index 000000000..c7536aeb8 --- /dev/null +++ b/src/third-party/libpng/tests/pngvalid-transform @@ -0,0 +1,2 @@ +#!/bin/sh +exec ./pngvalid --strict --transform From cc2362aea9c63bf914972bbeda8b2bae114da4f9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 15 Jul 2018 08:38:39 -0700 Subject: [PATCH 02/10] Switch: Initial port work --- CMakeLists.txt | 21 +++++++--- include/mgba-util/socket.h | 9 ++++- src/platform/switch/CMakeLists.txt | 24 +++++++++++ src/platform/switch/CMakeToolchain.txt | 56 ++++++++++++++++++++++++++ src/platform/switch/memory.c | 15 +++++++ src/platform/test/perf-main.c | 18 ++++++++- 6 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 src/platform/switch/CMakeLists.txt create mode 100644 src/platform/switch/CMakeToolchain.txt create mode 100644 src/platform/switch/memory.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 851d9ffc7..bf824be50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,9 @@ project(mGBA) set(BINARY_NAME mgba CACHE INTERNAL "Name of output binaries") if(NOT MSVC) set(GCC_STD "c99") - if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.3") + if(SWITCH) + set(GCC_STD "gnu11") + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.3") set(GCC_STD "gnu99") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -std=${GCC_STD}") @@ -65,7 +67,7 @@ file(GLOB GBA_CHEATS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/cheats/*.c) file(GLOB GBA_RR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/rr/*.c) file(GLOB CORE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/*.c) file(GLOB CORE_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/test/*.c) -file(GLOB UTIL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/*.[cSs]) +file(GLOB UTIL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/*.c) file(GLOB UTIL_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/test/*.c) file(GLOB GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/gui/*.c ${CMAKE_CURRENT_SOURCE_DIR}/src/feature/gui/*.c) file(GLOB GBA_RENDERER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/renderers/*.c) @@ -283,7 +285,7 @@ if(PSP2 OR WII) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format") endif() -if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII) +if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII OR DEFINED SWITCH) set(IS_EMBEDDED ON) set(USE_DEBUGGERS OFF) set(USE_SQLITE3 OFF) @@ -331,7 +333,7 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") check_function_exists(uselocale HAVE_USELOCALE) check_function_exists(setlocale HAVE_SETLOCALE) else() - if(DEFINED 3DS OR DEFINED WII) + if(DEFINED 3DS OR DEFINED WII OR DEFINED SWITCH) set(CMAKE_REQUIRED_FLAGS -Wl,--require-defined,snprintf_l) check_function_exists(snprintf_l HAVE_SNPRINTF_L) set(CMAKE_REQUIRED_FLAGS -Wl,--require-defined,strtof_l) @@ -583,10 +585,13 @@ if(WANT_PNG AND USE_ZLIB AND NOT USE_PNG) set(PNG_SHARED OFF CACHE BOOL "" FORCE) set(PNG_TESTS OFF CACHE BOOL "" FORCE) set(SKIP_INSTALL_ALL ON) + if (SWITCH) + set(PNG_ARM_NEON "off" CACHE STRING "" FORCE) + endif() add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng libpng) - set_property(TARGET png16_static PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/libpng;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng;${ZLIB_INCLUDE_DIRS}) + set_property(TARGET png_static PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/libpng;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng;${ZLIB_INCLUDE_DIRS}) set(PNG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng ${CMAKE_CURRENT_BINARY_DIR}/libpng) - list(APPEND DEPENDENCY_LIB png16_static) + list(APPEND DEPENDENCY_LIB png_static) set(USE_PNG ON) endif() @@ -775,6 +780,10 @@ if(DEFINED PSP2) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/psp2 ${CMAKE_CURRENT_BINARY_DIR}/psp2) endif() +if(DEFINED SWITCH) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/switch ${CMAKE_CURRENT_BINARY_DIR}/switch) +endif() + # Binaries list(APPEND CORE_SRC ${UTIL_SRC} diff --git a/include/mgba-util/socket.h b/include/mgba-util/socket.h index ad00696c0..a2cece335 100644 --- a/include/mgba-util/socket.h +++ b/include/mgba-util/socket.h @@ -55,6 +55,9 @@ struct Address { extern u32* SOCUBuffer; #endif +#ifdef SWITCH +#include +#endif static inline void SocketSubsystemInit() { #ifdef _WIN32 @@ -65,6 +68,8 @@ static inline void SocketSubsystemInit() { SOCUBuffer = memalign(SOCU_ALIGN, SOCU_BUFFERSIZE); socInit(SOCUBuffer, SOCU_BUFFERSIZE); } +#elif defined(SWITCH) + socketInitializeDefault(); #endif } @@ -75,6 +80,8 @@ static inline void SocketSubsystemDeinit() { socExit(); free(SOCUBuffer); SOCUBuffer = NULL; +#elif defined(SWITCH) + socketExit(); #endif } @@ -103,7 +110,7 @@ static inline ssize_t SocketSend(Socket socket, const void* buffer, size_t size) } static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) { -#ifdef _WIN32 +#if defined(_WIN32) || defined(SWITCH) return recv(socket, (char*) buffer, size, 0); #else return read(socket, buffer, size); diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt new file mode 100644 index 000000000..6b2e80679 --- /dev/null +++ b/src/platform/switch/CMakeLists.txt @@ -0,0 +1,24 @@ +find_program(ELF2NRO elf2nro) + +set(OS_DEFINES USE_VFS_FILE IOAPI_NO_64) +list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-file.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) + +file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/wii/wii-*.c) +if(${CMAKE_BUILD_TYPE} STREQUAL Debug OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) + list(APPEND OS_LIB nxd) +else() + list(APPEND OS_LIB nx) +endif() +set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) +set(OS_SRC ${OS_SRC} PARENT_SCOPE) +set(OS_LIB ${OS_LIB} PARENT_SCOPE) + +if(BUILD_PERF) + add_custom_target(${BINARY_NAME}-perf.nro ALL + ${ELF2NRO} ../${BINARY_NAME}-perf ${BINARY_NAME}-perf.nro + DEPENDS ${BINARY_NAME}-perf) + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}-perf.nro + DESTINATION . COMPONENT ${BINARY_NAME}-perf) +endif() diff --git a/src/platform/switch/CMakeToolchain.txt b/src/platform/switch/CMakeToolchain.txt new file mode 100644 index 000000000..bf9db0101 --- /dev/null +++ b/src/platform/switch/CMakeToolchain.txt @@ -0,0 +1,56 @@ +if(DEFINED ENV{DEVKITPRO}) + set(DEVKITPRO $ENV{DEVKITPRO}) +else() + message(FATAL_ERROR "Could not find DEVKITPRO in environment") +endif() + +if(DEFINED ENV{DEVKITA64}) + set(DEVKITA64 $ENV{DEVKITA64}) +else() + set(DEVKITA64 ${DEVKITPRO}/devkitA64) +endif() + +if(DEFINED ENV{LIBNX}) + set(LIBNX $ENV{LIBNX}) +else() + set(LIBNX ${DEVKITPRO}/libnx) +endif() + +set(extension) +if (CMAKE_HOST_WIN32) + set(extension .exe) +endif() + +set(CMAKE_PROGRAM_PATH ${DEVKITA64}/bin) +set(cross_prefix aarch64-none-elf-) +set(arch_flags "-mtune=cortex-a57 -ffunction-sections -march=armv8-a -mtp=soft -fPIC -ftls-model=local-exec") +set(inc_flags "-I${LIBNX}/include ${arch_flags}") +set(link_flags "-L${LIBNX}/lib -lnx -specs=${LIBNX}/switch.specs ${arch_flags}") + +set(CMAKE_SYSTEM_NAME Generic CACHE INTERNAL "system name") +set(CMAKE_SYSTEM_PROCESSOR aarch64 CACHE INTERNAL "processor") +set(CMAKE_LIBRARY_ARCHITECTURE aarch64-none-elf CACHE INTERNAL "abi") + +find_program(CMAKE_AR ${cross_prefix}gcc-ar${extension}) +find_program(CMAKE_RANLIB ${cross_prefix}gcc-ranlib${extension}) +find_program(CMAKE_C_COMPILER ${cross_prefix}gcc${extension}) +find_program(CMAKE_CXX_COMPILER ${cross_prefix}g++${extension}) +find_program(CMAKE_ASM_COMPILER ${cross_prefix}gcc${extension}) +find_program(CMAKE_LINKER ${cross_prefix}ld${extension}) +set(CMAKE_C_FLAGS ${inc_flags} CACHE INTERNAL "c compiler flags") +set(CMAKE_ASM_FLAGS ${inc_flags} CACHE INTERNAL "assembler flags") +set(CMAKE_CXX_FLAGS ${inc_flags} CACHE INTERNAL "cxx compiler flags") +SET(CMAKE_ASM_COMPILE_OBJECT " -o -c ") + +set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags") +set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags") +set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared link flags") + +set(CMAKE_FIND_ROOT_PATH ${DEVKITARM}/aarch64-none-elf ${DEVKITPRO}/portlibs/switch) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE INTERNAL "") +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "") +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "") +set(PKG_CONFIG_EXECUTABLE "/dev/null" CACHE INTERNAL "" FORCE) + +set(SWITCH ON) +add_definitions(-DSWITCH) diff --git a/src/platform/switch/memory.c b/src/platform/switch/memory.c new file mode 100644 index 000000000..6459d6abb --- /dev/null +++ b/src/platform/switch/memory.c @@ -0,0 +1,15 @@ +/* Copyright (c) 2013-2018 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +void* anonymousMemoryMap(size_t size) { + return malloc(size); +} + +void mappedMemoryFree(void* memory, size_t size) { + UNUSED(size); + free(memory); +} diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index aff3c30d8..29cad8e05 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -19,6 +19,9 @@ #ifdef _3DS #include <3ds.h> #endif +#ifdef SWITCH +#include +#endif #include #include @@ -49,6 +52,9 @@ struct PerfOpts { extern bool allocateRomBuffer(void); FS_Archive sdmcArchive; #endif +#ifdef SWITCH +TimeType __nx_time_type = TimeType_LocalSystemClock; +#endif static void _mPerfRunloop(struct mCore* context, int* frames, bool quiet); static void _mPerfShutdown(int signal); @@ -71,6 +77,10 @@ int main(int argc, char** argv) { if (!allocateRomBuffer()) { return 1; } +#elif defined(SWITCH) + UNUSED(_mPerfShutdown); + gfxInitDefault(); + consoleInit(NULL); #else signal(SIGINT, _mPerfShutdown); #endif @@ -128,6 +138,8 @@ int main(int argc, char** argv) { #ifdef _3DS gfxExit(); acExit(); +#elif defined(SWITCH) + gfxExit(); #endif return didFail; @@ -254,7 +266,10 @@ static bool _mPerfRunServer(const char* listen, const struct mArguments* args, c SocketSend(_socket, header, strlen(header)); } char path[PATH_MAX]; - while (SocketRecv(_socket, path, sizeof(path)) > 0) { + memset(path, 0, sizeof(path)); + ssize_t i; + while ((i = SocketRecv(_socket, path, sizeof(path) - 1)) > 0) { + path[i] = '\0'; char* nl = strchr(path, '\n'); if (nl == path) { break; @@ -265,6 +280,7 @@ static bool _mPerfRunServer(const char* listen, const struct mArguments* args, c if (!_mPerfRunCore(path, args, perfOpts)) { break; } + memset(path, 0, sizeof(path)); } SocketClose(_socket); SocketClose(server); From 4f312a099848ccc657fdf0cb39efbf710895039e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 12 Sep 2018 19:27:23 -0700 Subject: [PATCH 03/10] Util: Add missing PNG read functions --- include/mgba-util/png-io.h | 2 + src/util/png-io.c | 75 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/include/mgba-util/png-io.h b/include/mgba-util/png-io.h index 7156d67cb..4156b5d20 100644 --- a/include/mgba-util/png-io.h +++ b/include/mgba-util/png-io.h @@ -42,6 +42,8 @@ png_structp PNGReadOpen(struct VFile* source, unsigned offset); bool PNGInstallChunkHandler(png_structp png, void* context, ChunkHandler handler, const char* chunkName); bool PNGReadHeader(png_structp png, png_infop info); bool PNGReadPixels(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride); +bool PNGReadPixelsA(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride); +bool PNGReadPixels8(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride); bool PNGIgnorePixels(png_structp png, png_infop info); bool PNGReadFooter(png_structp png, png_infop end); void PNGReadClose(png_structp png, png_infop info, png_infop end); diff --git a/src/util/png-io.c b/src/util/png-io.c index 7ac760b93..e6c0487ca 100644 --- a/src/util/png-io.c +++ b/src/util/png-io.c @@ -323,6 +323,81 @@ bool PNGReadPixels(png_structp png, png_infop info, void* pixels, unsigned width return true; } +bool PNGReadPixelsA(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride) { + if (setjmp(png_jmpbuf(png))) { + return false; + } + + uint8_t* pixelData = pixels; + unsigned pngHeight = png_get_image_height(png, info); + if (height < pngHeight) { + pngHeight = height; + } + + unsigned pngWidth = png_get_image_width(png, info); + if (width < pngWidth) { + pngWidth = width; + } + + unsigned i; + png_bytep row = malloc(png_get_rowbytes(png, info)); + for (i = 0; i < pngHeight; ++i) { + png_read_row(png, row, 0); + unsigned x; + for (x = 0; x < pngWidth; ++x) { +#ifdef COLOR_16_BIT + uint16_t c = row[x * 4 + 2] >> 3; +#ifdef COLOR_5_6_5 + c |= (row[x * 4 + 1] << 3) & 0x7E0; + c |= (row[x * 4] << 8) & 0xF800; +#else + c |= (row[x * 4 + 1] << 2) & 0x3E0; + c |= (row[x * 4] << 7) & 0x7C00; +#endif + ((uint16_t*) pixelData)[stride * i + x] = c; +#else +#if __BIG_ENDIAN__ + pixelData[stride * i * 4 + x * 4 + 3] = row[x * 4]; + pixelData[stride * i * 4 + x * 4 + 2] = row[x * 4 + 1]; + pixelData[stride * i * 4 + x * 4 + 1] = row[x * 4 + 2]; + pixelData[stride * i * 4 + x * 4] = row[x * 4 + 3]; +#else + pixelData[stride * i * 4 + x * 4] = row[x * 4]; + pixelData[stride * i * 4 + x * 4 + 1] = row[x * 4 + 1]; + pixelData[stride * i * 4 + x * 4 + 2] = row[x * 4 + 2]; + pixelData[stride * i * 4 + x * 4 + 3] = row[x * 4 + 3]; +#endif +#endif + } + } + free(row); + return true; +} + +bool PNGReadPixels8(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride) { + if (setjmp(png_jmpbuf(png))) { + return false; + } + + uint8_t* pixelData = pixels; + unsigned pngHeight = png_get_image_height(png, info); + if (height < pngHeight) { + pngHeight = height; + } + + unsigned pngWidth = png_get_image_width(png, info); + if (width < pngWidth) { + pngWidth = width; + } + + unsigned i; + for (i = 0; i < pngHeight; ++i) { + png_read_row(png, &pixelData[stride * i], 0); + } + return true; +} + + bool PNGReadFooter(png_structp png, png_infop end) { if (setjmp(png_jmpbuf(png))) { return false; From c0a94967ca1295f747d69325787f33bc15f51e76 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 12 Sep 2018 19:27:53 -0700 Subject: [PATCH 04/10] GUI: Minor fixes --- src/util/gui/file-select.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/gui/file-select.c b/src/util/gui/file-select.c index ecb734dd6..5043a860c 100644 --- a/src/util/gui/file-select.c +++ b/src/util/gui/file-select.c @@ -64,6 +64,7 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, uint32_t input = 0; GUIPollInput(params, &input, 0); if (input & (1 << GUI_INPUT_CANCEL)) { + dir->close(dir); return false; } @@ -102,6 +103,7 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, uint32_t input = 0; GUIPollInput(params, &input, 0); if (input & (1 << GUI_INPUT_CANCEL)) { + dir->close(dir); return false; } @@ -168,6 +170,9 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool } if (reason == GUI_MENU_EXIT_ACCEPT) { if (params->fileIndex == 0) { + if (strncmp(params->currentPath, params->basePath, PATH_MAX) == 0) { + continue; + } _upDirectory(params->currentPath); if (!_refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents)) { break; From af03ad75be05379bbecbc326e849d26d25237652 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 13 Sep 2018 18:12:32 -0700 Subject: [PATCH 05/10] Switch: Initial mGUI port --- CMakeLists.txt | 8 +- include/mgba-util/socket.h | 8 +- include/mgba-util/threading.h | 8 +- res/font-new.png | Bin 0 -> 15466 bytes src/core/config.c | 4 +- src/platform/switch/CMakeLists.txt | 27 ++ src/platform/switch/CMakeToolchain.txt | 2 +- src/platform/switch/gui-font.c | 320 +++++++++++++++++++++++ src/platform/switch/icon.jpg | Bin 0 -> 20431 bytes src/platform/switch/main.c | 343 +++++++++++++++++++++++++ src/platform/test/perf-main.c | 8 +- src/util/gui/menu.c | 6 + 12 files changed, 718 insertions(+), 16 deletions(-) create mode 100644 res/font-new.png create mode 100644 src/platform/switch/gui-font.c create mode 100644 src/platform/switch/icon.jpg create mode 100644 src/platform/switch/main.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bf824be50..f885052dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,8 +46,8 @@ set(BUILD_PYTHON OFF CACHE BOOL "Build Python bindings") set(BUILD_STATIC OFF CACHE BOOL "Build a static library") set(BUILD_SHARED ON CACHE BOOL "Build a shared library") set(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro or OpenEmu cores)") -set(BUILD_GL ON CACHE STRING "Build with OpenGL") -set(BUILD_GLES2 OFF CACHE STRING "Build with OpenGL|ES 2") +set(BUILD_GL ON CACHE BOOL "Build with OpenGL") +set(BUILD_GLES2 OFF CACHE BOOL "Build with OpenGL|ES 2") set(USE_EPOXY ON CACHE STRING "Build with libepoxy") set(DISABLE_DEPS OFF CACHE BOOL "Build without dependencies") set(DISTBUILD OFF CACHE BOOL "Build distribution packages") @@ -295,6 +295,10 @@ if(DEFINED 3DS) add_definitions(-DFIXED_ROM_BUFFER) endif() +if(DEFINED SWITCH) + set(BUILD_GLES2 ON CACHE BOOL "Build with OpenGL|ES 2" FORCE) +endif() + if(NOT M_CORE_GBA) set(USE_GDB_STUB OFF) endif() diff --git a/include/mgba-util/socket.h b/include/mgba-util/socket.h index a2cece335..e0c52fb99 100644 --- a/include/mgba-util/socket.h +++ b/include/mgba-util/socket.h @@ -55,7 +55,7 @@ struct Address { extern u32* SOCUBuffer; #endif -#ifdef SWITCH +#ifdef __SWITCH__ #include #endif @@ -68,7 +68,7 @@ static inline void SocketSubsystemInit() { SOCUBuffer = memalign(SOCU_ALIGN, SOCU_BUFFERSIZE); socInit(SOCUBuffer, SOCU_BUFFERSIZE); } -#elif defined(SWITCH) +#elif defined(__SWITCH__) socketInitializeDefault(); #endif } @@ -80,7 +80,7 @@ static inline void SocketSubsystemDeinit() { socExit(); free(SOCUBuffer); SOCUBuffer = NULL; -#elif defined(SWITCH) +#elif defined(__SWITCH__) socketExit(); #endif } @@ -110,7 +110,7 @@ static inline ssize_t SocketSend(Socket socket, const void* buffer, size_t size) } static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) { -#if defined(_WIN32) || defined(SWITCH) +#if defined(_WIN32) || defined(__SWITCH__) return recv(socket, (char*) buffer, size, 0); #else return read(socket, buffer, size); diff --git a/include/mgba-util/threading.h b/include/mgba-util/threading.h index d59ebcc5a..a8b0b2176 100644 --- a/include/mgba-util/threading.h +++ b/include/mgba-util/threading.h @@ -13,12 +13,14 @@ CXX_GUARD_START #ifndef DISABLE_THREADING #ifdef USE_PTHREADS #include -#elif _WIN32 +#elif defined(_WIN32) #include -#elif PSP2 +#elif defined(PSP2) #include -#elif _3DS +#elif defined(_3DS) #include +#elif defined(__SWITCH__) +#include #else #define DISABLE_THREADING #endif diff --git a/res/font-new.png b/res/font-new.png new file mode 100644 index 0000000000000000000000000000000000000000..e08b5bccbd294cc63276c2f5ab35d2048f08dbae GIT binary patch literal 15466 zcmc(GbySqk|L-oXq#_^<9~4w#N$C3T|i1C1eQ(_kZx%fL0Up;>F(}W zHZGsv_x{fL-TVJN_naqY&OGya&&=~YGw*m!w8ncy(uZ^p0RRB0vXZ0%jW$xbsiUU^Ef(ha2yZ0+qN`Uct${nJ%J#%Zps%>ABV+z2|u)tvVOPYDkEn0uCp z!;<+Ir=NO&?14K$t*kRe|L{w-h&}w-!K4ftI+E{&&<_!;+4)hdU-J`XLs+BplUb8k zBlADW(kN{M(UB&(zz@01a#9-V{0UruJszArC2&7rZwmN1h5w1bcbr|pJl|IoTf91< zT||q=_|b2pUCsDt>2U!|r2^a!i)C-`JNUp=$-n~uAb$Ms2^?PxMgagU0A+bu9pAab zY(H0{zU*y?guHBic47;eEpq?CmSkE6v{$m%7Xv+ z4%tq)!nk-W35|Tdcm47K;BVF4VFjm$ za=r%8Z}vOqn?bnbk$SUEVHK1o#s2K-DZ&Y_ad$%avxpoQo2w{KmQP7U17rrEG9 z_)@+D$N=t>BlvP6zE_jFk4TeM^XPV83lG)h_ji9M$4+PC6rOh6?%6Om-~H)}%aJPX z2SzV%tx3mS41N@FSLV!=r^_v5($GRC+UyzQR35ukL7I4j?tW6R>(A%50COH#PvWF8 zkY0agHcM3Gs%yZl*T1_N722q4|Kfg@QuVr1Jzy`lBogZ(`)C7`)VpCu7I_B&g(q@X zG~W)4dbq^KR*MP9?O|_b1wJz`R;IuX80~Js z%z+s9=FM@Pc}oC(oD*BYZ9B&0pS+=T9l@s;3n zN;VtbdJ)Cwkws|Okm$l!bQr>lT+2vQS=1^-ca?N*@Ks{CvF+NcqIdx)fwo&MW>b`6 zO}$-=>}RpVMol5FJG&Zguhh)OA+J_deV{t(w`BH8`a{F#My34@mpdFY zfTs6u`n=xOA6ZY;yyt3ek#KJlQ-!+q<#Tr%7DL?Y?e_+a_7_T?3(4m zzUSB0f_IONZS7g!{y`hzu~2PlPB4%R;IQH{B$yemlf z4#Y~h!u}4No6)1d=7mhD>Q#<^)n!c|t|U1EqP||M#a4pHaGucvywGw@!q=^gW*HkQ z&cQgQM|->Eob*aY4`?KH3_B&m-aL<_8s1RoVySB)*yB~U=A)%HxPA=~Z4hozuENUS zW^!TrDeQ{Knet44+~7pQPth)bBFSLA2RA`emShThA+=R#y{YJjM-vNE0}lDk^X^0} zuK~=yV1aZ(B|$(kk}&N{1sO)B=>WRx7~CYT_dW^c@s_EDV=!<$Dc# z)zv(kNxFaw-Oqk|aCw1@FOPR+tiJn3-|#wiTY?+>nGnwx$MOI#B2$7)A^*0HyUhAK zCjVQYtMi!pE>0HNC`AhW)AuNufQ1zIUj8I<`yq>Cq!(P{iAQ6oW(9%P zqUy*98nwS5@Hj7LKikpS8DH_)wT15ntekCuw|Za8d4kp+-MxTf*$t7NT)C8%!I;9| zwuikG)gEuG?j$1tU1eK@Z>E2|1{x0`pJe$~t*{ive88jbNV1ju7zrck#d$-QplNJ_ zn-BqvA_Wv+fZql>V#R!PQ|7iE2FvDI#~8N>zJ%<5b+y%)Q;q0*M?ik=gnNzMt*I2X zd!P`xR_2n)LO0MLCBKJF6rRI5qiuHmQ5Ck2k#njTV}j}H{2lCCWFT>>!$@zv2AVOxu$vO!! zd^z@KC!s!_LF|Sm7QX#`6j!DxptOy}XJYy{0z03dD7M>{HF#4^k%{ zhD00!Pn_i6n(C2tj%&5rGs#F{==r4CvuRYntY#LT12%5{96h#e*A(mSApUHWz8FS3 zbY9KNPX>Pg(L{$ONe3+T%|3U*V3v5CWgcG?X9}>A_P_YIbB=(Ny^LJbnKZinkvxpw ze1jg-5wwJyeA=zbg&XgQp7HK8r{8Z!07?e#1S|Yh6Z_aXg$hqojo0M7V!?LjK#&Un z(wu=Y>GEO7EPwwK*i^pJ_bTdd7ketFMYMyL1n1j4%rCbLm-qwJdC5Mv%}WQ2p=iZ? zkzG%*FhGH{^Ptk_$y;0#xxcE8@pX%KK1{+9yX0HU>t|!@1{xpS^3!wWH<9KSRId_m zb6?-TwQpae7c*jfnKz^Y>-jRTOlp6bWfqiLe9;|)RlXt&`0|L1{>ZLY#o!z<==2{E zGAPDFJ;AyxHFd>O`?6m?l3OdL%jgq1YjtrPD+ZU%Vw@Z7k}clTb4WemXI^p*v+EVD zpgP+}MV{w$2JCj7+A75K7bQ4%eAn6=i}cY}ALNEMtlw58cc;@q^#T=e%{^azxM_&L z6we4LXLPa$K9%~gL9nB{6~f$ijU!E-kUI*OT@I8%#9BhBoK(a|Ji8p<67S%l9!Tw$Vlvu`d7ruE!E@`2Wx}g!g5`et&BTc zQs}BwC$%G?ho40lr9vf$*{kcM3OSW@YH^(Dj5+l;yqWhH;7pINfibENW4~|Vqk-0_ zy*c;BV+WdEOl2(lp0Xo@@^~g6JRg=Gq1OF^V-#Bdg_imPJs{E8V z(+0=yZ3)-{el;^yx}^_zMu-z)c7Qur&6DP&F|0azj{xwkpa+8P*NnVDd_WXR?aCVL zZ)>w9Y_zR#b`zi79HK@~mueh25b06h(e>|&+yoU4H+zJY(D4_8=PBOOre);n>;;fV z>BIGy2K$$E?E8S={FYl1y3T`{^VcWw))@^Iu~V_Lq zcQURs`T<^_ZEWN_?LP*JlX-j|T4#FPB7xcbN86c;ZV@UmQPJs$?0r>KBS>ZX4IiX1 zqEGWSb!*d4r4IC+am1khI{WJvQkk+8>acAm(U3>5LpnjIt50VleHtk^O@PNVIfe|T zY4Z=J+9%clDwzemAc1q3`R%W$NC(M^6YJnR z!PXSDE+5V9x(IiCMeW})j}faUyGN9Uz*fHW`YZTjk_18?1WEEzUCG1DtUgw}Q||@K zBh<~tMk4Y*eallTk5QsbCj^T)X}2__GL@snb}MR!iqf1vKHBc-CEfKS5>M&rbnZb3 zwSyS_$_jJ3wF>>coeGmW{AtrsB>tzQ8_X97wcV<+Z}-jX51|?DZkB77X#jX*dIX+d zT!sa?elPi46hfo7NpX*8bj!zsxp6(Vnf^);Dc14~ebq}>+Ph>U`V0Ib-k&VEg2X@* zlxIv|l^Xm}O;YAB3WuyL%|%kjOqz2wwW`rrP}moga<|}@sIoJ6+AqG@`SM1 z+m|x5>o=6cDU^^w-KmkQN~g9B{)-T6#XIFQqMM$NeDi=A&b_2t=7_EGCAx43P^qHF zZCdg-+$`qs;yFT-vqG$KkjEJ)i3Lj2(jNre?cm<(aQb zOrBnU1)aY|y-&v6v=%OUv!5LsM6#-&_!4eu5>niZ7?(%dPPeMt=;Td+!mo<9KvYbO z_6Ih8EMrE(g^ZP&*ogXYLu!hMOFK$9i;@8*dTk2?rd$YQvRaqhm9zp+LtP`&9Y_2T zCF-21mmZ@lCHE6sf#&=`TbCidK~sfD=a&DcN$el-=I}P_6!FbHQ`!1oocp`$u2NY1 zSPo@F1FWR_mYIxU?_qJ2Un$+}r^*$b2^%VI$bf6#pnni+L*R}3w83yb6_3$f<+G{C z{OgbnY6>GbQ(?}mj&+^zV3m3>V;n(ZBqrq#J51?Pe{uQUyAREtITB&qJzJkgvTzyI zJDgW4A{w@Mb(-*FgS<1KMrPLO8R$9PSYbp^!h^~ zA$!FVxHYd0FnJPPLhAjI(cfDa9xIS#CGuLGrTwx3VMq zwIJV<4pVbZQL=3wE%`@Vy+wPqmT%BX^`!i`FI?6XKDv;kSa|}y|4y;>Ii%XDY_Ffu z+RnO9-X>fL#6o|of&xn zwtAe<2n>hG8Q9pm`P?;jafg*m^dpn4dy+UpcV=5{Z ztjK&&jnL*E;_a22wT*{f?26b%lKlAfBZ(0hZqMKR=C#S~TXLz<)qOUf|ihq%;^l^8>ua_+s(@h8sLS*Zxy@F^}Z#l*Sb8YWiBmh{Yjt36;LE zz1NNqL8*3%owo6bq1gS$M>;9O`{1&$UeH}^y>q!bSk7=L z2CGcu_jKKn@nVhm*5&#&trEmi&LK-Z9wZ8nF_CJ4akn5;6NWaIfr zLWSbwNCGkOfD7q)c$^ke;2ndabP@x&xTFRV1DD&Cwtj)8(?hn<*)v{(0@xKHOfnu! z$^}k?uvm{nZ%wnR=}rf6xsi3|=umo%Ie~YganoZn+U>SGJ;G^H6LNhc->b^==F|YZwrB_j*TiTeeyD(XRG+hgQ55_ zb?J01R^{D73qPd)X>6godcgL0yaIKYK+dBr-f9u-xe0c1qP@Se*H(mSR)mBR`_x#q zE>*|y3`ZE#>KkT?y?s8cx6{0nPPl~^RZ&ve)-O-@>8UQRi-Q|`?wcWPsc@)1-Jr-D zjv%{tZn}=Rw*m=LoQK)(%zS<#pvcCJsP3P1bhPUFEDmL5>bDwsMGq%6cE4$unyFVN zl!jEj0wqa=6bZfARop2AsoCZ559iY?D6WtQLqOpE@jM5EEV+82 zVb2A$^PNE@y4a5*fk{@~?hXU|#8&$we_Y5ReP{o2Z3ywZV&{fDuOe+i8q&oHbclCB z2i<*Q+gUBq+1+(GQd1zZmxaVwfKtpc=a# zk&;#{4;#X;)z1*e#Z^^^n5ql%JmW{jG|mU8&{4oN(=zhz>UmtApN3MApdY%{x#fN{iv8WN1pF1s2fV9ZAOsOZK|7ng#j%{!X4HH0H`KhTv$7{}h~C!(*mz zRz+!c#0;(d=RJq91eTn-z;Ku5hqMY&a!}d2k8Fj32D9uUv$5*b!Y;-12-ie+2yLnv z=Tn+}Ge4`nC|>U8-nT<&T-4BbNO?)&0{>-;zs2nFM)=EWNnK)a3Q8c^`ug4`>}?5@ zM0W^w*fgDlZ2rxq<;lVl=3uNVE*eh3;M5Jf&UQ6m5+7JC&SVt1cZB z{O}g?uHL6@g3ifT4B{3%TpmwN$^S%5oLh`Y#x?*Lj}aP!@jKVM`)6L4cO^G; z$beYJYtOFm^Lt0!yK!)iS)?8FvM;9)@gCdEhR{|H>-;~O4fIIr1QT4wVlPL$vvdR~ z1zsL#jR8iiXb%(yxuaW4ioU2=pwLT8<*0FLLctH^#+_C#q{Aa+O_c;9V zQ?pFV-;rcPN3;MCeAtz6OIRiTd z1-_@*Zg*WRf0nI;Er_f2B!hokMrG$?X($9mJ7UxME86Q`r_C{~F+(LEBFJeJ{!DE? zkDO-7QHvinh;q6nf%dx?NC7U=nAaUJv8Om&j|yVqyV5^y6?wn89U9WN0W_ojIi=bY z__Qz$);61*$oczns$9zq1kti-Y2FhZ)@%xHax8x@y0=g%jiZDX2mAPwe1c+o5%`on;I(%}8%L|1sDUwV=gCG&Q`Z-N zr3b`BJcS-;ek@>0os4|T1}qn7&6B1~{5+koU&##Ai+H%beA$b%|B`J+Z{#6#EUmWN z&HHH2Jx$zm!n7kNb$Me&A?sM9v5}^d7rj4`sc2yaUyzpZYS>|3q1}98R$5+Ma*(>Y zZadl|czHQ^Beq&vBc*+tJ94WpI8j<3mjm$2`RvXpB-kx z9V0m+{{InkaD#P*VJmvkjdqcoRnS9LnII>e=RZ>c1RZrFOQaw#f)*O!Uk{nCco~0! z>Um^v`;C9V+RlGuYOJ5Tmv(c?S@1TV(8BhwFS}s+omUij9j`-hw}8S;xgRo5Yf4{L zri*EwG)iHfb~fYID47YG;LbP&!A%1#)EO+^N_ly~bArvpjWMLpJ6NXS;ErE3pX3N=c5pbx_5UjWPRX}8>B&=eSt7=y~fb;QLp%Xwtyx$hXL_|eYsY-9>t0ed3L?PZS0C0b$5sHMA64u)Ud7iBzflyav z>`P#W7QBikr!Djy2mIIJApgEU#fvy_z$%sOtDI%~3uIW<8oqqgW}sxbt5fFx>GBB;Y^CK4J)}(rtY()~hRL7%BQ= zB?Dm(wjnTAU9Kuw2LC3nr2K0TwD_`bu!VcysOZJKw2aMPn6gJ$L+Gv~j+*0i&C znqCQBi@90WeIr}(=!VhKLhsjmxoR}-r+=OE9EidIND9^btZwwz&AMB1Kx@mCi#W-k6TVeIW zcU{y?Etg<5Q@08N69iZa`xIarXYsgB39xhKfw4`eA3pr)2jB&@ZFTtST3g4e(mbcb z0M9H99HiIYb40Y#)3l4*0arV9E5WlLc2B~(-`Oxok?_0-AWA8SEoO>DEOAzA-4ShB zlF9n%O^Hn_XRDl#o(J7MM-q9>U&7njS$HpD8NQvu3E73aA<8~XP!Roe%W0cLX2tBd zy|q{EvtY~<4A617@^jl%;q2^hiC^16uw8n9+A>edqWromo5&G4k1XeIgx_}GG)(f- z6^hchf4zcPXbefTam&58#?-2VoYhC+rWDN zS<%~YDrvkO3$NOlV9cv*E2g_qn@af}ztD)#+WN})5*Hd;=DS^CfT2VR7rh@2$|}%! zT8?FIW?cxjK^__1_L8dY0eQK8T|BsGxlvR-_wNq#K`>>)Nn3IeVbOx8|Loz?rW`0I z(t9jHW&(|(${5&BqBwiD^`KT@XVYQluA6Nd!4x@HteBr8P=!#C7`LaWuhDo($M!=} zbPY|M+9KRtEHHj-4^ZrtWJdE)S8 zh%gn3v&f*=_<=F04qmOYqp7UoI;{^@kY==ZyjGQsytV-4pxeAz>7m6pbp;2z&L%-( z9yz}{Z_|+&TOUlmzeUx&-xLGKv|Wyf77rR!?;z>V*Q$4QKjf6He3GYfMMm@2@ys^v}aq2})O zS3gbJ_9 z&mDTI?8*e>ehc%yr!Si2gdSAp_=0oOvx$dMb~|^Qid+t<=c^H))v#$C6E|OUtT9yI z?Vizu(@i7#sBt4d4|*%+R>FwcPE}rUH;2rsB3BhqxVGEsD$5}0H?3LC4!lkrQaf8b z6N3MjA!s?hAN3wZ%S|e1cE-weA@i z5&!v5myI@LUv)e$b)#)&0KQ`%0PoI7dE%G+W`gER&*)bT~@TglZmFQd_O_~PQExr;5AV59i<^M~lBt&UH0iaSMB4F#*F z5;$aSzBz5#JK3kp(IXqg#D3&Yq|e`%|2ar;0lFQwL&Ozrd%UI(gPNa{cADMQ#2$!z zfTubn`cTMrzL$7<@a=Z5syTP5_dHu@jt-0SN#Y*f=dkI95-Gcv?K(4q&fls_`JiYs=yF$f~4tuG#%^Zg3iY z-px8KGWQ|S8`CIC&XNdOu;VmLKPeLZ7w}1tZ&^Lcd^$rcasY<4OM!d-^CD34HMa64 zzYy~jL$OvHfPEFw6X4R;QsS<|PFuVmz8`yDa;m*u96u4;2acqFI<(JV(eAQ2vB3bI zxM2AQ`ILc{0dQ?W!yWlpJ=P8ecVy=c^s4>F(rc)fX-hL{ig_X^*tz$IBp|Djrc!vM zxK~}4xtKnFlnlWa9?S zXycdF=LyWJan_$C`5%`>^_m#bFal`Bipa+0ppcj=5UL`2WTpx;WH@OeP~$3ZQFZ4|>+^vQyoP2?V}8UH(3#aE(&cHZcrGOFxmM529BMfGe zIfN<@<-%!AV&C|31%bjoB30gCW+J0`xJxYEIC2}^!MeQ@L1=C|si?;ukN#ZfKdai^ zG7CnRAo&~t^t=mcE#0Y;RDWV}D~d#>f^gkVWsKh%#yi4XAs6Z7>F*0S=TUbw9i7IHSdgHP#nO^3N~rjo_Sei6XDR8sAYx&Q zJ+J4(sG&+TE$IkS7KyWWdXXZU0vC&XQ@l3bsAI}(yyId02pYk){c!Dx)CfqRt_jwk ziR}BSU3{86ipxgKEjyi{mNRq(9C~%hwF( zK#5=KkY#UhVMoBmk|aSwV1)J^OQX+TtK#&cCE!~w1BQ0z!LmU~0q_8CO&~BeC!{q~ z?7xjPA~M`#`J0AYM_uU8QYi7%6KgAZ9=$=PuBu_Pht)d3xl){az0UA^zMTwi6Z#n9 z<|L&;l~?g<<#L`bgFp~E4+m0AZwcrE#Y%C$El*DfF02w%YX?U-YnPUZHzS6G(@Ozr zx*_l@n<+c!2)V;m1@Is_H-G-}frfT(1D2Bc0$lVk$~#jf!y*6IN1?aZCI2aZ0v>*F z=v@JMpr3<1=LtYt}vE>NC(5z zqLTHPEVXY7BWh)gy8aJvgMviIf@ZCMsHgTGub6xn`NvHUxe<^O~l;=I2)RyPkWS(TVX|m@OK4_!!Rib>F!X- zQ8Y+9s70`&nv*FA+%AtbkFi*uTP<0_FUyr}`%VQ?BdiNbTL=7+3zxW!|t3pdx5Y`va4P_>t^fPhG(jP?gtmo0`_X z_F(arUg^Km00n7TabuG3+VWa||G-}=b7knUE0HmUy_W6N!#~$=FVSGh-_H*qY`jgR zCbpi{nAlO>F3PG`J`GQTzCWV$_0Hf@4R15Dqm!XSy6<@y3I`ujM&B?p))kb7qt8H- zoa;&GuvZo5;>CG!)I6VBxRW%Tz!w6(AUpNB6_KFtl|I3Km|^=6CF8)^lvn&bs*7dg z6b*=^D|@$Vcu-)6>fQf)2lgmPqv-H1$?Wi_U?D% zHnu2AORMP*>Bl)~Dz)#DAU{6pZ?yxkWywrt7m2+tUsR`#_p@?0;Pv0WRfdClsk~6l zx<|K8*gyTN8e3r^Nv&rBFaTWRd2XMBW-#rnuc71jmvdZl1pvt)X(Kqu)Eaw6Ltlb~ z{PHzo?>=oRsdtrYKL%g5fx2Sgvvd&d-{_w0#+@}C%<;GlG{A4-v!=pqv)^p!+2Qy; z?ap;G>YfrQbbg8L&Fr?vJ&ErKn!z6-l$!`kCx4d7yz&`xk^RW}tn2+C0*pYz)vol_ zEUjz102dc%M|6iT^TLO;>L=W4_&P|e>kWZEN^iediJ4WSkcp6jJRtDAP2z-F0No~G z-Vf?Q_ki=#rvVSQG&?W5_Vh~#-bg&7nt7*$>v|t6ytj;VnTzzfnj_UuF4cwdcFcF< zM-iRt%+s;fb9iYCQ^wLC&lKfKsdXmtFXddf-2a9c=^VoT`awk;!)7ME{&CJ<__ewl zLn!ZLDA#S1CY3v^ukv2Xt4M{2b6~Jw`PUj|4Get&(Fuql-qIWn*Nrex?{B(-4UMS( z3Ou-{c)mfK70@NX;r0muQaNV<{EUP%dq?Z0k?aAe`l}?+Wp!g)XY$CPRXA{G_l^=7 z6ubMXcbJl~s)^rXP`CYk4x91t@) ze4TU^68H>+n>@Tf+_#V&Nd9jS@v|WuBrUypG`md3$=tX2jPJY&Hsq4*O+P zVKL!}{vOZ0n0V;Yw&(Kal2*qqRhe*#ysuw6M+rR6SW*W6c!)bTaUFvUq7y>~_6O~Z zCgrx$P?wk}VHkwq6GpTjKb2e_mgt?Z2VRqugb6PnXdW^%Uru{^5b(O=ziUd#1M9Tk zwpAR6L|DbGi%i%N`Pwey+FG+D``&NW zt&$kVWt;@6V;X7%nOpAkH}h{D%>22yeJH^o2jz;JvMyFDAz8yy{msayaqxF=1OG5#l7%jeCOgBi}Tr|d@htzSRWlr zW!UZI*k`RDi@9%0=iHp|&9w^~!{yj4lSEcnu^f(pqi*nSwEWNB6-NSz3^o!@${rYPOS*Li?35o85^H$GLnt?1je~ z0s3i{$gKI6!W(Uf9e)3bsu~-ojT=2lEue?X+?CFr#?~y}G`bL*Cx3HtuJCW{gRhgC zx8_(MUETP!0as7X9LgF2KKk2boLQo;Mhl_+4*XE)Sbn;?*!}<_RzIT0sN(p(|08=@* zA=rmxp1N4#_M1U+uzdJXOwMQnK>C_g!~1$V&TR6TYPQ#h@tEAG)K1$#Yl(u>A@O?j z@136ec6MgH4UUks8X!d8u?ip_lE8;iqRF(&JfDml?Rp!Bx=H&QC%P}!jN)g6VpKqw zY$w2wGC6C8>V*I*Yw_^(_(HR@O%}mczP2 zS2zE0mit(7oUHc!E`-CaxMCZGq^#o&?WQ)9Uj@c52m#A$nt{(V`|A~ z1{&0C5C+1~JICLBGqYm{m5pJ`;!nHW;oPL=a-L(&iK{NzKhN~eruFoG@d5(=v&(>& zuJbU=Q&Pst?^7G?lCy%c1?#a2qHxJs{(E^5V_tg;Neuc*5ZZiedNwW0+|R{rq5Wvi zn=Kmm2JL+{nz)Cy0azUO0HGlh<)V(K(zT9ZEaW^qLz z=Erg(eW%6TqBsf3@!Lfj;kUaUz?1{yi(md6qqsZQk8imVgPCe7G5KDwM`>k)4^#WV zV|e$9VcMrv+4JMjZJ4Xb_biH9VaUXUv`{E}wF~Krxzz0Bqf%f7lL%S+a)UZvAWd{nR!izS>s=>rIqJ{&Bu%twm5eafIrR-asqG<%M@F@ zY_o_|2)}ee+H(q3^G?d&Ewg3>=2ck#ZQYK~(KIw`zY57#ek+<@juK=&@NCC1x(WN0 zQw`o*sm*xrIw-O4$}P)=2IKZMOaFXgxp)A=Wr5@N3oo%(0M5af{n*xdNMl>} zhJd@{VX>m+m>@^MYK@pKC9n6}y>Vd?zp07HDY%Pxh@7tUZNyqx&ddAfX2X{I&3g8h z8wn_wYC5i(+6Yg|f=dcwdGQ)gwpW5ANErAt-I-x1N#sX(;GyQz0L4C#ZSPt4}Hm0?x!&`ApHKhpnCYk>eEDHRn6o{A3mGVz5V<%Ee<1+Kh z08ZJs6un9>ctE;ZW_Ml}R+9bZ(+e^hwM}oLZ|p0SwD@U`BYS6WCV){D+~Mp`21%02 zzVU9TAExe?zcMj>s->?}IE0hWr`t1^VRH3Pj}NCdTb{(&!jT|2QsK_cxB8mE+}TrH zU5J?TbsH`-l0b6Yu)0~=<2Xi2=>xQG!V6PirVv<4KjXC#zv{yJM0d95`b9CO8$TSF z7SAXdM8?zRcS2y;X?pK+_^>}q7I|YLCl`R|!Lj51Fw{Zt78GU+92rp$D#<@ze+UE4 zEaV=3;&2&$fy<>^udN^dYX9F2G=OcgO&r5cCVFT|{$-t2P4A5>bNy?P&ei^KC9^$+ zIOdf-=D}I9@zy=JkpV+W-i4J-n zIV!<6E-}Z*q^@tU0pk1q$)AjsX!KoWm?WlVnZ|}!+p{CK#CnAOiAzedl$t9+wMU!b zh|Nvr4!WbDDcv48Qy9O#yhS@!kt)msGA zCtRn{c~N%y+_ff>DIFSK##2{s6PQ;v$G3WMNHv`@>F*T~8x(CBx-N-}B|mXiX!SUU zHbQI5={hiG$4npeg#qu=!ryU}Js6YG!`cD^oB%)F-S_=_TW|Tvm#fLA+=Xi=SHU-8 z*Ifpk%x&pjbFzEbxl7&#U{j)3+$`SHN=Q9a@-^UB4_IBsaWd?@y%*_xK&%|}q z#GRo&yam%tkOy;k8(}{7pu+Ao@MrBhIC(kyG{8x!JlCY}=5t=tRm$fsik0<&)8&K^ z=upag_S)&uGI*dfF4bDV6b@0$t^1i;my^S*jiB59)T{LPX7PBBbzt?c)1CpUOdZp|#$;_OX`jlHmvraRo_k^NZhqu!{(+aoDk}?e) zz|7X45$C+4J`?cu$Zb@NM95qE%Vq8Tv~;iJiUXMj#B>_!4GaT5>&T4$kZ%HeaJPRds_Ka>|-e5qVl<*m4 zbRdm-v%vM|i+Jk+;h|Cut5i}z7b2BS|9wjjK5N)<`~c0TKloV8@0bFFJRb)bxC-&| zdO!X~zT4Tl>!{!GOd!b2d6#FQ>rt2R_-Ma#k};)it$5jBjA}DQ49~FoO9rpB3>9KI z?U#HmY8BRgOKiJrf}*7=*1J5av3`l&B6A%JXC_SpkK9h_cfnSpBv39C7l_59tELBf z^ldCLuvviovUk2#?Wf(H`;gBnyW+EsufYocXVBn(P~ra{@8tadEZ1uE7VBmn`VLF~ Sv+LhY#L92q%U8ZJ5B*=TEv{_< literal 0 HcmV?d00001 diff --git a/src/core/config.c b/src/core/config.c index 44861e3c2..cb5c1a6dc 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -179,7 +179,7 @@ void mCoreConfigMakePortable(const struct mCoreConfig* config) { WideCharToMultiByte(CP_UTF8, 0, wpath, -1, out, MAX_PATH, 0, 0); StringCchCatA(out, MAX_PATH, "\\portable.ini"); portable = VFileOpen(out, O_WRONLY | O_CREAT); -#elif defined(PSP2) || defined(_3DS) || defined(GEKKO) +#elif defined(PSP2) || defined(_3DS) || defined(__SWITCH__) || defined(GEKKO) // Already portable #else char out[PATH_MAX]; @@ -219,7 +219,7 @@ void mCoreConfigDirectory(char* out, size_t outLength) { UNUSED(portable); snprintf(out, outLength, "ux0:data/%s", projectName); sceIoMkdir(out, 0777); -#elif defined(GEKKO) +#elif defined(GEKKO) || defined(__SWITCH__) UNUSED(portable); snprintf(out, outLength, "/%s", projectName); mkdir(out, 0777); diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 6b2e80679..14c591f07 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -1,12 +1,21 @@ find_program(ELF2NRO elf2nro) +find_program(NACPTOOL nacptool) +find_program(BUILD_ROMFS build_romfs) +find_library(GLAPI_LIBRARY glapi REQUIRED) +find_library(EGL_LIBRARY EGL REQUIRED) set(OS_DEFINES USE_VFS_FILE IOAPI_NO_64) list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-file.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) +list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) + +include_directories(AFTER ${OPENGLES2_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIR}) file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/wii/wii-*.c) if(${CMAKE_BUILD_TYPE} STREQUAL Debug OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) + find_library(NOUVEAU_LIBRARY drm_nouveaud REQUIRED) list(APPEND OS_LIB nxd) else() + find_library(NOUVEAU_LIBRARY drm_nouveau REQUIRED) list(APPEND OS_LIB nx) endif() set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) @@ -22,3 +31,21 @@ if(BUILD_PERF) ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}-perf.nro DESTINATION . COMPONENT ${BINARY_NAME}-perf) endif() + +add_executable(${BINARY_NAME}.elf ${GUI_SRC} ${PLATFORM_SRC} main.c) +set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") +target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${OS_LIB} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY} ${GLAPI_LIBRARY} ${NOUVEAU_LIBRARY} stdc++) + +add_custom_command(OUTPUT control.nacp + COMMAND ${NACPTOOL} --create "${PROJECT_NAME}" "endrift" "${LIB_VERSION_STRING}" control.nacp) + +add_custom_command(OUTPUT romfs.bin + COMMAND ${CMAKE_COMMAND} -E make_directory romfs + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/res/font-new.png" romfs/ + COMMAND ${BUILD_ROMFS} romfs romfs.bin + COMMAND ${CMAKE_COMMAND} -E remove_directory romfs + DEPENDS "${CMAKE_SOURCE_DIR}/res/font-new.png") + +add_custom_target(${BINARY_NAME}.nro ALL + ${ELF2NRO} ${BINARY_NAME}.elf ${BINARY_NAME}.nro --romfs=romfs.bin --nacp=control.nacp --icon="${CMAKE_CURRENT_SOURCE_DIR}/icon.jpg" + DEPENDS ${BINARY_NAME}.elf control.nacp ${CMAKE_CURRENT_SOURCE_DIR}/icon.jpg romfs.bin) diff --git a/src/platform/switch/CMakeToolchain.txt b/src/platform/switch/CMakeToolchain.txt index bf9db0101..3dbc1ad87 100644 --- a/src/platform/switch/CMakeToolchain.txt +++ b/src/platform/switch/CMakeToolchain.txt @@ -53,4 +53,4 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "") set(PKG_CONFIG_EXECUTABLE "/dev/null" CACHE INTERNAL "" FORCE) set(SWITCH ON) -add_definitions(-DSWITCH) +add_definitions(-D__SWITCH__) diff --git a/src/platform/switch/gui-font.c b/src/platform/switch/gui-font.c new file mode 100644 index 000000000..382de6db0 --- /dev/null +++ b/src/platform/switch/gui-font.c @@ -0,0 +1,320 @@ +/* Copyright (c) 2013-2018 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include +#include +#include +#include +#include + +#include + +#define GLYPH_HEIGHT 24 +#define CELL_HEIGHT 32 +#define CELL_WIDTH 32 + +static const GLfloat _offsets[] = { + 0.f, 0.f, + 1.f, 0.f, + 1.f, 1.f, + 0.f, 1.f, +}; + +static const GLchar* const _gles2Header = + "#version 100\n" + "precision mediump float;\n"; + +static const char* const _vertexShader = + "attribute vec2 offset;\n" + "uniform vec3 origin;\n" + "uniform vec2 glyph;\n" + "uniform vec2 dims;\n" + "varying vec2 texCoord;\n" + + "void main() {\n" + " vec2 scaledOffset = offset * dims;\n" + " gl_Position = vec4((origin.x + scaledOffset.x) / 640.0 - 1.0, -(origin.y + scaledOffset.y) / 384.0 + 1.0, origin.z, 1.0);\n" + " texCoord = (glyph + scaledOffset) / 512.0;\n" + "}"; + +static const char* const _fragmentShader = + "varying vec2 texCoord;\n" + "uniform sampler2D tex;\n" + "uniform vec4 color;\n" + "uniform float cutoff;\n" + + "void main() {\n" + " vec4 texColor = color;\n" + " texColor.a *= texture2D(tex, texCoord).a;\n" + " texColor.a = clamp((texColor.a - cutoff) / (1.0 - cutoff), 0.0, 1.0);\n" + " gl_FragColor = texColor;\n" + "}"; + +struct GUIFont { + GLuint font; + GLuint program; + GLuint vbo; + GLuint offsetLocation; + GLuint texLocation; + GLuint dimsLocation; + GLuint colorLocation; + GLuint originLocation; + GLuint glyphLocation; + GLuint cutoffLocation; +}; + +static bool _loadTexture(const char* path) { + struct VFile* vf = VFileOpen(path, O_RDONLY); + if (!vf) { + return false; + } + png_structp png = PNGReadOpen(vf, 0); + png_infop info = png_create_info_struct(png); + png_infop end = png_create_info_struct(png); + bool success = false; + if (png && info && end) { + success = PNGReadHeader(png, info); + } + void* pixels = NULL; + if (success) { + unsigned height = png_get_image_height(png, info); + unsigned width = png_get_image_width(png, info); + pixels = malloc(width * height); + if (pixels) { + success = PNGReadPixels8(png, info, pixels, width, height, width); + success = success && PNGReadFooter(png, end); + } else { + success = false; + } + if (success) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + } + } + PNGReadClose(png, info, end); + if (pixels) { + free(pixels); + } + vf->close(vf); + return success; +} + +struct GUIFont* GUIFontCreate(void) { + struct GUIFont* font = malloc(sizeof(struct GUIFont)); + if (!font) { + return NULL; + } + glGenTextures(1, &font->font); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, font->font); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (!_loadTexture("romfs:/font-new.png")) { + GUIFontDestroy(font); + return NULL; + } + + font->program = glCreateProgram(); + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + const GLchar* shaderBuffer[2]; + + shaderBuffer[0] = _gles2Header; + + shaderBuffer[1] = _vertexShader; + glShaderSource(vertexShader, 2, shaderBuffer, NULL); + + shaderBuffer[1] = _fragmentShader; + glShaderSource(fragmentShader, 2, shaderBuffer, NULL); + + glAttachShader(font->program, vertexShader); + glAttachShader(font->program, fragmentShader); + + glCompileShader(fragmentShader); + + GLint success; + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) { + GLchar msg[512]; + glGetShaderInfoLog(fragmentShader, sizeof(msg), NULL, msg); + puts(msg); + } + + glCompileShader(vertexShader); + + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if (!success) { + GLchar msg[512]; + glGetShaderInfoLog(vertexShader, sizeof(msg), NULL, msg); + puts(msg); + } + glLinkProgram(font->program); + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + font->texLocation = glGetUniformLocation(font->program, "tex"); + font->colorLocation = glGetUniformLocation(font->program, "color"); + font->dimsLocation = glGetUniformLocation(font->program, "dims"); + font->originLocation = glGetUniformLocation(font->program, "origin"); + font->glyphLocation = glGetUniformLocation(font->program, "glyph"); + font->cutoffLocation = glGetUniformLocation(font->program, "cutoff"); + font->offsetLocation = glGetAttribLocation(font->program, "offset"); + + glGenBuffers(1, &font->vbo); + glBindBuffer(GL_ARRAY_BUFFER, font->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(_offsets), _offsets, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + return font; +} + +void GUIFontDestroy(struct GUIFont* font) { + glDeleteBuffers(1, &font->vbo); + glDeleteProgram(font->program); + glDeleteTextures(1, &font->font); + free(font); +} + +unsigned GUIFontHeight(const struct GUIFont* font) { + UNUSED(font); + return GLYPH_HEIGHT; +} + +unsigned GUIFontGlyphWidth(const struct GUIFont* font, uint32_t glyph) { + UNUSED(font); + if (glyph > 0x7F) { + glyph = '?'; + } + return defaultFontMetrics[glyph].width * 2; +} + +void GUIFontIconMetrics(const struct GUIFont* font, enum GUIIcon icon, unsigned* w, unsigned* h) { + UNUSED(font); + if (icon >= GUI_ICON_MAX) { + if (w) { + *w = 0; + } + if (h) { + *h = 0; + } + } else { + if (w) { + *w = defaultIconMetrics[icon].width * 2; + } + if (h) { + *h = defaultIconMetrics[icon].height * 2; + } + } +} + +void GUIFontDrawGlyph(const struct GUIFont* font, int x, int y, uint32_t color, uint32_t glyph) { + if (glyph > 0x7F) { + glyph = '?'; + } + struct GUIFontGlyphMetric metric = defaultFontMetrics[glyph]; + + glUseProgram(font->program); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, font->font); + glBindBuffer(GL_ARRAY_BUFFER, font->vbo); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glUniform1i(font->texLocation, 0); + glUniform2f(font->glyphLocation, (glyph & 15) * CELL_WIDTH + metric.padding.left * 2, (glyph >> 4) * CELL_HEIGHT + metric.padding.top * 2); + glUniform2f(font->dimsLocation, CELL_WIDTH - (metric.padding.left + metric.padding.right) * 2, CELL_HEIGHT - (metric.padding.top + metric.padding.bottom) * 2); + glUniform3f(font->originLocation, x, y - GLYPH_HEIGHT + metric.padding.top * 2, 0); + + glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(font->offsetLocation); + + glUniform1f(font->cutoffLocation, 0.1f); + glUniform4f(font->colorLocation, 0.0, 0.0, 0.0, ((color >> 24) & 0xFF) / 128.0f); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glUniform1f(font->cutoffLocation, 0.7f); + glUniform4f(font->colorLocation, ((color >> 16) & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f, (color & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(font->offsetLocation); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); +} + +void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) { + if (icon >= GUI_ICON_MAX) { + return; + } + struct GUIIconMetric metric = defaultIconMetrics[icon]; + switch (align & GUI_ALIGN_HCENTER) { + case GUI_ALIGN_HCENTER: + x -= metric.width; + break; + case GUI_ALIGN_RIGHT: + x -= metric.width * 2; + break; + } + switch (align & GUI_ALIGN_VCENTER) { + case GUI_ALIGN_VCENTER: + y -= metric.height; + break; + case GUI_ALIGN_BOTTOM: + y -= metric.height * 2; + break; + } + + glUseProgram(font->program); + switch (orient) { + case GUI_ORIENT_HMIRROR: + // TODO + break; + case GUI_ORIENT_VMIRROR: + // TODO + break; + case GUI_ORIENT_0: + default: + // TODO: Rotate + break; + } + + glUseProgram(font->program); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, font->font); + glBindBuffer(GL_ARRAY_BUFFER, font->vbo); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glUniform1i(font->texLocation, 0); + glUniform2f(font->glyphLocation, metric.x * 2, metric.y * 2 + 256); + glUniform2f(font->dimsLocation, metric.width * 2, metric.height * 2); + glUniform3f(font->originLocation, x, y, 0); + + glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(font->offsetLocation); + + glUniform1f(font->cutoffLocation, 0.1f); + glUniform4f(font->colorLocation, 0.0, 0.0, 0.0, ((color >> 24) & 0xFF) / 128.0f); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glUniform1f(font->cutoffLocation, 0.7f); + glUniform4f(font->colorLocation, ((color >> 16) & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f, (color & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(font->offsetLocation); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); +} + +void GUIFontDrawIconSize(const struct GUIFont* font, int x, int y, int w, int h, uint32_t color, enum GUIIcon icon) { + if (icon >= GUI_ICON_MAX) { + return; + } + struct GUIIconMetric metric = defaultIconMetrics[icon]; + // +} diff --git a/src/platform/switch/icon.jpg b/src/platform/switch/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..007c27d8cc50ac8e89f6f1bca7e4dcca4306c0cc GIT binary patch literal 20431 zcmc$_WmFtZ)Gj)>B*7uU9fAiE+yVsm!8JHRW^k7v!QI`Npo6=+yTc3++#$FI4)0m_ zTkEd->z-d{cdzQMuIl}Cch#z@-TT=uOD}%_IC4_5QUC-51c1!z26%x1B>v0&zXkDs zXZ}kO|3{FJkdgiqM8yA2kpB}zBoq{6(e2NxZWniF5l7=wUDm5|H9KQ0fGRvZ}6O+;tnSWW*~LQUN?zGwRVm;8di z#0)%zHMMnp=dTLMU!nd({2#d2BMR~>;;UMW*J4>*03res0tzx3G71JN+H2`+0RR~n z1@#q83=Ln^7@g)ntZD+T?&()N$G?O`A3mGJ*KC~AeNhX@@8OpCrfyn0^RfbX`wD`H zi-Zdh1w8+}f-uPe6aOzJS{7tXDZ~n5jeQ9MwnY-0dA-I!a~a*}VF^$nA=9@j0HPxQ z1;nL9Z?wpFJe!A`XJl92bSg4@G@5HM^7>4)SKOMZCe%@HH2$YI zRNiM}RPZh-Z|Bp2h2#heF>}1o+tq+_V&>C-Z#|=)sZ<;l zuMWBmc&1}jY^FMx%jlEprjZhL4RqD>^F4MJKBF*b6FxldIM%C=5?DXcA{BKu9gvkt z*T*J0y&ZW0jE9$i1n#BI!>YGGUqN*t1|CEh8Jp}xHRYm=18_93-bt`V(a)-uUxBw8 zCEA;Z6Q=`CATNArs@)2RwwD+nyujR?&p1#Hn53-#|DzQrghcFj%HS%81d5-hGc}Gg zXk3{q+!$A5BR~74P{caOT|i)uIa0q|n2Ui{m6!q< zWzF0@v(aPY*I`e-8$K<=3aT_H;fr?a=tJw9I`X%ArT3)BIq$1sg=>>PE^SuobZwc( z#;3(ty%XQY%Xa<2u4&>QEakGEn0^6FKlPI~_N7z`yZ}6!3^IQ(gFx~$#?>d zpAke@IjSnd3O>Zv`Ks)3Cim1qc$f|@;k-7Xh4mhV7wWV}Q%tZb2{zhPBpRIJvO$Rx z*oh5`*KlnkR|HCiNrxn;k;cj(rbh$$_9eNa3DJLjdT)|-DimqqJBJZV1>hQfrS-YM zg8pQ&pIxya!Bi-xLwy)N{RZXPhHQekYvuj`Ur3RMkH_sEXdmvTu@}m^;K1v@w zK-$i7x~=4X$8odPOHltSx8+q-$+??q+H{9Li4T2pKO4GOWPaBAwRNu(IvhL-g@tjz z+@B}hy`FrtSH_lk+~N*tpGCZq)@qz4C+75i?fk@^k|!1xz680WNMfQ@0RUyc>7uz$ zw^Y#lK9t45g|De)!W@{yJDu-XMEjT{9o~$6BjDL?^wZIHY5rDOS$uI-vF%l!e6!pS z7IYEBtQhPZQtB#81?}>e8VZi{s0M3(H?CBvt~XtTzAtnS^N|PD2gHY@awYGj^tsCU zZW3yDya4i6^b*_$X=W98jvu#Eibw@Nf#n&SZ-Zk)5FUwGtXGCewU>AGw1scU-?_>i ztBFp210mn4d_}t`m0!(SKC$MgJ;Y34JRS=_`nUMDlX(NWnFww`za%8p!A8=>@MKme zmC_02gWmAGxr{FeyktsD6Bb5LG%62Vo}1~dFd->jNtXRfW!7~23oU<#>s-{`^t2>J zliwt1K4q?3ID}WZr^U`_jfy^uRV1s0zAx|vpgW+uUSMhVaHFt72FR`=@{9RI{bLcX z9>ZLa@~tW*Q)0DuU-B!KWLI>jj$Bj?EXo`TP=9YUOdMT<_ShUC5OyUalCgk1?5w5r z>8fQ{_V+TR^fPh@qi~F@>k`lDw?b-#xI+R-Pp*k7sC1O2hv!e!fqw^riJZ>q+aJ!b zkNFZyn1r8O&>vak26E3sj8k}oCuPh=T^I7{9-+VWQ@L;_Dzr!v5wP)i?$QCayxWS_ zXI9x!S?R|RxJqA3o54Pv5YM`;zraRS=sf^W%O``(9gEw}nnW?HEa(k8wn|>2&pYw_ z_`+g{EE7Eo60;$n%%#Xd&2mxT z*@D!=ox??|kXLVn$X7OqlnMoe^g;8@(7$ZYRU0fpqh@1%C!-vUP~H&Gdo;AMd^N>7 z>|E!6_2x$+QLDB4u!$9xiNNbz_ua{AT2sc_j~M$bJqGw{5iu@t+hPw6_nILywG(PR zF94iW>#PSinOd{DA!bK|-&5t$hn25KG=NY3L$V-3>1nm zS-g)K#qHmEn%$?MLby(C;l$WUdM8S2@nb;@f(D4P=1pPt*YrQM3>pyMer2Yn0;{_s z?J6qolB}4TxYwCQs}BtP`IH#f(2YwXLzx6x&u7R$I^ij+I9SjejB1bXXh_;+IFDaKjf#vqtsW@7u5w{XzJhWe2^ zcw)SwE1M0OJ9}E%RP{ADKKCEz{Vel0J)iUQV%JX!aJ|2%3LiMLdZPC;nTYRc3oMb} zXT0FfYp-z~ZhZLpqj5!Q^pFh&QXEYXK9`YQ#&!mv}*|w8^mGbow=g8^>a99qp*mRQzBQT|LU7I+c{Dq&qaY^)k z0ca1~gKqqF2^o>wYMYH!A#}b+K}k8y2BHGFotCZQaM?zA5bezq&6eq1LQ|Qk{8jpi zlRTBd)z)hdpPS`nG6jVlz|X2n zGk6)NtL4L=T#IvS9Nv^^n*4h02^y|ef`IXxH@u&|Ua%8{h@LN)RXcdNSjM#_yz}Q4 zJ)m1U#nM|7$xD$4du$G}U_+XztR??e`dwByBj>J~NdM88>q&-?5q0`thI|=A`NvZ& z@Z*3OJt+!H#)oUqyo_pPHP0z>GCy7SrdzxcY7 zLueV#vZJ>b%@5(2btrH0(7G3>yChtB{5=&>0jgy1JuzLm`TNQQl=xJx(gpBf_55tmvZOe~cF+$nrO3iJMX zc9z)X(oF@-$v}Gk`(Aa~std&TJtvD-wT9RIE^{p{Dl^*Z4$r3R68+o@;2)utq4V?A zlN)gm8_Zq%F2xR1pLBbe>nfV1U%pmY=gHTR^SR?%(~`j+v}v0MtCY}q<5V~y?859F zh3&e9tl^JGBx@bsr^PVB96h3gos4zrScqj#7cX$K0)^f1qA{4O)Byz5gUa-1qX!vtam&xIelVpAHIrfLD1BFojtggP*J6i0lWgj9^&8#0iWU6@HshaK55mD`(O=@mAQPYp*Tfk# zkGI8sco4RCjG(k5;H)(s@toKQJnL<#5{HD>rMSZIO;;&>KGvqqW zZN%HkW(Rl^4%V8CiQpOdX(UIcL(s4cLgpR34Do?cP@e}|Jqoqyjd~Cw0;y)ugVHhk z=#l~K8;>tKO&Zn-9Md?Z19?YZIy7f~RkSc_*&j3j#2^AsNrRBXp#X#sR6{gju@Bt` zUFX8+mD|^HxBdNgHEMzFCT(M;pJtYH-4YE9^pXvvXA(dA!NCwY7VY?6MN+SeM#d~) zfxxEUDl@rjKn2wcKzi}J{mt&$oy%l(yIDQ=*pYUylJ4yBF_!7bEOyH#G+s`v;Z)#> ztKeD}ir2Xm1s;3fsLJJDB%?vbwztlMn8A+ zi?ZJ~ILNjF7aE2i z^Ro+`>I5NSz>^X-t^ z3$~fr(@7`Y2|&>d-D2e5n?xq_vHpMqZJ`*vsMrE~KfVB>oMo2cE(En`2$wvf=QG8q z{>+c+qEyZ*Ky{mod}a}aJ8+&SS>82CZ*DwUpW2=#=A^Fg-Dxt-H~U_e>J+q|ZLBBu zxC#e;1m%kU)zmP1hSqyeVf+3=@y>;1)c$N-*;(+tUL6q5I`Y3DG?RlZI#HfbmQ+l^ zj<4>uj9ec*b95_Bn_N|se{Yssk8)js*cz^GaxW?*Fr162#cITpn#DVE1wrb|3$Q52 zwL}YSPmewqT)c=LE$;npXg$t|yv6NAmCH(?kcZPcK~JV(#?nzdlGYoq$Yp5N_7jz# z5<1m6;S^W$Dq2jCntt8N9@3c#O^3`Oqz3c$`PLIMGz)tR9Ys{9PpJA!!6N=MNN?eL zU)8L`EeqtT0v0}s{iSt=o@<1*CEEffcOSO1YmfXSVcO~0grW{?3Q+lpK-sDh1&vYQ$G3h zS+rqL*J`4QR**oVe$i0q2{>B}42Sq&v=1(MAnvnJ_T=d_Qf}@ZPD^+w(W5$|b~_$( zEh4-C)c&+i1m2)9RDW5e5!=l;$ObN3S}6nh9&V>O{M_Q!u0*}O$cH@@|RO>eZAXjjUWxQq2)j?cCq(9ufcO4&MbY-A zw_1}|2Pib7v}L^*MLe(ks4!?I%Ab19#lkWa<{3jqAmz;$uM@z!GCeI9sGOjL@B3ESF&MxAKwn9&^iQ{*2j^S(nQgAHj*^N(eHP{gnxA`H2X=R zksSZzm4J3wOmJLCQK;EtKi@~c_4VR2IQ#0L#m+08vQ;b`!p}<@3ylZc1F^P`(IQ7& z&+%gO9{Qp|p8}m7Y5irj6dwYY=I@D|@K-R!$o_cCtQVIR=*&1%Ow|!L*!?hl8;@M&*_wxmV=<=*+n^ej)w1wB!)Sq+KmPXl3T{88k6REdVX4jL2>Ybgjx;gwj zUEJq*_OWr_pAcqUDQwGjTFv*!dhVEr-~ZNz>)h?aJfgd$TO;vsc45&PPg45TnKj*M z%T#7}QJcb>)BGZI^1t58Y^ywsLxqWEi;sUVAjW%z-;b|oS&+&v2bbO0^mFMn3y=LF zAEZFbKKAq3rrSzCWB;&~vBXiQb&Ei=5~O%dB+B|*{Oi=Z?k0w7){>vZ{LKud__Aclj<4p=MP&t<=;1AvPGTg! zwtZOzwf9%GD)K~sn(?2;%saPbw!6b7YIIjD=5jll2ikHy@tj1Jx!?Csz0TVyrO9F% zOLJ&XCj~CkS7fBlH;dxP%HGW+7RwctCZ*{&MgTiqw|hF#R1M49vr~Q+T*I(|1c~gf z7$Pj}Ow@89DO&bZ405dTVz9umqK8E2UJ&!=){~7PiHz)CbEK!TDb$?p6u5bt9$o)g zijeC+aKm66s9nc`9c6%6-wYzzs8)?2s~a!2FCI!2SPyC}U`SrMiKtH}8E%^G2m3dl z#wd8@7#`&^#;vAoPnPp3Dp9xQ&7a00-?Nw=#S=ebm#K!|pJ4LLD0!U`6X=Zg zZfk{?8Z|^)Iu*Ks9{$8uedX`;*nfVj*~q?$5Nfx71i0m`ZT6^ zP`>^bfKYe6;Zml_q^<91;&$n64({8AqHoSkD>#2$!~_8iN$Wo2Qll(b5J?$Zxq?d>aVg+ zwZDP7dtP2^9Pb;4;hk>D=b|E(aM1~f+j4Dgi%UNv(F#i*N%`s53GCuH@KlBJW~2JD z-Ldd{@@9SNW)it{7Yrs}7CGu4K=oLl)If*5A>5}(tE0{7w$SaamRqdMH*V<#KxXry znpDMEX+FlnReq;V?{bJ0`i_@CUd^A4LB?7_slYC?DlK#dDfNqsBw? zhTYS8r9d>MCx8&2CVa%_TrY&2zP`An&J`$vJLOWczK}EBKQd;8xiK5o_nqxrvpM#Y z4`^`R&lHbmxwXBq&y2i5RyVhS=hT|@ns*s;g1ON$n4ssVM9TGc6hCve<2J=gt$6;8 z9-wjKZkXtrUCn9-a6-c+>{=dyZPkF=%`gd*WZB35Kxv$OsMwcdZ}DRZpyld4Rti89 zjMm1pDU>DUi-V(4LSvGJGg&0K^vB@8V2WX=tKlPW+akC&zs#7n#HWw}`Q2VuL4?kN z>@P@<}P4Ou5fnrHy6WZ;D16682NyohhYW zNj-h27VQ8`Pq^442v$Ex}bc@^yRJeIhPWwjSQ z5pM*K2vZ#hT_A847Z)#-i6KWu8S=rM(zq5+&h=9+>fJL=km5fP%$ChXdMJP^umF%LfZ`?q{9U*8O zm3`L|tIR8*jjGtPWAk&Bec`@gI8^z_R5^5;cec@KqzVgmzaX`ELus(g$F{S8SRQYO z7Rkx=b>u6&N&nRj#5oU8dNTXOS3J!;q;$rym4t)l&}qFVCq^2#XW&e+**v8T&Jk_M zH6cc9;Xn9ZW?lqT+4|vtYzwRlqWhOSUoDE-Uy<4U_{}2IsVD|luEN&P|PMW!8H z$M1kd=W^<~L^X*?$hqEfup!U%_KOpSd12ncPh`FPLE&UhYSdn9!YuDwJ00UJTvUH8 z{DDtx$so)R(i<-w>Uobh1&CoVPmoN&ZP&(*NHinL*UH~}M#d19Hi)Hvlc1%^GlvsW^YLOMw6E^1WegYg`Ukk1Tv~OsHd{EIxY$jn?L3)haByF_VU4fm+aTfOTin64i4Jzd<8M>_J!uYSx%Ym1Dky zt}rf0?Fc+qGrC*vN%oP2TKFce@?bI_^yLkATOcwYin9NpIDasiST`CiH#Mt0ywA8v zWyIUs_Nq3#U1-jjWYNo`jg-|XslcXf7^7~|{&kL@5TrWw;yI&v3gPu!+7lza4_tKG z#kOl{yQ}9R?1oO&2{s)jRB2z))c($Nz%6+&`VfM6^pAERjf%{YR(JQCIq9{6R^z$p z)iI77T82e^ft@hXMzhx3qfj%7lClHSy)?%V23lHj`KpBZ2MYuK8d0-nw9DJ{v|h(^ zqfV>lL6dW{2K54xwokS%&Ib zn8J$=-hK2Ji49l8Ti3@ze(I#LD*-pVAYU4S!b)l@OFWXFrKKiIy{D%9PN7FphFLO> zCVue8$hcZZw4c8mo1f1nDh*`hCOEn00&C^v43%@3=Wsh$k_d8I>e2LSdVewIYU)tV@|%a$N3UW z78(<4MVN#XxiTc>l0WX4#y!n-k@fj@qFiPkjB0Y)Nq{G15%OL+nAKezM`{vxU>Qjno+v zskaVyRneEycsj&jwsWolnja)*$%;2O|J9RGMf(}{i56mdszQ4T{e30Vgi&Urx%@cY zv%YGD_HUj)uYoSkI|!s1VA){6y+AH9aq(qbBZ91hI7Lz~|M6-eUEgi#oYXRn-W+AS zxDZE17Uop-8Kd+`;Rla#-u?AJf5{SbMq&XNT)n{tv(V$7FG^zNwoZfr6Z75RkeXko zvWBbHDCth1&||L$t;0&&J`dZLvAKpNl;wPqMTD#_L8fk49%)vy)IS+$%?kTu!*`o& zc^^Ifc=cp@bioD{%$*Emu0~B0^ug?}rBG#A`CA=@AepX%NJ|mo$xaFlo$$KfLK-Cq z?5RU&_Ly;hqh{M(pTLKLPZ-SiuB7wA9Mo6T3$M0+Q?@hTN&rk-#8@JaBEM5}L!QI) zQw{d$2KP^SCe)~vG0FM#}$ zw5Kxq5z+`fH{`p!oqoSMZ+c8ju2`O3w7fGFGL4o*uS2mDp9Gm6exWjh!fHAc5G9^W7VnglcCB#oIe<#V*1N-tt0!1b(dkdMT=)rR)$upcdR{ie(G{A`o-FcKFa0Ibq(4K!tF@y zyTEYY8LGR^+F^r;lJ~L6sF(!=;l&FE>b>h@{IIeN$(~ojzSHkNy`g+0S&T%V96#1# zwMx^{G{3v24B=XJMB%8~c;I0s2+*9C!#?a5nkV;N#A0s}+QJW3#4(IMI%Q0p9Bc{< z^ht}UI%*)B8Aw{L0HHCgFx0`5S9Y1ioDzEXfM{XOfZc4K_-#ATdd-6MOrZ~T0N09o zmD&U$FQW|YE_S3SNdu5_I$y5Mfsu13?pfmyA05)N_qTkj+hu6trtwiLLybDAx87)) zAh*Lsj;#*jJ|c)!dj4>G0$&()cmWJlzSIBMHdXB9nT{KmAVRR!w^!$KvlDyu@D z{(9BrHM2}AcJL~a>@d{rZdG&X0SPa6IxJuXxD`Vq>)7H3?4T2>|G5L3FSdClH39|i zcm1#3r5d)jKoVpjlN>VAs#EJ5> z`-hv*<$5)ROE`tkElZ0*5&S$%)9M^-!os<^mIhjiVzZ6!M3rDs-Ov46_83^f-lTcc zYV;7|Fzjy9_&AX^(y(0nMzccuxH(^+*ZtDaXr+?XpIY%(k2h=LAkZVON-&;_VcZq! z@w?XrRFBhsn&Vv19@F8>M)OvJ+WWJexV^d=BI<@<8*{w8g*hJMTbG9?o4#2~`-COj zPO)~^1h{&*7rQ%WcYCg9PCpiI=FYugmfqD!FU5V}>eY29N5z{hf%kADQ3i9M5M93 zas*Ji*1O4H08Y1NNnp>!a+ZGb2HKQ~vgP&K#Yl3(!5Yi@E%Ex~q3dQlQP7Bk1?9K{ zV>(!rOL>N;fZ?O8Jw*%wi|LMPj6;^gH!J9H0zdYr-s0G?kX8A}a;i&e8P!#03Ztl_ z+7rdLh=-5E6w`x$-f2miO)vOd$TP){R45|N8cQVN`snDk3j;xTUI$jq zg&LwN0v=2%*J72(bK|?p05{{CH8fv%xLjwF!lfPkLWY}fbVG{tIiPY+PisG{gfv6g zb<7@f;aGGRAL$uE3w4a*gh78VJg0KUV5T#@Q=lAP6LGQvv#o`n-eTOea)?fUqLm2yC7@=_P!m9;X?iBmKck5WK?mn7q@DmA4$GI z8^`S=&`-|qhK2TF=r13g{l0RPnn68pv$~dk_y)NqhJ&2Su}2sj3+6v{5xwTk z1U@GyvO)zS+>IX%^%IT!vhS=VzP zen@zqXvw3MI(Sm%f+g2#agazbOd?EWLS(&G>9LOS9|ETNWLH_AtarC)yk&dk%j1+r?ba%a9gztu>? zalm|kD5CSF#A_q{CSoAMxQ~BR*!o);S$D?{WH9;MO4JEUTGS-y8@-(!%KaASu9+@~ z|8LML#&C7R0yO^exDMCe7-`(bxWN$V)~I#&E5GG*(GRNWR#|z{h>*8ov>Azs=xqQ9D#`^Oyx`cLb zDXI|$t}|l+XG>S#YaK0w)=trX_>sZ&X&YVeaaLwMl`Q}r=$SC4BDOEo>O&s1E?E3| zC)567KuKDJQm)l0PD_L{z^qwH8i};;1V3lEQaSlgcRf$YhJi*+G6V`?Vnc>7F{^be zUi^yJs46>CtIJWn@;rG@GIwk|W^v|LQ*ri#P1)qcx@~YN4=kBDvJgb@@d8@o5i4^l zF#lfqnwNS;VP!IT<%5(m(MpkamQfb{r@hfA>Uyq6#m;JFQRe2@n%LaJqKr&%Leibz zVlrP)y9uwR?F{Gs2gPcbWXCka*4gF#Hd}w&Rb>zYCbhReh7yd5!rVi8s8yDsoq$Ml zI_hJet}JmiRf>C5pNf62n@eqrsGf&Eg09e{GY9bF))<|G2-?>1HpbSrHO6SM7|=65 z3CER^#>Nyx3_7E(HX$k^HRvA|&LR^0%w#3PrSk?DKLYf_yrDZ8Z@yToZ`tq3TLn94 zG^y()yi&^S^;~|yE}$v1Hjse+Ac>~o9||4A`XR?^dd4h{{mdjII3dz}^l$b+K4PR4 z1rr@gy)Is6m&?+$%#Edo7zmBpI3FDOjL;`(5X!&{+*aY8N*(0PyUk`(gpoaUq%}?83CL0^|EFu>V+IW$>_Uw`7^$i5?UQ7ea~$N3lJ+2s17#^ZOiTor7(V71K5gx zY;!&A7hC^hxx174mN;|bW#IsTw>6v!X`!n9^pS(Qd8ieR#FWPL5!gd)G&mdcZQql*G$$ng}DdRMA*USEN(OP`p{nN`c@uulb5UY;6^rVB=M9M zO>=wIS((0f2d>hqhEH_W8?CF)jy~O!KtG>*$0QV3@yt=JpMDU$O$1LKGmS_pnHMHq zTfPn5hQ0xb{eXipHS?wdc+YgSRLhUe_<9AV+JYCZCz+bQEJ#N5iK~}=3Cde|CUh^= zmQ_$MOPULOSliauT)G;u!q8k-5_-inHKZX2Y9QS+9~(OW@i2D3@`6`gz&i1SQy zDj7mO?a1gxDi^nbRk|x^wZ4D+y^{DnhUdD#H9suy#DR&O6uToaM8ayYJOYCbVSK*d zMKHVlXhbT;dZEeQi(iL`^;sgKXW}G^KFoc=l;M?((`)`mPhE>2^PVo+S!5ZG!vpQO zarM&Rmi8Ny=I%PyRG{VParCYqJ3rQAsT(m-C=2*gjXTr7$=qB19v6!lQ6IF>EvxmB z?u@YFxUGf0P<2hASH=6b;X;BAD31E}TMB}KMO0v(p#)VVp~dbO4~f#M?g1<*tj||F zhJ{W4Zi)}E5g(e1bXlMRf(h1A#HA~aH+BMNQF8UGDc16CvON9LaYorVV+}(_m6;;( z{NWzho=5x2c;3uALfj6rebP0rE&xvb0u@`${af2tG7CssZ-v@%xZ>P+IF7KSI=(yd zI605s!K1Ke7mr{)aEo4EF8J5dzk0*5Qx4mOC()==;?;gSqV_qZ@xP(Et3fc#2dFCh zxvu0I34fT@XNP!cN9e;`lD$E=myq+Mg3FpEp!pfeW6*_UmW6Nl+}2bbK4zv1(JN2T zwp=|)pwJk>H?A*BOOfi9u*YA4g4S#Obg=%?<`4>bUfpUXd{pmcLff`x{V6^Aaj+gu z$9-gibIgNpPFBF>*Vha?1x=G6dDo-3q1e-LZ^oP?N?Zi#gyI9>`U%fmHpiD7@xNoR zKp`#GF{ek(N?7)UZIdf5sY(SGr#kGkw22;O3T=Ya74-o$d%V@l63pocNkS*5bNlGK z`}hhbDdNbNnoaMrDrnh)!f?mlb8(%8%Ir`}&Lv*t&~}#BJSy_-kMN<+WC_g+eaGmp zNAV!?zTx*6aP%rHquJ@TSlfm$za79}6ConKTbLc%p(A?ys0;#4R2H8oJS5kXM3hAh zr=q9>8KUT=FjF1Ei5MR_K zW0k=vzT=f->p_Q(iRYwknuABP`*GEwzI^s^@O_3uHt^;VhhKr|Id-h+`=gi>`qXAm zFxv`YST&tQI9!ZDV%lQVVbKGy=O8Y}pA4P*stYcW8Gw?3MGcblkq9?M8x{X@otP6LGkcn-l@W{=q2g02Pf?sX?56G9g_N!GnEFW z9TMBT-Z$!=^$!^EG)6O-z}@Agxja0QYG9g=mG!R6?SgW1E=(KqXDI3AcrDe^u|lEE zGF6#c?IOiahb5afwSwhA3nF~mBAq*i&YHCwmBx#)CyO(`*?U>mY&Dq>^zLr7W4wp= zqE|YzB*LFdJ6o*vs$>zK7_pqQD@+zHJ0~B?B875t*d!8y+>W&GpQ zlf<;lPS31nzXbsk6r~xG$f-ly=D%Cq6d5gLEGsc3nF=I>&J{A+le=cCPRD;SruBal zABn$H{_aOm?mta;1?_HyDaKdNzW`z@xsmnS{^U&}dZ5~ZnM6=RvYD+xTFQ-?dWs*h z&o)l@x^B~>W;$aZ$9=)|&ZPfVS$4Kdl1l0!vbsbnb*uy>bmXB_*T@vVDC3}^8-u}Z zv!PG<8ZGl45rIbTo1{ru)~x%8hfjb55tN$gx3M969XOk}&UXqte)T~~c?=Q;i(lH) zXXzKXOL(bbh=qpf`~c*#bN~@PVs14D2f{ijt7rnv*2EIwZpt4A1}0t!vwLdIf_~ZW z&9@{->(;mtiGX7!q4(ws+pwD7ZD{v{w2tV9$Wc#U=*a~TnJKu7WVy)SkDq=3fBkLl zE{g}%axY;D@(hRIz)k|^8SQ~}6eU2JLmq~eWy5Kn?;xFxX>;(klpG&I==ld$baE+2 z{w*?VfkEBcIkJ8ti96f?>CnCVd(HPPO(HQ#Q!jvwgS+ryA+nadz6IRs{W7)#I=iMN z80Bkgm20>;J>{_CH=NwuyAUSvamYA@c`HhnSdz52AY44>zM7f=FP# z18#8~6IyUwQ4Y)0Qx4nkQiABa6GR~VyWKbiy+GRkSn>IIIuT)H4bY& zwJaAKCP_L48O;R! zSPZ%_Bf@@0q)OCXT9TEhGlPWdxb!HRyb{lYaa&=6d=uOU-b|pTy7I6R*AZ-AwkxcM zTuA2KM6RxO^+1;>3bW8w2;LUljpY`Q5fcdsMe&=Lp869`vWHxjxX;M%QrgYgitH4} z(o7DR8sgYt%SM`g`bAK}*39;+@b0)_!)g!*C>Ou{u&#c}OV$|0HF~ll=+VtVV(v5o zwN;KvXe}xZeowI?&lE`EREQN?lMWe0JKILCfImo=DEuZidvhJ z##Czhsz;Eq*E~mQ0q6<-LqvK3EgO%%CNv18|=RwXjDO>){4NOWpAH`5$ae6_&&V>UM}M=BViVQ8QXU6^u27>+B~vfqy5uBFL%Gp@6?|ee=NC7R57j%a;$o zC>V*Lhj7w-4ijX0BX*dC1Sh%ghKckXk`gvF0#hfKz-Ass_QF82vo9XoBwTKC+4OFD z37Em{{wEa}LJ0h5u-R1|EFv4i@dSa-ar3)di~}}*A9^p#YUoGE`hvbCj`o7?ft`^) zC8sPXS}SC_=s;Oa<$0hobHWWt|C`TP-ZouIN8JOGwm90t51JCQ`fEH0ar~ZXMq%;d zNg&60fkieeP-D6as61{gs4#BB4>5RE*?N9RhkJp&cMbXX-~+!zAMIU77}ly;lvAIQxr3G+6A_XrV*$!QwVPk3M?ShL4z z`iPMToCW+JkxLXVi~0drtrwTBN9r<-ADr+ANhCO8MBjC(i_F~;t|C(mG|ycdNb9!y z$ZKRl($14zS?vLsT(Z|1Up2^*zP?6}m4^1v1gZA!XhoY$u#p_EUrDLeKskCP4msFt z^xfnZ2-f>z^QtfeS)3M|%fNI+e@3mnF}RHMiIG1GybbEfoY*qKxj@&3<6#XJGgQ8j zEFx;&oV|z05f@+y>@>i;b;pO1V)HQU5`)Owfa2(y!)3ZKi)MpU#TBXn;HgqjqNI!X z=aAl4H=)PP(s9Dni8|r&i0s>TZ;_Fdiw00J)@m$5(<>HwKf~I;r1d2E zG5UD_Fp(^B#gB#55i$T@mM9h`;3b@&(-&kIskp4iC+cUv_}dosPM`IxHS`)=Xc5_Pez`R_~@rJ;Ih75jF9`r#>fAbHhlZDu?Jn@zL+ zo>C2cDw}L<9rsq#tRq1pA!6=K!@BjtPf*bAyys2OxsFTC>c-k1xnbKe8lM&?-Vblo zG)aYAs8iDE--t`l7Be;<=_U!XcF|kOyL*obt2#X@)4u(_*7${xjyPyBU=>*aI~YP6 zH&^VuFRfU=$YRfHt_ws2ntk~N5e6J}tS3nyt%&60*C|?hkWXi$Z_~eqXjTjUZ88#- z`DNT(f}*4J&i!G`5Qx6ZcYRrI4y^r+C#1;Vtu7^a(HTp*{3PiK-dJ^gatnHgYWMc9ZkYQ( zp;;R9ri4QOWQ!pE6`VXiRtz|`iPx>UAuEBd^oI^}^yYD7$&UlW1((zlb3J=j37_B> zM7ocXqinp>9%~@CGX(s}E}h&WBXHZ5pT8nwBK2g1t>f)E8g)Ni2OeFkor`pwZRbe* zu_Y!@Gus(TSI%+v{qA^<#nGb%1TL>9BFNM*ffddrewC8Hdy%Q2#H&fZQU? zu%+0nu(gWQsa7T!X;gEH_H_PPZd1a~pB_>hbogx;Xh<^{&hY;h8N&JqwNOdrDtBx8#AX zG^%U4c=0Juh=fyz*Gg7ohP5juTS{xjd-OP*Cx^}tgA`4)w0x8LW+oL8{{%d)66=CG zW&9non?7{kdY`9Xsaa%(RZ|%6!F`t0)MqGttT|4q^vsgH^`cEg*gM~ea}cjAT20nZ zxMEnSeO~GUvA;>0PeLR8RLYY&n{OxIt^Bf8&#QZ71SB zyUkV6%?qH#s(*em8-CVh_iR17`g=4gVoo`dRYZvSyDnc%%B>ChqroddI6m91V$sj{ zXZf!3Wu<_Nh~eU+pBiWC?qS(4&71XIgYS1VxjY?OC$eh`=C>O8s8pdpEziF|m^80l z{tMl$kxIAju!Ou1bm<2paBi1iv}s#HfaULRrexoZMicN-F&VQrs2q78vNZ*`m8i`q z{^;ZOU4bmYHEQXD$T~fHEr;YAWn^Vm9clP$zBLt?wie6i>G{^zAqF+SO2u-6KP*qeH1?X0c3l-ISVPq(Wj9g0Rv6_v0Yi@`|-Rw5v-zsfALDcZWYAmzTHEdP3}jz-ingQLf}4YK}=G#JXYY)j;X1x}Ug8 z3KE^8U^G5sE9}?eW2gBfw`zDWSqF#8245}pH#L4ZNV93GI%HU3KV}7oY>e5Kq`muy z1Kg4astW|z_;xjL4fNuPuL{ng`MyVvtwCz(!zYO5n;#{(Y564> zH7L}*_vFRQ$<-!E(*qWj+Sa`8b1+MFgoy~ZZ2LbttRp3v?g}soCnjbm*{T=lpER_d zv_C4Iu3{a466W`vbg^n=NKp#^nX!7XA%FD1)oo7yyGNgY{Df(oI;oNAdiUT|yb@)t^+P1u^ZD0Vi7ohgCkKD^HQ)%x-3Y)y@dGK_U>$LQ=149bPj`Lc zJ66HvGoNM!QlqNA|4-3@R$fxjz$@L%Wd(WE>;`L6B8Obntnp|h7i*nHfRfgLdEwq9 z8AF$NuB?PA0G%q@D6kKAjwF=%bF_3%D-$p_w~k3h$?{VAEE3YmF2M zEGv8N`P1vj*9C+qt@_>Abg~HQj2tc1tmQt5IjVgMVIOx2bjEEXjy1&Q+T&;+*j*~T zq_u}Os2aj5* z@K$YFIe8{AM96F;S4bEnqoYQ`NwjxdkQ_bfy*^U^}$Wv=7ofHfF`48%R5a#dLMEZ6Wc}U^1FFw8 zCO_#|UjQ?$s*X15(0F=OqMs%*e`7X1eOGJyUNGe$*wv+R%u?hnr& z*YD@_FN?8W07-IEIe8AR<{q{=ldMZQkdj6-Kk(>WzyIJc3r&EiOeES{PO6MuLS9MA{zAy-kO=9JKN={)nP54S=6J5V}i~; z0#V6tcTduZ&JfN$EDMxo{WF2Of%f3LP^Nk*uI?#x05557|~*G}x77>$;noDdHdcu5+2!_Sd& z7@yqljp(0}|7puYDHeM@ZdP3Hc;&f*47ZG}HkNNXqF?+D>k@0T#wKa{WE~)VO1Jl1 zBku6vX?b% zJpZU%Slb)rVTn>#kwuCK2pDGZUh|R%gN^)fYneA|$*@Io;O{QYvhNU?Iz1n@NH&=e zi9Mq-?5iHAw_>29$Eru~Ekt@D>|M?e!fp;mI!F>v8kb4h=nU*lubB(I!r&Z1T_Gxk zb((Fm!Olh~;l$1RqE+%Xtl6Y4dDV!ordOncYRYOXy(d`!%;FgM^^U`{A&{%w-r={K z4;QD~35+emawUz#vE`%P36kShmBSvZneI#uEza(;j`lh$!E{-@3RY97PndCP}rbQ_+>Z0M~ZW z1tW=TlpZF}1gNy>g74ZJq!GS*ESMS2c_sg;C6Tl^LyjvJKxbGM+clOP2ZV?wSS+5> z5wgBQw8L(}!;+Ea408(5YYh9PTEtN9^$}jp+ivLH*XMmfKO&0rqo;a_L6jFJ?>ben zB2_DR8h0XTXLjdkRafyIpFGj#uC8k?W0J3xnTeZq+4M%254O2BC0u6cyzs{jkQ)X* zOaS`RFqw7-$IU{N!2!orhK2@oCXO{rbWX0Yi>LMUzTgJO|se<5(u%JRm> zV{eXiv;1$n4M~5cK3!-9=hrb_eOQc)*9F~GX26yMgP(T%VQ1a~zdI_?^8R(>PXF_o zn)rius0ajmg&06pI+BSJv_b-IgHg&sD;4N&~>VwVft=ETHHohjq;Z4u6 zGUg&vMxQxwd)8#(K3)xUn(E9kaMv15CLyDH?&hkv_&71_t~Y=Q^l+>E zV^ywp6Zt5meTyR3>-sBMVy(zs`BPuvAx1}F?sG&-!4=onLY)t+2nYPqBk$_gF@TkqP4SWG_|K!SF z&60KPVRwspgt$cbV(e`XAwe0twwLwo((O!FOVjkDNvc`(DNKap2lWEl7tZNHvi-rD7hb-bYy?6rSEe{3DTBUIFE&?!{4%kRRau9!B? z_t?)d@9Qbus|`l0{6}VTugJC8@iPE!Zk2YfpMS4Ze-!x6LQ-g=KJ}V%@vz*o`#f=y z;x)Hhe@Z7JvlR0|BcCxhUcD5MCMZudPdvVY=K>3KlS9GMb(2#O%kMmWUEv-qr*t^C z2V5k*o_GsAmTnEn%G)pS8&Aj;a~>Xee+Fn0Kxt`MfAcIWfzvK7_s9b`A^8Eqr^cPZM4-^xH`3qz9EXvT7$MJ#~8vzy*nLu zVqGW1CTh@$c>kv{@=16J357nT!zQcjau7Pr%w}4m@uvHalFd<;glcsvg~^kVKox~W&Pv5gs`jNpI!`3J`-0v6|KT{ zXjUSjx{AtE)$mU%E()$)`)vEu{ztDAz(-2<+;;nM32}D3V5N zlNmV^rjbTXvt?=Wa50&7Hoh6B!WfYBCu%6B<>A(udSl83{sY~I{*sgcN??pNF*<9y zfLN6SNZ=x5+=t_h_MNMow`MIkIwDa(x%f~!}G@a9hS|o3osuJYxI&V)~*?*eU0#7 z{7TZmH0y+Z%jGEsjc6g1gdCnz^f=ZdF-*4{>FXHAS)S0*$oPj?11d_qo-aX=wWBa=B>jyO2pVcpV)J=Zge zzrFGIyyF)4Gy6kgQzw12ePGqHnN%v))>N^&6zlMW*an>&mGnB1?I>ah+8XPrNO;MW zinEe|=ido2_)z-Mf)tIsS%qGP(WrmDVcT$%mLR`NZgyzxh>)qo77xEVXX`zkFg2-7 zw)Iszg2`~G_WBj+fsM6lRo@4PiMRLcDPm6k3uZxtC0+iM`zEHfv)9j^3>+boa}a$= zD}kuyKdKat@V6RXmNX`60k=sNnJcxH1_Jk?v5v7lXv3a@Zrh`h4f()NdBk+Nr;r$# z7>f5Vb!`JHw%D=1z&>RM+eOP$x|(QPkqvq_s2p#hpV-Y>mbEVw&6j{~a( zlz_>Ayx)3U^oA7KOyZxT)q**WtOLZVY48zs-r`f#<$u^20CeRMjwN~X(ri&SowZA2 z)@L#J5x}U%s*)dQJrGwzl05s3&UHU1D2XyzAAhuL*8jUOI~BJO&%85#?``*I<3p1o zK6$@qt=lsgU&x$+b=~s-Pva62FlHX9Z)|?+lb=qUqEW_QcGC#2kTyLgsaQ;4Vhn73 zwb4;%e!+X^%q{AR8%icG=GXo0J1Vz#Ur76E(IPnnmZh%#c*6Q>@5l@lhLS!w0m$NP z%60dlZKK_(m{M3&ox~bb4wM(9^3CobVWILW+=NcG8|~uUeoCi9B2qz~941I7V#RoJ zXldU(OXE~ZDnnV3*_%Mr(EbbOg^Aus*#|DU++scAcR~hkp!ZN_{<+bY$F7-)%+q~* zR{MTbUU_$$(lOT{KOw#gt0^VGWq19>Yb+L!xl?u!fbB|m1{n~Nej(@3a6PBKo&BZH zOp{59#wFjIog^?z9m%=#^Z}FkdqLL(wtFMTWERs7Y zoBS?Us5)7>HRng_7y!H1z!)(V)M?;u*_#g92%+jS$stw`H7sda(S_5s6+~DRXgRV% z(Om%*zhv)X?OYyd`maOX^G%#I?NIBZk@4XZ@6wTCju&~gXq~lT%%TFDLaBN|+&myd zkyVRO?gTci)FedqEAEq$MIQuva$_<-I47w5O{10$MXNZui_@d9aMpX!}7gxA@LQ&~eCob}~J9zN54uf-?R&&u2FHjEJ5&sA_NC5rz7KuRep#j_>(# zcATxqXmxnGMW0Va-9MHl7_v1|$n))lOp)X9gVBIe7Y@<^ONK4Q_VLgJGPCPv-0vq{ za=(uYRSlr|+u{W~M)$%hFmfktWrHcrE%?Sei!yho2g}bSk=i!W91Ll;b8h6bBM7yC z<`0HDAfxN*NzETY;x1 zDLHUR2RK5{0h83F_^3RX6=9`>hno)s-= zkA{k;8=No&?K$uIUw;b7ULgxvAHgKjdgda}2@%ze7Kecx&A@#OBxGC>R$she6yCPF zSq8&;+xJ@o^;3 +#include +#include +#include + +#include +#include +#include + +#define AUTO_INPUT 0x4E585031 + +static EGLDisplay s_display; +static EGLContext s_context; +static EGLSurface s_surface; + +static const GLfloat _offsets[] = { + 0.f, 0.f, + 1.f, 0.f, + 1.f, 1.f, + 0.f, 1.f, +}; + +static const GLchar* const _gles2Header = + "#version 100\n" + "precision mediump float;\n"; + +static const char* const _vertexShader = + "attribute vec2 offset;\n" + "uniform vec2 dims;\n" + "uniform vec2 insize;\n" + "varying vec2 texCoord;\n" + + "void main() {\n" + " vec2 ratio = insize / 256.0;\n" + " vec2 scaledOffset = offset * dims;\n" + " gl_Position = vec4(scaledOffset.x * 2.0 - dims.x, scaledOffset.y * -2.0 + dims.y, 0.0, 1.0);\n" + " texCoord = offset * ratio;\n" + "}"; + +static const char* const _fragmentShader = + "varying vec2 texCoord;\n" + "uniform sampler2D tex;\n" + "uniform vec4 color;\n" + + "void main() {\n" + " vec4 texColor = vec4(texture2D(tex, texCoord).rgb, 1.0);\n" + " texColor *= color;\n" + " gl_FragColor = texColor;\n" + "}"; + +static GLuint program; +static GLuint vbo; +static GLuint offsetLocation; +static GLuint texLocation; +static GLuint dimsLocation; +static GLuint insizeLocation; +static GLuint colorLocation; +static GLuint tex; + +static color_t frameBuffer[256 * 256]; + +static bool initEgl() { + s_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (!s_display) { + goto _fail0; + } + + eglInitialize(s_display, NULL, NULL); + + EGLConfig config; + EGLint numConfigs; + static const EGLint attributeList[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_NONE + }; + eglChooseConfig(s_display, attributeList, &config, 1, &numConfigs); + if (!numConfigs) { + goto _fail1; + } + + s_surface = eglCreateWindowSurface(s_display, config, "", NULL); + if (!s_surface) { + goto _fail1; + } + + s_context = eglCreateContext(s_display, config, EGL_NO_CONTEXT, NULL); + if (!s_context) { + goto _fail2; + } + + eglMakeCurrent(s_display, s_surface, s_surface, s_context); + return true; + +_fail2: + eglDestroySurface(s_display, s_surface); + s_surface = NULL; +_fail1: + eglTerminate(s_display); + s_display = NULL; +_fail0: + return false; +} + +static void deinitEgl() { + if (s_display) { + if (s_context) { + eglDestroyContext(s_display, s_context); + } + if (s_surface) { + eglDestroySurface(s_display, s_surface); + } + eglTerminate(s_display); + } +} + +static void _mapKey(struct mInputMap* map, uint32_t binding, int nativeKey, enum GBAKey key) { + mInputBindKey(map, binding, __builtin_ctz(nativeKey), key); +} + +static void _drawStart(void) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +static void _drawEnd(void) { + eglSwapBuffers(s_display, s_surface); +} + +static uint32_t _pollInput(const struct mInputMap* map) { + int keys = 0; + hidScanInput(); + u32 padkeys = hidKeysHeld(CONTROLLER_P1_AUTO); + keys |= mInputMapKeyBits(map, AUTO_INPUT, padkeys, 0); + return keys; +} + +static void _setup(struct mGUIRunner* runner) { + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_A, GBA_KEY_A); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_B, GBA_KEY_B); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_PLUS, GBA_KEY_START); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_MINUS, GBA_KEY_SELECT); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_DUP, GBA_KEY_UP); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_DDOWN, GBA_KEY_DOWN); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_DLEFT, GBA_KEY_LEFT); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_DRIGHT, GBA_KEY_RIGHT); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_L, GBA_KEY_L); + _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_R, GBA_KEY_R); + + runner->core->setVideoBuffer(runner->core, frameBuffer, 256); +} + +static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded) { + glBindBuffer(GL_ARRAY_BUFFER, vbo); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glUseProgram(program); + float aspectX = width / (float) runner->params.width; + float aspectY = height / (float) runner->params.height; + float max; + if (aspectX > aspectY) { + max = floor(1.0 / aspectX); + } else { + max = floor(1.0 / aspectY); + } + + aspectX *= max; + aspectY *= max; + + glUniform1i(texLocation, 0); + glUniform2f(dimsLocation, aspectX, aspectY); + glUniform2f(insizeLocation, width, height); + if (!faded) { + glUniform4f(colorLocation, 1.0f, 1.0f, 1.0f, 1.0f); + } else { + glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, 0.8f); + } + + glVertexAttribPointer(offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(offsetLocation); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(offsetLocation); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); +} + +static void _drawFrame(struct mGUIRunner* runner, bool faded) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer); + + unsigned width, height; + runner->core->desiredVideoDimensions(runner->core, &width, &height); + _drawTex(runner, width, height, faded); +} + +static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + _drawTex(runner, width, height, faded); +} + +static uint16_t _pollGameInput(struct mGUIRunner* runner) { + int keys = 0; + hidScanInput(); + u32 padkeys = hidKeysHeld(CONTROLLER_P1_AUTO); + keys |= mInputMapKeyBits(&runner->core->inputMap, AUTO_INPUT, padkeys, 0); + return keys; +} + +static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { + UNUSED(runner); +} + +static bool _running(struct mGUIRunner* runner) { + UNUSED(runner); + return appletMainLoop(); +} + +int main(int argc, char* argv[]) { + socketInitializeDefault(); + nxlinkStdio(); + initEgl(); + romfsInit(); + + struct GUIFont* font = GUIFontCreate(); + + u32 width = 1280; + u32 height = 720; + + glViewport(0, 0, width, height); + glClearColor(0.f, 0.f, 0.f, 1.f); + + glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + program = glCreateProgram(); + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + const GLchar* shaderBuffer[2]; + + shaderBuffer[0] = _gles2Header; + + shaderBuffer[1] = _vertexShader; + glShaderSource(vertexShader, 2, shaderBuffer, NULL); + + shaderBuffer[1] = _fragmentShader; + glShaderSource(fragmentShader, 2, shaderBuffer, NULL); + + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + + glCompileShader(fragmentShader); + + GLint success; + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) { + GLchar msg[512]; + glGetShaderInfoLog(fragmentShader, sizeof(msg), NULL, msg); + puts(msg); + } + + glCompileShader(vertexShader); + + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if (!success) { + GLchar msg[512]; + glGetShaderInfoLog(vertexShader, sizeof(msg), NULL, msg); + puts(msg); + } + glLinkProgram(program); + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + texLocation = glGetUniformLocation(program, "tex"); + colorLocation = glGetUniformLocation(program, "color"); + dimsLocation = glGetUniformLocation(program, "dims"); + insizeLocation = glGetUniformLocation(program, "insize"); + offsetLocation = glGetAttribLocation(program, "offset"); + + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(_offsets), _offsets, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + struct mGUIRunner runner = { + .params = { + width, height, + font, "/", + _drawStart, _drawEnd, + _pollInput, NULL, + NULL, + NULL, NULL, + }, + .nConfigExtra = 0, + .setup = _setup, + .teardown = NULL, + .gameLoaded = NULL, + .gameUnloaded = NULL, + .prepareForFrame = NULL, + .drawFrame = _drawFrame, + .drawScreenshot = _drawScreenshot, + .paused = NULL, + .unpaused = NULL, + .incrementScreenMode = NULL, + .setFrameLimiter = _setFrameLimiter, + .pollGameInput = _pollGameInput, + .running = _running + }; + mGUIInit(&runner, "switch"); + + _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_A, GUI_INPUT_SELECT); + _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_B, GUI_INPUT_BACK); + _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_X, GUI_INPUT_CANCEL); + _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_DUP, GUI_INPUT_UP); + _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_DDOWN, GUI_INPUT_DOWN); + _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_DLEFT, GUI_INPUT_LEFT); + _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_DRIGHT, GUI_INPUT_RIGHT); + + mGUIRunloop(&runner); + + deinitEgl(); + socketExit(); + return 0; +} diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index 29cad8e05..2f96057f2 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -19,7 +19,7 @@ #ifdef _3DS #include <3ds.h> #endif -#ifdef SWITCH +#ifdef __SWITCH__ #include #endif @@ -52,7 +52,7 @@ struct PerfOpts { extern bool allocateRomBuffer(void); FS_Archive sdmcArchive; #endif -#ifdef SWITCH +#ifdef __SWITCH__ TimeType __nx_time_type = TimeType_LocalSystemClock; #endif @@ -77,7 +77,7 @@ int main(int argc, char** argv) { if (!allocateRomBuffer()) { return 1; } -#elif defined(SWITCH) +#elif defined(__SWITCH__) UNUSED(_mPerfShutdown); gfxInitDefault(); consoleInit(NULL); @@ -138,7 +138,7 @@ int main(int argc, char** argv) { #ifdef _3DS gfxExit(); acExit(); -#elif defined(SWITCH) +#elif defined(__SWITCH__) gfxExit(); #endif diff --git a/src/util/gui/menu.c b/src/util/gui/menu.c index 6f8eb8327..763826c4b 100644 --- a/src/util/gui/menu.c +++ b/src/util/gui/menu.c @@ -10,6 +10,8 @@ #ifdef _3DS #include <3ds.h> +#elif defined(__SWITCH__) +#include #endif DEFINE_VECTOR(GUIMenuItemList, struct GUIMenuItem); @@ -31,6 +33,10 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men if (!aptMainLoop()) { return GUI_MENU_EXIT_CANCEL; } +#elif defined(__SWITCH__) + if (!appletMainLoop()) { + return GUI_MENU_EXIT_CANCEL; + } #endif uint32_t newInput = 0; GUIPollInput(params, &newInput, 0); From 21626502bb2d67c775715a74f265a8f2776a7fa9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 14 Sep 2018 20:21:12 -0700 Subject: [PATCH 06/10] Switch: Add audio, key mapping, fast-forward, bugfixes --- res/font-new.png | Bin 15466 -> 15473 bytes src/platform/switch/gui-font.c | 62 ++++++++++++++--- src/platform/switch/main.c | 119 +++++++++++++++++++++++++++++++-- src/util/gui/menu.c | 2 +- 4 files changed, 168 insertions(+), 15 deletions(-) diff --git a/res/font-new.png b/res/font-new.png index e08b5bccbd294cc63276c2f5ab35d2048f08dbae..1e7876a33777d8f0ffd87d20d1336468830b9b6e 100644 GIT binary patch literal 15473 zcmdtJRa9I}*EPDE#uEG?SkNRyaSKk9U`YrPAh^4`(=?5R5Ih8zh7epD4esv2-KBB& zhUO>F`@R1--^IB+H)o7Jdi1WUHCI*bUAwC0niZ@lFGF}@C0GNRHl5bSplXp|R?6oGmQH^OA@C(v+KwAhC2n!nhlesLauqTZ1C+*Ad zWnNoNek+&Cz29@LGrO3mIagEul)3I5YtaPx+L2wO#P`$B5}4=Y5^dJnik|kCkV8zQ z{(1RLA##xx8$=5AfADmN@f@ov!fCG_c&Yi_2SF3eJaCzEcMD1O8mva4g@HGu*#942 zfks!wv`p@nMWUvSD>LQy zyafvU_fiFfrrS^0ZpnSZ7g`y|>!Lrt94`2*9%cgJo0+5Np^Psa&*KKPzC(Am64;`D zq_Yb8cbbl{>U1@iHK-L&@0fgly^aFb$MwC#XvCpH%;-eT>4$S)1HO=dTcEhm@@{7_ z*-M;WjwuzEDkZe_Nh@P8$NgiGiyzkUE0dp3xc6hy(4QRpT~-~~gzCq6tV)PJk~dD@ z%!%(&rD^5&K*f$}>#tKd)z@LCF%L7rMX~T&bJy$Cy{2Rv5Nh{wmh8@X(V1B)xsPZ) zlbk(2#(>JUF8<>Sn3~GG!-ZbuN{XEjESDaFId?ODKWCF&ui$x$LHpI{@801WS+!Evs(3GJEjdGd9C&K&xi z>=sq`ICs}Asnq8ZYIEzw7qx4_#-`vyDXvU@*M*?olGKs5DZvvi-|CSDD-98@HDtT)Ep$djvdI0dAKWjPG5Jr(P-Ny^ZRJn>d-K?>Z z?wURSqn=$H+hmhaKoqAd$6h>4rM)08l5VZFx2TC_iy#25*MbD7G%ACtw&T51TYe^jmU zA%86L`%_mxIFZ|v6Jz%Wl}_l*V>QFh@RaSnJ6I}XTPzaF2|qSCl_4(UZ594JV{36gk3v9#V|>uy?1>17FT(E+bOX?{9aFeX@_ z-GIDtqlm`|FhwlxeG^6Z0`uV^$qC)XVO&sgC%TSu*H z4P&ggg}`#}RC!FHA}KxaHg{%c8zFdWYGrJ)dJiypTJS`_f>kD$26%>&ep1IndT&DR zN+46lrty>~b)^EJh#ev44rOzv zYu*5k?BO5rn(8p(%$psm*uZ0{kV?aEovY>3;^T7ctgu@GIE8sAR;ArSaF}dEQ1@Zn z$Dkz6@pDZFCywJQBQ7yI;J}^p!KDCTJ!eRN*Z&`E+1U=sqkH+iJS;NTQ)J*QSwZ&K zh2OZPe&#=2Eb<$}0m55t3#d3LNqfZK{5HI|Ma)EkM=A^qoZ=}>nbEpzi;Q1U)t}X{ zOQJ`L*d>ug%;c@Zw%mdmqO=U7y_1ew#15K*$v zY+WZnIY>O9Z_-M%z{z;AZf<^d`FYlOrN?{9{2QL8Hi}W+W$VcrR>X%c(Z}~mg6ldZ z*&Iz)?Fis=AZj;YDADVt!oC7~c3f!`E5z-arEmL;R`6vonFYU~(%Eyl##O3Y#Xd08 z6vPVoqG8t(R!3EJApNuEjSvUE_@xrdr;+0F!HivSP%4SxvX=i>nAjiZy_)4migRE` z26Dcxn5afJz!gt_7Q`B}+kk~^Y;zM9=DCHiFcQV>$G_Hdf#O0+-9ULIu9mjMu|{F_ z^-X~j|2)mkJobCLohQ5%nSv+oc3zFu_*6jAc71`lFJ?#ZG2k|Sdjz4oncfg~bH$v= zPGB4*q8?V%FBZb*94MPE%?Yi_E+NnEo1`&m!AI_z2?uYpHC=|>;As2IJqMb`{>fqE zqX$&gYE_N_fO)0Sq4)W(W51vE^*G->03f!d;ps+|YHRXa()*&L&9WZ`wDj7BFCM@W zuPIImvfq6YA#`@b5;smG`Px}!M8xox=0z9fqBHP?zDW~xGk>`|_5O@5nE2BSfo@P) z1#Q`WET6N{*=c4@OGpX^iRF%?juTmq1uBCUq|n~lO~|5fqyjwP!MPK*J|e3)aL8QO zt(GGJkVp?}0Athj1I4W$k~EwQU5Kf5kbYNzE3t&DN1@lK2ttp#&# z0kOZO^*+Cv=Kpz2*#AuF0m6!<0_0zEWYpA8n<0Cjqo^E!GgkHMraw-&-TW~?U`i&G zkfIgBlHLi_HP%O-R~ifB0AdRE-`#$ufFej1!??aL2XkCcN$lIK741yX!$0AXE@aHT z+PDHcIkBW(2?ZecF1AQ9hqe2!5anu|3;>-tUw}{g=r?AK*SDQD>G;P$7*Ryw>)-f@ zUwpP})~e$jU?5dPXWCSOqAH?76bz)tP?*+;SpmfZa^oIaxgoKl*OA|QU^4hXBO`uiLrCh&2SLWw75W$Ck*_0MtsvAEdyQFi}ps&{V?UWN$Cv} zFFp3-2xIHst;GUJ6IqYYzA<(Cs#DzIJDiB4;Tahql%#7WmL%$@yZSLr19lUMngB=s z$xzLQTw_|!6N!I)vVLsXcpGreAQvY*bK7q;70iA^6=CvRq)iA!X5EIno!ZGF5N0

MauvE%$m)wP=a-y=TEnM9DkkaJynDrV>M)I6Wb> z|5Qi(S64Xo&I{|G+aM;TwnT}?_eK2XgUE&dT8oG04W`@OcJ8(gQe{B6~t##x~4QTkv!L>!|T%q(JALh~%SJX?TIGQ#g z2Hu^}8#2;wCt*4BebiU6fIFbaTHA33*rKKIBDaq<9=bbCL@C_MqmHc^n{~aYEIn&Z z>(Oq6#?#UQX{j1PV_=-4&+VRT`EgO*R)5O)|G+koNyB<-?ccohBfr}vw@&%D>w5x? zH->UF-Zuwwbhc;3yaz3Lbnrr3m#GLokg^fDQZC3}tfKnYbj zs?c)=KIz>?q<1x+ZWs}F)IdkZ1;b*K#>GhLuIII{RS(6{gJK2TgE0|9>v}mxKla6j zCka=LTUZ~1y%Y2(_IEPZ@KQg^;CB_}a@@qf*j3jvn!G*c%=R93R=vdX+|D`~o+=>$ zo(yv4VwRQcMHibq@!%ys@gXb`3eLbAS_rr6OIK#aeLw=-Sbd@`k-x&4z4`ArSa$Ls z`cXY4cvx(y;q%lFunpIF*t#S^?y}`_JFr(oP6WWJ`c%)re>6WKY;LJFKZ13oprF<9 zBdGiqi9H(Kn33g>W z{Wd{9Z20=i{SVM*o!Y^OCnK04wovsE1e~=2jxB2@!2@Vl2|Q~g{8`k5%{db%s}RO} zdiPdni!TW} zn2x4y#Ao(xyq{$p?jyNBwk0i0>hsC+2#cDc-vGyUlxhrEK&@WU9)%?B*&c5bLr@$b zE;VuwU?1_}h-s(lG7ubhDFubfzs_J0n1arZ?IAIaQM<0(skS8qqt)3=z9@xbVyN@@;nAZCzyW>s{FJD9-?GWgg#s_9i{M zl)O&F-@7@{!^u2wgH8$I7lzg6Z~}mJo^ndm)`acBgCD1wEB1Ihfa`~0;nEANYFt

eA%Xx28W94}L6^X%xchV~11B+T2aQ`2h0dNriiCy&ZKjNJRtF=4cCwJnzi#S5Xp z`TjPjdWz-mnpxufT_YQpNNuJBu)v3DPv3L$KtXtBZvU-$EeX(}B8x(;+cRHO>>$co zj|2$)+-9ujmKPc?LXNy7_x_e@c)^ zH@LNc0I5qOqH*7z_dvU^`S&~%d}1Lr`JtK)CKPjfE;BEiFm()6dnKo(ldxnh-}n$M zo};SIDgk}b6Jib>ESCF`^CIv`%;mWfrxq=6b~!ax3-l+@fsX;r<9G0i0rZWmlvO@U zX?{cj7{8UZ4sGkx*y=^SXtC&_uF0^CW521iaQb3+!K}&BWq9p#@x)G;Giw=xS`~|lvUOYNo2Qi;I4UnV>Parce zV+X+B8c#q*&OZ|6DM{jyc2tK)R|L5VCDrSjFFG|x(g%$-N3yUa0c|Yad@Tz-UOxoF zVXuV;29%AEW{omy5ThLE`Xz|aJjZ3U@j8L-#sld0U=C||?+iF3Z@Y$Ec~;=+3R637 z5=Y(xzhW9pr<1WV-%0qyd$L0mI~ew-gnw<@GUs%(k%r`JfVP3hw>=R!>leR=whPP+ z6mwHAQzzNU8XKr@yCJi5s(qQlg^jG2+qWI7dT@zYvj;f6P8)Fuw%j8cV1X_=4ryjr z0Ck=6QiEBV2)>304bbB-zHi3tsyg55e0)M4ow&sTM(I^|G+@@o z*obG{O?ZnwbQ4=>_Ylj{@-lgENYd4vB|RV z)yl6A69p7MkrQQc$l#F>#wJa!Y(1ZjZum~6f#0dzYj+POPN6|R(S71((prPDsLaSJ9N zx|}{Z70XV0L*drgK-RTh*218k9?}dMN|L4>krroL0DEK#{0D+tP@U|7VSUsHKrt)pLe(?%R7SUzM(`p#R$GbkYo?8s=D3z>R zQ*sp;52_PwI6dF(UDcOT?26s8z9RvWVxk9{wm{s|J`QVfkF$C4@|jx?K^+~$uP>8B zT~62awd}|_$-gXw=-XKyX3avlue=9ppgP|5;q@Y7fRR+Pe2x0;M4Ynbnp%!e9BGAj z3ED}~igHvi9_=5JsTqD1P{CuhnSvHR7`xNf-Om%pt1-~eY~CRmY#H-wt4(~WShv@`%iz$WLg-GheTL%J!uD1TXtwHb z&o_c^3_NG&MT6qF+a*qJAGw^O1-*!F>N~={gf`#abT{ue7kp|Yc3M*X7k^QCT4mPj zKHcsY_IfE@XT)$HC@uN0dgr=#0Ld!WgwN2!z8k&0(66gS8t>_)-=v~DvM2FpYtg2+ zLtD*GrIAGL#(N3>)b1Jlhy0Bj)f-svxGnYKdje11?|3sq1hb|uCNfcaFqp|9=o?Gz zqn)1I(J(D*5>R};BLZG#I*)e}%I&IN;g&6U<->((TBnS>A9s_*BHBB;51yj0(YW%u zV{xn=6vd=EJ-5=>jLYY$=+4pm3i;DN%WG?QHv`I~3v=ofY`!6Zvjk@g2)5*R4uv#7 zl>WYY-8+cf5lJHE1yy}h$l1{e(gc|2AZ7lBo!szsiBPYcmExp~TPjjs!KGb~r15!; z8Eu=0m0~TU2So^CpeR$F+!7tMXmM;JKYK0RL8$RA=`LO^smIyf89j$ameiFFvf zmi@=;Yi(|dJ!TE1whpx80cSOrJw4Juwi6?7>E4jwSb>rrM{E3eim#%WkDh(KvpBb^ z+3Ip0>^#)fybbtcASP1ogv+6~oL_0QbWbF3P zKzgZTxT0h0{I%AKRqv-dKGk-j(K5aUT#>-KWv?!}#k1Fd${a{#x$_?;o&m~}!vZg7 zTRPG&#?w4><3$}ZBf*Ap$UP>JoQVU>0`qVD`uPzCrPLXVO$&4T*LNT#Xv)3^L@aXzXXpg_N_Zp5F%NvSKTn^TdE zR4dq)131M|V}ldtRx5`Dhhz`92zhc}SE|n7{O*__j`wU1S&bEJ@k@=A{La4Hg}xX(<6A5On;w}-22%c(vv^kpZ9 z5S*Jh)sdARfdik4KXUW%jD--8bb)btdKnqr<;dPC+9KnM=ENvFwor_WX_X92(Ru7z zpCpWTn1D8;0%upEBg(@;NaM}*idh@p;^r;S-)iYnGV0s#6{-HT+TPAQ^W5~@HOkOy z96x+NlU5`eXUY5;R0}P|bacg50le`?6VM>RH7A<@usQWZd+2=5|Fy z80xjeSyX9lYtg@HVn8G zl7NW$X7<{>{9wF{Pc7jLuPxl4sF;`{mr-a$rm)`z*xl~GUI*N#F|YQW*T@c@VCO{0 zrA?p8>2C~HUeqqFS?bG>kv_ruYc2U7>#~WN|7&fb2L=kapS)L}P69GvdK@|)f9tzt zME;_Lup)goI_cQJC9xFucUCjqj==G~MeFW?9=R1a-@d%X+JgOwGODvSGSyWcwe#)G z^NNu*1m_M;38r&d2ALUg$ruYY<`k{WkFY1a!$f5mWH}lfs^$=Fcn(r6>D1-y;vggR zgtT|FAs`^zu8_GUnR~R$8RV6*KT&*(G6=6PejZ-@SkKPoc21wm5yN_5Zdrz969Ks& zb63$j+`&UI&~%F{je9kT#>h90toiS^^%=*TX*?i79`F&EBJ^h6&kxotil}lU1>tYJ z8?#^tBg9NxMByOSiQnGGm*}u!DP&Dn z4aYg{P#l6NDI0Hb()JRDwuOa-rK&18DW^xg>e8T5mJ3IpG0ezi@$MA>J~1}aOR)Lu zk;tHws?c5F?(`(}l>nx5uLh{xT!ZSp{O7158~*TDVomR+5WJ$a4{q@>+3AouuC1S6)U|0Wu!Zon4XO%K zfDTm^QT5!FrKaYer}v)AG$)Bgj)z)A*6n$m@&nq*buj*-TlQM`7zN<&AyDt}u<85K zbJhef{*`;b_o2vZEpmRzU}-4)h<;?<4Q|L)UuYp%9>)+Fs*Az?vw9-6=)?=4X5^NOe# z4~I7WdMii*m>1A;u({mPXY@Pd_!`L&DJY;OoA%q;$i?6hkHW!J@lx%Nau~d@SwW6J zjIa6J+?s+u;tH+^RT}mWo}N5f5nKG&iGCw~6RIybKEkrK%uwqRQaGq{;Ut~&W6qbK`oZ?3r)x2HB%3X;6T}KjhGgI7127*<{SN^J(gIFs z-1l+hcxA{(IoLi4{OnVH_t?F~TIJyzK^z3fESQ)t`j@>h??X{n&EhlL9+g#l+ z6j)*>kDyCZw}%Id{Fp{uPFkeb$^Zc9SpRAP^cq|bXi;TD9)w?k-g?eNp432AwW{e2%n(AW!^Ys_*5W~N&iXY-uCsB96! zNNrr{1j5n(1LD3q8U}Bxc>?-xZz7+zBtKVgb_X`--lA+soKlLfIlOE%o)Yf<{vHmm*iN#bKb}B+9G1omB=j+lIP9!BVo{Dp}$LZG0Z@6Y(TFfrrsJBnIhUAyQmns!D( z-5S|A|9A!P*xF7B@3+*@Q!5tJ!L6jg-HDzE3Bkxcfd|`ZE1$JSZC~_sLV}O&27YC$ ziiI&Ycx32delQbSvn%MzE$5-?Wt#u&Tm2@PzJf^+!Y=fxfqqLfQo5BBFq@8b+0P)Y&yCo?9TF2ea&27|AaL47(<9< zFgQs|uuP%5kE=xMdnQ3m;+#|T^zO*`Ig69IBzGuLE;CQP>BH$wEwvv)PhdI{Lhq2c|Fal`W zIS@Bg@CK|Kb)g%a*oEivkuenxJo%+engndY%Dgx73Nc zh(@gvoVJSdhnd@`Kc%Pq52j07x`o7lVZam0z{7JVxg&(dn>=dqeJYO)0XuoqQ zTuv%mw%IDhQsT%@O;iO6nBte9Hhf%3hE-b-4Ne_$H#^zJC(r>)_5NSbV` z>|?ct?J4kII&@E9`fI%^x}??v{*h&8?;BRf6+@DoxnRNgt76S~olC^RWn3TlZu%Hs z&-Ps>I(?|b#3OGa1L|88*qNWw4*McKwtd9C;+*2lVz*YCTCWHpKI$0i*ty*8+*=1p z_IOm{rcziAU-0!=Z+cM-evae$bgP_Ug z{t1{05&-E|kgCG_D$i)Lw=;Q$$_B><8M0|BQQ5TAz1yqyBBhuzGf?sXkKb2nBYUVj zzD*%WmEdXA!(*Y_(uAhfwS?(!^z)_D9~;xckFuGl+dArw*dPBFtNA}r+YxK0jsnD< zj5r7V(C7N?)c(FrQO@+Wf#2VSd8GJw$SRRP#H;*_fo#3P(tZBqgMRFBw=)t?;L0eb zREjzq5wZLS1wV6?znaZ-KGi5D9nSFHaOLc!+D1t(^~T;(%HMJ92Os28sIHxFs^OX(iskBNpvO>h{F_bk3txaVf%j5GT#;ToLdgSdauxq5o@rxr%E`-?h((oqv1$64Db6;R`mt38$qf9sKM0DwN;{LZs z%>E;9VQ7y|yGamhVM^mz@})n`Q&Qj`#?dMUFw56uPI-kBqSWh*s}uJR6|EK2Uu}82 zr&M*{?LPoNwRQ3vJ$ypMR7dj-^Ij->XwF^7cd{a>Jlh5bJHbE{0BD((72G-B@U+*wE`qV*t3 zmChRHU>dhap@e4^3qTLTDH=ctq$FpyjVM_l^|SY2;7Kc)I!G0G_(&8cS`qcuk^ARKrU9g`L4X75ToN7wY&Cl(H`$bPOyf9y%?O!EhrFIx39dscmR!F`tT;Z* zV5-sF$^$hm+bo4IYaE9B3Q&sxN6byHwlP*`>R@VKo-#8iYu^(%k}eNr^uTAxW%)k2$vLT7J#D7PvQZWtnAaZBdPZcq`y{y%xx|aT<9UYq&ns$3@8^CI)bOfzmcJZ6F=x#yjrgK>kY(07Yvw=tuExDh z7q+2aNnc?0qd>GWxi1{Zt0%-3dF^K6okr6)T(&kSxC|-MOwll%&!u{%SCIe8G=@VR z$#mXW8tA!;O1TxG3^c{LO0I6P%>Mjtz3cob2$y%nV{QA_wzR+jWOPW8{y+#6fVn;u zORaZxz7up6x>evnWA{usvQMlpP2Fs8DpOis8fV@gkGw`smw!Osc%p87QC(&uG!5sy zIJjC@#UC2IW|P44wQtWD2B5grm9mXqJ1OjosWPF_Wzm{Ciw(pLYIkYS06Hcol1AC{ zrdlnb|Edq$7!E%@#GMEKE9z@_C9d^(v1E!@iU#M9Eb(3)UNJA9FpFA-$Y=QPyrwlv z2NetRhxh&I^clMg`cb)9<)3lZr|qmP|C2^GvF`L4B$VfO7uy^e<6Z5qUjw`-%r+P@ zi}qf?Whbih0J+a^eqm}*5A08L_QBi#$!*`M!13L5!zED0`E|uM#&(LYNxv>yhc~NC zT&(8sW$)AV{0i_T>xuySO;*=wp#U#@@Z!r@uxWlp-bZTY)v<{A|0yV!TsW@^KoYuq ztURJ7S7#7_W<7m=UcQxurK>7KRed6U7$s^f;#Ee#8$CT@SJqmr(@iDx9xiZD$murT zd%-u@STW*+u$)46t~ZbD)8<0JEOWEtm}Dwla$5BIUkMy0a557Mx!$T>a5d<-a>5at$NyNzMW>qbu=Qg^-O!%QN@oW7x3}EW3*u?VXpD|; zFsYjxCprYwuz%r+H%5(UMmO~PIN1IKEp#el!{Kga zX+=8?TD-2AhB>UP@z~#9yXUJ~6VdnC3?SUFASx7kHDKVjwDg9iB-+%xZ1RP+j>5v= z#6AHlana2Oa^+hN0Xy_Z?v&RPDz^FOH>}@+)Pz86VU3i_nB_xZYlkg1Ajbm4po^_O zoucC7U=fuD_1Yc7IzdPMyf7>-&!oSb=;)M%#f_K4#)0dIr|Z=I0{$0TVte3c^K@#I z96P_DE(R<|PCCAIs?S*H#Q)=563Hf~m9J`+@#@Bh+oKT2UVs7X?Zi)pQvrQj;+FAw zD+!S>h@$5G@N1=6Jtza4zBAm*W~R03^YSyGr{;$Kn8Wx+>P z0eETyBx3;;y$bbEQm)vSOX}_Q)5WttiLs0Yf1SJFw91lwCtMo-WasRugk3p5NFKni z&z;qRa*0s`nxLh|M;+^@{{|<4G&2uVox+8<31r8ti)0mMpTsVX|3?|_Qgrk_0&AL9 z$OH8b?=Jo>3_s7J@p@wR_(#?e(dRsSK-Akux)A{}J?{8ke*{pf(F08?o!?xl5-G{+ zcw-twB`jO6+!~*qaIW|W=gew}2;RtNGd59-NB}MSa`}6ace1B!sY7(Mo9pP6cl{l0 zb+@SmsI~KK%LNjS?Q_kcBJeBnZfs#8IPrSX?`WbXcSBna|MXXXA3Mj^xyHuE@u%wx zMiZZXJxx;+vaJJ53tV{@5b^ek?Q(%;R#G*!hw!VQJG0-;!yud(hCFan*uB&B<2(Hm z2fSBG)cU4D7YdT8w%?nc0qGXBY))B$7Q3t8m^uR+$r5q9UF1NK+@K@(1MF=bco7T{ zm@3AIH;>sy>{9mL`d-n#$jz|we^fjX!U6Q{SX*OGAS=B*H#b|VZPJ5wm|@5bvo@XB zWuF@dVIJeKoE8eWKEQpfz;j2>9OA4RAScPN+qeaWKqmv~7TdEriVUyl7NNXZ84H!d zlMdI;rK1G}DQkXisl@bhx{ot6k%0mT+>?jdVX3rx^{Er!UJ*ISO7-S#4yw)#= zP_$oZ6Z*mQ=KNL-XEk)NNBu4d@AUaWWj+T3{^N&l_UWX*DGk-;h(MPcvqm;gs1TF+ zP!fi7D{R1~R204^Dl+(gZ)*Ux+J&T4B9g8C=7;^~iw=#_z@KN&35UW;qRkrcNWKC8 zB}?1Da9%OEvxzXHjSE_43ezBY#4cV_nnL2^gN~@Vxe0CqF|(lgmMrAOw$9FOdLjJ-WNE@C)hB;(Oeiga@+D(l^D3mj1kC(JZJV8G;;dt`@TNYX1=LfiTh7pCilu+c$^mX*WH8*>E40xYWBr)oqIFz0IBCLZ zi7e-_wA&vKC(khZ+jT%lH*bFY`eC(CIb2vIvO9O=+IYchVpS|8yDm^ND}o2;*WuyYaBMbU`KJ^+_bvaBT~b6a6_ zUFryV?+Ew8+w_FTR5&n2?3(^iQN;x@rOn$)wyp1C)od}u{|7)llmrN!qYPDgHIE*f z2{Yza!6F&{zJ&+M1v5(^2|*Ib7j9adq3$M^gA`AvyW22N>L2C?4|8adF{JZDfh z*6V!t%8)HwOq`?kp3drxgKyH*YG?Yoir=R3_)o)c%{2=<+eFnT05GZ5m){%A7DKKs z^1G)Z*Td1*+XO=2#7an_DHb#o_q{v7@om@KQBa0|*~%&wx(6mCuHiudjDq?Z_nVv4 zW=FU-+kcPw>=;G!FFd1~R68346}!Z0yKg8e;%vwqNQn4W-VH8x-gsDpTc&IOWO zJ=zN>y*I}aaXsfG)tMZ<^)W-B9;HSnHgCyY)&S;r%(jP6Q(JnpdB`Qof zvfsQv8x#lN6v6Mu0$uL3PM^OGj+=F+_nB`VX?^>L+@Duu62eWaZ((_iuqIQr4)`)p zL=y1<>6gEYV#G*O(~ul65+!@x>Z!K$wDkG5Hik96eY;6B(4yAt6IeYh=JG&c zAyMs_x@bY(_5)#it?<+2J)8jsR$Py!hDQQ$!O6qiyI4nu?awD0{)1|vF-g@Njy2f$ zVkFJrYZ*q*2C^5*F(zjoHNH<6FCO=>r~LyA$nZFF)UL3qpwZtZ7&mabz-L6wpu4Em zAmDzp+f8wDDKBy_c}nAbKv^|q+#o_KV-d7`3PGs!uhw8a_lEzCNvS7b15v(xN$@>+ z7t6D&XuKVkc0m8^vKFLWGwLRK->uX1>Vf^mk@H>%T|$jH?85=P-2R5+ZXGQIpF&yS z!CjFx1OQxeVLL%@3|;!J2;$KMQz8T?_n(OAU!_>tJ@pNK8eN^qfC+joUE0!rw=RE~ z`gY~GIH7Kk|L%asE~CFld$AhK?qAs25t z69kD?1BnE7=+&DGt%3hNA#`+wPv7K~RW{2Gk68X&cgA+{XKkpkoXOnIWpMV7zb3vv zl@GlCv0dcrIHeMTAM~XZL-yI5?$)BP8(-ZWYn@D*^jZb3$a{w#UdlV8%G)z=rRt=A zSM9#EO)(8`PEYyKBJ@og_+M@|y2=Rbr#wAl5U0{_i|iRpNCOR^Qi_^hvQh^42hDw> z3U^w1I155L{`WvG1PV)fu#6Vxiqz2#F zRBl?88hOc>T9@G|NiGB*x?ugM6^79UlHPqXBmzutxgIo|FKTeWD<%nZanF1WfxDrJ z3y=LWVEhj}vn-wF{#wyRyx3vk`#ztBPdAb5&cFrJZ{u&66Y{P~f_Q>TtfsEXOs?{H z>3ZNFgXt6-$O~Nf>WOd)Y!ors*6&dz6p?BTv?%=#3X9qvln`O3BKnJfUR;2yGSFNk z*^P>67{XT*7?lN^Pvvc!S0)52Ao4JCjQ>tqPOAKx8Y)v|u+AvIY1Yg4%92cXT$eT-|QqILlUr9zM7#QZ2Z`P zNO8Zfp8dv1?x;KQRZNxD*KN>uwF%XE;h|^j_%tvtr3NNrt~375MlJ`b2TlV(w~vd* zr(ua--)(yQW>jC7HI|*P#qPDRt&)mGVdQ6RO0BT^Z5umvP1rl+E&0Uq@kb48b8|oT zt+&<9dv0q&RgOac?BwT1#nkc&3ntQcl$@=_?zik(o_mcfKObHQt_`#PlvCeAsBb2i zSNo#8Mw_8eqWNSPsiglume~=$Wt2`0l!6={ Ss{B1m{9a04vgob8-~R!Cd-I6^ literal 15466 zcmc(GbySqk|L-oXq#_^<9~4w#N$C3T|i1C1eQ(_kZx%fL0Up;>F(}W zHZGsv_x{fL-TVJN_naqY&OGya&&=~YGw*m!w8ncy(uZ^p0RRB0vXZ0%jW$xbsiUU^Ef(ha2yZ0+qN`Uct${nJ%J#%Zps%>ABV+z2|u)tvVOPYDkEn0uCp z!;<+Ir=NO&?14K$t*kRe|L{w-h&}w-!K4ftI+E{&&<_!;+4)hdU-J`XLs+BplUb8k zBlADW(kN{M(UB&(zz@01a#9-V{0UruJszArC2&7rZwmN1h5w1bcbr|pJl|IoTf91< zT||q=_|b2pUCsDt>2U!|r2^a!i)C-`JNUp=$-n~uAb$Ms2^?PxMgagU0A+bu9pAab zY(H0{zU*y?guHBic47;eEpq?CmSkE6v{$m%7Xv+ z4%tq)!nk-W35|Tdcm47K;BVF4VFjm$ za=r%8Z}vOqn?bnbk$SUEVHK1o#s2K-DZ&Y_ad$%avxpoQo2w{KmQP7U17rrEG9 z_)@+D$N=t>BlvP6zE_jFk4TeM^XPV83lG)h_ji9M$4+PC6rOh6?%6Om-~H)}%aJPX z2SzV%tx3mS41N@FSLV!=r^_v5($GRC+UyzQR35ukL7I4j?tW6R>(A%50COH#PvWF8 zkY0agHcM3Gs%yZl*T1_N722q4|Kfg@QuVr1Jzy`lBogZ(`)C7`)VpCu7I_B&g(q@X zG~W)4dbq^KR*MP9?O|_b1wJz`R;IuX80~Js z%z+s9=FM@Pc}oC(oD*BYZ9B&0pS+=T9l@s;3n zN;VtbdJ)Cwkws|Okm$l!bQr>lT+2vQS=1^-ca?N*@Ks{CvF+NcqIdx)fwo&MW>b`6 zO}$-=>}RpVMol5FJG&Zguhh)OA+J_deV{t(w`BH8`a{F#My34@mpdFY zfTs6u`n=xOA6ZY;yyt3ek#KJlQ-!+q<#Tr%7DL?Y?e_+a_7_T?3(4m zzUSB0f_IONZS7g!{y`hzu~2PlPB4%R;IQH{B$yemlf z4#Y~h!u}4No6)1d=7mhD>Q#<^)n!c|t|U1EqP||M#a4pHaGucvywGw@!q=^gW*HkQ z&cQgQM|->Eob*aY4`?KH3_B&m-aL<_8s1RoVySB)*yB~U=A)%HxPA=~Z4hozuENUS zW^!TrDeQ{Knet44+~7pQPth)bBFSLA2RA`emShThA+=R#y{YJjM-vNE0}lDk^X^0} zuK~=yV1aZ(B|$(kk}&N{1sO)B=>WRx7~CYT_dW^c@s_EDV=!<$Dc# z)zv(kNxFaw-Oqk|aCw1@FOPR+tiJn3-|#wiTY?+>nGnwx$MOI#B2$7)A^*0HyUhAK zCjVQYtMi!pE>0HNC`AhW)AuNufQ1zIUj8I<`yq>Cq!(P{iAQ6oW(9%P zqUy*98nwS5@Hj7LKikpS8DH_)wT15ntekCuw|Za8d4kp+-MxTf*$t7NT)C8%!I;9| zwuikG)gEuG?j$1tU1eK@Z>E2|1{x0`pJe$~t*{ive88jbNV1ju7zrck#d$-QplNJ_ zn-BqvA_Wv+fZql>V#R!PQ|7iE2FvDI#~8N>zJ%<5b+y%)Q;q0*M?ik=gnNzMt*I2X zd!P`xR_2n)LO0MLCBKJF6rRI5qiuHmQ5Ck2k#njTV}j}H{2lCCWFT>>!$@zv2AVOxu$vO!! zd^z@KC!s!_LF|Sm7QX#`6j!DxptOy}XJYy{0z03dD7M>{HF#4^k%{ zhD00!Pn_i6n(C2tj%&5rGs#F{==r4CvuRYntY#LT12%5{96h#e*A(mSApUHWz8FS3 zbY9KNPX>Pg(L{$ONe3+T%|3U*V3v5CWgcG?X9}>A_P_YIbB=(Ny^LJbnKZinkvxpw ze1jg-5wwJyeA=zbg&XgQp7HK8r{8Z!07?e#1S|Yh6Z_aXg$hqojo0M7V!?LjK#&Un z(wu=Y>GEO7EPwwK*i^pJ_bTdd7ketFMYMyL1n1j4%rCbLm-qwJdC5Mv%}WQ2p=iZ? zkzG%*FhGH{^Ptk_$y;0#xxcE8@pX%KK1{+9yX0HU>t|!@1{xpS^3!wWH<9KSRId_m zb6?-TwQpae7c*jfnKz^Y>-jRTOlp6bWfqiLe9;|)RlXt&`0|L1{>ZLY#o!z<==2{E zGAPDFJ;AyxHFd>O`?6m?l3OdL%jgq1YjtrPD+ZU%Vw@Z7k}clTb4WemXI^p*v+EVD zpgP+}MV{w$2JCj7+A75K7bQ4%eAn6=i}cY}ALNEMtlw58cc;@q^#T=e%{^azxM_&L z6we4LXLPa$K9%~gL9nB{6~f$ijU!E-kUI*OT@I8%#9BhBoK(a|Ji8p<67S%l9!Tw$Vlvu`d7ruE!E@`2Wx}g!g5`et&BTc zQs}BwC$%G?ho40lr9vf$*{kcM3OSW@YH^(Dj5+l;yqWhH;7pINfibENW4~|Vqk-0_ zy*c;BV+WdEOl2(lp0Xo@@^~g6JRg=Gq1OF^V-#Bdg_imPJs{E8V z(+0=yZ3)-{el;^yx}^_zMu-z)c7Qur&6DP&F|0azj{xwkpa+8P*NnVDd_WXR?aCVL zZ)>w9Y_zR#b`zi79HK@~mueh25b06h(e>|&+yoU4H+zJY(D4_8=PBOOre);n>;;fV z>BIGy2K$$E?E8S={FYl1y3T`{^VcWw))@^Iu~V_Lq zcQURs`T<^_ZEWN_?LP*JlX-j|T4#FPB7xcbN86c;ZV@UmQPJs$?0r>KBS>ZX4IiX1 zqEGWSb!*d4r4IC+am1khI{WJvQkk+8>acAm(U3>5LpnjIt50VleHtk^O@PNVIfe|T zY4Z=J+9%clDwzemAc1q3`R%W$NC(M^6YJnR z!PXSDE+5V9x(IiCMeW})j}faUyGN9Uz*fHW`YZTjk_18?1WEEzUCG1DtUgw}Q||@K zBh<~tMk4Y*eallTk5QsbCj^T)X}2__GL@snb}MR!iqf1vKHBc-CEfKS5>M&rbnZb3 zwSyS_$_jJ3wF>>coeGmW{AtrsB>tzQ8_X97wcV<+Z}-jX51|?DZkB77X#jX*dIX+d zT!sa?elPi46hfo7NpX*8bj!zsxp6(Vnf^);Dc14~ebq}>+Ph>U`V0Ib-k&VEg2X@* zlxIv|l^Xm}O;YAB3WuyL%|%kjOqz2wwW`rrP}moga<|}@sIoJ6+AqG@`SM1 z+m|x5>o=6cDU^^w-KmkQN~g9B{)-T6#XIFQqMM$NeDi=A&b_2t=7_EGCAx43P^qHF zZCdg-+$`qs;yFT-vqG$KkjEJ)i3Lj2(jNre?cm<(aQb zOrBnU1)aY|y-&v6v=%OUv!5LsM6#-&_!4eu5>niZ7?(%dPPeMt=;Td+!mo<9KvYbO z_6Ih8EMrE(g^ZP&*ogXYLu!hMOFK$9i;@8*dTk2?rd$YQvRaqhm9zp+LtP`&9Y_2T zCF-21mmZ@lCHE6sf#&=`TbCidK~sfD=a&DcN$el-=I}P_6!FbHQ`!1oocp`$u2NY1 zSPo@F1FWR_mYIxU?_qJ2Un$+}r^*$b2^%VI$bf6#pnni+L*R}3w83yb6_3$f<+G{C z{OgbnY6>GbQ(?}mj&+^zV3m3>V;n(ZBqrq#J51?Pe{uQUyAREtITB&qJzJkgvTzyI zJDgW4A{w@Mb(-*FgS<1KMrPLO8R$9PSYbp^!h^~ zA$!FVxHYd0FnJPPLhAjI(cfDa9xIS#CGuLGrTwx3VMq zwIJV<4pVbZQL=3wE%`@Vy+wPqmT%BX^`!i`FI?6XKDv;kSa|}y|4y;>Ii%XDY_Ffu z+RnO9-X>fL#6o|of&xn zwtAe<2n>hG8Q9pm`P?;jafg*m^dpn4dy+UpcV=5{Z ztjK&&jnL*E;_a22wT*{f?26b%lKlAfBZ(0hZqMKR=C#S~TXLz<)qOUf|ihq%;^l^8>ua_+s(@h8sLS*Zxy@F^}Z#l*Sb8YWiBmh{Yjt36;LE zz1NNqL8*3%owo6bq1gS$M>;9O`{1&$UeH}^y>q!bSk7=L z2CGcu_jKKn@nVhm*5&#&trEmi&LK-Z9wZ8nF_CJ4akn5;6NWaIfr zLWSbwNCGkOfD7q)c$^ke;2ndabP@x&xTFRV1DD&Cwtj)8(?hn<*)v{(0@xKHOfnu! z$^}k?uvm{nZ%wnR=}rf6xsi3|=umo%Ie~YganoZn+U>SGJ;G^H6LNhc->b^==F|YZwrB_j*TiTeeyD(XRG+hgQ55_ zb?J01R^{D73qPd)X>6godcgL0yaIKYK+dBr-f9u-xe0c1qP@Se*H(mSR)mBR`_x#q zE>*|y3`ZE#>KkT?y?s8cx6{0nPPl~^RZ&ve)-O-@>8UQRi-Q|`?wcWPsc@)1-Jr-D zjv%{tZn}=Rw*m=LoQK)(%zS<#pvcCJsP3P1bhPUFEDmL5>bDwsMGq%6cE4$unyFVN zl!jEj0wqa=6bZfARop2AsoCZ559iY?D6WtQLqOpE@jM5EEV+82 zVb2A$^PNE@y4a5*fk{@~?hXU|#8&$we_Y5ReP{o2Z3ywZV&{fDuOe+i8q&oHbclCB z2i<*Q+gUBq+1+(GQd1zZmxaVwfKtpc=a# zk&;#{4;#X;)z1*e#Z^^^n5ql%JmW{jG|mU8&{4oN(=zhz>UmtApN3MApdY%{x#fN{iv8WN1pF1s2fV9ZAOsOZK|7ng#j%{!X4HH0H`KhTv$7{}h~C!(*mz zRz+!c#0;(d=RJq91eTn-z;Ku5hqMY&a!}d2k8Fj32D9uUv$5*b!Y;-12-ie+2yLnv z=Tn+}Ge4`nC|>U8-nT<&T-4BbNO?)&0{>-;zs2nFM)=EWNnK)a3Q8c^`ug4`>}?5@ zM0W^w*fgDlZ2rxq<;lVl=3uNVE*eh3;M5Jf&UQ6m5+7JC&SVt1cZB z{O}g?uHL6@g3ifT4B{3%TpmwN$^S%5oLh`Y#x?*Lj}aP!@jKVM`)6L4cO^G; z$beYJYtOFm^Lt0!yK!)iS)?8FvM;9)@gCdEhR{|H>-;~O4fIIr1QT4wVlPL$vvdR~ z1zsL#jR8iiXb%(yxuaW4ioU2=pwLT8<*0FLLctH^#+_C#q{Aa+O_c;9V zQ?pFV-;rcPN3;MCeAtz6OIRiTd z1-_@*Zg*WRf0nI;Er_f2B!hokMrG$?X($9mJ7UxME86Q`r_C{~F+(LEBFJeJ{!DE? zkDO-7QHvinh;q6nf%dx?NC7U=nAaUJv8Om&j|yVqyV5^y6?wn89U9WN0W_ojIi=bY z__Qz$);61*$oczns$9zq1kti-Y2FhZ)@%xHax8x@y0=g%jiZDX2mAPwe1c+o5%`on;I(%}8%L|1sDUwV=gCG&Q`Z-N zr3b`BJcS-;ek@>0os4|T1}qn7&6B1~{5+koU&##Ai+H%beA$b%|B`J+Z{#6#EUmWN z&HHH2Jx$zm!n7kNb$Me&A?sM9v5}^d7rj4`sc2yaUyzpZYS>|3q1}98R$5+Ma*(>Y zZadl|czHQ^Beq&vBc*+tJ94WpI8j<3mjm$2`RvXpB-kx z9V0m+{{InkaD#P*VJmvkjdqcoRnS9LnII>e=RZ>c1RZrFOQaw#f)*O!Uk{nCco~0! z>Um^v`;C9V+RlGuYOJ5Tmv(c?S@1TV(8BhwFS}s+omUij9j`-hw}8S;xgRo5Yf4{L zri*EwG)iHfb~fYID47YG;LbP&!A%1#)EO+^N_ly~bArvpjWMLpJ6NXS;ErE3pX3N=c5pbx_5UjWPRX}8>B&=eSt7=y~fb;QLp%Xwtyx$hXL_|eYsY-9>t0ed3L?PZS0C0b$5sHMA64u)Ud7iBzflyav z>`P#W7QBikr!Djy2mIIJApgEU#fvy_z$%sOtDI%~3uIW<8oqqgW}sxbt5fFx>GBB;Y^CK4J)}(rtY()~hRL7%BQ= zB?Dm(wjnTAU9Kuw2LC3nr2K0TwD_`bu!VcysOZJKw2aMPn6gJ$L+Gv~j+*0i&C znqCQBi@90WeIr}(=!VhKLhsjmxoR}-r+=OE9EidIND9^btZwwz&AMB1Kx@mCi#W-k6TVeIW zcU{y?Etg<5Q@08N69iZa`xIarXYsgB39xhKfw4`eA3pr)2jB&@ZFTtST3g4e(mbcb z0M9H99HiIYb40Y#)3l4*0arV9E5WlLc2B~(-`Oxok?_0-AWA8SEoO>DEOAzA-4ShB zlF9n%O^Hn_XRDl#o(J7MM-q9>U&7njS$HpD8NQvu3E73aA<8~XP!Roe%W0cLX2tBd zy|q{EvtY~<4A617@^jl%;q2^hiC^16uw8n9+A>edqWromo5&G4k1XeIgx_}GG)(f- z6^hchf4zcPXbefTam&58#?-2VoYhC+rWDN zS<%~YDrvkO3$NOlV9cv*E2g_qn@af}ztD)#+WN})5*Hd;=DS^CfT2VR7rh@2$|}%! zT8?FIW?cxjK^__1_L8dY0eQK8T|BsGxlvR-_wNq#K`>>)Nn3IeVbOx8|Loz?rW`0I z(t9jHW&(|(${5&BqBwiD^`KT@XVYQluA6Nd!4x@HteBr8P=!#C7`LaWuhDo($M!=} zbPY|M+9KRtEHHj-4^ZrtWJdE)S8 zh%gn3v&f*=_<=F04qmOYqp7UoI;{^@kY==ZyjGQsytV-4pxeAz>7m6pbp;2z&L%-( z9yz}{Z_|+&TOUlmzeUx&-xLGKv|Wyf77rR!?;z>V*Q$4QKjf6He3GYfMMm@2@ys^v}aq2})O zS3gbJ_9 z&mDTI?8*e>ehc%yr!Si2gdSAp_=0oOvx$dMb~|^Qid+t<=c^H))v#$C6E|OUtT9yI z?Vizu(@i7#sBt4d4|*%+R>FwcPE}rUH;2rsB3BhqxVGEsD$5}0H?3LC4!lkrQaf8b z6N3MjA!s?hAN3wZ%S|e1cE-weA@i z5&!v5myI@LUv)e$b)#)&0KQ`%0PoI7dE%G+W`gER&*)bT~@TglZmFQd_O_~PQExr;5AV59i<^M~lBt&UH0iaSMB4F#*F z5;$aSzBz5#JK3kp(IXqg#D3&Yq|e`%|2ar;0lFQwL&Ozrd%UI(gPNa{cADMQ#2$!z zfTubn`cTMrzL$7<@a=Z5syTP5_dHu@jt-0SN#Y*f=dkI95-Gcv?K(4q&fls_`JiYs=yF$f~4tuG#%^Zg3iY z-px8KGWQ|S8`CIC&XNdOu;VmLKPeLZ7w}1tZ&^Lcd^$rcasY<4OM!d-^CD34HMa64 zzYy~jL$OvHfPEFw6X4R;QsS<|PFuVmz8`yDa;m*u96u4;2acqFI<(JV(eAQ2vB3bI zxM2AQ`ILc{0dQ?W!yWlpJ=P8ecVy=c^s4>F(rc)fX-hL{ig_X^*tz$IBp|Djrc!vM zxK~}4xtKnFlnlWa9?S zXycdF=LyWJan_$C`5%`>^_m#bFal`Bipa+0ppcj=5UL`2WTpx;WH@OeP~$3ZQFZ4|>+^vQyoP2?V}8UH(3#aE(&cHZcrGOFxmM529BMfGe zIfN<@<-%!AV&C|31%bjoB30gCW+J0`xJxYEIC2}^!MeQ@L1=C|si?;ukN#ZfKdai^ zG7CnRAo&~t^t=mcE#0Y;RDWV}D~d#>f^gkVWsKh%#yi4XAs6Z7>F*0S=TUbw9i7IHSdgHP#nO^3N~rjo_Sei6XDR8sAYx&Q zJ+J4(sG&+TE$IkS7KyWWdXXZU0vC&XQ@l3bsAI}(yyId02pYk){c!Dx)CfqRt_jwk ziR}BSU3{86ipxgKEjyi{mNRq(9C~%hwF( zK#5=KkY#UhVMoBmk|aSwV1)J^OQX+TtK#&cCE!~w1BQ0z!LmU~0q_8CO&~BeC!{q~ z?7xjPA~M`#`J0AYM_uU8QYi7%6KgAZ9=$=PuBu_Pht)d3xl){az0UA^zMTwi6Z#n9 z<|L&;l~?g<<#L`bgFp~E4+m0AZwcrE#Y%C$El*DfF02w%YX?U-YnPUZHzS6G(@Ozr zx*_l@n<+c!2)V;m1@Is_H-G-}frfT(1D2Bc0$lVk$~#jf!y*6IN1?aZCI2aZ0v>*F z=v@JMpr3<1=LtYt}vE>NC(5z zqLTHPEVXY7BWh)gy8aJvgMviIf@ZCMsHgTGub6xn`NvHUxe<^O~l;=I2)RyPkWS(TVX|m@OK4_!!Rib>F!X- zQ8Y+9s70`&nv*FA+%AtbkFi*uTP<0_FUyr}`%VQ?BdiNbTL=7+3zxW!|t3pdx5Y`va4P_>t^fPhG(jP?gtmo0`_X z_F(arUg^Km00n7TabuG3+VWa||G-}=b7knUE0HmUy_W6N!#~$=FVSGh-_H*qY`jgR zCbpi{nAlO>F3PG`J`GQTzCWV$_0Hf@4R15Dqm!XSy6<@y3I`ujM&B?p))kb7qt8H- zoa;&GuvZo5;>CG!)I6VBxRW%Tz!w6(AUpNB6_KFtl|I3Km|^=6CF8)^lvn&bs*7dg z6b*=^D|@$Vcu-)6>fQf)2lgmPqv-H1$?Wi_U?D% zHnu2AORMP*>Bl)~Dz)#DAU{6pZ?yxkWywrt7m2+tUsR`#_p@?0;Pv0WRfdClsk~6l zx<|K8*gyTN8e3r^Nv&rBFaTWRd2XMBW-#rnuc71jmvdZl1pvt)X(Kqu)Eaw6Ltlb~ z{PHzo?>=oRsdtrYKL%g5fx2Sgvvd&d-{_w0#+@}C%<;GlG{A4-v!=pqv)^p!+2Qy; z?ap;G>YfrQbbg8L&Fr?vJ&ErKn!z6-l$!`kCx4d7yz&`xk^RW}tn2+C0*pYz)vol_ zEUjz102dc%M|6iT^TLO;>L=W4_&P|e>kWZEN^iediJ4WSkcp6jJRtDAP2z-F0No~G z-Vf?Q_ki=#rvVSQG&?W5_Vh~#-bg&7nt7*$>v|t6ytj;VnTzzfnj_UuF4cwdcFcF< zM-iRt%+s;fb9iYCQ^wLC&lKfKsdXmtFXddf-2a9c=^VoT`awk;!)7ME{&CJ<__ewl zLn!ZLDA#S1CY3v^ukv2Xt4M{2b6~Jw`PUj|4Get&(Fuql-qIWn*Nrex?{B(-4UMS( z3Ou-{c)mfK70@NX;r0muQaNV<{EUP%dq?Z0k?aAe`l}?+Wp!g)XY$CPRXA{G_l^=7 z6ubMXcbJl~s)^rXP`CYk4x91t@) ze4TU^68H>+n>@Tf+_#V&Nd9jS@v|WuBrUypG`md3$=tX2jPJY&Hsq4*O+P zVKL!}{vOZ0n0V;Yw&(Kal2*qqRhe*#ysuw6M+rR6SW*W6c!)bTaUFvUq7y>~_6O~Z zCgrx$P?wk}VHkwq6GpTjKb2e_mgt?Z2VRqugb6PnXdW^%Uru{^5b(O=ziUd#1M9Tk zwpAR6L|DbGi%i%N`Pwey+FG+D``&NW zt&$kVWt;@6V;X7%nOpAkH}h{D%>22yeJH^o2jz;JvMyFDAz8yy{msayaqxF=1OG5#l7%jeCOgBi}Tr|d@htzSRWlr zW!UZI*k`RDi@9%0=iHp|&9w^~!{yj4lSEcnu^f(pqi*nSwEWNB6-NSz3^o!@${rYPOS*Li?35o85^H$GLnt?1je~ z0s3i{$gKI6!W(Uf9e)3bsu~-ojT=2lEue?X+?CFr#?~y}G`bL*Cx3HtuJCW{gRhgC zx8_(MUETP!0as7X9LgF2KKk2boLQo;Mhl_+4*XE)Sbn;?*!}<_RzIT0sN(p(|08=@* zA=rmxp1N4#_M1U+uzdJXOwMQnK>C_g!~1$V&TR6TYPQ#h@tEAG)K1$#Yl(u>A@O?j z@136ec6MgH4UUks8X!d8u?ip_lE8;iqRF(&JfDml?Rp!Bx=H&QC%P}!jN)g6VpKqw zY$w2wGC6C8>V*I*Yw_^(_(HR@O%}mczP2 zS2zE0mit(7oUHc!E`-CaxMCZGq^#o&?WQ)9Uj@c52m#A$nt{(V`|A~ z1{&0C5C+1~JICLBGqYm{m5pJ`;!nHW;oPL=a-L(&iK{NzKhN~eruFoG@d5(=v&(>& zuJbU=Q&Pst?^7G?lCy%c1?#a2qHxJs{(E^5V_tg;Neuc*5ZZiedNwW0+|R{rq5Wvi zn=Kmm2JL+{nz)Cy0azUO0HGlh<)V(K(zT9ZEaW^qLz z=Erg(eW%6TqBsf3@!Lfj;kUaUz?1{yi(md6qqsZQk8imVgPCe7G5KDwM`>k)4^#WV zV|e$9VcMrv+4JMjZJ4Xb_biH9VaUXUv`{E}wF~Krxzz0Bqf%f7lL%S+a)UZvAWd{nR!izS>s=>rIqJ{&Bu%twm5eafIrR-asqG<%M@F@ zY_o_|2)}ee+H(q3^G?d&Ewg3>=2ck#ZQYK~(KIw`zY57#ek+<@juK=&@NCC1x(WN0 zQw`o*sm*xrIw-O4$}P)=2IKZMOaFXgxp)A=Wr5@N3oo%(0M5af{n*xdNMl>} zhJd@{VX>m+m>@^MYK@pKC9n6}y>Vd?zp07HDY%Pxh@7tUZNyqx&ddAfX2X{I&3g8h z8wn_wYC5i(+6Yg|f=dcwdGQ)gwpW5ANErAt-I-x1N#sX(;GyQz0L4C#ZSPt4}Hm0?x!&`ApHKhpnCYk>eEDHRn6o{A3mGVz5V<%Ee<1+Kh z08ZJs6un9>ctE;ZW_Ml}R+9bZ(+e^hwM}oLZ|p0SwD@U`BYS6WCV){D+~Mp`21%02 zzVU9TAExe?zcMj>s->?}IE0hWr`t1^VRH3Pj}NCdTb{(&!jT|2QsK_cxB8mE+}TrH zU5J?TbsH`-l0b6Yu)0~=<2Xi2=>xQG!V6PirVv<4KjXC#zv{yJM0d95`b9CO8$TSF z7SAXdM8?zRcS2y;X?pK+_^>}q7I|YLCl`R|!Lj51Fw{Zt78GU+92rp$D#<@ze+UE4 zEaV=3;&2&$fy<>^udN^dYX9F2G=OcgO&r5cCVFT|{$-t2P4A5>bNy?P&ei^KC9^$+ zIOdf-=D}I9@zy=JkpV+W-i4J-n zIV!<6E-}Z*q^@tU0pk1q$)AjsX!KoWm?WlVnZ|}!+p{CK#CnAOiAzedl$t9+wMU!b zh|Nvr4!WbDDcv48Qy9O#yhS@!kt)msGA zCtRn{c~N%y+_ff>DIFSK##2{s6PQ;v$G3WMNHv`@>F*T~8x(CBx-N-}B|mXiX!SUU zHbQI5={hiG$4npeg#qu=!ryU}Js6YG!`cD^oB%)F-S_=_TW|Tvm#fLA+=Xi=SHU-8 z*Ifpk%x&pjbFzEbxl7&#U{j)3+$`SHN=Q9a@-^UB4_IBsaWd?@y%*_xK&%|}q z#GRo&yam%tkOy;k8(}{7pu+Ao@MrBhIC(kyG{8x!JlCY}=5t=tRm$fsik0<&)8&K^ z=upag_S)&uGI*dfF4bDV6b@0$t^1i;my^S*jiB59)T{LPX7PBBbzt?c)1CpUOdZp|#$;_OX`jlHmvraRo_k^NZhqu!{(+aoDk}?e) zz|7X45$C+4J`?cu$Zb@NM95qE%Vq8Tv~;iJiUXMj#B>_!4GaT5>&T4$kZ%HeaJPRds_Ka>|-e5qVl<*m4 zbRdm-v%vM|i+Jk+;h|Cut5i}z7b2BS|9wjjK5N)<`~c0TKloV8@0bFFJRb)bxC-&| zdO!X~zT4Tl>!{!GOd!b2d6#FQ>rt2R_-Ma#k};)it$5jBjA}DQ49~FoO9rpB3>9KI z?U#HmY8BRgOKiJrf}*7=*1J5av3`l&B6A%JXC_SpkK9h_cfnSpBv39C7l_59tELBf z^ldCLuvviovUk2#?Wf(H`;gBnyW+EsufYocXVBn(P~ra{@8tadEZ1uE7VBmn`VLF~ Sv+LhY#L92q%U8ZJ5B*=TEv{_< diff --git a/src/platform/switch/gui-font.c b/src/platform/switch/gui-font.c index 382de6db0..1f28b3e1e 100644 --- a/src/platform/switch/gui-font.c +++ b/src/platform/switch/gui-font.c @@ -31,12 +31,13 @@ static const char* const _vertexShader = "uniform vec3 origin;\n" "uniform vec2 glyph;\n" "uniform vec2 dims;\n" + "uniform mat2 transform;\n" "varying vec2 texCoord;\n" "void main() {\n" - " vec2 scaledOffset = offset * dims;\n" - " gl_Position = vec4((origin.x + scaledOffset.x) / 640.0 - 1.0, -(origin.y + scaledOffset.y) / 384.0 + 1.0, origin.z, 1.0);\n" - " texCoord = (glyph + scaledOffset) / 512.0;\n" + " texCoord = (glyph + offset * dims) / 512.0;\n" + " vec2 scaledOffset = (transform * (offset * 2.0 - vec2(1.0)) + vec2(1.0)) / 2.0 * dims;\n" + " gl_Position = vec4((origin.x + scaledOffset.x) / 640.0 - 1.0, -(origin.y + scaledOffset.y) / 360.0 + 1.0, origin.z, 1.0);\n" "}"; static const char* const _fragmentShader = @@ -46,9 +47,10 @@ static const char* const _fragmentShader = "uniform float cutoff;\n" "void main() {\n" - " vec4 texColor = color;\n" - " texColor.a *= texture2D(tex, texCoord).a;\n" - " texColor.a = clamp((texColor.a - cutoff) / (1.0 - cutoff), 0.0, 1.0);\n" + " vec4 texColor = texture2D(tex, texCoord);\n" + " texColor.a = clamp((texColor.a - cutoff) / (1.0 - cutoff), 0.0, 1.0);\n" + " texColor.rgb = color.rgb;\n" + " texColor.a *= color.a;\n" " gl_FragColor = texColor;\n" "}"; @@ -59,6 +61,7 @@ struct GUIFont { GLuint offsetLocation; GLuint texLocation; GLuint dimsLocation; + GLuint transformLocation; GLuint colorLocation; GLuint originLocation; GLuint glyphLocation; @@ -159,6 +162,7 @@ struct GUIFont* GUIFontCreate(void) { font->texLocation = glGetUniformLocation(font->program, "tex"); font->colorLocation = glGetUniformLocation(font->program, "color"); font->dimsLocation = glGetUniformLocation(font->program, "dims"); + font->transformLocation = glGetUniformLocation(font->program, "transform"); font->originLocation = glGetUniformLocation(font->program, "origin"); font->glyphLocation = glGetUniformLocation(font->program, "glyph"); font->cutoffLocation = glGetUniformLocation(font->program, "cutoff"); @@ -229,6 +233,7 @@ void GUIFontDrawGlyph(const struct GUIFont* font, int x, int y, uint32_t color, glUniform2f(font->glyphLocation, (glyph & 15) * CELL_WIDTH + metric.padding.left * 2, (glyph >> 4) * CELL_HEIGHT + metric.padding.top * 2); glUniform2f(font->dimsLocation, CELL_WIDTH - (metric.padding.left + metric.padding.right) * 2, CELL_HEIGHT - (metric.padding.top + metric.padding.bottom) * 2); glUniform3f(font->originLocation, x, y - GLYPH_HEIGHT + metric.padding.top * 2, 0); + glUniformMatrix2fv(font->transformLocation, 1, GL_FALSE, (float[4]) {1.0, 0.0, 0.0, 1.0}); glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(font->offsetLocation); @@ -251,6 +256,9 @@ void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment return; } struct GUIIconMetric metric = defaultIconMetrics[icon]; + + float hFlip = 1.0f; + float vFlip = 1.0f; switch (align & GUI_ALIGN_HCENTER) { case GUI_ALIGN_HCENTER: x -= metric.width; @@ -271,10 +279,10 @@ void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment glUseProgram(font->program); switch (orient) { case GUI_ORIENT_HMIRROR: - // TODO + hFlip = -1.0; break; case GUI_ORIENT_VMIRROR: - // TODO + vFlip = -1.0; break; case GUI_ORIENT_0: default: @@ -294,6 +302,7 @@ void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment glUniform2f(font->glyphLocation, metric.x * 2, metric.y * 2 + 256); glUniform2f(font->dimsLocation, metric.width * 2, metric.height * 2); glUniform3f(font->originLocation, x, y, 0); + glUniformMatrix2fv(font->transformLocation, 1, GL_FALSE, (float[4]) {hFlip, 0.0, 0.0, vFlip}); glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(font->offsetLocation); @@ -316,5 +325,40 @@ void GUIFontDrawIconSize(const struct GUIFont* font, int x, int y, int w, int h, return; } struct GUIIconMetric metric = defaultIconMetrics[icon]; - // + + if (!w) { + w = metric.width * 2; + } + if (!h) { + h = metric.height * 2; + } + + glUseProgram(font->program); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, font->font); + glBindBuffer(GL_ARRAY_BUFFER, font->vbo); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glUniform1i(font->texLocation, 0); + glUniform2f(font->glyphLocation, metric.x * 2, metric.y * 2 + 256); + glUniform2f(font->dimsLocation, metric.width * 2, metric.height * 2); + glUniform3f(font->originLocation, x + w / 2 - metric.width, y + h / 2 - metric.height, 0); + glUniformMatrix2fv(font->transformLocation, 1, GL_FALSE, (float[4]) {w * 0.5f / metric.width, 0.0, 0.0, h * 0.5f / metric.height}); + + glVertexAttribPointer(font->offsetLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(font->offsetLocation); + + glUniform1f(font->cutoffLocation, 0.1f); + glUniform4f(font->colorLocation, 0.0, 0.0, 0.0, ((color >> 24) & 0xFF) / 128.0f); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glUniform1f(font->cutoffLocation, 0.7f); + glUniform4f(font->colorLocation, ((color >> 16) & 0xFF) / 255.0f, ((color >> 8) & 0xFF) / 255.0f, (color & 0xFF) / 255.0f, ((color >> 24) & 0xFF) / 255.0f); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableVertexAttribArray(font->offsetLocation); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); } diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index e0c9ceadb..4fd4e7881 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -4,7 +4,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "feature/gui/gui-runner.h" +#include #include +#include #include #include #include @@ -14,6 +16,11 @@ #include #define AUTO_INPUT 0x4E585031 +#define SAMPLES 0x400 +#define BUFFER_SIZE 0x1000 +#define N_BUFFERS 3 + +TimeType __nx_time_type = TimeType_UserSystemClock; static EGLDisplay s_display; static EGLContext s_context; @@ -38,7 +45,7 @@ static const char* const _vertexShader = "void main() {\n" " vec2 ratio = insize / 256.0;\n" - " vec2 scaledOffset = offset * dims;\n" + " vec2 scaledOffset = offset * dims;\n" " gl_Position = vec4(scaledOffset.x * 2.0 - dims.x, scaledOffset.y * -2.0 + dims.y, 0.0, 1.0);\n" " texCoord = offset * ratio;\n" "}"; @@ -64,6 +71,13 @@ static GLuint colorLocation; static GLuint tex; static color_t frameBuffer[256 * 256]; +static struct mAVStream stream; +static int audioBufferActive; +static struct GBAStereoSample audioBuffer[N_BUFFERS][SAMPLES] __attribute__((__aligned__(0x1000))); +static AudioOutBuffer audoutBuffer[N_BUFFERS]; +static int enqueuedBuffers; +static bool frameLimiter = true; +static int framecount = 0; static bool initEgl() { s_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); @@ -91,6 +105,10 @@ static bool initEgl() { goto _fail1; } + //EGLint contextAttributeList[] = { + // EGL_CONTEXT_CLIENT_VERSION, 2, + // EGL_NONE + //}; s_context = eglCreateContext(s_display, config, EGL_NO_CONTEXT, NULL); if (!s_context) { goto _fail2; @@ -130,7 +148,9 @@ static void _drawStart(void) { } static void _drawEnd(void) { - eglSwapBuffers(s_display, s_surface); + if (frameLimiter || (framecount & 2) == 0) { + eglSwapBuffers(s_display, s_surface); + } } static uint32_t _pollInput(const struct mInputMap* map) { @@ -154,6 +174,15 @@ static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_R, GBA_KEY_R); runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + runner->core->setAVStream(runner->core, &stream); +} + +static void _gameLoaded(struct mGUIRunner* runner) { + u32 samplerate = audoutGetSampleRate(); + + double ratio = GBAAudioCalculateRatio(1, 60.0, 1); + blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate * ratio); + blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate * ratio); } static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded) { @@ -202,6 +231,8 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { unsigned width, height; runner->core->desiredVideoDimensions(runner->core, &width, &height); _drawTex(runner, width, height, faded); + + ++framecount; } static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { @@ -222,18 +253,41 @@ static uint16_t _pollGameInput(struct mGUIRunner* runner) { static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { UNUSED(runner); -} + frameLimiter = limit; +} static bool _running(struct mGUIRunner* runner) { UNUSED(runner); return appletMainLoop(); } +static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { + UNUSED(stream); + static AudioOutBuffer* releasedBuffers; + u32 audoutNReleasedBuffers; + audoutGetReleasedAudioOutBuffer(&releasedBuffers, &audoutNReleasedBuffers); + enqueuedBuffers -= audoutNReleasedBuffers; + if (!frameLimiter && enqueuedBuffers == N_BUFFERS) { + blip_clear(left); + blip_clear(right); + return; + } + + struct GBAStereoSample* samples = audioBuffer[audioBufferActive]; + blip_read_samples(left, &samples[0].left, SAMPLES, true); + blip_read_samples(right, &samples[0].right, SAMPLES, true); + audoutAppendAudioOutBuffer(&audoutBuffer[audioBufferActive]); + audioBufferActive += 1; + audioBufferActive %= N_BUFFERS; + ++enqueuedBuffers; +} + int main(int argc, char* argv[]) { socketInitializeDefault(); nxlinkStdio(); initEgl(); romfsInit(); + audoutInitialize(); struct GUIFont* font = GUIFontCreate(); @@ -301,6 +355,23 @@ int main(int argc, char* argv[]) { glBufferData(GL_ARRAY_BUFFER, sizeof(_offsets), _offsets, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); + stream.videoDimensionsChanged = NULL; + stream.postVideoFrame = NULL; + stream.postAudioFrame = NULL; + stream.postAudioBuffer = _postAudioBuffer; + + memset(audioBuffer, 0, sizeof(audioBuffer)); + audioBufferActive = 0; + enqueuedBuffers = 0; + size_t i; + for (i = 0; i < N_BUFFERS; ++i) { + audoutBuffer[i].next = NULL; + audoutBuffer[i].buffer = audioBuffer[i]; + audoutBuffer[i].buffer_size = BUFFER_SIZE; + audoutBuffer[i].data_size = BUFFER_SIZE; + audoutBuffer[i].data_offset = 0; + } + struct mGUIRunner runner = { .params = { width, height, @@ -310,16 +381,52 @@ int main(int argc, char* argv[]) { NULL, NULL, NULL, }, + .keySources = (struct GUIInputKeys[]) { + { + .name = "Controller Input", + .id = AUTO_INPUT, + .keyNames = (const char*[]) { + "A", + "B", + "X", + "Y", + "L Stick", + "R Stick", + "L", + "R", + "ZL", + "ZR", + "+", + "-", + "Left", + "Up", + "Right", + "Down", + "L Left", + "L Up", + "L Right", + "L Down", + "R Left", + "R Up", + "R Right", + "R Down", + "SL", + "SR" + }, + .nKeys = 26 + }, + { .id = 0 } + }, .nConfigExtra = 0, .setup = _setup, .teardown = NULL, - .gameLoaded = NULL, + .gameLoaded = _gameLoaded, .gameUnloaded = NULL, .prepareForFrame = NULL, .drawFrame = _drawFrame, .drawScreenshot = _drawScreenshot, .paused = NULL, - .unpaused = NULL, + .unpaused = _gameLoaded, .incrementScreenMode = NULL, .setFrameLimiter = _setFrameLimiter, .pollGameInput = _pollGameInput, @@ -335,8 +442,10 @@ int main(int argc, char* argv[]) { _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_DLEFT, GUI_INPUT_LEFT); _mapKey(&runner.params.keyMap, AUTO_INPUT, KEY_DRIGHT, GUI_INPUT_RIGHT); + audoutStartAudioOut(); mGUIRunloop(&runner); + audoutExit(); deinitEgl(); socketExit(); return 0; diff --git a/src/util/gui/menu.c b/src/util/gui/menu.c index 763826c4b..f9cba3d36 100644 --- a/src/util/gui/menu.c +++ b/src/util/gui/menu.c @@ -176,8 +176,8 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men GUIFontIconMetrics(params->font, GUI_ICON_SCROLLBAR_BUTTON, &right, 0); GUIFontIconMetrics(params->font, GUI_ICON_SCROLLBAR_TRACK, &w, 0); right = (right - w) / 2; + GUIFontDrawIconSize(params->font, params->width - right - 8, top, 0, bottom - top, 0xA0FFFFFF, GUI_ICON_SCROLLBAR_TRACK); GUIFontDrawIcon(params->font, params->width - 8, top, GUI_ALIGN_HCENTER | GUI_ALIGN_BOTTOM, GUI_ORIENT_VMIRROR, 0xFFFFFFFF, GUI_ICON_SCROLLBAR_BUTTON); - GUIFontDrawIconSize(params->font, params->width - right - 8, top, 0, bottom - top, 0xFFFFFFFF, GUI_ICON_SCROLLBAR_TRACK); GUIFontDrawIcon(params->font, params->width - 8, bottom, GUI_ALIGN_HCENTER | GUI_ALIGN_TOP, GUI_ORIENT_0, 0xFFFFFFFF, GUI_ICON_SCROLLBAR_BUTTON); y = menu->index * (bottom - top - 16) / GUIMenuItemListSize(&menu->items); From 7bbc607a4c57ab8b64be823b2d389c850a6f0ae7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 15 Sep 2018 11:10:36 -0700 Subject: [PATCH 07/10] Switch: Buildfix --- src/platform/switch/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 14c591f07..415e31ad3 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -34,7 +34,7 @@ endif() add_executable(${BINARY_NAME}.elf ${GUI_SRC} ${PLATFORM_SRC} main.c) set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") -target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${OS_LIB} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY} ${GLAPI_LIBRARY} ${NOUVEAU_LIBRARY} stdc++) +target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY} ${GLAPI_LIBRARY} ${NOUVEAU_LIBRARY} stdc++ ${OS_LIB}) add_custom_command(OUTPUT control.nacp COMMAND ${NACPTOOL} --create "${PROJECT_NAME}" "endrift" "${LIB_VERSION_STRING}" control.nacp) From c14e5dcb88fc7fcc9feda4af8298e89f25c912e0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 15 Sep 2018 11:13:30 -0700 Subject: [PATCH 08/10] Switch: Add touch --- src/platform/switch/main.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 4fd4e7881..6f4e73063 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -161,6 +161,19 @@ static uint32_t _pollInput(const struct mInputMap* map) { return keys; } +static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) { + hidScanInput(); + if (hidTouchCount() < 1) { + return GUI_CURSOR_NOT_PRESENT; + } + touchPosition touch; + hidTouchRead(&touch, 0); + *x = touch.px; + *y = touch.py; + return GUI_CURSOR_DOWN; +} + + static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_A, GBA_KEY_A); _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_B, GBA_KEY_B); @@ -377,7 +390,7 @@ int main(int argc, char* argv[]) { width, height, font, "/", _drawStart, _drawEnd, - _pollInput, NULL, + _pollInput, _pollCursor, NULL, NULL, NULL, }, From a4d058f1263f93ed67d05f0295c5544e875e8f62 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 15 Sep 2018 11:21:46 -0700 Subject: [PATCH 09/10] Switch: Add battery state --- src/platform/switch/main.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 6f4e73063..59a183298 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -295,12 +295,22 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig ++enqueuedBuffers; } +static int _batteryState(void) { + u32 charge; + int state = 0; + if (R_SUCCEEDED(psmGetBatteryChargePercentage(&charge))) { + state = charge / 25; + } + return state; +} + int main(int argc, char* argv[]) { socketInitializeDefault(); nxlinkStdio(); initEgl(); romfsInit(); audoutInitialize(); + psmInitialize(); struct GUIFont* font = GUIFontCreate(); @@ -391,7 +401,7 @@ int main(int argc, char* argv[]) { font, "/", _drawStart, _drawEnd, _pollInput, _pollCursor, - NULL, + _batteryState, NULL, NULL, }, .keySources = (struct GUIInputKeys[]) { @@ -458,6 +468,7 @@ int main(int argc, char* argv[]) { audoutStartAudioOut(); mGUIRunloop(&runner); + psmExit(); audoutExit(); deinitEgl(); socketExit(); From 0bab397851cf5b5847b7438ac08864ba313dacf4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 15 Sep 2018 12:14:51 -0700 Subject: [PATCH 10/10] Switch: Minor fixes --- src/platform/switch/CMakeLists.txt | 2 +- src/platform/switch/gui-font.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 415e31ad3..c21d34cd0 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -37,7 +37,7 @@ set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DE target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${M_LIBRARY} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY} ${GLAPI_LIBRARY} ${NOUVEAU_LIBRARY} stdc++ ${OS_LIB}) add_custom_command(OUTPUT control.nacp - COMMAND ${NACPTOOL} --create "${PROJECT_NAME}" "endrift" "${LIB_VERSION_STRING}" control.nacp) + COMMAND ${NACPTOOL} --create "${PROJECT_NAME}" "endrift" "${VERSION_STRING}" control.nacp) add_custom_command(OUTPUT romfs.bin COMMAND ${CMAKE_COMMAND} -E make_directory romfs diff --git a/src/platform/switch/gui-font.c b/src/platform/switch/gui-font.c index 1f28b3e1e..814c0c63a 100644 --- a/src/platform/switch/gui-font.c +++ b/src/platform/switch/gui-font.c @@ -114,7 +114,7 @@ struct GUIFont* GUIFontCreate(void) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (!_loadTexture("romfs:/font-new.png")) { GUIFontDestroy(font); return NULL;