From 3f6efbd8e254377388588072332c1d94c9dbd84b Mon Sep 17 00:00:00 2001 From: John Bowler Date: Tue, 22 Sep 2015 13:44:16 -0500 Subject: [PATCH] Squashed commit of the following: commit bf51c644f7d29400d884e20def9a0bee74904308 Author: John Bowler Date: Tue Sep 22 09:05:13 2015 -0700 Updated contrib/testpngs/*.png Corrected copyright/licensing information, corrected filtering. Signed-off-by: John Bowler commit 05399c8c82d7b188357dc6fa05a8cdd89426b155 Author: John Bowler Date: Tue Sep 22 09:04:03 2015 -0700 makepng.c: correct the first row filter setting It needs to include the "UP" filter so that libpng knows to retain the first line for the UP filter on the next one. Without this libpng ended up using NONE for the second line. Signed-off-by: John Bowler commit 8fae6609c063c7e0a5eeb592f8eec15849617ae9 Author: John Bowler Date: Mon Sep 21 17:15:45 2015 -0700 makepng: spelling corrections, single test output Corrections to some obvious mistakes, plus one output file. Signed-off-by: John Bowler commit a2245a2c54a679d25f8f1609f85654d155936863 Author: John Bowler Date: Mon Sep 21 13:39:48 2015 -0700 Updated testpngs files with new Licensing tag Signed-off-by: John Bowler commit 46d3f863cace5b7aa769c9b882fca49e2a821138 Author: John Bowler Date: Mon Sep 21 13:38:34 2015 -0700 Updated makepng.c This supports more test cases and a reduced licence keyword (now licensing). The extra text cases require more slack in pngstest.c Signed-off-by: John Bowler commit 7c9a08b8bc5e2542184d4abb25c33c516bc0adc7 Author: John Bowler Date: Sun Sep 20 20:55:19 2015 -0700 Test PNG files These files were generated by contrib/testpngs/makepngs.sh --small with MAKEPNG set to the makepng compiled from the current contrib/libtests/makepngs.sh Signed-off-by: John Bowler commit c2a8a01b2ac733b8029478d10f700f5ab8a713f2 Author: John Bowler Date: Sun Sep 20 20:51:06 2015 -0700 makepng --small This patch adds code to 'makepng' to allow the generation of smaller images that also give better test case coverage. It also adds copyright and licence to the generated images, reflecting the fact that they are original works of the author of the code. The licence used is the Creative Commons Public Domain one, appropriate to a non-source-code work. The resultant image were used to generate the updated pngstest-errors.h file in a prior commit. Signed-off-by: John Bowler commit 8c025bcf3fdfb68fb8b1e5fab4b7deb0f94453f6 Author: John Bowler Date: Sun Sep 20 20:40:52 2015 -0700 Simplified API sRGB gamma handling correction If a gamma encoded file that has a gamma not matching that of sRGB is passed to the simplified API the previous code simply interpreted it as a power law encoding. However old Mac files had a power law correction of 1.45 built in to the encoding, even though the display devices were consistent with sRGB. Assuming a power law encoding results in substantial differences in the interpretation of low 8-bit values; below 10. For example an Apple '5' which is equivalent to an sRGB '17' ends up as the value '8'. This patch provides some measure of correction for this by making the gamma correction done within the simplified API assume that any encoded data is encoded relative to an sRGB-like transfer function; the data is corrected back to the PNG-nominal 2.2 value then decoded to linear (if required) using the sRGB transfer function. This reduces the errors reported by pngstest for such files (colormapped ones) but still leaves the issue with files where the standard libpng code does the gamma decoding. To cope with the latter cases the patch also includes a new pngstest-errors which allows the result, however this is still a work-in-progress; a better solution is possible. Signed-off-by: John Bowler --- ANNOUNCE | 32 +- CHANGES | 30 +- contrib/libtests/makepng.c | 447 +++++++++++++++++++-- contrib/libtests/pngstest-errors.h | 26 +- contrib/testpngs/gray-1-1.8-tRNS.png | Bin 0 -> 325 bytes contrib/testpngs/gray-1-1.8.png | Bin 0 -> 311 bytes contrib/testpngs/gray-1-linear-tRNS.png | Bin 0 -> 325 bytes contrib/testpngs/gray-1-linear.png | Bin 0 -> 311 bytes contrib/testpngs/gray-1-sRGB-tRNS.png | Bin 0 -> 278 bytes contrib/testpngs/gray-1-sRGB.png | Bin 0 -> 264 bytes contrib/testpngs/gray-1-tRNS.png | Bin 0 -> 265 bytes contrib/testpngs/gray-1.png | Bin 0 -> 251 bytes contrib/testpngs/gray-16-1.8-tRNS.png | Bin 0 -> 744 bytes 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 contrib/testpngs/gray-16-sRGB.png | Bin 0 -> 697 bytes contrib/testpngs/gray-16-tRNS.png | Bin 0 -> 684 bytes contrib/testpngs/gray-16.png | Bin 0 -> 684 bytes contrib/testpngs/gray-2-1.8-tRNS.png | Bin 0 -> 325 bytes contrib/testpngs/gray-2-1.8.png | Bin 0 -> 311 bytes contrib/testpngs/gray-2-linear-tRNS.png | Bin 0 -> 325 bytes contrib/testpngs/gray-2-linear.png | Bin 0 -> 311 bytes contrib/testpngs/gray-2-sRGB-tRNS.png | Bin 0 -> 278 bytes contrib/testpngs/gray-2-sRGB.png | Bin 0 -> 264 bytes contrib/testpngs/gray-2-tRNS.png | Bin 0 -> 265 bytes contrib/testpngs/gray-2.png | Bin 0 -> 251 bytes contrib/testpngs/gray-4-1.8-tRNS.png | Bin 0 -> 327 bytes contrib/testpngs/gray-4-1.8.png | Bin 0 -> 313 bytes contrib/testpngs/gray-4-linear-tRNS.png | Bin 0 -> 327 bytes contrib/testpngs/gray-4-linear.png | Bin 0 -> 313 bytes contrib/testpngs/gray-4-sRGB-tRNS.png | Bin 0 -> 280 bytes contrib/testpngs/gray-4-sRGB.png | Bin 0 -> 266 bytes contrib/testpngs/gray-4-tRNS.png | Bin 0 -> 267 bytes contrib/testpngs/gray-4.png | Bin 0 -> 253 bytes contrib/testpngs/gray-8-1.8-tRNS.png | Bin 0 -> 327 bytes contrib/testpngs/gray-8-1.8.png | Bin 0 -> 313 bytes contrib/testpngs/gray-8-linear-tRNS.png | Bin 0 -> 327 bytes contrib/testpngs/gray-8-linear.png | Bin 0 -> 313 bytes contrib/testpngs/gray-8-sRGB-tRNS.png | Bin 0 -> 280 bytes contrib/testpngs/gray-8-sRGB.png | Bin 0 -> 266 bytes contrib/testpngs/gray-8-tRNS.png | Bin 0 -> 267 bytes 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 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 contrib/testpngs/gray-alpha-8.png | Bin 0 -> 684 bytes contrib/testpngs/makepngs.sh | 33 +- contrib/testpngs/palette-1-1.8-tRNS.png | Bin 0 -> 342 bytes contrib/testpngs/palette-1-1.8.png | Bin 0 -> 329 bytes contrib/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 contrib/testpngs/palette-1.png | Bin 0 -> 269 bytes contrib/testpngs/palette-2-1.8-tRNS.png | Bin 0 -> 350 bytes contrib/testpngs/palette-2-1.8.png | Bin 0 -> 335 bytes contrib/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 contrib/testpngs/palette-2.png | Bin 0 -> 275 bytes contrib/testpngs/palette-4-1.8-tRNS.png | Bin 0 -> 400 bytes contrib/testpngs/palette-4-1.8.png | Bin 0 -> 373 bytes contrib/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 contrib/testpngs/palette-4.png | Bin 0 -> 313 bytes contrib/testpngs/palette-8-1.8-tRNS.png | Bin 0 -> 1360 bytes contrib/testpngs/palette-8-1.8.png | Bin 0 -> 1093 bytes contrib/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 contrib/testpngs/palette-8.png | Bin 0 -> 1033 bytes contrib/testpngs/rgb-16-1.8-tRNS.png | Bin 0 -> 1211 bytes contrib/testpngs/rgb-16-1.8.png | Bin 0 -> 1211 bytes contrib/testpngs/rgb-16-linear-tRNS.png | Bin 0 -> 1211 bytes contrib/testpngs/rgb-16-linear.png | Bin 0 -> 1211 bytes contrib/testpngs/rgb-16-sRGB-tRNS.png | Bin 0 -> 1164 bytes contrib/testpngs/rgb-16-sRGB.png | Bin 0 -> 1164 bytes contrib/testpngs/rgb-16-tRNS.png | Bin 0 -> 1151 bytes contrib/testpngs/rgb-16.png | Bin 0 -> 1151 bytes contrib/testpngs/rgb-8-1.8-tRNS.png | Bin 0 -> 837 bytes contrib/testpngs/rgb-8-1.8.png | Bin 0 -> 819 bytes contrib/testpngs/rgb-8-linear-tRNS.png | Bin 0 -> 837 bytes contrib/testpngs/rgb-8-linear.png | Bin 0 -> 819 bytes contrib/testpngs/rgb-8-sRGB-tRNS.png | Bin 0 -> 790 bytes contrib/testpngs/rgb-8-sRGB.png | Bin 0 -> 772 bytes contrib/testpngs/rgb-8-tRNS.png | Bin 0 -> 777 bytes 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 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 contrib/testpngs/rgb-alpha-8.png | Bin 0 -> 859 bytes pngread.c | 132 ++++-- pngrtran.c | 3 - 111 files changed, 618 insertions(+), 85 deletions(-) create mode 100644 contrib/testpngs/gray-1-1.8-tRNS.png create mode 100644 contrib/testpngs/gray-1-1.8.png create mode 100644 contrib/testpngs/gray-1-linear-tRNS.png create mode 100644 contrib/testpngs/gray-1-linear.png create mode 100644 contrib/testpngs/gray-1-sRGB-tRNS.png create mode 100644 contrib/testpngs/gray-1-sRGB.png create mode 100644 contrib/testpngs/gray-1-tRNS.png create mode 100644 contrib/testpngs/gray-1.png create mode 100644 contrib/testpngs/gray-16-1.8-tRNS.png create mode 100644 contrib/testpngs/gray-16-1.8.png create mode 100644 contrib/testpngs/gray-16-linear-tRNS.png create mode 100644 contrib/testpngs/gray-16-linear.png create mode 100644 contrib/testpngs/gray-16-sRGB-tRNS.png create mode 100644 contrib/testpngs/gray-16-sRGB.png create mode 100644 contrib/testpngs/gray-16-tRNS.png create mode 100644 contrib/testpngs/gray-16.png create mode 100644 contrib/testpngs/gray-2-1.8-tRNS.png create mode 100644 contrib/testpngs/gray-2-1.8.png create mode 100644 contrib/testpngs/gray-2-linear-tRNS.png create mode 100644 contrib/testpngs/gray-2-linear.png create mode 100644 contrib/testpngs/gray-2-sRGB-tRNS.png create mode 100644 contrib/testpngs/gray-2-sRGB.png create mode 100644 contrib/testpngs/gray-2-tRNS.png create mode 100644 contrib/testpngs/gray-2.png create mode 100644 contrib/testpngs/gray-4-1.8-tRNS.png create mode 100644 contrib/testpngs/gray-4-1.8.png create mode 100644 contrib/testpngs/gray-4-linear-tRNS.png create mode 100644 contrib/testpngs/gray-4-linear.png create mode 100644 contrib/testpngs/gray-4-sRGB-tRNS.png create mode 100644 contrib/testpngs/gray-4-sRGB.png create mode 100644 contrib/testpngs/gray-4-tRNS.png create mode 100644 contrib/testpngs/gray-4.png create mode 100644 contrib/testpngs/gray-8-1.8-tRNS.png create mode 100644 contrib/testpngs/gray-8-1.8.png create mode 100644 contrib/testpngs/gray-8-linear-tRNS.png create mode 100644 contrib/testpngs/gray-8-linear.png create mode 100644 contrib/testpngs/gray-8-sRGB-tRNS.png create mode 100644 contrib/testpngs/gray-8-sRGB.png create mode 100644 contrib/testpngs/gray-8-tRNS.png create mode 100644 contrib/testpngs/gray-8.png create mode 100644 contrib/testpngs/gray-alpha-16-1.8.png create mode 100644 contrib/testpngs/gray-alpha-16-linear.png create mode 100644 contrib/testpngs/gray-alpha-16-sRGB.png create mode 100644 contrib/testpngs/gray-alpha-16.png create mode 100644 contrib/testpngs/gray-alpha-8-1.8.png create mode 100644 contrib/testpngs/gray-alpha-8-linear.png create mode 100644 contrib/testpngs/gray-alpha-8-sRGB.png create mode 100644 contrib/testpngs/gray-alpha-8.png create mode 100644 contrib/testpngs/palette-1-1.8-tRNS.png create mode 100644 contrib/testpngs/palette-1-1.8.png create mode 100644 contrib/testpngs/palette-1-linear-tRNS.png create mode 100644 contrib/testpngs/palette-1-linear.png create mode 100644 contrib/testpngs/palette-1-sRGB-tRNS.png create mode 100644 contrib/testpngs/palette-1-sRGB.png create mode 100644 contrib/testpngs/palette-1-tRNS.png create mode 100644 contrib/testpngs/palette-1.png create mode 100644 contrib/testpngs/palette-2-1.8-tRNS.png create mode 100644 contrib/testpngs/palette-2-1.8.png create mode 100644 contrib/testpngs/palette-2-linear-tRNS.png create mode 100644 contrib/testpngs/palette-2-linear.png create mode 100644 contrib/testpngs/palette-2-sRGB-tRNS.png create mode 100644 contrib/testpngs/palette-2-sRGB.png create mode 100644 contrib/testpngs/palette-2-tRNS.png create mode 100644 contrib/testpngs/palette-2.png create mode 100644 contrib/testpngs/palette-4-1.8-tRNS.png create mode 100644 contrib/testpngs/palette-4-1.8.png create mode 100644 contrib/testpngs/palette-4-linear-tRNS.png create mode 100644 contrib/testpngs/palette-4-linear.png create mode 100644 contrib/testpngs/palette-4-sRGB-tRNS.png create mode 100644 contrib/testpngs/palette-4-sRGB.png create mode 100644 contrib/testpngs/palette-4-tRNS.png create mode 100644 contrib/testpngs/palette-4.png create mode 100644 contrib/testpngs/palette-8-1.8-tRNS.png create mode 100644 contrib/testpngs/palette-8-1.8.png create mode 100644 contrib/testpngs/palette-8-linear-tRNS.png create mode 100644 contrib/testpngs/palette-8-linear.png create mode 100644 contrib/testpngs/palette-8-sRGB-tRNS.png create mode 100644 contrib/testpngs/palette-8-sRGB.png create mode 100644 contrib/testpngs/palette-8-tRNS.png create mode 100644 contrib/testpngs/palette-8.png create mode 100644 contrib/testpngs/rgb-16-1.8-tRNS.png create mode 100644 contrib/testpngs/rgb-16-1.8.png create mode 100644 contrib/testpngs/rgb-16-linear-tRNS.png create mode 100644 contrib/testpngs/rgb-16-linear.png create mode 100644 contrib/testpngs/rgb-16-sRGB-tRNS.png create mode 100644 contrib/testpngs/rgb-16-sRGB.png create mode 100644 contrib/testpngs/rgb-16-tRNS.png create mode 100644 contrib/testpngs/rgb-16.png create mode 100644 contrib/testpngs/rgb-8-1.8-tRNS.png create mode 100644 contrib/testpngs/rgb-8-1.8.png create mode 100644 contrib/testpngs/rgb-8-linear-tRNS.png create mode 100644 contrib/testpngs/rgb-8-linear.png create mode 100644 contrib/testpngs/rgb-8-sRGB-tRNS.png create mode 100644 contrib/testpngs/rgb-8-sRGB.png create mode 100644 contrib/testpngs/rgb-8-tRNS.png create mode 100644 contrib/testpngs/rgb-8.png create mode 100644 contrib/testpngs/rgb-alpha-16-1.8.png create mode 100644 contrib/testpngs/rgb-alpha-16-linear.png create mode 100644 contrib/testpngs/rgb-alpha-16-sRGB.png create mode 100644 contrib/testpngs/rgb-alpha-16.png create mode 100644 contrib/testpngs/rgb-alpha-8-1.8.png create mode 100644 contrib/testpngs/rgb-alpha-8-linear.png create mode 100644 contrib/testpngs/rgb-alpha-8-sRGB.png create mode 100644 contrib/testpngs/rgb-alpha-8.png diff --git a/ANNOUNCE b/ANNOUNCE index 58f92846c..e49bb717a 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.7.0beta66 - September 20, 2015 +Libpng 1.7.0beta66 - September 22, 2015 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -871,7 +871,7 @@ Version 1.7.0beta65 [September 16, 2015] (but not yet by the writer) (John Bowler). Implemented shared transform handling that is used throughout (John Bowler). -Version 1.7.0beta66 [September 20, 2015] +Version 1.7.0beta66 [September 22, 2015] Enabled the low-bit-depth gray tests that were disabled in prior versions of libpng because of problems that should have been fixed by the recent changes to libpng17. Enabling the tests revealed bugs in those changes @@ -901,6 +901,34 @@ Version 1.7.0beta66 [September 20, 2015] did further corrections, only shown by using files with gAMA 1/1.52 in pngstest (John Bowler). Suppressed bogus Coverity issues in pngrutil.c and pngwutil.c. + Corrected sRGB gamma handling in the Simplified API (John Bowler). + If a gamma encoded file that has a gamma not matching that of sRGB is + passed to the simplified API the previous code simply interpreted it as + a power law encoding. However old Mac files had a power law correction + of 1.45 built in to the encoding, even though the display devices were + consistent with sRGB. Assuming a power law encoding results in + substantial differences in the interpretation of low 8-bit values; + below 10. For example an Apple '5' which is equivalent to an sRGB '17' + ends up as the value '8'. This patch provides some measure of correction + for this by making the gamma correction done within the simplified API + assume that any encoded data is encoded relative to an sRGB-like transfer + function; the data is corrected back to the PNG-nominal 2.2 value then + decoded to linear (if required) using the sRGB transfer function. + This reduces the errors reported by pngstest for such files (colormapped + ones) but still leaves the issue with files where the standard libpng + code does the gamma decoding. To cope with the latter cases there is a + new pngstest-errors which allows the result; however, this is still a + work-in-progress; a better solution is possible. + Added a '--small' option to 'makepng' to allow the generation of smaller + images that also give better test case coverage. Also added copyright + and licence to the generated images, reflecting the fact that they are + original works of the author of the code. The licence used is the + Creative Commons Public Domain (CC0-1.0) one, which is appropriate + for non-source-code works. The resultant images were used to generate + the recently-updated pngstest-errors.h file. + Added test files generated by "contrib/testpngs/makepngs.sh --small" + with MAKEPNG set to the makepng compiled from the current + contrib/libtests/makepngs.sh, to the "contrib/testpngs" directory. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 8f5123e7f..6c54176d8 100644 --- a/CHANGES +++ b/CHANGES @@ -5170,7 +5170,7 @@ Version 1.7.0beta65 [September 16, 2015] (but not yet by the writer) (John Bowler). Implemented shared transform handling that is used throughout (John Bowler). -Version 1.7.0beta66 [September 20, 2015] +Version 1.7.0beta66 [September 22, 2015] Enabled the low-bit-depth gray tests that were disabled in prior versions of libpng because of problems that should have been fixed by the recent changes to libpng17. Enabling the tests revealed bugs in those changes @@ -5200,6 +5200,34 @@ Version 1.7.0beta66 [September 20, 2015] did further corrections, only shown by using files with gAMA 1/1.52 in pngstest (John Bowler). Suppressed bogus Coverity issues in pngrutil.c and pngwutil.c. + Corrected sRGB gamma handling in the Simplified API (John Bowler). + If a gamma encoded file that has a gamma not matching that of sRGB is + passed to the simplified API the previous code simply interpreted it as + a power law encoding. However old Mac files had a power law correction + of 1.45 built in to the encoding, even though the display devices were + consistent with sRGB. Assuming a power law encoding results in + substantial differences in the interpretation of low 8-bit values; + below 10. For example an Apple '5' which is equivalent to an sRGB '17' + ends up as the value '8'. This patch provides some measure of correction + for this by making the gamma correction done within the simplified API + assume that any encoded data is encoded relative to an sRGB-like transfer + function; the data is corrected back to the PNG-nominal 2.2 value then + decoded to linear (if required) using the sRGB transfer function. + This reduces the errors reported by pngstest for such files (colormapped + ones) but still leaves the issue with files where the standard libpng + code does the gamma decoding. To cope with the latter cases there is a + new pngstest-errors which allows the result; however, this is still a + work-in-progress; a better solution is possible. + Added a '--small' option to 'makepng' to allow the generation of smaller + images that also give better test case coverage. Also added copyright + and licence to the generated images, reflecting the fact that they are + original works of the author of the code. The licence used is the + Creative Commons Public Domain (CC0-1.0) one, which is appropriate + for non-source-code works. The resultant images were used to generate + the recently-updated pngstest-errors.h file. + Added test files generated by "contrib/testpngs/makepngs.sh --small" + with MAKEPNG set to the makepng compiled from the current + contrib/libtests/makepngs.sh, to the "contrib/testpngs" directory. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/contrib/libtests/makepng.c b/contrib/libtests/makepng.c index 73fa44755..7f54e24a2 100644 --- a/contrib/libtests/makepng.c +++ b/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.7.0 [September 20, 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,7 @@ #include #include #include +#include #include #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) @@ -97,6 +146,8 @@ # include "../../png.h" #endif +#include + /* Work round for GCC complaints about casting a (double) function result to * an unsigned: */ @@ -153,7 +204,8 @@ pixel_depth_of_type(int color_type, int 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; @@ -162,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) @@ -325,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. @@ -545,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; } @@ -573,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); @@ -600,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); @@ -607,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<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/contrib/libtests/pngstest-errors.h b/contrib/libtests/pngstest-errors.h index b818fd497..241ec6206 100644 --- a/contrib/libtests/pngstest-errors.h +++ b/contrib/libtests/pngstest-errors.h @@ -32,7 +32,7 @@ static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] = { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 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, 15, 13, 0 }, { 0, 19, 1, 0 }, { 0, 0, 0, 0 }, + { 0, 14, 13, 0 }, { 0, 15, 13, 0 }, { 0, 19, 1, 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 } @@ -52,7 +52,7 @@ static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] = { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 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, 17, 9, 0 }, + { 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 } @@ -73,7 +73,7 @@ static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] = { 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, 462, 0 }, { 0, 717, 462, 0 }, + { 0, 585, 427, 0 }, { 0, 585, 427, 0 }, { 0, 717, 584, 0 }, { 0, 717, 584, 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 */ @@ -115,7 +115,7 @@ static png_uint_16 gpc_error_via_linear[16][4/*out*/][4] = }, { /* 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 } + { 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 */ @@ -123,7 +123,7 @@ static png_uint_16 gpc_error_via_linear[16][4/*out*/][4] = }, { /* 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, 3, 0 }, { 0, 32, 3, 0 } + { 0, 4, 8, 0 }, { 0, 9, 8, 0 }, { 0, 9, 9, 0 }, { 0, 32, 9, 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 */ @@ -138,28 +138,28 @@ 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 } + { 0, 0, 742, 0 }, { 0, 0, 742, 0 }, { 0, 0, 742, 0 }, { 0, 0, 742, 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 } + { 0, 19, 6, 0 }, { 0, 255, 6, 25 }, { 0, 88, 6, 0 }, { 0, 255, 6, 25 }, + { 0, 1012, 911, 0 }, { 0, 16026, 911, 6425 }, { 0, 1012, 911, 0 }, { 0, 16026, 911, 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, 220, 25, 0 }, { 0, 255, 25, 67 }, - { 0, 17534, 18491, 0 }, { 0, 15614, 2824, 6425 }, { 0, 14019, 13677, 0 }, { 0, 48573, 13677, 17219 } + { 0, 63, 77, 0 }, { 0, 255, 19, 25 }, { 0, 225, 25, 0 }, { 0, 255, 25, 67 }, + { 0, 17534, 18491, 0 }, { 0, 15998, 2824, 6425 }, { 0, 14103, 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, 97, 74, 0 }, { 0, 255, 74, 25 }, - { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6552 }, { 0, 18919, 18907, 0 }, { 0, 24549, 18907, 6552 } + { 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, 46509, 24992, 17347 } + { 0, 18141, 18137, 0 }, { 0, 17494, 17504, 6553 }, { 0, 24979, 24992, 0 }, { 0, 49172, 24992, 17347 } } }; /* END MACHINE GENERATED */ diff --git a/contrib/testpngs/gray-1-1.8-tRNS.png b/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/contrib/testpngs/gray-1-1.8.png b/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/contrib/testpngs/gray-1-sRGB-tRNS.png b/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/contrib/testpngs/gray-1-sRGB.png b/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/contrib/testpngs/gray-1-tRNS.png b/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/contrib/testpngs/gray-1.png b/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/contrib/testpngs/gray-16-1.8-tRNS.png b/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/contrib/testpngs/gray-16.png b/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/contrib/testpngs/gray-2-1.8-tRNS.png b/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/contrib/testpngs/gray-2-sRGB.png b/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/contrib/testpngs/gray-4-1.8.png b/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/contrib/testpngs/gray-4-linear-tRNS.png b/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/contrib/testpngs/gray-4-linear.png b/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/contrib/testpngs/gray-4-sRGB-tRNS.png b/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/contrib/testpngs/gray-4-sRGB.png b/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/contrib/testpngs/gray-4-tRNS.png b/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/contrib/testpngs/gray-4.png b/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/contrib/testpngs/gray-8-1.8.png b/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/contrib/testpngs/gray-8-linear.png b/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/contrib/testpngs/gray-8-sRGB.png b/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/contrib/testpngs/gray-8-tRNS.png b/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/contrib/testpngs/gray-8.png b/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/contrib/testpngs/gray-alpha-16.png b/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/contrib/testpngs/gray-alpha-8-1.8.png b/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/contrib/testpngs/gray-alpha-8-linear.png b/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/contrib/testpngs/gray-alpha-8-sRGB.png b/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" >&2 + echo " $0 [--all|--coverage|--small]" >&2 exit 1 esac diff --git a/contrib/testpngs/palette-1-1.8-tRNS.png b/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/contrib/testpngs/palette-1-1.8.png b/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/contrib/testpngs/palette-1-linear-tRNS.png b/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/contrib/testpngs/palette-1-linear.png b/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/contrib/testpngs/palette-1-sRGB-tRNS.png b/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/contrib/testpngs/palette-1-tRNS.png b/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/contrib/testpngs/palette-1.png b/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/contrib/testpngs/palette-2-1.8-tRNS.png b/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/contrib/testpngs/palette-2-1.8.png b/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/contrib/testpngs/palette-2-linear-tRNS.png b/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/contrib/testpngs/palette-2-linear.png b/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/contrib/testpngs/palette-2-sRGB.png b/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/contrib/testpngs/palette-2-tRNS.png b/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/contrib/testpngs/palette-2.png b/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/contrib/testpngs/palette-4-1.8-tRNS.png b/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/contrib/testpngs/palette-4-1.8.png b/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/contrib/testpngs/palette-4-linear-tRNS.png b/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/contrib/testpngs/palette-4-linear.png b/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/contrib/testpngs/palette-4-sRGB.png b/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/contrib/testpngs/palette-4-tRNS.png b/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/contrib/testpngs/palette-4.png b/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/contrib/testpngs/palette-8-1.8.png b/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/contrib/testpngs/palette-8-linear.png b/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/contrib/testpngs/palette-8-sRGB-tRNS.png b/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/contrib/testpngs/palette-8-sRGB.png b/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/contrib/testpngs/palette-8.png b/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/contrib/testpngs/rgb-16-sRGB.png b/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/contrib/testpngs/rgb-16-tRNS.png b/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/contrib/testpngs/rgb-8-linear-tRNS.png b/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/contrib/testpngs/rgb-8-sRGB-tRNS.png b/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/contrib/testpngs/rgb-8-tRNS.png b/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/contrib/testpngs/rgb-8.png b/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/contrib/testpngs/rgb-alpha-16-1.8.png b/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/contrib/testpngs/rgb-alpha-16-linear.png b/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/contrib/testpngs/rgb-alpha-16-sRGB.png b/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/contrib/testpngs/rgb-alpha-8-1.8.png b/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/pngread.c b/pngread.c index 5295bbcaa..5e9ca7066 100644 --- a/pngread.c +++ b/pngread.c @@ -756,7 +756,7 @@ png_read_destroy(png_structrp png_ptr) if (png_ptr->zstream.state != NULL) { int ret = inflateEnd(&png_ptr->zstream); - + if (ret != Z_OK) { png_zstream_error(png_ptr, ret); @@ -1081,7 +1081,7 @@ typedef struct png_voidp first_row; ptrdiff_t row_bytes; /* step between rows */ int file_encoding; /* E_ values above */ - png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */ + png_fixed_point file_to_sRGB; /* Cached correction factor */ int colormap_processing; /* PNG_CMAP_ values above */ } png_image_read_control; @@ -1445,20 +1445,15 @@ png_image_skip_unused_chunks(png_structrp png_ptr) static void set_file_encoding(png_image_read_control *display) { + /* First test for an encoding close to linear: */ if (png_need_gamma_correction(display->image->opaque->png_ptr, 0/*PNG gamma*/, 0/*not sRGB*/)) { png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; + /* Now look for one close to sRGB: */ if (png_gamma_not_sRGB(g)) - { display->file_encoding = P_FILE; - /* Record the reciprocal of 'g', the colorspace gamma. If this - * overflows just store FP_1. - */ - if (!png_muldiv(&display->gamma_to_linear, PNG_FP_1, PNG_FP_1, g)) - display->gamma_to_linear = PNG_FP_1; - } else display->file_encoding = P_sRGB; @@ -1468,6 +1463,96 @@ set_file_encoding(png_image_read_control *display) display->file_encoding = P_LINEAR8; } +/* For colormap entries we end up doing the gamma correction here and the + * following routines are provided to separate out the code. In all cases the + * input value is in the range 0..255 and is encoded P_FILE with the gamma value + * stored in the png_struct colorspace. + */ +static void +init_correct(png_const_structrp png_ptr, png_fixed_point *correct) +{ + /* Record the convertion necessary to get from the encoding values to + * sRGB. If this overflows just store FP_1. + * + * NOTE: this code used to store, and use, a convertion factor to + * linear then use the sRGB encoding tables to get back to sRGB, but + * this smashes the low values; the ones which fall in the linear part + * of the sRGB transfer function. + * + * The new version of this code assumes an encoding which is neither + * linear nor sRGB is a power law transform of the sRGB curve, not + * linear values. This is somewhat at odds with a precise reading of + * the PNG spec, but given that we are trying to produce sRGB values + * here it is most likely to be correct. + */ + affirm(png_ptr->colorspace.gamma > 0); + + if (!png_muldiv(correct, PNG_GAMMA_sRGB_INVERSE, PNG_FP_1, + png_ptr->colorspace.gamma)) + *correct = PNG_FP_1; +} + +static png_uint_32 +convert_to_sRGB(png_image_read_control *display, png_uint_32 value) +{ + /* Converts an 8-bit value from P_FILE to P_sRGB */ + png_const_structrp png_ptr = display->image->opaque->png_ptr; + + affirm(value <= 255U); + + if (display->file_to_sRGB == 0) + init_correct(png_ptr, &display->file_to_sRGB); + + /* Now simply apply this correction factor and scale back to 8 bits. */ + if (display->file_to_sRGB != PNG_FP_1) + value = PNG_DIV257( + png_gamma_16bit_correct(png_ptr, value*257U, display->file_to_sRGB)); + + return value; +} + +static png_uint_32 +convert_to_linear(png_image_read_control *display, png_uint_32 value) +{ + /* Converts an 8-bit value from P_FILE to 16-bit P_LINEAR */ + png_const_structrp png_ptr = display->image->opaque->png_ptr; + + affirm(value <= 255U); + + if (display->file_to_sRGB == 0) + init_correct(png_ptr, &display->file_to_sRGB); + + /* Use this correct to get a 16-bit sRGB value: */ + value *= 257U; + + if (display->file_to_sRGB != PNG_FP_1) + value = png_gamma_16bit_correct(png_ptr, value, display->file_to_sRGB); + + /* Now convert this back to linear, using the correct transfer function. */ + if (value <= 2650U /* 65535 * 0.04045 */) + { + /* We want to divide a 12-bit number by 12.92, do this by scaling to 32 + * bits then dividing by 2^24, with rounding: + */ + value = (value * 1298546U + 649273U) >> 24; + } + + else + { + /* Calculate for v in the range 0.04045..1.0 calculate: + * + * ((v + 0.055)/1.055)^2.4 + * + * the gamma correction function needs a 16-bit value: + */ + value *= 62119U; + value += 223904831U+32768U; /* cannot overflow; test with 65535 */ + value = png_gamma_16bit_correct(png_ptr, value >> 16, 240000); + } + + return value; +} + static unsigned int decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) { @@ -1483,8 +1568,7 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) switch (encoding) { case P_FILE: - value = png_gamma_16bit_correct(display->image->opaque->png_ptr, - value*257, display->gamma_to_linear); + value = convert_to_linear(display, value); break; case P_sRGB: @@ -1567,31 +1651,26 @@ png_create_colormap_entry(png_image_read_control *display, if (display->file_encoding == P_NOTSET) set_file_encoding(display); - /* Note that the cached value may be P_FILE too, but if it is then the - * gamma_to_linear member has been set. - */ + /* Note that the cached value may be P_FILE too. */ encoding = display->file_encoding; } if (encoding == P_FILE) { - png_fixed_point g = display->gamma_to_linear; - - red = png_gamma_16bit_correct(png_ptr, red*257, g); - green = png_gamma_16bit_correct(png_ptr, green*257, g); - blue = png_gamma_16bit_correct(png_ptr, blue*257, g); - if (convert_to_Y != 0 || output_encoding == P_LINEAR) { + red = convert_to_linear(display, red); + green = convert_to_linear(display, green); + blue = convert_to_linear(display, blue); alpha *= 257; encoding = P_LINEAR; } else { - red = PNG_sRGB_FROM_LINEAR(png_ptr, red * 255); - green = PNG_sRGB_FROM_LINEAR(png_ptr, green * 255); - blue = PNG_sRGB_FROM_LINEAR(png_ptr, blue * 255); + red = convert_to_sRGB(display, red); + green = convert_to_sRGB(display, green); + blue = convert_to_sRGB(display, blue); encoding = P_sRGB; } } @@ -1960,7 +2039,12 @@ png_image_read_colormap(png_voidp argument) else png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + /* Make sure libpng doesn't ignore the setting: */ + if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) + png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA; + + else + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; } /* Decide what to do based on the PNG color type of the input data. The diff --git a/pngrtran.c b/pngrtran.c index 98ef61569..df317d2fc 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -4926,10 +4926,7 @@ png_do_background_alpha_GA(png_transformp *transform, png_transform_controlp tc) case 65535U: /* opaque */ if (copy) - { memcpy(dp, sp, 4U); - UNTESTED - } break; }