diff options
Diffstat (limited to 'java/openjdk8/files/patch-8u45-b14')
-rw-r--r-- | java/openjdk8/files/patch-8u45-b14 | 45638 |
1 files changed, 0 insertions, 45638 deletions
diff --git a/java/openjdk8/files/patch-8u45-b14 b/java/openjdk8/files/patch-8u45-b14 deleted file mode 100644 index 19470282608c..000000000000 --- a/java/openjdk8/files/patch-8u45-b14 +++ /dev/null @@ -1,45638 +0,0 @@ ---- ./.hgtags Wed Jan 28 12:08:30 2015 -0800 -+++ ./.hgtags Tue Mar 17 11:22:18 2015 -0700 -@@ -336,6 +336,8 @@ - d117f01bfb4f34668ac216c9837e88acead14dce jdk8u25-b17 - efac90a2da447c2b2d43ee1b1e20c0828659f9c5 jdk8u25-b18 - 1a0b4ec68abc4e9248ca6041fff04612674a9b9f jdk8u25-b31 -+cc8541804eb47d86b30c5b005c6fa6ecb6a53538 jdk8u25-b32 -+ec5219b942d277059d89063fb3702bc5e076dfd0 jdk8u25-b33 - 6db0898d3f90ad9eae2f017299314b88766446e3 jdk8u31-b00 - 85792859f3bdd6a2c1bdfcf2828bb2730e06ac3c jdk8u31-b01 - 4898a7460ae620ac5356cb224e1fdf3c29312533 jdk8u31-b02 -@@ -350,6 +352,8 @@ - ec85d5d0e3c05b0b6d61f4fc3f41313448ed9b05 jdk8u31-b11 - ca98e3e9727ffdcde2c9980668d0c7f344261938 jdk8u31-b12 - fde671d8b2537b6be61f67e583164b5b8b33ac5b jdk8u31-b13 -+a198f93b1e0be5edce7a351b1399cb5c4e64c8f4 jdk8u31-b31 -+99c79d83152585991682bd86e21fdcfe6f6ab9b2 jdk8u31-b32 - 0dccc4aca1859b1ff7dca9db214f7f38c4ddbbce jdk8u40-b00 - f8736a40a35df0c8055c8a94b96e5381b381ad33 jdk8u40-b01 - b6a148730f2b14193c308bc9c866c36ee6c08ed3 jdk8u40-b02 -@@ -374,3 +378,21 @@ - 765a17e75fd622f7b892381e23c9b2c531d416f0 jdk8u40-b21 - b6d03a810a61116268fea08517a9632bd66a7363 jdk8u40-b22 - 5dd2ad6c7911a1e21f15a28f13ffad662378a3be jdk8u40-b23 -+5b37e6757d7c95c9c58b07fb3c9eba234567385a jdk8u40-b24 -+e26f15704e37f28acebb22378c4785891aaec637 jdk8u40-b25 -+7a552439756eaad0618ae82a94c034edb65f5d7e jdk8u40-b26 -+12deacac825756e266e91a906db9edab73c4c90b jdk8u40-b27 -+ec4bcc6e4dcf190a165106627ed3eef1e7d94d0c jdk8u45-b00 -+635ba0c81b894a88ff737fefc9d7af398f761643 jdk8u45-b01 -+801c65bb74b770600a2d48189764e416e5cfe265 jdk8u45-b02 -+7d11a7eee8c0512fa15d3ed2dcded5391b0c091d jdk8u45-b03 -+3d79ef8a102ffe22b083d07649a1d9e22cf784b6 jdk8u45-b04 -+45f8fc9d30021026a5101c8946af98f7c079b537 jdk8u45-b05 -+9a5843fdd2cf8120515d98572440c5c35118254d jdk8u45-b06 -+74ef61db0fe02e3eaa5156a7bab9f00f2a2143de jdk8u45-b07 -+0c10bc33556383b8e665998c62145a8398e7f7ef jdk8u45-b08 -+733d16eb42cb105749588c9b93cc408155ed99ad jdk8u45-b09 -+9a343fd13810a8f09d3dd4a9e2e20791bb866166 jdk8u45-b10 -+6738b8755c80905e3eecedf94e27f03d23f02ba9 jdk8u45-b11 -+54709b761404dd3bc1b58acf5582fa9bd70ff59a jdk8u45-b12 -+6b2f1bf5c72873d01b37103fc20ac7a63e7881dd jdk8u45-b13 ---- ./THIRD_PARTY_README Wed Jan 28 12:08:30 2015 -0800 -+++ ./THIRD_PARTY_README Tue Mar 17 11:22:18 2015 -0700 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - ---- ./corba/.hgtags Wed Jan 28 12:08:31 2015 -0800 -+++ ./corba/.hgtags Tue Mar 17 11:22:27 2015 -0700 -@@ -334,6 +334,8 @@ - f46df0af2ca8c7d896de375c8edac8ce09318318 jdk8u25-b17 - ee069d67c12df902cdb06ecf1747f8ff9d495a61 jdk8u25-b18 - 8d0faa0eac61c04c6a5bbff2e084c9da0bd5251c jdk8u25-b31 -+6617e1de7aa536d2e3671e3c50c340262b2b053e jdk8u25-b32 -+c123ac2adfdc6049034d5970bec89b51ce5d8889 jdk8u25-b33 - 69793b08060c9d216fa84d679c48b9e22d2400ac jdk8u31-b00 - fd5f8e3713803ca2d7898407a53996f3aa41521e jdk8u31-b01 - b6e2d1b1b24585bd02512e360d842d4713afa644 jdk8u31-b02 -@@ -348,6 +350,8 @@ - 7e2056eba0b62247407e065f3f88a89358fc26a6 jdk8u31-b11 - 285b0e589c50e46ca7ad3434221335901a547d66 jdk8u31-b12 - f89b454638d89ee5f44422b7a5b8e5651260e68f jdk8u31-b13 -+705d3a4298f44f0a14925bfee5017f5824b6c0ca jdk8u31-b31 -+072d325a052a5894019b74118803bf5fb9e30692 jdk8u31-b32 - 7d1e0f0b63f1d66c77924d8b2a1accdf8f7480db jdk8u40-b00 - c5d9822a3c18cd9e274dfe99e91c33e02bd8f8f4 jdk8u40-b01 - 504b4455570e14b7fc0a837a09c6401c603516d9 jdk8u40-b02 -@@ -372,3 +376,21 @@ - 9c54cc92c0beb29179abbce272d3f5c8ba4ffd0e jdk8u40-b21 - 4c7421f74674ebefb8e91eba59ab2a2db8c1abd7 jdk8u40-b22 - 62f7faef5ed956cd481cae6216b22fdb4b6e3e46 jdk8u40-b23 -+472aa5bae0e78614e873d56bcc31e7caba49963c jdk8u40-b24 -+2220744100b8487976debff79e5d0c7d70738bda jdk8u40-b25 -+cab2b99c6bb2e15165a58eaa36157788f82592f1 jdk8u40-b26 -+bd0186cd2419129357b110fe3f13519f68b29774 jdk8u40-b27 -+5761efbc739fdedcbff224e22f920e88b29af4cf jdk8u45-b00 -+6a52852476c9ccb2d52153d1b94b675e863bb28c jdk8u45-b01 -+3b9d342f9f584465ea5976e06357b45682f9681d jdk8u45-b02 -+d3678799ed35f162928f387308d72f5401b37e84 jdk8u45-b03 -+9dd8c8e1b0facfcf21657c91fc99bcb5319d1196 jdk8u45-b04 -+b82ecb056ae3fd6ee06e765995c564b17a761221 jdk8u45-b05 -+f538a9334f09535ef8fe13072f6a4a52e3187e1c jdk8u45-b06 -+4dec7b828f1ee3adbf3c2b6430400db8b1abb5ad jdk8u45-b07 -+16cb989c8b6220330a54fe78ae27b2f50fc5e794 jdk8u45-b08 -+ace36a054b7faadb702d6f23e569efb77f0a7513 jdk8u45-b09 -+b9ef43c59b425961526b04e92d7fa66014ec25eb jdk8u45-b10 -+08c2ce4b6d59bc6b29e61fd8562b9e3d39b257a5 jdk8u45-b11 -+c9bf2543c0c045ef31f0296bc355381e1a4bd4ac jdk8u45-b12 -+326f02235e7a9a6da78428410320dcc980827d40 jdk8u45-b13 ---- ./corba/THIRD_PARTY_README Wed Jan 28 12:08:31 2015 -0800 -+++ ./corba/THIRD_PARTY_README Tue Mar 17 11:22:27 2015 -0700 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - ---- ./hotspot/.hgtags Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/.hgtags Tue Mar 17 11:22:51 2015 -0700 -@@ -547,6 +547,8 @@ - 28b50d07f6f8c5a567b6a25e95a423948114a004 jdk8u25-b17 - 639abc668bfe995dba811dd35411b9ea8a9041cd jdk8u25-b18 - c3528699fb33fe3eb1d117504184ae7ab2507aa1 jdk8u25-b31 -+631f0c7b49c091c6865d79d248d6551a270ac22f jdk8u25-b32 -+4e1f52384f9ffa803838acad545cd63de48a7b35 jdk8u25-b33 - 5bb683bbe2c74876d585b5c3232fc3aab7b23e97 jdk8u31-b00 - 5bb686ae3b89f8aa1c74331b2d24e2a5ebd43448 jdk8u31-b01 - 087678da96603c9705b38b6cc4a6569ac7b4420a jdk8u31-b02 -@@ -561,6 +563,8 @@ - 9906d432d6dbd2cda242e3f3cfde7cf6c90245bf jdk8u31-b11 - e13839545238d1ecf17f0489bb6fb765de46719a jdk8u31-b12 - 4206e725d584be942c25ff46ff23d8e299ca4a4c jdk8u31-b13 -+b517d3a9aebf0fee64808f9a7c0ef8e0b82d5ed3 jdk8u31-b31 -+15d8108258cb60a58bdd03b9ff8e77dd6727a804 jdk8u31-b32 - 1b3abbeee961dee49780c0e4af5337feb918c555 jdk8u40-b10 - f10fe402dfb1543723b4b117a7cba3ea3d4159f1 hs25.40-b15 - 99372b2fee0eb8b3452f47230e84aa6e97003184 jdk8u40-b11 -@@ -586,3 +590,21 @@ - 0f0cb4eeab2d871274f4ffdcd6017d2fdfa89238 hs25.40-b25 - 0ee548a1cda08c884eccd563e2d5fdb6ee769b5a jdk8u40-b22 - 0e67683b700174eab71ea205d1cfa4f1cf4523ba jdk8u40-b23 -+fa4e797f61e6dda1a60e06944018213bff2a1b76 jdk8u40-b24 -+698dd28ecc785ffc43e3f12266b13e85382c26a8 jdk8u40-b25 -+f39b6944ad447269b81e06ca5da9edff9e9e67c8 jdk8u40-b26 -+6824e2475e0432e27f9cc51838bc34ea5fbf5113 jdk8u40-b27 -+b95f13f05f553309cd74d6ccf8fcedb259c6716c jdk8u45-b00 -+41c3c456e326185053f0654be838f4b0bfb38078 jdk8u45-b01 -+626fd8c2eec63e2a2dff3839bfe12c0431bf00a4 jdk8u45-b02 -+f41aa01b0a043611ee0abcb81a40f7d80085ec27 jdk8u45-b03 -+2f586e3c4b6db807ac6036b485b2890ff82f7bfd jdk8u45-b04 -+344ff6e45a1e2960ac4a583f63ebfb54cd52e6b4 jdk8u45-b05 -+3afa9cc6e8d537ee456b8e12d1abb1da520b5ddc jdk8u45-b06 -+5871f3dd9b4a2c4b44e7da2184f4430323e0c04b jdk8u45-b07 -+35c7330b68e21d0dfaaedaaf74b794fd10606e9c jdk8u45-b08 -+35d8318de0b6d4e68e2e0a04f6e20cafd113ca54 jdk8u45-b09 -+a9f5786079202b74b3651e1097c0b2341b2178b9 jdk8u45-b10 -+f4822d12204179e6a3e7aaf98991b6171670cbf2 jdk8u45-b11 -+dc29108bcbcbfcd49eaa9135368306dc85db73a6 jdk8u45-b12 -+efbf340fc7f56e49735111c23cef030413146409 jdk8u45-b13 ---- ./hotspot/THIRD_PARTY_README Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/THIRD_PARTY_README Tue Mar 17 11:22:51 2015 -0700 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - ---- ./hotspot/make/hotspot_version Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/make/hotspot_version Tue Mar 17 11:22:51 2015 -0700 -@@ -34,8 +34,8 @@ - HOTSPOT_VM_COPYRIGHT=Copyright 2015 - - HS_MAJOR_VER=25 --HS_MINOR_VER=40 --HS_BUILD_NUMBER=25 -+HS_MINOR_VER=45 -+HS_BUILD_NUMBER=02 - - JDK_MAJOR_VER=1 - JDK_MINOR_VER=8 ---- ./hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Tue Mar 17 11:22:51 2015 -0700 -@@ -630,7 +630,12 @@ - - inline void MacroAssembler::ldf(FloatRegisterImpl::Width w, const Address& a, FloatRegister d, int offset) { - relocate(a.rspec(offset)); -- ldf(w, a.base(), a.disp() + offset, d); -+ if (a.has_index()) { -+ assert(offset == 0, ""); -+ ldf(w, a.base(), a.index(), d); -+ } else { -+ ldf(w, a.base(), a.disp() + offset, d); -+ } - } - - // returns if membar generates anything, obviously this code should mirror ---- ./hotspot/src/share/vm/classfile/defaultMethods.cpp Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/src/share/vm/classfile/defaultMethods.cpp Tue Mar 17 11:22:51 2015 -0700 -@@ -731,10 +731,12 @@ - Method* m = iklass->find_method(_method_name, _method_signature); - // private interface methods are not candidates for default methods - // invokespecial to private interface methods doesn't use default method logic -+ // private class methods are not candidates for default methods, -+ // private methods do not override default methods, so need to perform -+ // default method inheritance without including private methods - // The overpasses are your supertypes' errors, we do not include them - // future: take access controls into account for superclass methods -- if (m != NULL && !m->is_static() && !m->is_overpass() && -- (!iklass->is_interface() || m->is_public())) { -+ if (m != NULL && !m->is_static() && !m->is_overpass() && !m->is_private()) { - if (_family == NULL) { - _family = new StatefulMethodFamily(); - } -@@ -745,6 +747,9 @@ - } else { - // This is the rule that methods in classes "win" (bad word) over - // methods in interfaces. This works because of single inheritance -+ // private methods in classes do not "win", they will be found -+ // first on searching, but overriding for invokevirtual needs -+ // to find default method candidates for the same signature - _family->set_target_if_empty(m); - } - } ---- ./hotspot/src/share/vm/memory/referenceProcessor.cpp Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/src/share/vm/memory/referenceProcessor.cpp Tue Mar 17 11:22:51 2015 -0700 -@@ -252,7 +252,7 @@ - // Cleaner references to be temporary, and don't want to deal with - // possible incompatibilities arising from making it more visible. - phantom_count += -- process_discovered_reflist(_discoveredCleanerRefs, NULL, false, -+ process_discovered_reflist(_discoveredCleanerRefs, NULL, true, - is_alive, keep_alive, complete_gc, task_executor); - } - ---- ./hotspot/src/share/vm/oops/klassVtable.cpp Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/src/share/vm/oops/klassVtable.cpp Tue Mar 17 11:22:51 2015 -0700 -@@ -401,13 +401,15 @@ - // get super_klass for method_holder for the found method - InstanceKlass* super_klass = super_method->method_holder(); - -- if (is_default -+ // private methods are also never overridden -+ if (!super_method->is_private() && -+ (is_default - || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) - || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) - && ((super_klass = find_transitive_override(super_klass, - target_method, i, target_loader, - target_classname, THREAD)) -- != (InstanceKlass*)NULL)))) -+ != (InstanceKlass*)NULL))))) - { - // Package private methods always need a new entry to root their own - // overriding. They may also override other methods. -@@ -689,9 +691,15 @@ - // check if a method is a miranda method, given a class's methods table, - // its default_method table and its super - // Miranda methods are calculated twice: --// first: before vtable size calculation: including abstract and default -+// first: before vtable size calculation: including abstract and superinterface default -+// We include potential default methods to give them space in the vtable. -+// During the first run, the default_methods list is empty - // This is seen by default method creation --// Second: recalculated during vtable initialization: only abstract -+// Second: recalculated during vtable initialization: only include abstract methods. -+// During the second run, default_methods is set up, so concrete methods from -+// superinterfaces with matching names/signatures to default_methods are already -+// in the default_methods list and do not need to be appended to the vtable -+// as mirandas - // This is seen by link resolution and selection. - // "miranda" means not static, not defined by this class. - // private methods in interfaces do not belong in the miranda list. -@@ -706,8 +714,9 @@ - } - Symbol* name = m->name(); - Symbol* signature = m->signature(); -+ Method* mo; - -- if (InstanceKlass::find_instance_method(class_methods, name, signature) == NULL) { -+ if ((mo = InstanceKlass::find_instance_method(class_methods, name, signature)) == NULL) { - // did not find it in the method table of the current class - if ((default_methods == NULL) || - InstanceKlass::find_method(default_methods, name, signature) == NULL) { -@@ -716,7 +725,7 @@ - return true; - } - -- Method* mo = InstanceKlass::cast(super)->lookup_method(name, signature); -+ mo = InstanceKlass::cast(super)->lookup_method(name, signature); - while (mo != NULL && mo->access_flags().is_static() - && mo->method_holder() != NULL - && mo->method_holder()->super() != NULL) -@@ -728,6 +737,18 @@ - return true; - } - } -+ } else { -+ // if the local class has a private method, the miranda will not -+ // override it, so a vtable slot is needed -+ if (mo->access_flags().is_private()) { -+ -+ // Second round, weed out any superinterface methods that turned -+ // into default methods, i.e. were concrete not abstract in the end -+ if ((default_methods == NULL) || -+ InstanceKlass::find_method(default_methods, name, signature) == NULL) { -+ return true; -+ } -+ } - } - - return false; ---- ./hotspot/src/share/vm/runtime/arguments.cpp Fri Jan 30 15:14:31 2015 -0800 -+++ ./hotspot/src/share/vm/runtime/arguments.cpp Tue Mar 17 11:22:51 2015 -0700 -@@ -2310,7 +2310,7 @@ - "G1ConcMarkStepDurationMillis"); - status = status && verify_interval(G1ConcRSHotCardLimit, 0, max_jubyte, - "G1ConcRSHotCardLimit"); -- status = status && verify_interval(G1ConcRSLogCacheSize, 0, 31, -+ status = status && verify_interval(G1ConcRSLogCacheSize, 0, 27, - "G1ConcRSLogCacheSize"); - status = status && verify_interval(StringDeduplicationAgeThreshold, 1, markOopDesc::max_age, - "StringDeduplicationAgeThreshold"); ---- ./jaxp/.hgtags Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/.hgtags Tue Mar 17 11:23:49 2015 -0700 -@@ -336,6 +336,8 @@ - 7a721e57b38ff6c1d34af0b86f6482540a815d90 jdk8u25-b17 - fddbc00bde281d7d437b052262e921ed51de8b9a jdk8u25-b18 - 30420a31a81f21e363f412ae9801b7467c8cc908 jdk8u25-b31 -+b4231e682f98c8f7037e00fe6ef446d05a01811b jdk8u25-b32 -+1c17ffddb76625e835d225c84a8c6ff23c1e5729 jdk8u25-b33 - 19b6e16343925a4bf27879795b530d4f64e5d262 jdk8u31-b00 - 469792d179304c9b3218930112547577e1aecb77 jdk8u31-b01 - adbd3e31ef1a95b3f80a77dfbb843d52c053c6d3 jdk8u31-b02 -@@ -350,6 +352,8 @@ - f475dbc70345904bda6b520af43955e244292886 jdk8u31-b11 - 6563e438377f2086253577e08593b1ddfb901eff jdk8u31-b12 - 1dd828fd98f1b84de5dcadb904322b711e7489ff jdk8u31-b13 -+dcc563c9db9ef290a0783378d43a039cd92a08e3 jdk8u31-b31 -+119f4ae3151f4134a5e62034e66a4c17f524838b jdk8u31-b32 - 3a1bba8076da4e54882123e98e219eab1c31ccef jdk8u40-b00 - f219da378d0768ff042d77221e5d20676ecc16f0 jdk8u40-b01 - 16ef2134c32a4e60b5a60105b371163aa5936278 jdk8u40-b02 -@@ -374,3 +378,21 @@ - 78d90db9de2801eec010ccb9f0db3caf969dfc3b jdk8u40-b21 - 54a13451ce243f2159ed3996e6efcf374a5750ca jdk8u40-b22 - e07fbae1efeac4e50514384caa7d226af7414114 jdk8u40-b23 -+048cebd17f73f23ce2295e360f31c1b6788195aa jdk8u40-b24 -+4c0d4c38279c5790aa5b61b03c4cfa9b2a58bc72 jdk8u40-b25 -+f693ef62c207dd0290957c95bd62ab653afe4626 jdk8u40-b26 -+56f6ca79467d04eb95383102046836b6ac7d2811 jdk8u40-b27 -+9286acc600a779acb8bcfab38e82d4f50704afe3 jdk8u45-b00 -+9fded65e1d36e3388111955d50ebf8511dd0345e jdk8u45-b01 -+62566a3dbe5982565ce3e468ee3980b7937a86cc jdk8u45-b02 -+629096783c27510c656229b1adc7fb180cada9c6 jdk8u45-b03 -+85585012b976b72665f8f7740526bde25ccc62e4 jdk8u45-b04 -+da025bade645f0d1e0ef2f825320bd5af0c23eba jdk8u45-b05 -+49bc5472ded41c77dabb0840d385cbee1d60d8e9 jdk8u45-b06 -+061930bd7d8fc2f05042e7eeb32adff1759c6d62 jdk8u45-b07 -+50fba38f3a29f55baaae2da9b392bf9abc8389c1 jdk8u45-b08 -+f893d8b9a0d148951014610b1aab2ba0a5105dfe jdk8u45-b09 -+4de18a629048b90e0d875b9c0bd31800f1cc02ae jdk8u45-b10 -+d4042340fe0aa9d33a161890e179bc21b6c7b8e6 jdk8u45-b11 -+91d1102264e9b58b2ada4b5f112d472f0d86092b jdk8u45-b12 -+a15025742f201f05ead3d731780a4ad437524491 jdk8u45-b13 ---- ./jaxp/THIRD_PARTY_README Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/THIRD_PARTY_README Tue Mar 17 11:23:49 2015 -0700 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - ---- ./jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java Tue Mar 17 11:23:49 2015 -0700 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -151,6 +151,16 @@ - */ - public static final String SP_MAX_ELEMENT_DEPTH = "jdk.xml.maxElementDepth"; - -+ /** -+ * JDK TransformerFactory and Transformer attribute that specifies a class -+ * loader that will be used for extension functions class loading -+ * Value: a "null", the default value, means that the default EF class loading -+ * path will be used. -+ * Instance of ClassLoader: the specified instance of ClassLoader will be used -+ * for extension functions loading during translation process -+ */ -+ public static final String JDK_EXTENSION_CLASSLOADER = "jdk.xml.transform.extensionClassLoader"; -+ - //legacy System Properties - public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit"; - public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ; ---- ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java Tue Mar 17 11:23:49 2015 -0700 -@@ -104,6 +104,9 @@ - protected final static String EXSLT_STRINGS = - "http://exslt.org/strings"; - -+ protected final static String XALAN_CLASSPACKAGE_NAMESPACE = -+ "xalan://"; -+ - // Namespace format constants - protected final static int NAMESPACE_FORMAT_JAVA = 0; - protected final static int NAMESPACE_FORMAT_CLASS = 1; -@@ -900,8 +903,22 @@ - if (_className != null && _className.length() > 0) { - final int nArgs = _arguments.size(); - try { -- if (_clazz == null) { -- _clazz = ObjectFactory.findProviderClass(_className, true); -+ if (_clazz == null) { -+ final boolean isSecureProcessing = getXSLTC().isSecureProcessing(); -+ final boolean isExtensionFunctionEnabled = getXSLTC() -+ .getFeature(FeatureManager.Feature.ORACLE_ENABLE_EXTENSION_FUNCTION); -+ -+ //Check if FSP and SM - only then proceed with loading -+ if (namespace != null && isSecureProcessing -+ && isExtensionFunctionEnabled -+ && (namespace.equals(JAVA_EXT_XALAN) -+ || namespace.equals(JAVA_EXT_XSLTC) -+ || namespace.equals(JAVA_EXT_XALAN_OLD) -+ || namespace.startsWith(XALAN_CLASSPACKAGE_NAMESPACE))) { -+ _clazz = getXSLTC().loadExternalFunction(_className); -+ } else { -+ _clazz = ObjectFactory.findProviderClass(_className, true); -+ } - - if (_clazz == null) { - final ErrorMsg msg = ---- ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Tue Mar 17 11:23:49 2015 -0700 -@@ -23,24 +23,6 @@ - - package com.sun.org.apache.xalan.internal.xsltc.compiler; - --import java.io.BufferedOutputStream; --import java.io.ByteArrayOutputStream; --import java.io.File; --import java.io.FileOutputStream; --import java.io.IOException; --import java.io.InputStream; --import java.net.URL; --import java.util.Date; --import java.util.Enumeration; --import java.util.Hashtable; --import java.util.Map; --import java.util.Properties; --import java.util.Vector; --import java.util.jar.JarEntry; --import java.util.jar.JarOutputStream; --import java.util.jar.Manifest; --import javax.xml.XMLConstants; -- - import com.sun.org.apache.bcel.internal.classfile.JavaClass; - import com.sun.org.apache.xalan.internal.XalanConstants; - import com.sun.org.apache.xalan.internal.utils.FeatureManager; -@@ -50,7 +32,27 @@ - import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; - import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; - import com.sun.org.apache.xml.internal.dtm.DTM; -- -+import java.io.BufferedOutputStream; -+import java.io.ByteArrayOutputStream; -+import java.io.File; -+import java.io.FileOutputStream; -+import java.io.IOException; -+import java.io.InputStream; -+import java.net.URL; -+import java.security.AccessController; -+import java.security.PrivilegedAction; -+import java.util.Collections; -+import java.util.Date; -+import java.util.Enumeration; -+import java.util.HashMap; -+import java.util.Hashtable; -+import java.util.Map; -+import java.util.Properties; -+import java.util.Vector; -+import java.util.jar.JarEntry; -+import java.util.jar.JarOutputStream; -+import java.util.jar.Manifest; -+import javax.xml.XMLConstants; - import org.xml.sax.InputSource; - import org.xml.sax.XMLReader; - -@@ -153,11 +155,25 @@ - private final FeatureManager _featureManager; - - /** -+ * Extension function class loader variables -+ */ -+ -+ /* Class loader reference that will be used for external extension functions loading */ -+ private ClassLoader _extensionClassLoader; -+ -+ /** -+ * HashMap with the loaded classes -+ */ -+ private final Map<String, Class> _externalExtensionFunctions; -+ -+ /** - * XSLTC compiler constructor - */ - public XSLTC(boolean useServicesMechanism, FeatureManager featureManager) { - _parser = new Parser(this, useServicesMechanism); - _featureManager = featureManager; -+ _extensionClassLoader = null; -+ _externalExtensionFunctions = new HashMap<>(); - } - - /** -@@ -207,6 +223,8 @@ - return _accessExternalDTD; - } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { - return _xmlSecurityManager; -+ } else if (name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) { -+ return _extensionClassLoader; - } - return null; - } -@@ -222,6 +240,11 @@ - _accessExternalDTD = (String)value; - } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { - _xmlSecurityManager = (XMLSecurityManager)value; -+ } else if (name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) { -+ _extensionClassLoader = (ClassLoader) value; -+ /* Clear the external extension functions HashMap if extension class -+ loader was changed */ -+ _externalExtensionFunctions.clear(); - } - } - -@@ -256,6 +279,41 @@ - _bcelClasses = new Vector(); - } - -+ private void setExternalExtensionFunctions(String name, Class clazz) { -+ if (_isSecureProcessing && clazz != null && !_externalExtensionFunctions.containsKey(name)) { -+ _externalExtensionFunctions.put(name, clazz); -+ } -+ } -+ -+ /* -+ * Function loads an external extension functions. -+ * The filtering of function types (external,internal) takes place in FunctionCall class -+ * -+ */ -+ Class loadExternalFunction(String name) throws ClassNotFoundException { -+ Class loaded = null; -+ //Check if the function is not loaded already -+ if (_externalExtensionFunctions.containsKey(name)) { -+ loaded = _externalExtensionFunctions.get(name); -+ } else if (_extensionClassLoader != null) { -+ loaded = Class.forName(name, true, _extensionClassLoader); -+ setExternalExtensionFunctions(name, loaded); -+ } -+ if (loaded == null) { -+ throw new ClassNotFoundException(name); -+ } -+ //Return loaded class -+ return (Class) loaded; -+ } -+ -+ /* -+ * Returns unmodifiable view of HashMap with loaded external extension -+ * functions - will be needed for the TransformerImpl -+ */ -+ public Map<String, Class> getExternalExtensionFunctions() { -+ return Collections.unmodifiableMap(_externalExtensionFunctions); -+ } -+ - /** - * Initializes the compiler to produce a new translet - */ -@@ -283,6 +341,7 @@ - -1, // LEVEL_MULTIPLE - -1 // LEVEL_ANY - }; -+ _externalExtensionFunctions.clear(); - } - - /** ---- ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Tue Mar 17 11:23:49 2015 -0700 -@@ -599,6 +599,9 @@ - {ErrorMsg.JAXP_INVALID_ATTR_ERR, - "TransformerFactory does not recognise attribute ''{0}''."}, - -+ {ErrorMsg.JAXP_INVALID_ATTR_VALUE_ERR, -+ "Incorrect value specified for ''{0}'' attribute."}, -+ - /* - * Note to translators: "setResult()" and "startDocument()" are Java - * method names that should not be translated. ---- ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Tue Mar 17 11:23:49 2015 -0700 -@@ -117,6 +117,7 @@ - public static final String JAXP_NO_SOURCE_ERR = "JAXP_NO_SOURCE_ERR"; - public static final String JAXP_COMPILE_ERR = "JAXP_COMPILE_ERR"; - public static final String JAXP_INVALID_ATTR_ERR = "JAXP_INVALID_ATTR_ERR"; -+ public static final String JAXP_INVALID_ATTR_VALUE_ERR = "JAXP_INVALID_ATTR_VALUE_ERR"; - public static final String JAXP_SET_RESULT_ERR = "JAXP_SET_RESULT_ERR"; - public static final String JAXP_NO_TRANSLET_ERR = "JAXP_NO_TRANSLET_ERR"; - public static final String JAXP_NO_HANDLER_ERR = "JAXP_NO_HANDLER_ERR"; ---- ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Tue Mar 17 11:23:49 2015 -0700 -@@ -270,8 +270,8 @@ - if (Double.isNaN(start)) - return(EMPTYSTRING); - -- final int strlen = value.length(); -- int istart = (int)Math.round(start) - 1; -+ final int strlen = value.length(); -+ int istart = (int)Math.round(start) - 1; - - if (istart > strlen) - return(EMPTYSTRING); -@@ -292,10 +292,11 @@ - public static String substringF(String value, double start, double length) { - if (Double.isInfinite(start) || - Double.isNaN(start) || -- Double.isNaN(length)) -+ Double.isNaN(length) || -+ length < 0) - return(EMPTYSTRING); - -- int istart = (int)Math.round(start) - 1; -+ int istart = (int)Math.round(start) - 1; - final int isum; - if (Double.isInfinite(length)) - isum = Integer.MAX_VALUE; ---- ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Tue Mar 17 11:23:49 2015 -0700 -@@ -24,28 +24,27 @@ - package com.sun.org.apache.xalan.internal.xsltc.trax; - - import com.sun.org.apache.xalan.internal.XalanConstants; -+import com.sun.org.apache.xalan.internal.utils.ObjectFactory; -+import com.sun.org.apache.xalan.internal.utils.SecuritySupport; -+import com.sun.org.apache.xalan.internal.xsltc.DOM; -+import com.sun.org.apache.xalan.internal.xsltc.Translet; -+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; -+import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; -+import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable; - import java.io.IOException; - import java.io.ObjectInputStream; - import java.io.ObjectOutputStream; - import java.io.Serializable; --import java.util.Properties; - import java.security.AccessController; - import java.security.PrivilegedAction; -- -+import java.util.Map; -+import java.util.Properties; - import javax.xml.XMLConstants; - import javax.xml.transform.Templates; - import javax.xml.transform.Transformer; - import javax.xml.transform.TransformerConfigurationException; - import javax.xml.transform.URIResolver; - --import com.sun.org.apache.xalan.internal.xsltc.DOM; --import com.sun.org.apache.xalan.internal.xsltc.Translet; --import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; --import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; --import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable; --import com.sun.org.apache.xalan.internal.utils.ObjectFactory; --import com.sun.org.apache.xalan.internal.utils.SecuritySupport; -- - /** - * @author Morten Jorgensen - * @author G. Todd Millerj -@@ -131,8 +130,30 @@ - private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT; - - static final class TransletClassLoader extends ClassLoader { -+ -+ private final Map<String,Class> _loadedExternalExtensionFunctions; -+ - TransletClassLoader(ClassLoader parent) { - super(parent); -+ _loadedExternalExtensionFunctions = null; -+ } -+ -+ TransletClassLoader(ClassLoader parent,Map<String, Class> mapEF) { -+ super(parent); -+ _loadedExternalExtensionFunctions = mapEF; -+ } -+ -+ public Class<?> loadClass(String name) throws ClassNotFoundException { -+ Class<?> ret = null; -+ // The _loadedExternalExtensionFunctions will be empty when the -+ // SecurityManager is not set and the FSP is turned off -+ if (_loadedExternalExtensionFunctions != null) { -+ ret = _loadedExternalExtensionFunctions.get(name); -+ } -+ if (ret == null) { -+ ret = super.loadClass(name); -+ } -+ return ret; - } - - /** -@@ -330,7 +351,7 @@ - TransletClassLoader loader = (TransletClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { -- return new TransletClassLoader(ObjectFactory.findClassLoader()); -+ return new TransletClassLoader(ObjectFactory.findClassLoader(),_tfactory.getExternalExtensionsMap()); - } - }); - ---- ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Wed Jan 28 12:08:37 2015 -0800 -+++ ./jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Tue Mar 17 11:23:49 2015 -0700 -@@ -27,12 +27,12 @@ - import com.sun.org.apache.xalan.internal.utils.FactoryImpl; - import com.sun.org.apache.xalan.internal.utils.FeatureManager; - import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase; -+import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase.State; - import com.sun.org.apache.xalan.internal.utils.ObjectFactory; - import com.sun.org.apache.xalan.internal.utils.SecuritySupport; - import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager; - import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager; - import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property; --import com.sun.org.apache.xalan.internal.utils.FeaturePropertyBase.State; - import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants; - import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader; - import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; -@@ -50,6 +50,7 @@ - import java.net.URL; - import java.util.Enumeration; - import java.util.Hashtable; -+import java.util.Map; - import java.util.Properties; - import java.util.Vector; - import java.util.zip.ZipEntry; -@@ -57,7 +58,6 @@ - import javax.xml.XMLConstants; - import javax.xml.parsers.SAXParser; - import javax.xml.parsers.SAXParserFactory; -- - import javax.xml.transform.ErrorListener; - import javax.xml.transform.Source; - import javax.xml.transform.Templates; -@@ -231,6 +231,13 @@ - - private final FeatureManager _featureManager; - -+ private ClassLoader _extensionClassLoader = null; -+ -+ // Unmodifiable view of external extension function from xslt compiler -+ // It will be populated by user-specified extension functions during the -+ // type checking -+ private Map<String, Class> _xsltcExtensionFunctions; -+ - /** - * javax.xml.transform.sax.TransformerFactory implementation. - */ -@@ -261,6 +268,12 @@ - - //Parser's security manager - _xmlSecurityManager = new XMLSecurityManager(true); -+ //Unmodifiable hash map with loaded external extension functions -+ _xsltcExtensionFunctions = null; -+ } -+ -+ public Map<String,Class> getExternalExtensionsMap() { -+ return _xsltcExtensionFunctions; - } - - /** -@@ -324,6 +337,8 @@ - return Boolean.FALSE; - } else if (name.equals(XalanConstants.SECURITY_MANAGER)) { - return _xmlSecurityManager; -+ } else if (name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) { -+ return _extensionClassLoader; - } - - /** Check to see if the property is managed by the security manager **/ -@@ -439,6 +454,16 @@ - return; - } - } -+ else if ( name.equals(XalanConstants.JDK_EXTENSION_CLASSLOADER)) { -+ if (value instanceof ClassLoader) { -+ _extensionClassLoader = (ClassLoader) value; -+ return; -+ } else { -+ final ErrorMsg err -+ = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_VALUE_ERR, "Extension Functions ClassLoader"); -+ throw new IllegalArgumentException(err.toString()); -+ } -+ } - - if (_xmlSecurityManager != null && - _xmlSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) { -@@ -881,7 +906,6 @@ - // Reset the per-session attributes to their default values - // after each newTemplates() call. - resetTransientAttributes(); -- - return new TemplatesImpl(bytecodes, transletClassName, null, _indentNumber, this); - } - } -@@ -898,8 +922,10 @@ - xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, _accessExternalStylesheet); - xsltc.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); - xsltc.setProperty(XalanConstants.SECURITY_MANAGER, _xmlSecurityManager); -+ xsltc.setProperty(XalanConstants.JDK_EXTENSION_CLASSLOADER, _extensionClassLoader); - xsltc.init(); -- -+ if (!_isNotSecureProcessing) -+ _xsltcExtensionFunctions = xsltc.getExternalExtensionFunctions(); - // Set a document loader (for xsl:include/import) if defined - if (_uriResolver != null) { - xsltc.setSourceLoader(this); ---- ./jaxws/.hgtags Wed Jan 28 12:08:39 2015 -0800 -+++ ./jaxws/.hgtags Tue Mar 17 11:23:59 2015 -0700 -@@ -334,6 +334,8 @@ - d47a47f961ee423ce03623098f62d79254c6f328 jdk8u25-b17 - cb0ad90bfe3c497c7236c5480447c4bde110934f jdk8u25-b18 - a345282d661be80f2cdee3c43e12fbe01e7ff6d5 jdk8u25-b31 -+90b0097a98f161c3e605dc26abf97bb9fc278f33 jdk8u25-b32 -+da8457217afd472276c62f558fb1431f7e0e3bc0 jdk8u25-b33 - 3a676fe898c93ad3afcaa55a71da96455e5f230e jdk8u31-b00 - 1c73ca9179f22d4a73d1a248a3254f891c71ee30 jdk8u31-b01 - c1f1ed28e0bb68d7536fb30bb6f1a3623816b12a jdk8u31-b02 -@@ -348,6 +350,8 @@ - 497c783d228ed188d61964edd409794af3ad3e5c jdk8u31-b11 - 959e8fca46155528c8147da69a7c49edfb002cb1 jdk8u31-b12 - 9d0c737694ece23547c0a27dcd0ba6cbcdf577f2 jdk8u31-b13 -+49e91817cbe1b14f856c26f6e55b7151e3f8c3a8 jdk8u31-b31 -+9e20c5acb448c5f9b05a4e9b4efc222b3b616c23 jdk8u31-b32 - 31d43d250c836c13fcc87025837783788c5cd0de jdk8u40-b00 - 262fb5353ffa661f88b4a9cf2581fcad8c2a43f7 jdk8u40-b01 - 8043f77ef8a4ded9505269a356c4e2f4f9604cd9 jdk8u40-b02 -@@ -372,3 +376,21 @@ - 16485a38b6bc762b363f4e439047486742fbcfcb jdk8u40-b21 - 6e928fd9152541eddf25694be89eb881434a5c5f jdk8u40-b22 - b6755a463ccf6a79b1e1a43ed7bdb1c5cb1ac17d jdk8u40-b23 -+5fbbfd66643edb81cfa0688825d698dcc5f2eb11 jdk8u40-b24 -+b6120aaf2aeef7c5608d578e15e82db7eb24fb2e jdk8u40-b25 -+1bcb30bdd9883cc7fc1bf70800ea03a4429eaa80 jdk8u40-b26 -+a5f2cdedb940511674e153dce8d3cbc3a0598c9e jdk8u40-b27 -+667a4aee3720373f5c286a50f537afd0ff4b65ae jdk8u45-b00 -+cb6added4913f4899bd1689e77be1fe4efcff4f1 jdk8u45-b01 -+855a7b9302053546e4da94b67cc3b8956f5b4985 jdk8u45-b02 -+698a88182586b0914b204de27cc45d6f0dfe7683 jdk8u45-b03 -+c7307f75843b64e6096205425ba2f7387017ee9e jdk8u45-b04 -+6bd873f17e03cf285f576f69340123e3b2d8922f jdk8u45-b05 -+a5e99f4d067ebea01e438e5b3e9b09bda47ddb25 jdk8u45-b06 -+145ea6d2899f5cc6bd4e1108903e4d22ad063eca jdk8u45-b07 -+f3d678fe58e7c026fb62be8b72c46ce1015aadf6 jdk8u45-b08 -+8f2e5110151810dc5b56a3ce05d955e400bee937 jdk8u45-b09 -+5cf887e3e1368d1910181eaab2794b25058fe8b6 jdk8u45-b10 -+855fd9dfcbee177b508413dbab6e46b57dd367c4 jdk8u45-b11 -+3f6c3f48179ac8bab98509be8708edcea32727b6 jdk8u45-b12 -+15fb2359f5f86dbacc1bc120f663853b5292cd14 jdk8u45-b13 ---- ./jaxws/THIRD_PARTY_README Wed Jan 28 12:08:39 2015 -0800 -+++ ./jaxws/THIRD_PARTY_README Tue Mar 17 11:23:59 2015 -0700 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - ---- ./jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/ap/SchemaGenerator.java Wed Jan 28 12:08:39 2015 -0800 -+++ ./jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/ap/SchemaGenerator.java Tue Mar 17 11:23:59 2015 -0700 -@@ -135,7 +135,7 @@ - - private void filterClass(List<Reference> classes, Collection<? extends Element> elements) { - for (Element element : elements) { -- if (element.getKind().equals(ElementKind.CLASS)) { -+ if (element.getKind().equals(ElementKind.CLASS) || element.getKind().equals(ElementKind.ENUM)) { - classes.add(new Reference((TypeElement) element, processingEnv)); - filterClass(classes, ElementFilter.typesIn(element.getEnclosedElements())); - } ---- ./jdk/.hgtags Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/.hgtags Thu Feb 05 13:00:26 2015 +0100 -@@ -337,6 +337,8 @@ - 67b22a82345bfa1ae1492679bdf3c4d54f4eacde jdk8u25-b17 - a4e88eaf15ea0569f3275a807a976fe0e04a086c jdk8u25-b18 - 556c79ef8a1d2fa38f79b3d3e102e80e0b0c9731 jdk8u25-b31 -+5c06b8274d27aa45870f9555dcc60b7602236fa5 jdk8u25-b32 -+afefb260f8f095bc02e758b58a4c354f2ea7bc69 jdk8u25-b33 - f935349e2c065487c745bc41f81ddc7869bd2d2d jdk8u31-b00 - caebf6158e9d522df41a2c89a1602e5013bac401 jdk8u31-b01 - b1cef4d76664564732004cf3aedb0cbaa1972683 jdk8u31-b02 -@@ -351,6 +353,9 @@ - a21dd7999d1e4ba612c951c2c78504d23eb7243a jdk8u31-b11 - 6a12f34816d2ee12368274fc21225384a8893426 jdk8u31-b12 - 1fbdd5d80d0671decd8acb5adb64866f609e986f jdk8u31-b13 -+ced84cf3eebc69f7e04b0098d85dcb3a6b872586 jdk8u31-b31 -+367c7f061c5831ee54cd197f727e06109a67875b jdk8u31-b14 -+287e3219f3f531b2f20b50b180802a563a782b26 jdk8u31-b15 - e6ed015afbbf3459ba3297e270b4f3170e989c80 jdk8u40-b00 - 6e223d48080ef40f4ec11ecbcd19b4a20813b9eb jdk8u40-b01 - 4797cd0713b44b009525f1276d571ade7e24f3f5 jdk8u40-b02 -@@ -375,3 +380,21 @@ - 564bca490631e4ed4f7993e6633ed9ee62067624 jdk8u40-b21 - d168113f9841a77b3cee3a6a45fcd85b7351ac90 jdk8u40-b22 - 41fe61722ce96b75dd3a1ba5072473122e21e5a0 jdk8u40-b23 -+9d903721276c8684706db7ecfb6cda568e9f4f69 jdk8u40-b24 -+f0d5cb59b0e6a67fa102465458cc4725c6e59089 jdk8u40-b25 -+97f258823d7d8ee0ec7d774b79cd30492520cc10 jdk8u40-b26 -+d4453d784fb6c52e4ed998b167588551e2fd43c5 jdk8u40-b27 -+1ecc234bd38950a2bc047aa253a5e803f0836a4e jdk8u45-b00 -+e0c7864bbca3f76cde680722f2ae58dff2bff61d jdk8u45-b01 -+9505c0392cddbfb905401e9fccc23262edc3254f jdk8u45-b02 -+17af4523dfc7a0b978c9ca3d05212f07828e31d0 jdk8u45-b03 -+a26b2f5bc72904eb269176d13afaf39b57a80b29 jdk8u45-b04 -+4d95b1faad78b1e377eacceaa4ff81a3d7bbf549 jdk8u45-b05 -+85ffe9aa18ac7c7fc474af03c61e4e96bb045796 jdk8u45-b06 -+cdf1a9436aec569615913b96734df7a0e77c20e5 jdk8u45-b07 -+6656dca5d05913fa204c79754624cd8fe77d7b49 jdk8u45-b08 -+1083da8a8ec17058de5a35be3e5a821affc19e4e jdk8u45-b09 -+3edfbb32b3c04941eedc551c02d4eec1e0f92078 jdk8u45-b10 -+c669323bd55ac59ad26c7ee4f47a6daefc82af8e jdk8u45-b11 -+6a8f9512afa687632f0a0d881bbdb446d984a74c jdk8u45-b12 -+55a75b0db87693e1e186752f553c337cb035a38e jdk8u45-b13 ---- ./jdk/THIRD_PARTY_README Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/THIRD_PARTY_README Thu Feb 05 13:00:26 2015 +0100 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - ---- ./jdk/make/data/swingbeaninfo/SwingBeanInfo.template Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/swingbeaninfo/SwingBeanInfo.template Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -92,25 +92,38 @@ - /** - * @return an icon of the specified kind for @(BeanClassName) - */ -- public Image getIcon(int kind) { -+ public Image getIcon(final int kind) { - Image i; - switch (kind){ - case ICON_COLOR_32x32: -- i = loadImage("beaninfo/images/@(BeanClassName)Color32.gif"); -- return ((i == null) ? loadImage("beaninfo/images/JComponentColor32.gif") : i); -+ i = loadStandardImage("beaninfo/images/@(BeanClassName)Color32.gif"); -+ return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor32.gif") : i); - case ICON_COLOR_16x16: -- i = loadImage("beaninfo/images/@(BeanClassName)Color16.gif"); -- return ((i == null) ? loadImage("beaninfo/images/JComponentColor16.gif") : i); -+ i = loadStandardImage("beaninfo/images/@(BeanClassName)Color16.gif"); -+ return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor16.gif") : i); - case ICON_MONO_32x32: -- i = loadImage("beaninfo/images/@(BeanClassName)Mono32.gif"); -- return ((i == null) ? loadImage("beaninfo/images/JComponentMono32.gif") : i); -+ i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono32.gif"); -+ return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono32.gif") : i); - case ICON_MONO_16x16: -- i = loadImage("beaninfo/images/@(BeanClassName)Mono16.gif"); -- return ((i == null) ? loadImage("beaninfo/images/JComponentMono16.gif") : i); -+ i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono16.gif"); -+ return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono16.gif") : i); - default: - return super.getIcon(kind); - } - } -+ -+ /** -+ * This is a utility method to help in loading standard icon images. -+ * -+ * @param resourceName A pathname relative to the directory holding the -+ * class file of the current class -+ * @return an image object. May be null if the load failed. -+ * @see java.beans.SimpleBeanInfo#loadImage(String) -+ */ -+ private Image loadStandardImage(final String resourceName) { -+ return java.security.AccessController.doPrivileged( -+ (java.security.PrivilegedAction<Image>) () -> loadImage(resourceName)); -+ } - } - - ---- ./jdk/make/data/tzdata/VERSION Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/VERSION Thu Feb 05 13:00:26 2015 +0100 -@@ -21,4 +21,4 @@ - # or visit www.oracle.com if you need additional information or have any - # questions. - # --tzdata2014j -+tzdata2015a ---- ./jdk/make/data/tzdata/antarctica Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/antarctica Thu Feb 05 13:00:26 2015 +0100 -@@ -70,8 +70,8 @@ - Rule ChileAQ 2010 only - Apr Sun>=1 3:00u 0 - - Rule ChileAQ 2011 only - May Sun>=2 3:00u 0 - - Rule ChileAQ 2011 only - Aug Sun>=16 4:00u 1:00 S --Rule ChileAQ 2012 max - Apr Sun>=23 3:00u 0 - --Rule ChileAQ 2012 max - Sep Sun>=2 4:00u 1:00 S -+Rule ChileAQ 2012 2015 - Apr Sun>=23 3:00u 0 - -+Rule ChileAQ 2012 2014 - Sep Sun>=2 4:00u 1:00 S - - # Argentina - year-round bases - # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05 -@@ -377,9 +377,10 @@ - # - # Zone NAME GMTOFF RULES FORMAT [UNTIL] - Zone Antarctica/Palmer 0 - zzz 1965 -- -4:00 ArgAQ AR%sT 1969 Oct 5 -+ -4:00 ArgAQ AR%sT 1969 Oct 5 - -3:00 ArgAQ AR%sT 1982 May -- -4:00 ChileAQ CL%sT -+ -4:00 ChileAQ CL%sT 2015 Apr 26 3:00u -+ -3:00 - CLT - # - # - # McMurdo Station, Ross Island, since 1955-12 ---- ./jdk/make/data/tzdata/asia Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/asia Thu Feb 05 13:00:26 2015 +0100 -@@ -168,10 +168,7 @@ - 4:00 Azer AZ%sT - - # Bahrain --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Bahrain 3:22:20 - LMT 1920 # Manamah -- 4:00 - GST 1972 Jun -- 3:00 - AST -+# See Asia/Qatar. - - # Bangladesh - # From Alexander Krivenyshev (2009-05-13): -@@ -1754,9 +1751,7 @@ - ############################################################################### - - # Kuwait --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Kuwait 3:11:56 - LMT 1950 -- 3:00 - AST -+# See Asia/Riyadh. - - # Laos - # See Asia/Bangkok. -@@ -1977,12 +1972,7 @@ - 5:45 - NPT # Nepal Time - - # Oman -- --# Milne says 3:54:24 was the meridian of the Muscat Tidal Observatory. -- --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Muscat 3:54:24 - LMT 1920 -- 4:00 - GST -+# See Asia/Dubai. - - # Pakistan - -@@ -2476,6 +2466,7 @@ - Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah / Doha - 4:00 - GST 1972 Jun - 3:00 - AST -+Link Asia/Qatar Asia/Bahrain - - # Saudi Arabia - # -@@ -2502,6 +2493,8 @@ - # Zone NAME GMTOFF RULES FORMAT [UNTIL] - Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14 - 3:00 - AST -+Link Asia/Riyadh Asia/Aden # Yemen -+Link Asia/Riyadh Asia/Kuwait - - # Singapore - # taken from Mok Ly Yng (2003-10-30) -@@ -2790,6 +2783,7 @@ - # Zone NAME GMTOFF RULES FORMAT [UNTIL] - Zone Asia/Dubai 3:41:12 - LMT 1920 - 4:00 - GST -+Link Asia/Dubai Asia/Muscat # Oman - - # Uzbekistan - # Byalokoz 1919 says Uzbekistan was 4:27:53. -@@ -2874,10 +2868,4 @@ - 7:00 - ICT - - # Yemen -- --# Milne says 2:59:54 was the meridian of the saluting battery at Aden, --# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia. -- --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Aden 2:59:54 - LMT 1950 -- 3:00 - AST -+# See Asia/Riyadh. ---- ./jdk/make/data/tzdata/backward Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/backward Thu Feb 05 13:00:26 2015 +0100 -@@ -28,7 +28,7 @@ - # and their old names. Many names changed in late 1993. - - # Link TARGET LINK-NAME --Link Africa/Asmara Africa/Asmera -+Link Africa/Nairobi Africa/Asmera - Link Africa/Abidjan Africa/Timbuktu - Link America/Argentina/Catamarca America/Argentina/ComodRivadavia - Link America/Adak America/Atka ---- ./jdk/make/data/tzdata/europe Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/europe Thu Feb 05 13:00:26 2015 +0100 -@@ -1430,35 +1430,32 @@ - # might be a reference to the Julian calendar as opposed to Gregorian, or it - # might mean something else (???). - # --# From Paul Eggert (2006-03-22): --# The Iceland Almanak, Shanks & Pottenger, and Whitman disagree on many points. --# We go with the Almanak, except for one claim from Shanks & Pottenger, namely --# that Reykavik was 21W57 from 1837 to 1908, local mean time before that. -+# From Paul Eggert (2014-11-22): -+# The information below is taken from the 1988 Almanak; see -+# http://www.almanak.hi.is/klukkan.html - # - # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S --Rule Iceland 1917 1918 - Feb 19 23:00 1:00 S -+Rule Iceland 1917 1919 - Feb 19 23:00 1:00 S - Rule Iceland 1917 only - Oct 21 1:00 0 - --Rule Iceland 1918 only - Nov 16 1:00 0 - -+Rule Iceland 1918 1919 - Nov 16 1:00 0 - -+Rule Iceland 1921 only - Mar 19 23:00 1:00 S -+Rule Iceland 1921 only - Jun 23 1:00 0 - - Rule Iceland 1939 only - Apr 29 23:00 1:00 S --Rule Iceland 1939 only - Nov 29 2:00 0 - -+Rule Iceland 1939 only - Oct 29 2:00 0 - - Rule Iceland 1940 only - Feb 25 2:00 1:00 S --Rule Iceland 1940 only - Nov 3 2:00 0 - --Rule Iceland 1941 only - Mar 2 1:00s 1:00 S --Rule Iceland 1941 only - Nov 2 1:00s 0 - --Rule Iceland 1942 only - Mar 8 1:00s 1:00 S --Rule Iceland 1942 only - Oct 25 1:00s 0 - -+Rule Iceland 1940 1941 - Nov Sun>=2 1:00s 0 - -+Rule Iceland 1941 1942 - Mar Sun>=2 1:00s 1:00 S - # 1943-1946 - first Sunday in March until first Sunday in winter - Rule Iceland 1943 1946 - Mar Sun>=1 1:00s 1:00 S --Rule Iceland 1943 1948 - Oct Sun>=22 1:00s 0 - -+Rule Iceland 1942 1948 - Oct Sun>=22 1:00s 0 - - # 1947-1967 - first Sunday in April until first Sunday in winter - Rule Iceland 1947 1967 - Apr Sun>=1 1:00s 1:00 S --# 1949 Oct transition delayed by 1 week -+# 1949 and 1967 Oct transitions delayed by 1 week - Rule Iceland 1949 only - Oct 30 1:00s 0 - - Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 - - Rule Iceland 1967 only - Oct 29 1:00s 0 - - # Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Atlantic/Reykjavik -1:27:24 - LMT 1837 -- -1:27:48 - RMT 1908 # Reykjavik Mean Time? -+Zone Atlantic/Reykjavik -1:28 - LMT 1908 - -1:00 Iceland IS%sT 1968 Apr 7 1:00s - 0:00 - GMT - ---- ./jdk/make/data/tzdata/leapseconds Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/leapseconds Thu Feb 05 13:00:26 2015 +0100 -@@ -77,3 +77,7 @@ - Leap 2005 Dec 31 23:59:60 + S - Leap 2008 Dec 31 23:59:60 + S - Leap 2012 Jun 30 23:59:60 + S -+Leap 2015 Jun 30 23:59:60 + S -+ -+# Updated through IERS Bulletin C49 -+# File expires on: 28 December 2015 ---- ./jdk/make/data/tzdata/northamerica Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/northamerica Thu Feb 05 13:00:26 2015 +0100 -@@ -147,7 +147,7 @@ - Rule US 1918 1919 - Oct lastSun 2:00 0 S - Rule US 1942 only - Feb 9 2:00 1:00 W # War - Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace --Rule US 1945 only - Sep 30 2:00 0 S -+Rule US 1945 only - Sep lastSun 2:00 0 S - Rule US 1967 2006 - Oct lastSun 2:00 0 S - Rule US 1967 1973 - Apr lastSun 2:00 1:00 D - Rule US 1974 only - Jan 6 2:00 1:00 D -@@ -2147,11 +2147,11 @@ - - # Mexico - --# From Paul Eggert (2001-03-05): -+# From Paul Eggert (2014-12-07): - # The Investigation and Analysis Service of the - # Mexican Library of Congress (MLoC) has published a - # history of Mexican local time (in Spanish) --# http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/ -+# http://www.diputados.gob.mx/bibliot/publica/inveyana/polisoc/horver/index.htm - # - # Here are the discrepancies between Shanks & Pottenger (S&P) and the MLoC. - # (In all cases we go with the MLoC.) -@@ -2320,6 +2320,24 @@ - # efecto desde las dos horas del segundo domingo de marzo y concluirá a - # las dos horas del primer domingo de noviembre. - -+# From Steffen Thorsen (2014-12-08), translated by Gwillim Law: -+# The Mexican state of Quintana Roo will likely change to EST in 2015. -+# -+# http://www.unioncancun.mx/articulo/2014/12/04/medio-ambiente/congreso-aprueba-una-hora-mas-de-sol-en-qroo -+# "With this change, the time conflict that has existed between the municipios -+# of Quintana Roo and the municipio of Felipe Carrillo Puerto may come to an -+# end. The latter declared itself in rebellion 15 years ago when a time change -+# was initiated in Mexico, and since then it has refused to change its time -+# zone along with the rest of the country." -+# -+# From Steffen Thorsen (2015-01-14), translated by Gwillim Law: -+# http://sipse.com/novedades/confirman-aplicacion-de-nueva-zona-horaria-para-quintana-roo-132331.html -+# "...the new time zone will come into effect at two o'clock on the first Sunday -+# of February, when we will have to advance the clock one hour from its current -+# time..." -+# -+# Also, the new zone will not use DST. -+ - # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S - Rule Mexico 1939 only - Feb 5 0:00 1:00 D - Rule Mexico 1939 only - Jun 25 0:00 0 S -@@ -2340,7 +2358,8 @@ - Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56 - -6:00 - CST 1981 Dec 23 - -5:00 Mexico E%sT 1998 Aug 2 2:00 -- -6:00 Mexico C%sT -+ -6:00 Mexico C%sT 2015 Feb 1 2:00 -+ -5:00 - EST - # Campeche, Yucatán; represented by Mérida - Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32 - -6:00 - CST 1981 Dec 23 ---- ./jdk/make/data/tzdata/southamerica Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/southamerica Thu Feb 05 13:00:26 2015 +0100 -@@ -1229,6 +1229,11 @@ - # DST Start: first Saturday of September 2014 (Sun 07 Sep 2014 04:00 UTC) - # http://www.diariooficial.interior.gob.cl//media/2014/02/19/do-20140219.pdf - -+# From Juan Correa (2015-01-28): -+# ... today the Ministry of Energy announced that Chile will drop DST, will keep -+# "summer time" (UTC -3 / UTC -5) all year round.... -+# http://www.minenergia.cl/ministerio/noticias/generales/ministerio-de-energia-anuncia.html -+ - # NOTE: ChileAQ rules for Antarctic bases are stored separately in the - # 'antarctica' file. - -@@ -1270,8 +1275,8 @@ - Rule Chile 2010 only - Apr Sun>=1 3:00u 0 - - Rule Chile 2011 only - May Sun>=2 3:00u 0 - - Rule Chile 2011 only - Aug Sun>=16 4:00u 1:00 S --Rule Chile 2012 max - Apr Sun>=23 3:00u 0 - --Rule Chile 2012 max - Sep Sun>=2 4:00u 1:00 S -+Rule Chile 2012 2015 - Apr Sun>=23 3:00u 0 - -+Rule Chile 2012 2014 - Sep Sun>=2 4:00u 1:00 S - # IATA SSIM anomalies: (1992-02) says 1992-03-14; - # (1996-09) says 1998-03-08. Ignore these. - # Zone NAME GMTOFF RULES FORMAT [UNTIL] -@@ -1282,11 +1287,13 @@ - -4:00 - CLT 1919 Jul 1 # Chile Time - -4:42:46 - SMT 1927 Sep 1 # Santiago Mean Time - -5:00 Chile CL%sT 1947 May 22 # Chile Time -- -4:00 Chile CL%sT -+ -4:00 Chile CL%sT 2015 Apr 26 3:00u -+ -3:00 - CLT - Zone Pacific/Easter -7:17:44 - LMT 1890 - -7:17:28 - EMT 1932 Sep # Easter Mean Time -- -7:00 Chile EAS%sT 1982 Mar 13 21:00 # Easter Time -- -6:00 Chile EAS%sT -+ -7:00 Chile EAS%sT 1982 Mar 13 3:00u # Easter Time -+ -6:00 Chile EAS%sT 2015 Apr 26 3:00u -+ -5:00 - EAST - # - # Salas y Gómez Island is uninhabited. - # Other Chilean locations, including Juan Fernández Is, Desventuradas Is, ---- ./jdk/make/data/tzdata/zone.tab Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/make/data/tzdata/zone.tab Thu Feb 05 13:00:26 2015 +0100 -@@ -297,7 +297,7 @@ - MV +0410+07330 Indian/Maldives - MW -1547+03500 Africa/Blantyre - MX +1924-09909 America/Mexico_City Central Time - most locations --MX +2105-08646 America/Cancun Central Time - Quintana Roo -+MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo - MX +2058-08937 America/Merida Central Time - Campeche, Yucatan - MX +2540-10019 America/Monterrey Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border - MX +2550-09730 America/Matamoros US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border ---- ./jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/macosx/native/sun/awt/splashscreen/splashscreen_sys.m Thu Feb 05 13:00:26 2015 +0100 -@@ -131,11 +131,7 @@ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - *scaleFactor = 1; - char* scaledFile = nil; -- __block float screenScaleFactor = 1; -- -- [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ -- screenScaleFactor = [SplashNSScreen() backingScaleFactor]; -- }]; -+ float screenScaleFactor = 1; - - if (screenScaleFactor > 1) { - NSString *fileName = [NSString stringWithUTF8String: file]; ---- ./jdk/src/macosx/native/sun/font/AWTStrike.m Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/macosx/native/sun/font/AWTStrike.m Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -25,14 +25,11 @@ - - #import <JavaNativeFoundation/JavaNativeFoundation.h> - #import "java_awt_geom_PathIterator.h" --#import "sun_awt_SunHints.h" - #import "sun_font_CStrike.h" - #import "sun_font_CStrikeDisposer.h" - #import "CGGlyphImages.h" - #import "CGGlyphOutlines.h" --#import "AWTStrike.h" - #import "CoreTextSupport.h" --//#import "jni_util.h" - #include "fontscalerdefs.h" - - /* Use THIS_FILE when it is available. */ -@@ -65,10 +62,10 @@ - invDevTx.b *= -1; - invDevTx.c *= -1; - fFontTx = CGAffineTransformConcat(CGAffineTransformConcat(tx, invDevTx), sInverseTX); -- fDevTx = CGAffineTransformInvert(invDevTx); -+ fDevTx = CGAffineTransformInvert(CGAffineTransformConcat(invDevTx, sInverseTX)); - - // the "font size" is the square root of the determinant of the matrix -- fSize = sqrt(abs(fFontTx.a * fFontTx.d - fFontTx.b * fFontTx.c)); -+ fSize = sqrt(fabs(fFontTx.a * fFontTx.d - fFontTx.b * fFontTx.c)); - } - return self; - } ---- ./jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -349,7 +349,7 @@ - switch (mode) { - case MODE_SIGN: - data = padding.pad(buffer, 0, bufOfs); -- return RSACore.rsa(data, privateKey); -+ return RSACore.rsa(data, privateKey, true); - case MODE_VERIFY: - byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs); - data = RSACore.rsa(verifyBuffer, publicKey); -@@ -359,7 +359,7 @@ - return RSACore.rsa(data, publicKey); - case MODE_DECRYPT: - byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs); -- data = RSACore.rsa(decryptBuffer, privateKey); -+ data = RSACore.rsa(decryptBuffer, privateKey, false); - return padding.unpad(data); - default: - throw new AssertionError("Internal error"); ---- ./jdk/src/share/classes/java/awt/EventQueue.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/java/awt/EventQueue.java Thu Feb 05 13:00:26 2015 +0100 -@@ -182,7 +182,14 @@ - - private FwDispatcher fwDispatcher; - -- private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue"); -+ private static volatile PlatformLogger eventLog; -+ -+ private static final PlatformLogger getEventLog() { -+ if(eventLog == null) { -+ eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue"); -+ } -+ return eventLog; -+ } - - static { - AWTAccessor.setEventQueueAccessor( -@@ -759,8 +766,8 @@ - dispatchThread.stopDispatching(); - } - } else { -- if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { -- eventLog.fine("Unable to dispatch event: " + event); -+ if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) { -+ getEventLog().fine("Unable to dispatch event: " + event); - } - } - } -@@ -857,8 +864,8 @@ - * @since 1.2 - */ - public void push(EventQueue newEventQueue) { -- if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { -- eventLog.fine("EventQueue.push(" + newEventQueue + ")"); -+ if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) { -+ getEventLog().fine("EventQueue.push(" + newEventQueue + ")"); - } - - pushPopLock.lock(); -@@ -883,8 +890,8 @@ - // Use getNextEventPrivate() as it doesn't call flushPendingEvents() - newEventQueue.postEventPrivate(topQueue.getNextEventPrivate()); - } catch (InterruptedException ie) { -- if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { -- eventLog.fine("Interrupted push", ie); -+ if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) { -+ getEventLog().fine("Interrupted push", ie); - } - } - } -@@ -922,8 +929,8 @@ - * @since 1.2 - */ - protected void pop() throws EmptyStackException { -- if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { -- eventLog.fine("EventQueue.pop(" + this + ")"); -+ if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) { -+ getEventLog().fine("EventQueue.pop(" + this + ")"); - } - - pushPopLock.lock(); -@@ -945,8 +952,8 @@ - try { - prevQueue.postEventPrivate(topQueue.getNextEventPrivate()); - } catch (InterruptedException ie) { -- if (eventLog.isLoggable(PlatformLogger.Level.FINE)) { -- eventLog.fine("Interrupted pop", ie); -+ if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) { -+ getEventLog().fine("Interrupted pop", ie); - } - } - } ---- ./jdk/src/share/classes/java/beans/Beans.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/java/beans/Beans.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -46,9 +46,6 @@ - - import java.net.URL; - --import java.security.AccessController; --import java.security.PrivilegedAction; -- - import java.util.Enumeration; - import java.util.Hashtable; - import java.util.Iterator; -@@ -179,16 +176,10 @@ - - // Try to find a serialized object with this name - final String serName = beanName.replace('.','/').concat(".ser"); -- final ClassLoader loader = cls; -- ins = AccessController.doPrivileged -- (new PrivilegedAction<InputStream>() { -- public InputStream run() { -- if (loader == null) -- return ClassLoader.getSystemResourceAsStream(serName); -- else -- return loader.getResourceAsStream(serName); -- } -- }); -+ if (cls == null) -+ ins = ClassLoader.getSystemResourceAsStream(serName); -+ else -+ ins = cls.getResourceAsStream(serName); - if (ins != null) { - try { - if (cls == null) { -@@ -279,19 +270,10 @@ - URL docBase = null; - - // Now get the URL correponding to the resource name. -- -- final ClassLoader cloader = cls; -- objectUrl = -- AccessController.doPrivileged -- (new PrivilegedAction<URL>() { -- public URL run() { -- if (cloader == null) -- return ClassLoader.getSystemResource -- (resourceName); -- else -- return cloader.getResource(resourceName); -- } -- }); -+ if (cls == null) { -+ objectUrl = ClassLoader.getSystemResource(resourceName); -+ } else -+ objectUrl = cls.getResource(resourceName); - - // If we found a URL, we try to locate the docbase by taking - // of the final path name component, and the code base by taking ---- ./jdk/src/share/classes/java/beans/SimpleBeanInfo.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/java/beans/SimpleBeanInfo.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -25,6 +25,11 @@ - - package java.beans; - -+import java.awt.Image; -+import java.awt.Toolkit; -+import java.awt.image.ImageProducer; -+import java.net.URL; -+ - /** - * This is a support class to make it easier for people to provide - * BeanInfo classes. -@@ -99,7 +104,7 @@ - * Claim there are no icons available. You can override - * this if you want to provide icons for your bean. - */ -- public java.awt.Image getIcon(int iconKind) { -+ public Image getIcon(int iconKind) { - return null; - } - -@@ -114,33 +119,17 @@ - * "wombat.gif". - * @return an image object. May be null if the load failed. - */ -- public java.awt.Image loadImage(final String resourceName) { -+ public Image loadImage(final String resourceName) { - try { -- final Class<?> c = getClass(); -- java.awt.image.ImageProducer ip = (java.awt.image.ImageProducer) -- java.security.AccessController.doPrivileged( -- new java.security.PrivilegedAction<Object>() { -- public Object run() { -- java.net.URL url; -- if ((url = c.getResource(resourceName)) == null) { -- return null; -- } else { -- try { -- return url.getContent(); -- } catch (java.io.IOException ioe) { -- return null; -- } -- } -- } -- }); -- -- if (ip == null) -- return null; -- java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit(); -- return tk.createImage(ip); -- } catch (Exception ex) { -- return null; -+ final URL url = getClass().getResource(resourceName); -+ if (url != null) { -+ final ImageProducer ip = (ImageProducer) url.getContent(); -+ if (ip != null) { -+ return Toolkit.getDefaultToolkit().createImage(ip); -+ } -+ } -+ } catch (final Exception ignored) { - } -+ return null; - } -- - } ---- ./jdk/src/share/classes/java/net/SocksSocketImpl.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/java/net/SocksSocketImpl.java Thu Feb 05 13:00:26 2015 +0100 -@@ -388,14 +388,13 @@ - } - while (iProxy.hasNext()) { - p = iProxy.next(); -- if (p == null || p == Proxy.NO_PROXY) { -+ if (p == null || p.type() != Proxy.Type.SOCKS) { - super.connect(epoint, remainingMillis(deadlineMillis)); - return; - } -- if (p.type() != Proxy.Type.SOCKS) -- throw new SocketException("Unknown proxy type : " + p.type()); -+ - if (!(p.address() instanceof InetSocketAddress)) -- throw new SocketException("Unknow address type for proxy: " + p); -+ throw new SocketException("Unknown address type for proxy: " + p); - // Use getHostString() to avoid reverse lookups - server = ((InetSocketAddress) p.address()).getHostString(); - serverPort = ((InetSocketAddress) p.address()).getPort(); -@@ -703,13 +702,12 @@ - } - while (iProxy.hasNext()) { - p = iProxy.next(); -- if (p == null || p == Proxy.NO_PROXY) { -+ if (p == null || p.type() != Proxy.Type.SOCKS) { - return; - } -- if (p.type() != Proxy.Type.SOCKS) -- throw new SocketException("Unknown proxy type : " + p.type()); -+ - if (!(p.address() instanceof InetSocketAddress)) -- throw new SocketException("Unknow address type for proxy: " + p); -+ throw new SocketException("Unknown address type for proxy: " + p); - // Use getHostString() to avoid reverse lookups - server = ((InetSocketAddress) p.address()).getHostString(); - serverPort = ((InetSocketAddress) p.address()).getPort(); ---- ./jdk/src/share/classes/sun/security/krb5/Config.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/krb5/Config.java Thu Feb 05 13:00:26 2015 +0100 -@@ -763,9 +763,9 @@ - - private static String trimmed(String s) { - s = s.trim(); -- if (s.isEmpty()) return s; -- if (s.charAt(0) == '"' && s.charAt(s.length()-1) == '"' || -- s.charAt(0) == '\'' && s.charAt(s.length()-1) == '\'') { -+ if (s.length() >= 2 && -+ ((s.charAt(0) == '"' && s.charAt(s.length()-1) == '"') || -+ (s.charAt(0) == '\'' && s.charAt(s.length()-1) == '\''))) { - s = s.substring(1, s.length()-1).trim(); - } - return s; ---- ./jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Thu Feb 05 13:00:26 2015 +0100 -@@ -707,6 +707,11 @@ - - entry.protectedPrivKey = key.clone(); - if (chain != null) { -+ // validate cert-chain -+ if ((chain.length > 1) && (!validateChain(chain))) { -+ throw new KeyStoreException("Certificate chain is " -+ + "not valid"); -+ } - entry.chain = chain.clone(); - certificateCount += chain.length; - -@@ -1448,7 +1453,12 @@ - if (!(issuerDN.equals(subjectDN))) - return false; - } -- return true; -+ -+ // Check for loops in the chain. If there are repeated certs, -+ // the Set of certs in the chain will contain fewer certs than -+ // the chain -+ Set<Certificate> set = new HashSet<>(Arrays.asList(certChain)); -+ return set.size() == certChain.length; - } - - -@@ -2022,7 +2032,24 @@ - ArrayList<X509Certificate> chain = - new ArrayList<X509Certificate>(); - X509Certificate cert = findMatchedCertificate(entry); -+ -+ mainloop: - while (cert != null) { -+ // Check for loops in the certificate chain -+ if (!chain.isEmpty()) { -+ for (X509Certificate chainCert : chain) { -+ if (cert.equals(chainCert)) { -+ if (debug != null) { -+ debug.println("Loop detected in " + -+ "certificate chain. Skip adding " + -+ "repeated cert to chain. Subject: " + -+ cert.getSubjectX500Principal() -+ .toString()); -+ } -+ break mainloop; -+ } -+ } -+ } - chain.add(cert); - X500Principal issuerDN = cert.getIssuerX500Principal(); - if (issuerDN.equals(cert.getSubjectX500Principal())) { ---- ./jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -541,10 +541,10 @@ - // set interim reasons mask to the intersection of - // reasons in the DP and onlySomeReasons in the IDP - boolean[] idpReasonFlags = reasons.getFlags(); -- for (int i = 0; i < idpReasonFlags.length; i++) { -- if (idpReasonFlags[i] && pointReasonFlags[i]) { -- interimReasonsMask[i] = true; -- } -+ for (int i = 0; i < interimReasonsMask.length; i++) { -+ interimReasonsMask[i] = -+ (i < idpReasonFlags.length && idpReasonFlags[i]) && -+ (i < pointReasonFlags.length && pointReasonFlags[i]); - } - } else { - // set interim reasons mask to the value of -@@ -558,7 +558,6 @@ - interimReasonsMask = pointReasonFlags.clone(); - } else { - // set interim reasons mask to the special value all-reasons -- interimReasonsMask = new boolean[9]; - Arrays.fill(interimReasonsMask, true); - } - } -@@ -567,7 +566,9 @@ - // not included in the reasons mask - boolean oneOrMore = false; - for (int i = 0; i < interimReasonsMask.length && !oneOrMore; i++) { -- if (!reasonsMask[i] && interimReasonsMask[i]) { -+ if (interimReasonsMask[i] && -+ !(i < reasonsMask.length && reasonsMask[i])) -+ { - oneOrMore = true; - } - } -@@ -693,11 +694,11 @@ - } - - // update reasonsMask -- for (int i = 0; i < interimReasonsMask.length; i++) { -- if (!reasonsMask[i] && interimReasonsMask[i]) { -- reasonsMask[i] = true; -- } -+ for (int i = 0; i < reasonsMask.length; i++) { -+ reasonsMask[i] = reasonsMask[i] || -+ (i < interimReasonsMask.length && interimReasonsMask[i]); - } -+ - return true; - } - ---- ./jdk/src/share/classes/sun/security/rsa/RSACore.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/rsa/RSACore.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -102,12 +102,24 @@ - - /** - * Perform an RSA private key operation. Uses CRT if the key is a -- * CRT key. -+ * CRT key with additional verification check after the signature -+ * is computed. - */ -+ @Deprecated - public static byte[] rsa(byte[] msg, RSAPrivateKey key) - throws BadPaddingException { -+ return rsa(msg, key, true); -+ } -+ -+ /** -+ * Perform an RSA private key operation. Uses CRT if the key is a -+ * CRT key. Set 'verify' to true if this function is used for -+ * generating a signature. -+ */ -+ public static byte[] rsa(byte[] msg, RSAPrivateKey key, boolean verify) -+ throws BadPaddingException { - if (key instanceof RSAPrivateCrtKey) { -- return crtCrypt(msg, (RSAPrivateCrtKey)key); -+ return crtCrypt(msg, (RSAPrivateCrtKey)key, verify); - } else { - return priCrypt(msg, key.getModulus(), key.getPrivateExponent()); - } -@@ -148,10 +160,11 @@ - * RSA private key operations with CRT. Algorithm and variable naming - * are taken from PKCS#1 v2.1, section 5.1.2. - */ -- private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key) -- throws BadPaddingException { -+ private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key, -+ boolean verify) throws BadPaddingException { - BigInteger n = key.getModulus(); -- BigInteger c = parseMsg(msg, n); -+ BigInteger c0 = parseMsg(msg, n); -+ BigInteger c = c0; - BigInteger p = key.getPrimeP(); - BigInteger q = key.getPrimeQ(); - BigInteger dP = key.getPrimeExponentP(); -@@ -184,6 +197,9 @@ - if (ENABLE_BLINDING) { - m = m.multiply(brp.v).mod(n); - } -+ if (verify && !c0.equals(m.modPow(e, n))) { -+ throw new BadPaddingException("RSA private key operation failed"); -+ } - - return toByteArray(m, getByteLength(n)); - } ---- ./jdk/src/share/classes/sun/security/rsa/RSASignature.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/rsa/RSASignature.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -173,7 +173,7 @@ - try { - byte[] encoded = encodeSignature(digestOID, digest); - byte[] padded = padding.pad(encoded); -- byte[] encrypted = RSACore.rsa(padded, privateKey); -+ byte[] encrypted = RSACore.rsa(padded, privateKey, true); - return encrypted; - } catch (GeneralSecurityException e) { - throw new SignatureException("Could not sign data", e); ---- ./jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -289,7 +289,7 @@ - case K_ECDH_RSA: - throw new SSLProtocolException( - "Protocol violation: server sent a server key exchange" -- + "message for key exchange " + keyExchange); -+ + " message for key exchange " + keyExchange); - case K_KRB5: - case K_KRB5_EXPORT: - throw new SSLProtocolException( ---- ./jdk/src/share/classes/sun/security/ssl/Handshaker.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/ssl/Handshaker.java Thu Feb 05 13:00:26 2015 +0100 -@@ -697,6 +697,16 @@ - continue; - } - -+ if (!algorithmConstraints.permits( -+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), -+ protocol.name, null)) { -+ if (debug != null && Debug.isOn("verbose")) { -+ System.out.println( -+ "Ignoring disabled protocol: " + protocol); -+ } -+ -+ continue; -+ } - boolean found = false; - for (CipherSuite suite : enabledCipherSuites.collection()) { - if (suite.isAvailable() && suite.obsoleted > protocol.v && ---- ./jdk/src/share/classes/sun/security/util/HostnameChecker.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/util/HostnameChecker.java Thu Feb 05 13:00:26 2015 +0100 -@@ -26,6 +26,8 @@ - package sun.security.util; - - import java.io.IOException; -+import java.net.InetAddress; -+import java.net.UnknownHostException; - import java.util.*; - - import java.security.Principal; -@@ -148,6 +150,17 @@ - String ipAddress = (String)next.get(1); - if (expectedIP.equalsIgnoreCase(ipAddress)) { - return; -+ } else { -+ // compare InetAddress objects in order to ensure -+ // equality between a long IPv6 address and its -+ // abbreviated form. -+ try { -+ if (InetAddress.getByName(expectedIP).equals( -+ InetAddress.getByName(ipAddress))) { -+ return; -+ } -+ } catch (UnknownHostException e) { -+ } catch (SecurityException e) {} - } - } - } ---- ./jdk/src/share/classes/sun/security/x509/KeyUsageExtension.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/x509/KeyUsageExtension.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -83,7 +83,8 @@ - * @param position the position in the bit string to check. - */ - private boolean isSet(int position) { -- return bitString[position]; -+ return (position < bitString.length) && -+ bitString[position]; - } - - /** -@@ -275,41 +276,40 @@ - * Returns a printable representation of the KeyUsage. - */ - public String toString() { -- String s = super.toString() + "KeyUsage [\n"; -+ StringBuilder sb = new StringBuilder(); -+ sb.append(super.toString()); -+ sb.append("KeyUsage [\n"); - -- try { -- if (isSet(0)) { -- s += " DigitalSignature\n"; -- } -- if (isSet(1)) { -- s += " Non_repudiation\n"; -- } -- if (isSet(2)) { -- s += " Key_Encipherment\n"; -- } -- if (isSet(3)) { -- s += " Data_Encipherment\n"; -- } -- if (isSet(4)) { -- s += " Key_Agreement\n"; -- } -- if (isSet(5)) { -- s += " Key_CertSign\n"; -- } -- if (isSet(6)) { -- s += " Crl_Sign\n"; -- } -- if (isSet(7)) { -- s += " Encipher_Only\n"; -- } -- if (isSet(8)) { -- s += " Decipher_Only\n"; -- } -- } catch (ArrayIndexOutOfBoundsException ex) {} -+ if (isSet(0)) { -+ sb.append(" DigitalSignature\n"); -+ } -+ if (isSet(1)) { -+ sb.append(" Non_repudiation\n"); -+ } -+ if (isSet(2)) { -+ sb.append(" Key_Encipherment\n"); -+ } -+ if (isSet(3)) { -+ sb.append(" Data_Encipherment\n"); -+ } -+ if (isSet(4)) { -+ sb.append(" Key_Agreement\n"); -+ } -+ if (isSet(5)) { -+ sb.append(" Key_CertSign\n"); -+ } -+ if (isSet(6)) { -+ sb.append(" Crl_Sign\n"); -+ } -+ if (isSet(7)) { -+ sb.append(" Encipher_Only\n"); -+ } -+ if (isSet(8)) { -+ sb.append(" Decipher_Only\n"); -+ } -+ sb.append("]\n"); - -- s += "]\n"; -- -- return (s); -+ return sb.toString(); - } - - /** ---- ./jdk/src/share/classes/sun/security/x509/NetscapeCertTypeExtension.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/x509/NetscapeCertTypeExtension.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -136,7 +136,8 @@ - * @param position the position in the bit string to check. - */ - private boolean isSet(int position) { -- return bitString[position]; -+ return (position < bitString.length) && -+ bitString[position]; - } - - /** -@@ -236,27 +237,34 @@ - * Returns a printable representation of the NetscapeCertType. - */ - public String toString() { -- String s = super.toString() + "NetscapeCertType [\n"; -+ StringBuilder sb = new StringBuilder(); -+ sb.append(super.toString()); -+ sb.append("NetscapeCertType [\n"); - -- try { -- if (isSet(getPosition(SSL_CLIENT))) -- s += " SSL client\n"; -- if (isSet(getPosition(SSL_SERVER))) -- s += " SSL server\n"; -- if (isSet(getPosition(S_MIME))) -- s += " S/MIME\n"; -- if (isSet(getPosition(OBJECT_SIGNING))) -- s += " Object Signing\n"; -- if (isSet(getPosition(SSL_CA))) -- s += " SSL CA\n"; -- if (isSet(getPosition(S_MIME_CA))) -- s += " S/MIME CA\n"; -- if (isSet(getPosition(OBJECT_SIGNING_CA))) -- s += " Object Signing CA" ; -- } catch (Exception e) { } -+ if (isSet(0)) { -+ sb.append(" SSL client\n"); -+ } -+ if (isSet(1)) { -+ sb.append(" SSL server\n"); -+ } -+ if (isSet(2)) { -+ sb.append(" S/MIME\n"); -+ } -+ if (isSet(3)) { -+ sb.append(" Object Signing\n"); -+ } -+ if (isSet(5)) { -+ sb.append(" SSL CA\n"); -+ } -+ if (isSet(6)) { -+ sb.append(" S/MIME CA\n"); -+ } -+ if (isSet(7)) { -+ sb.append(" Object Signing CA"); -+ } - -- s += "]\n"; -- return (s); -+ sb.append("]\n"); -+ return sb.toString(); - } - - /** ---- ./jdk/src/share/classes/sun/security/x509/ReasonFlags.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/security/x509/ReasonFlags.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -99,7 +99,8 @@ - * @param position the position in the bit string to check. - */ - private boolean isSet(int position) { -- return bitString[position]; -+ return (position < bitString.length) && -+ bitString[position]; - } - - /** -@@ -199,23 +200,38 @@ - * Returns a printable representation of the ReasonFlags. - */ - public String toString() { -- String s = "Reason Flags [\n"; -+ StringBuilder sb = new StringBuilder("Reason Flags [\n"); - -- try { -- if (isSet(0)) s += " Unused\n"; -- if (isSet(1)) s += " Key Compromise\n"; -- if (isSet(2)) s += " CA Compromise\n"; -- if (isSet(3)) s += " Affiliation_Changed\n"; -- if (isSet(4)) s += " Superseded\n"; -- if (isSet(5)) s += " Cessation Of Operation\n"; -- if (isSet(6)) s += " Certificate Hold\n"; -- if (isSet(7)) s += " Privilege Withdrawn\n"; -- if (isSet(8)) s += " AA Compromise\n"; -- } catch (ArrayIndexOutOfBoundsException ex) {} -+ if (isSet(0)) { -+ sb.append(" Unused\n"); -+ } -+ if (isSet(1)) { -+ sb.append(" Key Compromise\n"); -+ } -+ if (isSet(2)) { -+ sb.append(" CA Compromise\n"); -+ } -+ if (isSet(3)) { -+ sb.append(" Affiliation_Changed\n"); -+ } -+ if (isSet(4)) { -+ sb.append(" Superseded\n"); -+ } -+ if (isSet(5)) { -+ sb.append(" Cessation Of Operation\n"); -+ } -+ if (isSet(6)) { -+ sb.append(" Certificate Hold\n"); -+ } -+ if (isSet(7)) { -+ sb.append(" Privilege Withdrawn\n"); -+ } -+ if (isSet(8)) { -+ sb.append(" AA Compromise\n"); -+ } -+ sb.append("]\n"); - -- s += "]\n"; -- -- return (s); -+ return sb.toString(); - } - - /** ---- ./jdk/src/share/classes/sun/tools/jar/Main.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/tools/jar/Main.java Thu Feb 05 13:00:26 2015 +0100 -@@ -74,8 +74,10 @@ - * Mflag: DO NOT generate a manifest file (just ZIP) - * iflag: generate jar index - * nflag: Perform jar normalization at the end -+ * pflag: preserve/don't strip leading slash and .. component from file name -+ * - */ -- boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag; -+ boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag; - - static final String MANIFEST_DIR = "META-INF/"; - static final String VERSION = "1.0"; -@@ -187,6 +189,7 @@ - addMainClass(manifest, ename); - } - } -+ expand(null, files, false); - OutputStream out; - if (fname != null) { - out = new FileOutputStream(fname); -@@ -208,13 +211,12 @@ - tmpfile = createTemporaryFile(tmpbase, ".jar"); - out = new FileOutputStream(tmpfile); - } -- expand(null, files, false); - create(new BufferedOutputStream(out, 4096), manifest); - if (in != null) { - in.close(); - } - out.close(); -- if(nflag) { -+ if (nflag) { - JarFile jarFile = null; - File packFile = null; - JarOutputStream jos = null; -@@ -291,7 +293,7 @@ - list(fname, files); - } else { - InputStream in = new FileInputStream(FileDescriptor.in); -- try{ -+ try { - list(new BufferedInputStream(in), files); - } finally { - in.close(); -@@ -410,6 +412,9 @@ - case 'e': - ename = args[count++]; - break; -+ case 'P': -+ pflag = true; -+ break; - default: - error(formatMsg("error.illegal.option", - String.valueOf(flags.charAt(i)))); -@@ -662,7 +667,6 @@ - return updateOk; - } - -- - private void addIndex(JarIndex index, ZipOutputStream zos) - throws IOException - { -@@ -699,6 +703,47 @@ - return true; - } - -+ private static final boolean isWinDriveLetter(char c) { -+ return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); -+ } -+ -+ private String safeName(String name) { -+ if (!pflag) { -+ int len = name.length(); -+ int i = name.lastIndexOf("../"); -+ if (i == -1) { -+ i = 0; -+ } else { -+ i += 3; // strip any dot-dot components -+ } -+ if (File.separatorChar == '\\') { -+ // the spec requests no drive letter. skip if -+ // the entry name has one. -+ while (i < len) { -+ int off = i; -+ if (i + 1 < len && -+ name.charAt(i + 1) == ':' && -+ isWinDriveLetter(name.charAt(i))) { -+ i += 2; -+ } -+ while (i < len && name.charAt(i) == '/') { -+ i++; -+ } -+ if (i == off) { -+ break; -+ } -+ } -+ } else { -+ while (i < len && name.charAt(i) == '/') { -+ i++; -+ } -+ } -+ if (i != 0) { -+ name = name.substring(i); -+ } -+ } -+ return name; -+ } - - private String entryName(String name) { - name = name.replace(File.separatorChar, '/'); -@@ -710,10 +755,10 @@ - } - } - name = name.substring(matchPath.length()); -- -- if (name.startsWith("/")) { -- name = name.substring(1); -- } else if (name.startsWith("./")) { -+ name = safeName(name); -+ // the old implementaton doesn't remove -+ // "./" if it was led by "/" (?) -+ if (name.startsWith("./")) { - name = name.substring(2); - } - return name; -@@ -913,8 +958,11 @@ - for (ZipEntry ze : zes) { - long lastModified = ze.getTime(); - if (lastModified != -1) { -- File f = new File(ze.getName().replace('/', File.separatorChar)); -- f.setLastModified(lastModified); -+ String name = safeName(ze.getName().replace(File.separatorChar, '/')); -+ if (name.length() != 0) { -+ File f = new File(name.replace('/', File.separatorChar)); -+ f.setLastModified(lastModified); -+ } - } - } - } -@@ -958,7 +1006,6 @@ - Enumeration<? extends ZipEntry> zes = zf.entries(); - while (zes.hasMoreElements()) { - ZipEntry e = zes.nextElement(); -- InputStream is; - if (files == null) { - dirs.add(extractFile(zf.getInputStream(e), e)); - } else { -@@ -982,8 +1029,16 @@ - */ - ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException { - ZipEntry rc = null; -- String name = e.getName(); -- File f = new File(e.getName().replace('/', File.separatorChar)); -+ // The spec requres all slashes MUST be forward '/', it is possible -+ // an offending zip/jar entry may uses the backwards slash in its -+ // name. It might cause problem on Windows platform as it skips -+ // our "safe" check for leading slahs and dot-dot. So replace them -+ // with '/'. -+ String name = safeName(e.getName().replace(File.separatorChar, '/')); -+ if (name.length() == 0) { -+ return rc; // leading '/' or 'dot-dot' only path -+ } -+ File f = new File(name.replace('/', File.separatorChar)); - if (e.isDirectory()) { - if (f.exists()) { - if (!f.isDirectory()) { ---- ./jdk/src/share/classes/sun/tools/jar/resources/jar.properties Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/tools/jar/resources/jar.properties Thu Feb 05 13:00:26 2015 +0100 -@@ -68,7 +68,7 @@ - (in = {0}) (out= {1}) - - usage=\ --Usage: jar {ctxui}[vfmn0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\ -+Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\ - Options:\n\ - \ \ -c create new archive\n\ - \ \ -t list table of contents for archive\n\ -@@ -81,6 +81,7 @@ - \ \ -e specify application entry point for stand-alone application \n\ - \ \ bundled into an executable jar file\n\ - \ \ -0 store only; use no ZIP compression\n\ -+\ \ -P preserve leading '/' (absolute path) and ".." (parent directory) components from file names\n\ - \ \ -M do not create a manifest file for the entries\n\ - \ \ -i generate index information for the specified jar files\n\ - \ \ -C change to the specified directory and include the following file\n\ ---- ./jdk/src/share/classes/sun/util/resources/TimeZoneNames.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/TimeZoneNames.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -408,7 +408,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Venezuela Time", "VET", - "Venezuela Summer Time", "VEST", - "Venezuela Time", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Venezuelanische Zeit", "VET", - "Venezuelanische Sommerzeit", "VEST", - "Venezuelanische Zeit", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Hora de Venezuela", "VET", - "Hora de verano de Venezuela", "VEST", - "Hora de Venezuela", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Heure du Venezuela", "VET", - "Heure d'\u00e9t\u00e9 du Venezuela", "VEST", - "Heure du Venezuela", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Ora del Venezuela", "VET", - "Ora estiva del Venezuela", "VEST", - "Ora del Venezuela", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\u30d9\u30cd\u30ba\u30a8\u30e9\u6642\u9593", "VET", - "\u30d9\u30cd\u30ba\u30a8\u30e9\u590f\u6642\u9593", "VEST", - "\u30D9\u30CD\u30BA\u30A8\u30E9\u6642\u9593", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\ubca0\ub124\uc218\uc5d8\ub77c \uc2dc\uac04", "VET", - "\ubca0\ub124\uc218\uc5d8\ub77c \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "VEST", - "\uBCA0\uB124\uC218\uC5D8\uB77C \uD45C\uC900\uC2DC", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Fuso hor\u00e1rio da Venezuela", "VET", - "Fuso hor\u00e1rio de ver\u00e3o da Venezuela", "VEST", - "Hor\u00E1rio da Venezuela", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"Venezuela, normaltid", "VET", - "Venezuela, sommartid", "VEST", - "Venezuelansk tid", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\u59d4\u5185\u745e\u62c9\u65f6\u95f4", "VET", - "\u59d4\u5185\u745e\u62c9\u590f\u4ee4\u65f6", "VEST", - "\u59D4\u5185\u745E\u62C9\u65F6\u95F4", "VET"}}, ---- ./jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -409,7 +409,7 @@ - {"America/Buenos_Aires", AGT}, - {"America/Cambridge_Bay", MST}, - {"America/Campo_Grande", AMT}, -- {"America/Cancun", CST}, -+ {"America/Cancun", EST}, - {"America/Caracas", new String[] {"\u59d4\u5167\u745e\u62c9\u6642\u9593", "VET", - "\u59d4\u5167\u745e\u62c9\u590f\u4ee4\u6642\u9593", "VEST", - "\u59D4\u5167\u745E\u62C9\u6642\u9593", "VET"}}, ---- ./jdk/src/share/native/sun/awt/libpng/CHANGES Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/CHANGES Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -23,8 +23,6 @@ - * questions. - */ - --#if 0 --libpng_changes(){ /* - CHANGES - changes for libpng - - Version 0.2 -@@ -205,7 +203,7 @@ - Fixed serious bug with < 8bpp images introduced in 0.95 - Fixed 256-color transparency bug (Greg Roelofs) - Fixed up documentation (Greg Roelofs, Laszlo Nyul) -- Fixed "error" in pngconf.h for Linux setjmp() behaviour -+ Fixed "error" in pngconf.h for Linux setjmp() behavior - Fixed DOS medium model support (Tim Wegner) - Fixed png_check_keyword() for case with error in static string text - Added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul) -@@ -222,18 +220,20 @@ - Added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P) - Minor corrections in libpng.txt - Added simple sRGB support (Glenn R-P) -- Easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; -+ Easier conditional compiling, e.g., -+ define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; - all configurable options can be selected from command-line instead - of having to edit pngconf.h (Glenn R-P) - Fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P) - Added more conditions for png_do_background, to avoid changing - black pixels to background when a background is supplied and - no pixels are transparent -- Repaired PNG_NO_STDIO behaviour -- Tested NODIV support and made it default behaviour (Greg Roelofs) -+ Repaired PNG_NO_STDIO behavior -+ Tested NODIV support and made it default behavior (Greg Roelofs) - Added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler) - Regularized version numbering scheme and bumped shared-library major -- version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs) -+ version number to 2 to avoid problems with libpng 0.89 apps -+ (Greg Roelofs) - - Version 0.98 [January, 1998] - Cleaned up some typos in libpng.txt and in code documentation -@@ -1803,7 +1803,7 @@ - Removed AC_FUNC_MALLOC from configure.ac - Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h - Change "logical" to "bitwise" throughout documentation. -- Detect and fix attempt to write wrong iCCP profile length. -+ Detect and fix attempt to write wrong iCCP profile length (CVE-2006-7244) - - Version 1.0.21, 1.2.13 [November 14, 2006] - Fix potential buffer overflow in sPLT chunk handler. -@@ -2126,7 +2126,7 @@ - png_decompress_chunk(), and remove "chunkdata" from parameter list. - Put a call to png_check_chunk_name() in png_read_chunk_header(). - Revised png_check_chunk_name() to reject a name with a lowercase 3rd byte. -- Removed two calls to png_check_chunk_name() occurring later in the process. -+ Removed two calls to png_check_chunk_name() occuring later in the process. - Define PNG_NO_ERROR_NUMBERS by default in pngconf.h - - Version 1.4.0beta25 [July 30, 2008] -@@ -2386,7 +2386,7 @@ - - Version 1.4.0beta73 [August 1, 2009] - Reject attempt to write iCCP chunk with negative embedded profile length -- (JD Chen) -+ (JD Chen) (CVE-2009-5063). - - Version 1.4.0beta74 [August 8, 2009] - Changed png_ptr and info_ptr member "trans" to "trans_alpha". -@@ -3174,8 +3174,8 @@ - in version 1.5.0beta36 but is not noted in the CHANGES. Similarly, - it was changed from png_charpp to png_const_bytepp in png_set_iCCP(). - Ensure that png_rgb_to_gray ignores palette mapped images, if libpng -- internally happens to call it with one. -- Fixed a failure to handle palette mapped images correctly. -+ internally happens to call it with one, and fixed a failure to handle -+ palette mapped images correctly. This fixes CVE-2690. - - Version 1.5.1beta02 [January 14, 2011] - Fixed a bug in handling of interlaced images (bero at arklinux.org). -@@ -3314,8 +3314,8 @@ - - Version 1.5.3beta01 [April 1, 2011] - Re-initialize the zlib compressor before compressing non-IDAT chunks. -- Added API functions to set parameters for zlib compression of non-IDAT -- chunks. -+ Added API functions (png_set_text_compression_level() and four others) to -+ set parameters for zlib compression of non-IDAT chunks. - - Version 1.5.3beta02 [April 3, 2011] - Updated scripts/symbols.def with new API functions. -@@ -3372,7 +3372,7 @@ - dependency of the tIME-supporting RFC1132 code on stdio is removed and - PNG_NO_WARNINGS does actually work now. - Pass "" instead of '\0' to png_default_error() in png_err(). This mistake -- was introduced in libpng-1.2.20beta01. -+ was introduced in libpng-1.2.20beta01. This fixes CVE-2011-2691. - Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte - optimization configureable. - IDAT compression failed if preceded by a compressed text chunk (bug -@@ -3403,7 +3403,8 @@ - Documented png_set_alpha_mode(), other changes in libpng.3/libpng-manual.txt - The cHRM chunk now sets the defaults for png_set_rgb_to_gray() (when negative - parameters are supplied by the caller), while in the absence of cHRM -- sRGB/Rec 709 values are still used. -+ sRGB/Rec 709 values are still used. This introduced a divide-by-zero -+ bug in png_handle_cHRM(). - The bKGD chunk no longer overwrites the background value set by - png_set_background(), allowing the latter to be used before the file - header is read. It never performed any useful function to override -@@ -3443,7 +3444,8 @@ - Frank Busse, CVE-2011-2501, related to CVE-2004-0421). - - Version 1.5.3beta11 [June 11, 2011] -- Fixed png_handle_sCAL which is broken in 1.5; added sCAL to pngtest.png -+ Fixed png_handle_sCAL which is broken in 1.5. This fixes CVE 2011-2692. -+ Added sCAL to pngtest.png - Revised documentation about png_set_user_limits() to say that it also affects - png writing. - Revised handling of png_set_user_limits() so that it can increase the -@@ -3468,7 +3470,7 @@ - Removed string/memory macros that are no longer used and are not - necessarily fully supportable, particularly png_strncpy and png_snprintf. - Added log option to pngvalid.c and attempted to improve gamma messages. -- -+ - Version 1.5.3 [omitted] - People found the presence of a beta release following an rc release - to be confusing; therefore we bump the version to libpng-1.5.4beta01 -@@ -3532,6 +3534,1620 @@ - Define PNG_ALLOCATED to "restrict" only if MSC_VER >= 1400. - - Version 1.5.4 [July 7, 2011] -+ No changes. -+ -+Version 1.5.5beta01 [July 13, 2011] -+ Fixed some typos and made other minor changes in the manual. -+ Updated contrib/pngminus/makefile.std (Samuli Souminen) -+ -+Version 1.5.5beta02 [July 14, 2011] -+ Revised Makefile.am and Makefile.in to look in the right directory for -+ pnglibconf.h.prebuilt -+ -+Version 1.5.5beta03 [July 27, 2011] -+ Enabled compilation with g++ compiler. This compiler does not recognize -+ the file extension, so it always compiles with C++ rules. Made minor -+ changes to pngrutil.c to cast results where C++ expects it but C does not. -+ Minor editing of libpng.3 and libpng-manual.txt. -+ -+Version 1.5.5beta04 [July 29, 2011] -+ Revised CMakeLists.txt (Clifford Yapp) -+ Updated commentary about the png_rgb_to_gray() default coefficients -+ in the manual and in pngrtran.c -+ -+Version 1.5.5beta05 [August 17, 2011] -+ Prevent unexpected API exports from non-libpng DLLs on Windows. The "_DLL" -+ is removed from the test of whether a DLL is being built (this erroneously -+ caused the libpng APIs to be marked as DLL exports in static builds under -+ Microsoft Visual Studio). Almost all of the libpng building configuration -+ is moved from pngconf.h to pngpriv.h, but PNG_DLL_EXPORT remains in -+ pngconf.h, though, so that it is colocated with the import definition (it -+ is no longer used anywhere in the installed headers). The VStudio project -+ definitions have been cleaned up: "_USRDLL" has been removed from the -+ static library builds (this was incorrect), and PNG_USE_DLL has been added -+ to pngvalid to test the functionality (pngtest does not supply it, -+ deliberately). The spurious "_EXPORTS" has been removed from the -+ libpng build (all these errors were a result of copy/paste between project -+ configurations.) -+ Added new types and internal functions for CIE RGB end point handling to -+ pngpriv.h (functions yet to be implemented). -+ -+Version 1.5.5beta06 [August 26, 2011] -+ Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt -+ (Clifford Yap) -+ Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler): -+ The rgb_to_gray code had errors when combined with gamma correction. -+ Some pixels were treated as true grey when they weren't and such pixels -+ and true grey ones were not gamma corrected (the original value of the -+ red component was used instead). APIs to get and set cHRM using color -+ space end points have been added and the rgb_to_gray code that defaults -+ based on cHRM, and the divide-by-zero bug in png_handle_cHRM (CERT -+ VU#477046, CVE-2011-3328, introduced in 1.5.4) have been corrected. -+ A considerable number of tests has been added to pngvalid for the -+ rgb_to_gray transform. -+ Arithmetic errors in rgb_to_gray whereby the calculated gray value was -+ truncated to the bit depth rather than rounded have been fixed except in -+ the 8-bit non-gamma-corrected case (where consistency seems more important -+ than correctness.) The code still has considerable inaccuracies in the -+ 8-bit case because 8-bit linear arithmetic is used. -+ -+Version 1.5.5beta07 [September 7, 2011] -+ Added "$(ARCH)" option to makefile.darwin -+ Added SunOS support to configure.ac and Makefile.am -+ Changed png_chunk_benign_error() to png_warning() in png.c, in -+ png_XYZ_from_xy_checked(). -+ -+Version 1.5.5beta08 [September 10, 2011] -+ Fixed 64-bit compilation errors (gcc). The errors fixed relate -+ to conditions where types that are 32 bits in the GCC 32-bit -+ world (uLong and png_size_t) become 64 bits in the 64-bit -+ world. This produces potential truncation errors which the -+ compiler correctly flags. -+ Relocated new HAVE_SOLARIS_LD definition in configure.ac -+ Constant changes for 64-bit compatibility (removal of L suffixes). The -+ 16-bit cases still use "L" as we don't have a 16-bit test system. -+ -+Version 1.5.5rc01 [September 15, 2011] -+ Removed "L" suffixes in pngpriv.h -+ -+Version 1.5.5 [September 22, 2011] -+ No changes. -+ -+Version 1.5.6beta01 [September 22, 2011] -+ Fixed some 64-bit type conversion warnings in pngrtran.c -+ Moved row_info from png_struct to a local variable. -+ The various interlace mask arrays have been made into arrays of -+ bytes and made PNG_CONST and static (previously some arrays were -+ marked PNG_CONST and some weren't). -+ Additional checks have been added to the transform code to validate the -+ pixel depths after the transforms on both read and write. -+ Removed some redundant code from pngwrite.c, in png_destroy_write_struct(). -+ Changed chunk reading/writing code to use png_uint_32 instead of png_byte[4]. -+ This removes the need to allocate temporary strings for chunk names on -+ the stack in the read/write code. Unknown chunk handling still uses the -+ string form because this is exposed in the API. -+ -+Version 1.5.6beta02 [September 26, 2011] -+ Added a note in the manual the png_read_update_info() must be called only -+ once with a particular info_ptr. -+ Fixed a typo in the definition of the new PNG_STRING_FROM_CHUNK(s,c) macro. -+ -+Version 1.5.6beta03 [September 28, 2011] -+ Revised test-pngtest.sh to report FAIL when pngtest fails. -+ Added "--strict" option to pngtest, to report FAIL when the failure is -+ only because the resulting valid files are different. -+ Revised CMakeLists.txt to work with mingw and removed some material from -+ CMakeLists.txt that is no longer useful in libpng-1.5. -+ -+Version 1.5.6beta04 [October 5, 2011] -+ Fixed typo in Makefile.in and Makefile.am ("-M Wl" should be "-M -Wl")." -+ -+Version 1.5.6beta05 [October 12, 2011] -+ Speed up png_combine_row() for interlaced images. This reduces the generality -+ of the code, allowing it to be optimized for Adam7 interlace. The masks -+ passed to png_combine_row() are now generated internally, avoiding -+ some code duplication and localizing the interlace handling somewhat. -+ Align png_struct::row_buf - previously it was always unaligned, caused by -+ a bug in the code that attempted to align it; the code needs to subtract -+ one from the pointer to take account of the filter byte prepended to -+ each row. -+ Optimized png_combine_row() when rows are aligned. This gains a small -+ percentage for 16-bit and 32-bit pixels in the typical case where the -+ output row buffers are appropriately aligned. The optimization was not -+ previously possible because the png_struct buffer was always misaligned. -+ Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01. -+ -+Version 1.5.6beta06 [October 17, 2011] -+ Removed two redundant tests for unitialized row. -+ Fixed a relatively harmless memory overwrite in compressed text writing -+ with a 1 byte zlib buffer. -+ Add ability to call png_read_update_info multiple times to pngvalid.c. -+ Fixes for multiple calls to png_read_update_info. These fixes attend to -+ most of the errors revealed in pngvalid, however doing the gamma work -+ twice results in inaccuracies that can't be easily fixed. There is now -+ a warning in the code if this is going to happen. -+ Turned on multiple png_read_update_info in pngvalid transform tests. -+ Prevent libpng from overwriting unused bits at the end of the image when -+ it is not byte aligned, while reading. Prior to libpng-1.5.6 libpng would -+ overwrite the partial byte at the end of each row if the row width was not -+ an exact multiple of 8 bits and the image is not interlaced. -+ -+Version 1.5.6beta07 [October 21, 2011] -+ Made png_ptr->prev_row an aligned pointer into png_ptr->big_prev_row -+ (Mans Rullgard). -+ -+Version 1.5.6rc01 [October 26, 2011] -+ Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM" -+ -+Version 1.5.6rc02 [October 27, 2011] -+ Added LSR() macro to defend against buggy compilers that evaluate non-taken -+ code branches and complain about out-of-range shifts. -+ -+Version 1.5.6rc03 [October 28, 2011] -+ Renamed the LSR() macro to PNG_LSR() and added PNG_LSL() macro. -+ Fixed compiler warnings with Intel and MSYS compilers. The logical shift -+ fix for Microsoft Visual C is required by other compilers, so this -+ enables that fix for all compilers when using compile-time constants. -+ Under MSYS 'byte' is a name declared in a system header file, so we -+ changed the name of a local variable to avoid the warnings that result. -+ Added #define PNG_ALIGN_TYPE PNG_ALIGN_NONE to contrib/pngminim/*/pngusr.h -+ -+Version 1.5.6 [November 3, 2011] -+ No changes. -+ -+Version 1.5.7beta01 [November 4, 2011] -+ Added support for ARM processor, when decoding all PNG up-filtered rows -+ and any other-filtered rows with 3 or 4 bytes per pixel (Mans Rullgard). -+ Fixed bug in pngvalid on early allocation failure; fixed type cast in -+ pngmem.c; pngvalid would attempt to call png_error() if the allocation -+ of a png_struct or png_info failed. This would probably have led to a -+ crash. The pngmem.c implementation of png_malloc() included a cast -+ to png_size_t which would fail on large allocations on 16-bit systems. -+ Fix for the preprocessor of the Intel C compiler. The preprocessor -+ splits adjacent @ signs with a space; this changes the concatentation -+ token from @-@-@ to PNG_JOIN; that should work with all compiler -+ preprocessors. -+ Paeth filter speed improvements from work by Siarhei Siamashka. This -+ changes the 'Paeth' reconstruction function to improve the GCC code -+ generation on x86. The changes are only part of the suggested ones; -+ just the changes that definitely improve speed and remain simple. -+ The changes also slightly increase the clarity of the code. -+ -+Version 1.5.7beta02 [November 11, 2011] -+ Check compression_type parameter in png_get_iCCP and remove spurious -+ casts. The compression_type parameter is always assigned to, so must -+ be non-NULL. The cast of the profile length potentially truncated the -+ value unnecessarily on a 16-bit int system, so the cast of the (byte) -+ compression type to (int) is specified by ANSI-C anyway. -+ Fixed FP division by zero in pngvalid.c; the 'test_pixel' code left -+ the sBIT fields in the test pixel as 0, which resulted in a floating -+ point division by zero which was irrelevant but causes systems where -+ FP exceptions cause a crash. Added code to pngvalid to turn on FP -+ exceptions if the appropriate glibc support is there to ensure this is -+ tested in the future. -+ Updated scripts/pnglibconf.mak and scripts/makefile.std to handle the -+ new PNG_JOIN macro. -+ Added versioning to pnglibconf.h comments. -+ Simplified read/write API initial version; basic read/write tested on -+ a variety of images, limited documentation (in the header file.) -+ Installed more accurate linear to sRGB conversion tables. The slightly -+ modified tables reduce the number of 16-bit values that -+ convert to an off-by-one 8-bit value. The "makesRGB.c" code that was used -+ to generate the tables is now in a contrib/sRGBtables sub-directory. -+ -+Version 1.5.7beta03 [November 17, 2011] -+ Removed PNG_CONST from the sRGB table declarations in pngpriv.h and png.c -+ Added run-time detection of NEON support. -+ Added contrib/libtests; includes simplified API test and timing test and -+ a color conversion utility for rapid checking of failed 'pngstest' results. -+ Multiple transform bug fixes plus a work-round for double gamma correction. -+ libpng does not support more than one transform that requires linear data -+ at once - if this is tried typically the results is double gamma -+ correction. Since the simplified APIs can need rgb to gray combined with -+ a compose operation it is necessary to do one of these outside the main -+ libpng transform code. This check-in also contains fixes to various bugs -+ in the simplified APIs themselves and to some bugs in compose and rgb to -+ gray (on palette) itself. -+ Fixes for C++ compilation using g++ When libpng source is compiled -+ using g++. The compiler imposes C++ rules on the C source; thus it -+ is desireable to make the source work with either C or C++ rules -+ without throwing away useful error information. This change adds -+ png_voidcast to allow C semantic (void*) cases or the corresponding -+ C++ static_cast operation, as appropriate. -+ Added --noexecstack to assembler file compilation. GCC does not set -+ this on assembler compilation, even though it does on C compilation. -+ This creates security issues if assembler code is enabled; the -+ work-around is to set it by default in the flags for $(CCAS) -+ Work around compilers that don't support declaration of const data. Some -+ compilers fault 'extern const' data declarations (because the data is -+ not initialized); this turns on const-ness only for compilers where -+ this is known to work. -+ -+Version 1.5.7beta04 [November 17, 2011] -+ Since the gcc driver does not recognize the --noexecstack flag, we must -+ use the -Wa prefix to have it passed through to the assembler. -+ Also removed a duplicate setting of this flag. -+ Added files that were omitted from the libpng-1.5.7beta03 zip distribution. -+ -+Version 1.5.7beta05 [November 25, 2011] -+ Removed "zTXt" from warning in generic chunk decompression function. -+ Validate time settings passed to pngset() and png_convert_to_rfc1123() -+ (Frank Busse). -+ Added MINGW support to CMakeLists.txt -+ Reject invalid compression flag or method when reading the iTXt chunk. -+ Backed out 'simplified' API changes. The API seems too complex and there -+ is a lack of consensus or enthusiasm for the proposals. The API also -+ reveals significant bugs inside libpng (double gamma correction and the -+ known bug of being unable to retrieve a corrected palette). It seems -+ better to wait until the bugs, at least, are corrected. -+ Moved pngvalid.c into contrib/libtests -+ Rebuilt Makefile.in, configure, etc., with autoconf-2.68 -+ -+Version 1.5.7rc01 [December 1, 2011] -+ Replaced an "#if" with "#ifdef" in pngrtran.c -+ Revised #if PNG_DO_BC block in png.c (use #ifdef and add #else) -+ -+Version 1.5.7rc02 [December 5, 2011] -+ Revised project files and contrib/pngvalid/pngvalid.c to account for -+ the relocation of pngvalid into contrib/libtests. -+ Revised pngconf.h to use " __declspec(restrict)" only when MSC_VER >= 1400, -+ as in libpng-1.5.4. -+ Put CRLF line endings in the owatcom project files. -+ -+Version 1.5.7rc03 [December 7, 2011] -+ Updated CMakeLists.txt to account for the relocation of pngvalid.c -+ -+Version 1.5.7 [December 15, 2011] -+ Minor fixes to pngvalid.c for gcc 4.6.2 compatibility to remove warnings -+ reported by earlier versions. -+ Fixed minor memset/sizeof errors in pngvalid.c. -+ -+Version 1.6.0beta01 [December 15, 2011] -+ Removed machine-generated configure files from the GIT repository (they will -+ continue to appear in the tarball distributions and in the libpng15 and -+ earlier GIT branches). -+ Restored the new 'simplified' API, which was started in libpng-1.5.7beta02 -+ but later deleted from libpng-1.5.7beta05. -+ Added example programs for the new 'simplified' API. -+ Added ANSI-C (C90) headers and require them, and take advantage of the -+ change. Also fixed some of the projects/* and contrib/* files that needed -+ updates for libpng16 and the move of pngvalid.c. -+ With this change the required ANSI-C header files are assumed to exist: the -+ implementation must provide float.h, limits.h, stdarg.h and stddef.h and -+ libpng relies on limits.h and stddef.h existing and behaving as defined -+ (the other two required headers aren't used). Non-ANSI systems that don't -+ have stddef.h or limits.h will have to provide an appropriate fake -+ containing the relevant types and #defines. -+ The use of FAR/far has been eliminated and the definition of png_alloc_size_t -+ is now controlled by a flag so that 'small size_t' systems can select it -+ if necessary. Libpng 1.6 may not currently work on such systems -- it -+ seems likely that it will ask 'malloc' for more than 65535 bytes with any -+ image that has a sufficiently large row size (rather than simply failing -+ to read such images). -+ New tools directory containing tools used to generate libpng code. -+ Fixed race conditions in parallel make builds. With higher degrees of -+ parallelism during 'make' the use of the same temporary file names such -+ as 'dfn*' can result in a race where a temporary file from one arm of the -+ build is deleted or overwritten in another arm. This changes the -+ temporary files for suffix rules to always use $* and ensures that the -+ non-suffix rules use unique file names. -+ -+Version 1.6.0beta02 [December 21, 2011] -+ Correct configure builds where build and source directories are separate. -+ The include path of 'config.h' was erroneously made relative in pngvalid.c -+ in libpng 1.5.7. -+ -+Version 1.6.0beta03 [December 22, 2011] -+ Start-up code size improvements, error handler flexibility. These changes -+ alter how the tricky allocation of the initial png_struct and png_info -+ structures are handled. png_info is now handled in pretty much the same -+ way as everything else, except that the allocations handle NULL return -+ silently. png_struct is changed in a similar way on allocation and on -+ deallocation a 'safety' error handler is put in place (which should never -+ be required). The error handler itself is changed to permit mismatches -+ in the application and libpng error buffer size; however, this means a -+ silent change to the API to return the jmp_buf if the size doesn't match -+ the size from the libpng compilation; libpng now allocates the memory and -+ this may fail. Overall these changes result in slight code size -+ reductions; however, this is a reduction in code that is always executed -+ so is particularly valuable. Overall on a 64-bit system the libpng DLL -+ decreases in code size by 1733 bytes. pngerror.o increases in size by -+ about 465 bytes because of the new functionality. -+ Added png_convert_to_rfc1123_buffer() and deprecated png_convert_to_rfc1123() -+ to avoid including a spurious buffer in the png_struct. -+ -+Version 1.6.0beta04 [December 30, 2011] -+ Regenerated configure scripts with automake-1.11.2 -+ Eliminated png_info_destroy(). It is now used only in png.c and only calls -+ one other internal function and memset(). -+ Enabled png_get_sCAL_fixed() if floating point APIs are enabled. Previously -+ it was disabled whenever internal fixed point arithmetic was selected, -+ which meant it didn't exist even on systems where FP was available but not -+ preferred. -+ Added pngvalid.c compile time checks for const APIs. -+ Implemented 'restrict' for png_info and png_struct. Because of the way -+ libpng works both png_info and png_struct are always accessed via a -+ single pointer. This means adding C99 'restrict' to the pointer gives -+ the compiler some opportunity to optimize the code. This change allows -+ that. -+ Moved AC_MSG_CHECKING([if libraries can be versioned]) later to the proper -+ location in configure.ac (Gilles Espinasse). -+ Changed png_memcpy to C assignment where appropriate. Changed all those -+ uses of png_memcpy that were doing a simple assignment to assignments -+ (all those cases where the thing being copied is a non-array C L-value). -+ Added some error checking to png_set_*() routines. -+ Removed the reference to the non-exported function png_memcpy() from -+ example.c. -+ Fixed the Visual C 64-bit build - it requires jmp_buf to be aligned, but -+ it had become misaligned. -+ Revised contrib/pngminus/pnm2png.c to avoid warnings when png_uint_32 -+ and unsigned long are of different sizes. -+ -+Version 1.6.0beta05 [January 15, 2012] -+ Updated manual with description of the simplified API (copied from png.h) -+ Fix bug in pngerror.c: some long warnings were being improperly truncated -+ (CVE-2011-3464, bug introduced in libpng-1.5.3beta05). -+ -+Version 1.6.0beta06 [January 24, 2012] -+ Added palette support to the simplified APIs. This commit -+ changes some of the macro definitions in png.h, app code -+ may need corresponding changes. -+ Increased the formatted warning buffer to 192 bytes. -+ Added color-map support to simplified API. This is an initial version for -+ review; the documentation has not yet been updated. -+ Fixed Min/GW uninstall to remove libpng.dll.a -+ -+Version 1.6.0beta07 [January 28, 2012] -+ Eliminated Intel icc/icl compiler warnings. The Intel (GCC derived) -+ compiler issues slightly different warnings from those issued by the -+ current vesions of GCC. This eliminates those warnings by -+ adding/removing casts and small code rewrites. -+ Updated configure.ac from autoupdate: added --enable-werror option. -+ Also some layout regularization and removal of introduced tab characters -+ (replaced with 3-character indentation). Obsolete macros identified by -+ autoupdate have been removed; the replacements are all in 2.59 so -+ the pre-req hasn't been changed. --enable-werror checks for support -+ for -Werror (or the given argument) in the compiler. This mimics the -+ gcc configure option by allowing -Werror to be turned on safely; without -+ the option the tests written in configure itself fail compilation because -+ they cause compiler warnings. -+ Rewrote autogen.sh to run autoreconf instead of running tools one-by-one. -+ Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt and -+ set CMAKE_LIBRARY_OUTPUT_DIRECTORY to "lib" on all platforms (C. Yapp). -+ Freeze libtool files in the 'scripts' directory. This version of autogen.sh -+ attempts to dissuade people from running it when it is not, or should not, -+ be necessary. In fact, autogen.sh does not work when run in a libpng -+ directory extracted from a tar distribution anymore. You must run it in -+ a GIT clone instead. -+ Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale), -+ and renamed three whose names were inconsistent with those in -+ pngsuite/README.txt. -+ -+Version 1.6.0beta08 [February 1, 2012] -+ Fixed Image::colormap misalignment in pngstest.c -+ Check libtool/libtoolize version number (2.4.2) in configure.ac -+ Divide test-pngstest.sh into separate pngstest runs for basic and -+ transparent images. -+ Moved automake options to AM_INIT_AUTOMAKE in configure.ac -+ Added color-tests, silent-rules (Not yet implemented in Makefile.am) and -+ version checking to configure.ac -+ Improved pngstest speed by not doing redundant tests and add const to -+ the background parameter of png_image_finish_read. The --background -+ option is now done automagically only when required, so that commandline -+ option no longer exists. -+ Cleaned up pngpriv.h to consistently declare all functions and data. -+ Also eliminated PNG_CONST_DATA, which is apparently not needed but we -+ can't be sure until it is gone. -+ Added symbol prefixing that allows all the libpng external symbols -+ to be prefixed (suggested by Reuben Hawkins). -+ Updated "ftbb*.png" list in the owatcom and vstudio projects. -+ Fixed 'prefix' builds on clean systems. The generation of pngprefix.h -+ should not require itself. -+ Updated INSTALL to explain that autogen.sh must be run in a GIT clone, -+ not in a libpng directory extracted from a tar distribution. -+ -+Version 1.6.0beta09 [February 1, 2012] -+ Reverted the prebuilt configure files to libpng-1.6.0beta05 condition. -+ -+Version 1.6.0beta10 [February 3, 2012] -+ Added Z_SOLO for zlib-1.2.6+ and correct pngstest tests -+ Updated list of test images in CMakeLists.txt -+ Updated the prebuilt configure files to current condition. -+ Revised INSTALL information about autogen.sh; it works in tar distributions. -+ -+Version 1.6.0beta11 [February 16, 2012] -+ Fix character count in pngstest command in projects/owatcom/pngstest.tgt -+ Revised test-pngstest.sh to report PASS/FAIL for each image. -+ Updated documentation about the simplified API. -+ Corrected estimate of error in libpng png_set_rgb_to_gray API. The API is -+ extremely inaccurate for sRGB conversions because it uses an 8-bit -+ intermediate linear value and it does not use the sRGB transform, so it -+ suffers from the known instability in gamma transforms for values close -+ to 0 (see Poynton). The net result is that the calculation has a maximum -+ error of 14.99/255; 0.5/255^(1/2.2). pngstest now uses 15 for the -+ permitted 8-bit error. This may still not be enough because of arithmetic -+ error. -+ Removed some unused arrays (with #ifdef) from png_read_push_finish_row(). -+ Fixed a memory overwrite bug in simplified read of RGB PNG with -+ non-linear gamma Also bugs in the error checking in pngread.c and changed -+ quite a lot of the checks in pngstest.c to be correct; either correctly -+ written or not over-optimistic. The pngstest changes are insufficient to -+ allow all possible RGB transforms to be passed; pngstest cmppixel needs -+ to be rewritten to make it clearer which errors it allows and then changed -+ to permit known inaccuracies. -+ Removed tests for no-longer-used *_EMPTY_PLTE_SUPPORTED from pngstruct.h -+ Fixed fixed/float API export conditionals. 1) If FIXED_POINT or -+ FLOATING_POINT options were switched off, png.h ended up with lone ';' -+ characters. This is not valid ANSI-C outside a function. The ';' -+ characters have been moved inside the definition of PNG_FP_EXPORT and -+ PNG_FIXED_EXPORT. 2) If either option was switched off, the declaration -+ of the corresponding functions were completely omitted, even though some -+ of them are still used internally. The result is still valid, but -+ produces warnings from gcc with some warning options (including -Wall). The -+ fix is to cause png.h to declare the functions with PNG_INTERNAL_FUNCTION -+ when png.h is included from pngpriv.h. -+ Check for invalid palette index while reading paletted PNG. When one is -+ found, issue a warning and increase png_ptr->num_palette accordingly. -+ Apps are responsible for checking to see if that happened. -+ -+Version 1.6.0beta12 [February 18, 2012] -+ Do not increase num_palette on invalid_index. -+ Relocated check for invalid palette index to pngrtran.c, after unpacking -+ the sub-8-bit pixels. -+ Fixed CVE-2011-3026 buffer overrun bug. This bug was introduced when -+ iCCP chunk support was added at libpng-1.0.6. Deal more correctly with the -+ test on iCCP chunk length. Also removed spurious casts that may hide -+ problems on 16-bit systems. -+ -+Version 1.6.0beta13 [February 24, 2012] -+ Eliminated redundant png_push_read_tEXt|zTXt|iTXt|unknown code from -+ pngpread.c and use the sequential png_handle_tEXt, etc., in pngrutil.c; -+ now that png_ptr->buffer is inaccessible to applications, the special -+ handling is no longer useful. -+ Added PNG_SAFE_LIMITS feature to pnglibconf.dfa, pngpriv.h, and new -+ pngusr.dfa to reset the user limits to safe ones if PNG_SAFE_LIMITS is -+ defined. To enable, use "CPPFLAGS=-DPNG_SAFE_LIMITS_SUPPORTED=1" on the -+ configure command or put #define PNG_SAFE_LIMITS_SUPPORTED in -+ pnglibconf.h.prebuilt and pnglibconf.h. -+ -+Version 1.6.0beta14 [February 27, 2012] -+ Added information about the new limits in the manual. -+ Updated Makefile.in -+ -+Version 1.6.0beta15 [March 2, 2012] -+ Removed unused "current_text" members of png_struct and the png_free() -+ of png_ptr->current_text from pngread.c -+ Rewrote pngstest.c for substantial speed improvement. -+ Fixed transparent pixel and 16-bit rgb tests in pngstest and removed a -+ spurious check in pngwrite.c -+ Added PNG_IMAGE_FLAG_FAST for the benefit of applications that store -+ intermediate files, or intermediate in-memory data, while processing -+ image data with the simplified API. The option makes the files larger -+ but faster to write and read. pngstest now uses this by default; this -+ can be disabled with the --slow option. -+ Improved pngstest fine tuning of error numbers, new test file generator. -+ The generator generates images that test the full range of sample values, -+ allow the error numbers in pngstest to be tuned and checked. makepng -+ also allows generation of images with extra chunks, although this is -+ still work-in-progress. -+ Added check for invalid palette index while reading. -+ Fixed some bugs in ICC profile writing. The code should now accept -+ all potentially valid ICC profiles and reject obviously invalid ones. -+ It now uses png_error() to do so rather than casually writing a PNG -+ without the necessary color data. -+ Removed whitespace from the end of lines in all source files and scripts. -+ -+Version 1.6.0beta16 [March 6, 2012] -+ Relocated palette-index checking function from pngrutil.c to pngtrans.c -+ Added palette-index checking while writing. -+ Changed png_inflate() and calling routines to avoid overflow problems. -+ This is an intermediate check-in that solves the immediate problems and -+ introduces one performance improvement (avoiding a copy via png_ptr->zbuf.) -+ Further changes will be made to make ICC profile handling more secure. -+ Fixed build warnings (MSVC, GCC, GCC v3). Cygwin GCC with default options -+ declares 'index' as a global, causing a warning if it is used as a local -+ variable. GCC 64-bit warns about assigning a (size_t) (unsigned 64-bit) -+ to an (int) (signed 32-bit). MSVC, however, warns about using the -+ unary '-' operator on an unsigned value (even though it is well defined -+ by ANSI-C to be ~x+1). The padding calculation was changed to use a -+ different method. Removed the tests on png_ptr->pass. -+ Added contrib/libtests/tarith.c to test internal arithmetic functions from -+ png.c. This is a libpng maintainer program used to validate changes to the -+ internal arithmetic functions. -+ Made read 'inflate' handling like write 'deflate' handling. The read -+ code now claims and releases png_ptr->zstream, like the write code. -+ The bug whereby the progressive reader failed to release the zstream -+ is now fixed, all initialization is delayed, and the code checks for -+ changed parameters on deflate rather than always calling -+ deflatedEnd/deflateInit. -+ Validate the zTXt strings in pngvalid. -+ Added code to validate the windowBits value passed to deflateInit2(). -+ If the call to deflateInit2() is wrong a png_warning will be issued -+ (in fact this is harmless, but the PNG data produced may be sub-optimal). -+ -+Version 1.6.0beta17 [March 10, 2012] -+ Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition. -+ Reject all iCCP chunks after the first, even if the first one is invalid. -+ Deflate/inflate was reworked to move common zlib calls into single -+ functions [rw]util.c. A new shared keyword check routine was also added -+ and the 'zbuf' is no longer allocated on progressive read. It is now -+ possible to call png_inflate() incrementally. A warning is no longer -+ issued if the language tag or translated keyword in the iTXt chunk -+ has zero length. -+ If benign errors are disabled use maximum window on ancilliary inflate. -+ This works round a bug introduced in 1.5.4 where compressed ancillary -+ chunks could end up with a too-small windowBits value in the deflate -+ header. -+ -+Version 1.6.0beta18 [March 16, 2012] -+ Issue a png_benign_error() instead of png_warning() about bad palette index. -+ In pngtest, treat benign errors as errors if "-strict" is present. -+ Fixed an off-by-one error in the palette index checking function. -+ Fixed a compiler warning under Cygwin (Windows-7, 32-bit system) -+ Revised example.c to put text strings in a temporary character array -+ instead of directly assigning string constants to png_textp members. -+ This avoids compiler warnings when -Wwrite-strings is enabled. -+ Added output flushing to aid debugging under Visual Studio. Unfortunately -+ this is necessary because the VS2010 output window otherwise simply loses -+ the error messages on error (they weren't flushed to the window before -+ the process exited, apparently!) -+ Added configuration support for benign errors and changed the read -+ default. Also changed some warnings in the iCCP and sRGB handling -+ from to benign errors. Configuration now makes read benign -+ errors warnings and write benign errors to errors by default (thus -+ changing the behavior on read). The simplified API always forces -+ read benign errors to warnings (regardless of the system default, unless -+ this is disabled in which case the simplified API can't be built.) -+ -+Version 1.6.0beta19 [March 18, 2012] -+ Work around for duplicate row start calls; added warning messages. -+ This turns on PNG_FLAG_DETECT_UNINITIALIZED to detect app code that -+ fails to call one of the 'start' routines (not enabled in libpng-1.5 -+ because it is technically an API change, since it did normally work -+ before.) It also makes duplicate calls to png_read_start_row (an -+ internal function called at the start of the image read) benign, as -+ they were before changes to use png_inflate_claim. Somehow webkit is -+ causing this to happen; this is probably a mis-feature in the zlib -+ changes so this commit is only a work-round. -+ Removed erroneous setting of DETECT_UNINITIALIZED and added more -+ checks. The code now does a png_error if an attempt is made to do the -+ row initialization twice; this is an application error and it has -+ serious consequences because the transform data in png_struct is -+ changed by each call. -+ Added application error reporting and added chunk names to read -+ benign errors; also added --strict to pngstest - not enabled -+ yet because a warning is produced. -+ Avoid the double gamma correction warning in the simplified API. -+ This allows the --strict option to pass in the pngstest checks -+ -+Version 1.6.0beta20 [March 29, 2012] -+ Changed chunk handler warnings into benign errors, incrementally load iCCP -+ Added checksum-icc.c to contrib/tools -+ Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice. -+ Recognize known sRGB ICC profiles while reading; prefer writing the -+ iCCP profile over writing the sRGB chunk, controlled by the -+ PNG_sRGB_PROFILE_CHECKS option. -+ Revised png_set_text_2() to avoid potential memory corruption (fixes -+ CVE-2011-3048, also known as CVE-2012-3425). -+ -+Version 1.6.0beta21 [April 27, 2012] -+ Revised scripts/makefile.darwin: use system zlib; remove quotes around -+ architecture list; add missing ppc architecture; add architecture options -+ to shared library link; don't try to create a shared lib based on missing -+ RELEASE variable. -+ Enable png_set_check_for_invalid_index() for both read and write. -+ Removed #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED in pngpriv.h around -+ declaration of png_handle_unknown(). -+ Added -lssp_nonshared in a comment in scripts/makefile.freebsd -+ and changed deprecated NOOBJ and NOPROFILE to NO_OBJ and NO_PROFILE. -+ -+Version 1.6.0beta22 [May 23, 2012] -+ Removed need for -Wno-cast-align with clang. clang correctly warns on -+ alignment increasing pointer casts when -Wcast-align is passed. This -+ fixes the cases that clang warns about either by eliminating the -+ casts from png_bytep to png_uint_16p (pngread.c), or, for pngrutil.c -+ where the cast is previously verified or pngstest.c where it is OK, by -+ introducing new png_aligncast macros to do the cast in a way that clang -+ accepts. -+ -+Version 1.6.0beta23 [June 6, 2012] -+ Revised CMakeLists.txt to not attempt to make a symlink under mingw. -+ Made fixes for new optimization warnings from gcc 4.7.0. The compiler -+ performs an optimization which is safe; however it then warns about it. -+ Changing the type of 'palette_number' in pngvalid.c removes the warning. -+ Do not depend upon a GCC feature macro being available for use in generating -+ the linker mapfile symbol prefix. -+ Improved performance of new do_check_palette_indexes() function (only -+ update the value when it actually increases, move test for whether -+ the check is wanted out of the function. -+ -+Version 1.6.0beta24 [June 7, 2012] -+ Don't check palette indexes if num_palette is 0 (as it can be in MNG files). -+ -+Version 1.6.0beta25 [June 16, 2012] -+ Revised png_set_keep_unknown_chunks() so num_chunks < 0 means ignore all -+ unknown chunks and all known chunks except for IHDR, PLTE, tRNS, IDAT, -+ and IEND. Previously it only meant ignore all unknown chunks, the -+ same as num_chunks == 0. Revised png_image_skip_unused_chunks() to -+ provide a list of chunks to be processed instead of a list of chunks to -+ ignore. Revised contrib/gregbook/readpng2.c accordingly. -+ -+Version 1.6.0beta26 [July 10, 2012] -+ Removed scripts/makefile.cegcc from the *.zip and *.7z distributions; it -+ depends on configure, which is not included in those archives. -+ Moved scripts/chkfmt to contrib/tools. -+ Changed "a+w" to "u+w" in Makefile.in to fix CVE-2012-3386. -+ -+Version 1.6.0beta27 [August 11, 2012] -+ Do not compile PNG_DEPRECATED, PNG_ALLOC and PNG_PRIVATE when __GNUC__ < 3. -+ Do not use __restrict when GNUC is <= 3.1 -+ Removed references to png_zalloc() and png_zfree() from the manual. -+ Fixed configurations where floating point is completely disabled. Because -+ of the changes to support symbol prefixing PNG_INTERNAL_FUNCTION declares -+ floating point APIs during libpng builds even if they are completely -+ disabled. This requires the png floating point types (png_double*) to be -+ declared even though the functions are never actually defined. This -+ change provides a dummy definition so that the declarations work, yet any -+ implementation will fail to compile because of an incomplete type. -+ Re-eliminated the use of strcpy() in pngtest.c. An unncessary use of -+ strcpy() was accidentally re-introduced in libpng16; this change replaces -+ it with strncpy(). -+ Eliminated use of png_sizeof(); use sizeof() instead. -+ Use a consistent style for (sizeof type) and (sizeof (array)) -+ Cleanup of png_set_filler(). This function does very different things on -+ read and write. In libpng 1.6 the two cases can be distinguished and -+ considerable code cleanup, and extra error checking, is possible. This -+ makes calls on the write side that have no effect be ignored with a -+ png_app_error(), which can be disabled in the app using -+ png_set_benign_errors(), and removes the spurious use of usr_channels -+ on the read side. -+ Insist on autotools 1.12.1 for git builds because there are security issues -+ with 1.12 and insisting on anything less would allow 1.12 to be used. -+ Removed info_ptr->signature[8] from WRITE-only builds. -+ Add some conditions for compiling png_fixed(). This is a small function -+ but it requires "-lm" on some platforms. -+ Cause pngtest --strict to fail on any warning from libpng (not just errors) -+ and cause it not to fail at the comparison step if libpng lacks support -+ for writing chunks that it reads from the input (currently only implemented -+ for compressed text chunks). -+ Make all three "make check" test programs work without READ or WRITE support. -+ Now "make check" will succeed even if libpng is compiled with -DPNG_NO_READ -+ or -DPNG_NO_WRITE. The tests performed are reduced, but the basic reading -+ and writing of a PNG file is always tested by one or more of the tests. -+ Consistently use strlen(), memset(), memcpy(), and memcmp() instead of the -+ png_strlen(), png_memset(), png_memcpy(), and png_memcmp() macros. -+ Removed the png_sizeof(), png_strlen(), png_memset(), png_memcpy(), and -+ png_memcmp() macros. -+ Work around gcc 3.x and Microsoft Visual Studio 2010 complaints. Both object -+ to the split initialization of num_chunks. -+ -+Version 1.6.0beta28 [August 29, 2012] -+ Unknown handling fixes and clean up. This adds more correct option -+ control of the unknown handling, corrects the pre-existing bug where -+ the per-chunk 'keep' setting is ignored and makes it possible to skip -+ IDAT chunks in the sequential reader (broken in earlier 1.6 versions). -+ There is a new test program, test-unknown.c, which is a work in progress -+ (not currently part of the test suite). Comments in the header files now -+ explain how the unknown handling works. -+ Allow fine grain control of unknown chunk APIs. This change allows -+ png_set_keep_unknown_chunks() to be turned off if not required and causes -+ both read and write to behave appropriately (on read this is only possible -+ if the user callback is used to handle unknown chunks). The change -+ also removes the support for storing unknown chunks in the info_struct -+ if the only unknown handling enabled is via the callback, allowing libpng -+ to be configured with callback reading and none of the unnecessary code. -+ Corrected fix for unknown handling in pngtest. This reinstates the -+ libpng handling of unknown chunks other than vpAg and sTER (including -+ unsafe-to-copy chunks which were dropped before) and eliminates the -+ repositioning of vpAg and sTER in pngtest.png by changing pngtest.png -+ (so the chunks are where libpng would put them). -+ Added "tunknown" test and corrected a logic error in png_handle_unknown() -+ when SAVE support is absent. Moved the shell test scripts for -+ contrib/libtests from the libpng top directory to contrib/libtests. -+ png_handle_unknown() must always read or skip the chunk, if -+ SAVE_UNKNOWN_CHUNKS is turned off *and* the application does not set -+ a user callback an unknown chunk will not be read, leading to a read -+ error, which was revealed by the "tunknown" test. -+ Cleaned up and corrected ICC profile handling. -+ contrib/libtests/makepng: corrected 'rgb' and 'gray' cases. profile_error -+ messages could be truncated; made a correct buffer size calculation and -+ adjusted pngerror.c appropriately. png_icc_check_* checking improved; -+ changed the functions to receive the correct color type of the PNG on read -+ or write and check that it matches the color space of the profile (despite -+ what the comments said before, there is danger in assuming the app will -+ cope correctly with an RGB profile on a grayscale image and, since it -+ violates the PNG spec, allowing it is certain to produce inconsistent -+ app behavior and might even cause app crashes.) Check that profiles -+ contain the tags needed to process the PNG (tags all required by the ICC -+ spec). Removed unused PNG_STATIC from pngpriv.h. -+ -+Version 1.6.0beta29 [September 4, 2012] -+ Fixed the simplified API example programs to add the *colormap parameter -+ to several of he API and improved the error message if the version field -+ is not set. -+ Added contrib/examples/* to the *.zip and *.7z distributions. -+ Updated simplified API synopses and description of the png_image structure -+ in the manual. -+ Made makepng and pngtest produce identical PNGs, add "--relaxed" option -+ to pngtest. The "--relaxed" option turns off the benign errors that are -+ enabled by default in pre-RC builds. makepng can now write ICC profiles -+ where the length has not been extended to a multiple of 4, and pngtest -+ now intercepts all libpng errors, allowing the previously-introduced -+ "--strict test" on no warnings to actually work. -+ Improved ICC profile handling including cHRM chunk generation and fixed -+ Cygwin+MSVC build errors. The ICC profile handling now includes more -+ checking. Several errors that caused rejection of the profile are now -+ handled with a warning in such a way that the invalid profiles will be -+ read by default in release (but not pre-RC) builds but will not be -+ written by default. The easy part of handling the cHRM chunk is written, -+ where the ICC profile contains the required data. The more difficult -+ part plus guessing a gAMA value requires code to pass selected RGB values -+ through the profile. -+ -+Version 1.6.0beta30 [October 24, 2012] -+ Changed ICC profile matrix/vector types to not depend on array type rules. -+ By the ANSI-C standard the new types should be identical to the previous -+ versions, and all known versions of gcc tested with the previous versions -+ except for GCC-4.2.1 work with this version. The change makes the ANSI-C -+ rule that const applied to an array of elements applies instead to the -+ elements in the array moot by explicitly applying const to the base -+ elements of the png_icc_matrix and png_icc_vector types. The accidental -+ (harmless) 'const' previously applied to the parameters of two of the -+ functions have also been removed. -+ Added a work around for GCC 4.2 optimization bug. -+ Marked the broken (bad white point) original HP sRGB profiles correctly and -+ correct comments. -+ Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7 -+ Use /MDd for vstudio debug builds. Also added pngunkown to the vstudio -+ builds, fixed build errors and corrected a minor exit code error in -+ pngvalid if the 'touch' file name is invalid. -+ Add updated WARNING file to projects/vstudio from libpng 1.5/vstudio -+ Fixed build when using #define PNG_NO_READ_GAMMA in png_do_compose() in -+ pngrtran.c (Domani Hannes). -+ -+Version 1.6.0beta31 [November 1, 2012] -+ Undid the erroneous change to vstudio/pngvalid build in libpng-1.6.0beta30. -+ Made pngvalid so that it will build outside the libpng source tree. -+ Made builds -DPNG_NO_READ_GAMMA compile (the unit tests still fail). -+ Made PNG_NO_READ_GAMMA switch off interfaces that depend on READ_GAMMA. -+ Prior to 1.6.0 switching off READ_GAMMA did unpredictable things to the -+ interfaces that use it (specifically, png_do_background in 1.4 would -+ simply display composite for grayscale images but do composition -+ with the incorrect arithmetic for color ones). In 1.6 the semantic -+ of -DPNG_NO_READ_GAMMA is changed to simply disable any interface that -+ depends on it; this obliges people who set it to consider whether they -+ really want it off if they happen to use any of the interfaces in -+ question (typically most users who disable it won't). -+ Fixed GUIDs in projects/vstudio. Some were duplicated or missing, -+ resulting in VS2010 having to update the files. -+ Removed non-working ICC profile support code that was mostly added to -+ libpng-1.6.0beta29 and beta30. There was too much code for too little -+ gain; implementing full ICC color correction may be desireable but is left -+ up to applications. -+ -+Version 1.6.0beta32 [November 25, 2012] -+ Fixed an intermittent SEGV in pngstest due to an uninitialized array element. -+ Added the ability for contrib/libtests/makepng.c to make a PNG with just one -+ color. This is useful for debugging pngstest color inaccuracy reports. -+ Fixed error checking in the simplified write API (Olaf van der Spek) -+ Made png_user_version_check() ok to use with libpng version 1.10.x and later. -+ -+Version 1.6.0beta33 [December 15, 2012] -+ Fixed typo in png.c (PNG_SET_CHUNK_MALLOC_MAX should be PNG_CHUNK_MALLOC_MAX) -+ that causes the MALLOC_MAX limit not to work (John Bowler) -+ Change png_warning() to png_app_error() in pngwrite.c and comment the -+ fall-through condition. -+ Change png_warning() to png_app_warning() in png_write_tRNS(). -+ Rearranged the ARM-NEON optimizations: Isolated the machine specific code -+ to the hardware subdirectory and added comments to pngrutil.c so that -+ implementors of other optimizations know what to do. -+ Fixed cases of unquoted DESTDIR in Makefile.am -+ Rebuilt Makefile.in, etc., with autoconf-2.69 and automake-1.12.5. -+ -+Version 1.6.0beta34 [December 19, 2012] -+ Cleaned up whitespace in the synopsis portion of the manpage "libpng.3" -+ Disassembled the version number in scripts/options.awk (necessary for -+ building on SunOs). -+ -+Version 1.6.0beta35 [December 23, 2012] -+ Made default Zlib compression settings be configurable. This adds #defines to -+ pnglibconf.h to control the defaults. -+ Fixed Windows build issues, enabled ARM compilation. Various warnings issued -+ by earlier versions of GCC fixed for Cygwin and Min/GW (which both use old -+ GCCs.) ARM support is enabled by default in zlib.props (unsupported by -+ Microsoft) and ARM compilation is made possible by deleting the check for -+ x86. The test programs cannot be run because they are not signed. -+ -+Version 1.6.0beta36 [January 2, 2013] -+ Discontinued distributing libpng-1.x.x.tar.bz2. -+ Discontinued distributing libpng-1.7.0-1.6.0-diff.txt and similar. -+ Rebuilt configure with autoconf-2.69 (inadvertently not done in beta33) -+ Fixed 'make distcheck' on SUN OS - libpng.so was not being removed -+ -+Version 1.6.0beta37 [January 10, 2013] -+ Fixed conceivable but difficult to repro overflow. Also added two test -+ programs to generate and test a PNG which should have the problem. -+ -+Version 1.6.0beta39 [January 19, 2013] -+ Again corrected attempt at overflow detection in png_set_unknown_chunks() -+ (CVE-2013-7353). Added overflow detection in png_set_sPLT() and -+ png_set_text_2() (CVE-2013-7354). -+ -+Version 1.6.0beta40 [January 20, 2013] -+ Use consistent handling of overflows in text, sPLT and unknown png_set_* APIs -+ -+Version 1.6.0rc01 [January 26, 2013] -+ No changes. -+ -+Version 1.6.0rc02 [February 4, 2013] -+ Added png_get_palette_max() function. -+ -+Version 1.6.0rc03 [February 5, 2013] -+ Fixed the png_get_palette_max API. -+ -+Version 1.6.0rc04 [February 7, 2013] -+ Turn serial tests back on (recently turned off by autotools upgrade). -+ -+Version 1.6.0rc05 [February 8, 2013] -+ Update manual about png_get_palette_max(). -+ -+Version 1.6.0rc06 [February 9, 2013] -+ Fixed missing dependency in --prefix builds The intermediate -+ internal 'prefix.h' file can only be generated correctly after -+ pnglibconf.h, however the dependency was not in Makefile.am. The -+ symptoms are unpredictable depending on the order make chooses to -+ build pngprefix.h and pnglibconf.h, often the error goes unnoticed -+ because there is a system pnglibconf.h to use instead. -+ -+Version 1.6.0rc07 [February 10, 2013] -+ Enclosed the new png_get_palette_max in #ifdef PNG_GET_PALETTE_MAX_SUPPORTED -+ block, and revised pnglibconf.h and pnglibconf.h.prebuilt accordingly. -+ -+Version 1.6.0rc08 [February 10, 2013] -+ Fix typo in png.h #ifdef -+ -+Version 1.6.0 [February 14, 2013] -+ No changes. -+ -+Version 1.6.1beta01 [February 16, 2013] -+ Made symbol prefixing work with the ARM neon optimizations. Also allow -+ pngpriv.h to be included for preprocessor definitions only, so it can -+ be used in non-C/C++ files. Back ported from libpng 1.7. -+ Made sRGB check numbers consistent. -+ Ported libpng 1.5 options.awk/dfn file handling to 1.6, fixed one bug. -+ Removed cc -E workround, corrected png_get_palette_max API Tested on -+ SUN OS cc 5.9, which demonstrates the tokenization problem previously -+ avoided by using /lib/cpp. Since all .dfn output is now protected in -+ double quotes unless it is to be macro substituted the fix should -+ work everywhere. -+ Enabled parallel tests - back ported from libpng-1.7. -+ scripts/pnglibconf.dfa formatting improvements back ported from libpng17. -+ Fixed a race condition in the creation of the build 'scripts' directory -+ while building with a parallel make. -+ Use approved/supported Android method to check for NEON, use Linux/POSIX -+ 1003.1 API to check /proc/self/auxv avoiding buffer allocation and other -+ library calls (ported from libpng15). -+ -+Version 1.6.1beta02 [February 19, 2013] -+ Use parentheses more consistently in "#if defined(MACRO)" tests. -+ Folded long lines. -+ Reenabled code to allow zero length PLTE chunks for MNG. -+ -+Version 1.6.1beta03 [February 22, 2013] -+ Fixed ALIGNED_MEMORY support. -+ Allow run-time ARM NEON checking to be disabled. A new configure option: -+ --enable-arm-neon=always will stop the run-time checks. New checks -+ within arm/arm_init.c will cause the code not to be compiled unless -+ __ARM_NEON__ is set. This should make it fail safe (if someone asks -+ for it on then the build will fail if it can't be done.) -+ Updated the INSTALL document. -+ -+Version 1.6.1beta04 [February 27, 2013] -+ Revised INSTALL to recommend using CPPFLAGS instead of INCLUDES. -+ Revised scripts/makefile.freebsd to respect ZLIBLIB and ZLIBINC. -+ Revised scripts/dfn.awk to work with the buggy MSYS awk that has trouble -+ with CRLF line endings. -+ -+Version 1.6.1beta05 [March 1, 2013] -+ Avoid a possible memory leak in contrib/gregbook/readpng.c -+ -+Version 1.6.1beta06 [March 4, 2013] -+ Better documentation of unknown handling API interactions. -+ Corrected Android builds and corrected libpng.vers with symbol -+ prefixing. This adds an API to set optimization options externally, -+ providing an alternative and general solution for the non-portable -+ run-time tests used by the ARM Neon code. It also makes those tests -+ compile and link on Android. -+ The order of settings vs options in pnglibconf.h is reversed to allow -+ settings to depend on options and options can now set (or override) the -+ defaults for settings. -+ -+Version 1.6.1beta07 [March 7, 2013] -+ Corrected simplified API default gamma for color-mapped output, added -+ a flag to change default. In 1.6.0 when the simplified API was used -+ to produce color-mapped output from an input image with no gamma -+ information the gamma assumed for the input could be different from -+ that assumed for non-color-mapped output. In particular 16-bit depth -+ input files were assumed to be sRGB encoded, whereas in the 'direct' -+ case they were assumed to have linear data. This was an error. The -+ fix makes the simplified API treat all input files the same way and -+ adds a new flag to the png_image::flags member to allow the -+ application/user to specify that 16-bit files contain sRGB data -+ rather than the default linear. -+ Fixed bugs in the pngpixel and makepng test programs. -+ -+Version 1.6.1beta08 [March 7, 2013] -+ Fixed CMakelists.txt to allow building a single variant of the library -+ (Claudio Bley): -+ Introduced a PNG_LIB_TARGETS variable that lists all activated library -+ targets. It is an error if this variable ends up empty, ie. you have -+ to build at least one library variant. -+ Made the *_COPY targets only depend on library targets actually being build. -+ Use PNG_LIB_TARGETS to unify a code path. -+ Changed the CREATE_SYMLINK macro to expect the full path to a file as the -+ first argument. When symlinking the filename component of that path is -+ determined and used as the link target. -+ Use copy_if_different in the CREATE_SYMLINK macro. -+ -+Version 1.6.1beta09 [March 13, 2013] -+ Eliminated two warnings from the Intel C compiler. The warnings are -+ technically valid, although a reasonable treatment of division would -+ show it to be incorrect. -+ -+Version 1.6.1rc01 [March 21, 2013] -+ No changes. -+ -+Version 1.6.1 [March 28, 2013] -+ No changes. -+ -+Version 1.6.2beta01 [April 14, 2013] -+ Updated documentation of 1.5.x to 1.6.x changes in iCCP chunk handling. -+ Fixed incorrect warning of excess deflate data. End condition - the -+ warning would be produced if the end of the deflate stream wasn't read -+ in the last row. The warning is harmless. -+ Corrected the test on user transform changes on read. It was in the -+ png_set of the transform function, but that doesn't matter unless the -+ transform function changes the rowbuf size, and that is only valid if -+ transform_info is called. -+ Corrected a misplaced closing bracket in contrib/libtests/pngvalid.c -+ (Flavio Medeiros). -+ Corrected length written to uncompressed iTXt chunks (Samuli Suominen). -+ Bug was introduced in libpng-1.6.0. -+ -+Version 1.6.2rc01 [April 18, 2013] -+ Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length -+ written by libpng-1.6.0 and 1.6.1. -+ Disallow storing sRGB information when the sRGB is not supported. -+ -+Version 1.6.2rc02 [April 18, 2013] -+ Merge pngtest.c with libpng-1.7.0 -+ -+Version 1.6.2rc03 [April 22, 2013] -+ Trivial spelling cleanup. -+ -+Version 1.6.2rc04 and 1.6.2rc05 [omitted] -+ -+Version 1.6.2rc06 [April 24, 2013] -+ Reverted to version 1.6.2rc03. Recent changes to arm/neon support -+ have been ported to libpng-1.7.0beta09 and will reappear in version -+ 1.6.3beta01. -+ -+Version 1.6.2 [April 25, 2013] -+ No changes. -+ -+Version 1.6.3beta01 [April 25, 2013] -+ Revised stack marking in arm/filter_neon.S and configure.ac. -+ Ensure that NEON filter stuff is completely disabled when switched 'off'. -+ Previously the ARM NEON specific files were still built if the option -+ was switched 'off' as opposed to being explicitly disabled. -+ -+Version 1.6.3beta02 [April 26, 2013] -+ Test for 'arm*' not just 'arm' in the host_cpu configure variable. -+ Rebuilt the configure scripts. -+ -+Version 1.6.3beta03 [April 30, 2013] -+ Expanded manual paragraph about writing private chunks, particularly -+ the need to call png_set_keep_unknown_chunks() when writing them. -+ Avoid dereferencing NULL pointer possibly returned from -+ png_create_write_struct() (Andrew Church). -+ -+Version 1.6.3beta05 [May 9, 2013] -+ Calculate our own zlib windowBits when decoding rather than trusting the -+ CMF bytes in the PNG datastream. -+ Added an option to force maximum window size for inflating, which was -+ the behavior of libpng15 and earlier. -+ Added png-fix-itxt and png-fix-too-far-back to the built programs and -+ removed warnings from the source code and timepng that are revealed as -+ a result. -+ Detect wrong libpng versions linked to png-fix-too-far-back, which currently -+ only works with libpng versions that can be made to reliably fail when -+ the deflate data contains an out-of-window reference. This means only -+ 1.6 and later. -+ Fixed gnu issues: g++ needs a static_cast, gcc 4.4.7 has a broken warning -+ message which it is easier to work round than ignore. -+ Updated contrib/pngminus/pnm2png.c (Paul Stewart): -+ Check for EOF -+ Ignore "#" delimited comments in input file to pnm2png.c. -+ Fixed whitespace handling -+ Added a call to png_set_packing() -+ Initialize dimension values so if sscanf fails at least we have known -+ invalid values. -+ Attempt to detect configuration issues with png-fix-too-far-back, which -+ requires both the correct libpng and the correct zlib to function -+ correctly. -+ Check ZLIB_VERNUM for mismatches, enclose #error in quotes -+ Added information in the documentation about problems with and fixes for -+ the bad CRC and bad iTXt chunk situations. -+ -+Version 1.6.3beta06 [May 12, 2013] -+ Allow contrib/pngminus/pnm2png.c to compile without WRITE_INVERT and -+ WRITE_PACK supported (writes error message that it can't read P1 or -+ P4 PBM files). -+ Improved png-fix-too-far-back usage message, added --suffix option. -+ Revised contrib/pngminim/*/makefile to generate pnglibconf.h with the -+ right zlib header files. -+ Separated CPPFLAGS and CFLAGS in contrib/pngminim/*/makefile -+ -+Version 1.6.3beta07 [June 8, 2013] -+ Removed a redundant test in png_set_IHDR(). -+ Added set(CMAKE_CONFIGURATION_TYPES ...) to CMakeLists.txt (Andrew Hundt) -+ Deleted set(CMAKE_BUILD_TYPE) block from CMakeLists.txt -+ Enclose the prototypes for the simplified write API in -+ #ifdef PNG_STDIO_SUPPORTED/#endif -+ Make ARM NEON support work at compile time (not just configure time). -+ This moves the test on __ARM_NEON__ into pngconf.h to avoid issues when -+ using a compiler that compiles for multiple architectures at one time. -+ Removed PNG_FILTER_OPTIMIZATIONS and PNG_ARM_NEON_SUPPORTED from -+ pnglibconf.h, allowing more of the decisions to be made internally -+ (pngpriv.h) during the compile. Without this, symbol prefixing is broken -+ under certain circumstances on ARM platforms. Now only the API parts of -+ the optimizations ('check' vs 'api') are exposed in the public header files -+ except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the -+ decision about whether or not to use the optimizations. -+ Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage. -+ Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test -+ on __ARM_NEON__ from configure time to compile time. This breaks symbol -+ prefixing because the definition of the special png_init_filter_functions -+ call was hidden at configure time if the relevant compiler arguments are -+ passed in CFLAGS as opposed to CC. This change attempts to avoid all -+ the confusion that would result by declaring the init function even when -+ it is not used, so that it will always get prefixed. -+ -+Version 1.6.3beta08 [June 18, 2013] -+ Revised libpng.3 so that "doclifter" can process it. -+ -+Version 1.6.3beta09 [June 27, 2013] -+ Revised example.c to illustrate use of PNG_DEFAULT_sRGB and PNG_GAMMA_MAC_18 -+ as parameters for png_set_gamma(). These have been available since -+ libpng-1.5.4. -+ Renamed contrib/tools/png-fix-too-far-back.c to pngfix.c and revised it -+ to check all compressed chunks known to libpng. -+ -+Version 1.6.3beta10 [July 5, 2013] -+ Updated documentation to show default behavior of benign errors correctly. -+ Only compile ARM code when PNG_READ_SUPPORTED is defined. -+ Fixed undefined behavior in contrib/tools/pngfix.c and added new strip -+ option. pngfix relied on undefined behavior and even a simple change from -+ gcc to g++ caused it to fail. The new strip option 'unsafe' has been -+ implemented and is the default if --max is given. Option names have -+ been clarified, with --strip=transform now stripping the bKGD chunk, -+ which was stripped previously with --strip=unused. -+ Added all documented chunk types to pngpriv.h -+ Unified pngfix.c source with libpng17. -+ -+Version 1.6.3rc01 [July 11, 2013] -+ No changes. -+ -+Version 1.6.3 [July 18, 2013] -+ Revised manual about changes in iTXt chunk handling made in libpng-1.6.0. -+ Added "/* SAFE */" comments in pngrutil.c and pngrtran.c where warnings -+ may be erroneously issued by code-checking applications. -+ -+Version 1.6.4beta01 [August 21, 2013] -+ Added information about png_set_options() to the manual. -+ Delay calling png_init_filter_functions() until a row with nonzero filter -+ is found. -+ -+Version 1.6.4beta02 [August 30, 2013] -+ Fixed inconsistent conditional compilation of png_chunk_unknown_handling() -+ prototype, definition, and usage. Made it depend on -+ PNG_HANDLE_AS_UNKNOWN_SUPPORTED everywhere. -+ -+Version 1.6.4rc01 [September 5, 2013] -+ No changes. -+ -+Version 1.6.4 [September 12, 2013] -+ No changes. -+ -+Version 1.6.5 [September 14, 2013] -+ Removed two stray lines of code from arm/arm_init.c. -+ -+Version 1.6.6 [September 16, 2013] -+ Removed two stray lines of code from arm/arm_init.c, again. -+ -+Version 1.6.7beta01 [September 30, 2013] -+ Revised unknown chunk code to correct several bugs in the NO_SAVE_/NO_WRITE -+ combination -+ Allow HANDLE_AS_UNKNOWN to work when other options are configured off. Also -+ fixed the pngminim makefiles to work when $(MAKEFLAGS) contains stuff -+ which terminates the make options (as by default in recent versions of -+ Gentoo). -+ Avoid up-cast warnings in pngvalid.c. On ARM the alignment requirements of -+ png_modifier are greater than that of png_store and as a consequence -+ compilation of pngvalid.c results in a warning about increased alignment -+ requirements because of the bare cast to (png_modifier*). The code is safe, -+ because the pointer is known to point to a stack allocated png_modifier, -+ but this change avoids the warning. -+ Fixed default behavior of ARM_NEON_API. If the ARM NEON API option was -+ compiled without the CHECK option it defaulted to on, not off. -+ Check user callback behavior in pngunknown.c. Previous versions compiled -+ if SAVE_UNKNOWN was not available but did nothing since the callback -+ was never implemented. -+ Merged pngunknown.c with 1.7 version and back ported 1.7 improvements/fixes -+ -+Version 1.6.7beta02 [October 12, 2013] -+ Made changes for compatibility with automake 1.14: -+ 1) Added the 'compile' program to the list of programs that must be cleaned -+ in autogen.sh -+ 2) Added 'subdir-objects' which causes .c files in sub-directories to be -+ compiled such that the corresponding .o files are also in the -+ sub-directory. This is because automake 1.14 warns that the -+ current behavior of compiling to the top level directory may be removed -+ in the future. -+ 3) Updated dependencies on pnglibconf.h to match the new .o locations and -+ added all the files in contrib/libtests and contrib/tools that depend -+ on pnglibconf.h -+ 4) Added 'BUILD_SOURCES = pnglibconf.h'; this is the automake recommended -+ way of handling the dependencies of sources that are machine generated; -+ unfortunately it only works if the user does 'make all' or 'make check', -+ so the dependencies (3) are still required. -+ Cleaned up (char*) casts of zlib messages. The latest version of the Intel C -+ compiler complains about casting a string literal as (char*), so copied the -+ treatment of z_const from the library code into pngfix.c -+ Simplified error message code in pngunknown. The simplification has the -+ useful side effect of avoiding a bogus warning generated by the latest -+ version of the Intel C compiler (it objects to -+ condition ? string-literal : string-literal). -+ Make autogen.sh work with automake 1.13 as well as 1.14. Do this by always -+ removing the 1.14 'compile' script but never checking for it. -+ -+Version 1.6.7beta03 [October 19, 2013] -+ Added ARMv8 support (James Yu <james.yu at linaro.org>). Added file -+ arm/filter_neon_intrinsics.c; enable with -mfpu=neon. -+ Revised pngvalid to generate size images with as many filters as it can -+ manage, limited by the number of rows. -+ Cleaned up ARM NEON compilation handling. The tests are now in pngpriv.h -+ and detect the broken GCC compilers. -+ -+Version 1.6.7beta04 [October 26, 2013] -+ Allow clang derived from older GCC versions to use ARM intrinsics. This -+ causes all clang builds that use -mfpu=neon to use the intrinsics code, -+ not the assembler code. This has only been tested on iOS 7. It may be -+ necessary to exclude some earlier clang versions but this seems unlikely. -+ Changed NEON implementation selection mechanism. This allows assembler -+ or intrinsics to be turned on at compile time during the build by defining -+ PNG_ARM_NEON_IMPLEMENTATION to the correct value (2 or 1). This macro -+ is undefined by default and the build type is selected in pngpriv.h. -+ -+Version 1.6.7rc01 [November 2, 2013] -+ No changes. -+ -+Version 1.6.7rc02 [November 7, 2013] -+ Fixed #include in filter_neon_intrinsics.c and ctype macros. The ctype char -+ checking macros take an unsigned char argument, not a signed char. -+ -+Version 1.6.7 [November 14, 2013] -+ No changes. -+ -+Version 1.6.8beta01 [November 24, 2013] -+ Moved prototype for png_handle_unknown() in pngpriv.h outside of -+ the #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED/#endif block. -+ Added "-Wall" to CFLAGS in contrib/pngminim/*/makefile -+ Conditionally compile some unused functions reported by -Wall in -+ pngminim. -+ Fixed 'minimal' builds. Various obviously useful minimal configurations -+ don't build because of missing contrib/libtests test programs and -+ overly complex dependencies in scripts/pnglibconf.dfa. This change -+ adds contrib/conftest/*.dfa files that can be used in automatic build -+ scripts to ensure that these configurations continue to build. -+ Enabled WRITE_INVERT and WRITE_PACK in contrib/pngminim/encoder. -+ Fixed pngvalid 'fail' function declaration on the Intel C Compiler. -+ This reverts to the previous 'static' implementation and works round -+ the 'unused static function' warning by using PNG_UNUSED(). -+ -+Version 1.6.8beta02 [November 30, 2013] -+ Removed or marked PNG_UNUSED some harmless "dead assignments" reported -+ by clang scan-build. -+ Changed tabs to 3 spaces in png_debug macros and changed '"%s"m' -+ to '"%s" m' to improve portability among compilers. -+ Changed png_free_default() to free() in pngtest.c -+ -+Version 1.6.8rc01 [December 12, 2013] -+ Tidied up pngfix inits and fixed pngtest no-write builds. -+ -+Version 1.6.8rc02 [December 14, 2013] -+ Handle zero-length PLTE chunk or NULL palette with png_error() -+ instead of png_chunk_report(), which by default issues a warning -+ rather than an error, leading to later reading from a NULL pointer -+ (png_ptr->palette) in png_do_expand_palette(). This is CVE-2013-6954 -+ and VU#650142. Libpng-1.6.1 through 1.6.7 are vulnerable. -+ Libpng-1.6.0 and earlier do not have this bug. -+ -+Version 1.6.8 [December 19, 2013] -+ No changes. -+ -+Version 1.6.9beta01 [December 26, 2013] -+ Bookkeeping: Moved functions around (no changes). Moved transform -+ function definitions before the place where they are called so that -+ they can be made static. Move the intrapixel functions and the -+ grayscale palette builder out of the png?tran.c files. The latter -+ isn't a transform function and is no longer used internally, and the -+ former MNG specific functions are better placed in pngread/pngwrite.c -+ Made transform implementation functions static. This makes the internal -+ functions called by png_do_{read|write}_transformations static. On an -+ x86-64 DLL build (Gentoo Linux) this reduces the size of the text -+ segment of the DLL by 1208 bytes, about 0.6%. It also simplifies -+ maintenance by removing the declarations from pngpriv.h and allowing -+ easier changes to the internal interfaces. -+ Rebuilt configure scripts with automake-1.14.1 and autoconf-2.69 -+ in the tar distributions. -+ -+Version 1.6.9beta02 [January 1, 2014] -+ Added checks for libpng 1.5 to pngvalid.c. This supports the use of -+ this version of pngvalid in libpng 1.5 -+ Merged with pngvalid.c from libpng-1.7 changes to create a single -+ pngvalid.c -+ Removed #error macro from contrib/tools/pngfix.c (Thomas Klausner). -+ Merged pngrio.c, pngtrans.c, pngwio.c, and pngerror.c with libpng-1.7.0 -+ Merged libpng-1.7.0 changes to make no-interlace configurations work -+ with test programs. -+ Revised pngvalid.c to support libpng 1.5, which does not support the -+ PNG_MAXIMUM_INFLATE_WINDOW option, so #define it out when appropriate in -+ pngvalid.c -+ Allow unversioned links created on install to be disabled in configure. -+ In configure builds 'make install' changes/adds links like png.h -+ and libpng.a to point to the newly installed, versioned, files (e.g. -+ libpng17/png.h and libpng17.a). Three new configure options and some -+ rearrangement of Makefile.am allow creation of these links to be disabled. -+ -+Version 1.6.9beta03 [January 10, 2014] -+ Removed potentially misleading warning from png_check_IHDR(). -+ -+Version 1.6.9beta04 [January 20, 2014] -+ Updated scripts/makefile.* to use CPPFLAGS (Cosmin). -+ Added clang attribute support (Cosmin). -+ -+Version 1.6.9rc01 [January 28, 2014] -+ No changes. -+ -+Version 1.6.9rc02 [January 30, 2014] -+ Quiet an uninitialized memory warning from VC2013 in png_get_png(). -+ -+Version 1.6.9 [February 6, 2014] -+ -+Version 1.6.10beta01 [February 9, 2014] -+ Backported changes from libpng-1.7.0beta30 and beta31: -+ Fixed a large number of instances where PNGCBAPI was omitted from -+ function definitions. -+ Added pngimage test program for png_read_png() and png_write_png() -+ with two new test scripts. -+ Removed dependence on !PNG_READ_EXPAND_SUPPORTED for calling -+ png_set_packing() in png_read_png(). -+ Fixed combination of ~alpha with shift. On read invert alpha, processing -+ occurred after shift processing, which causes the final values to be -+ outside the range that should be produced by the shift. Reversing the -+ order on read makes the two transforms work together correctly and mirrors -+ the order used on write. -+ Do not read invalid sBIT chunks. Previously libpng only checked sBIT -+ values on write, so a malicious PNG writer could therefore cause -+ the read code to return an invalid sBIT chunk, which might lead to -+ application errors or crashes. Such chunks are now skipped (with -+ chunk_benign_error). -+ Make png_read_png() and png_write_png() prototypes in png.h depend -+ upon PNG_READ_SUPPORTED and PNG_WRITE_SUPPORTED. -+ Support builds with unsupported PNG_TRANSFORM_* values. All of the -+ PNG_TRANSFORM_* values are always defined in png.h and, because they -+ are used for both read and write in some cases, it is not reliable -+ to #if out ones that are totally unsupported. This change adds error -+ detection in png_read_image() and png_write_image() to do a -+ png_app_error() if the app requests something that cannot be done -+ and it adds corresponding code to pngimage.c to handle such options -+ by not attempting to test them. -+ -+Version 1.6.10beta02 [February 23, 2014] -+ Moved redefines of png_error(), png_warning(), png_chunk_error(), -+ and png_chunk_warning() from pngpriv.h to png.h to make them visible -+ to libpng-calling applications. -+ Moved OS dependent code from arm/arm_init.c, to allow the included -+ implementation of the ARM NEON discovery function to be set at -+ build-time and provide sample implementations from the current code in the -+ contrib/arm-neon subdirectory. The __linux__ code has also been changed to -+ compile and link on Android by using /proc/cpuinfo, and the old linux code -+ is in contrib/arm-neon/linux-auxv.c. The new code avoids POSIX and Linux -+ dependencies apart from opening /proc/cpuinfo and is C90 compliant. -+ Check for info_ptr == NULL early in png_read_end() so we don't need to -+ run all the png_handle_*() and depend on them to return if info_ptr == NULL. -+ This improves the performance of png_read_end(png_ptr, NULL) and makes -+ it more robust against future programming errors. -+ Check for __has_extension before using it in pngconf.h, to -+ support older Clang versions (Jeremy Sequoia). -+ Treat CRC error handling with png_set_crc_action(), instead of with -+ png_set_benign_errors(), which has been the case since libpng-1.6.0beta18. -+ Use a user warning handler in contrib/gregbook/readpng2.c instead of default, -+ so warnings will be put on stderr even if libpng has CONSOLE_IO disabled. -+ Added png_ptr->process_mode = PNG_READ_IDAT_MODE in png_push_read_chunk -+ after recognizing the IDAT chunk, which avoids an infinite loop while -+ reading a datastream whose first IDAT chunk is of zero-length. -+ This fixes CERT VU#684412 and CVE-2014-0333. -+ Don't recognize known sRGB profiles as sRGB if they have been hacked, -+ but don't reject them and don't issue a copyright violation warning. -+ -+Version 1.6.10beta03 [February 25, 2014] -+ Moved some documentation from png.h to libpng.3 and libpng-manual.txt -+ Minor editing of contrib/arm-neon/README and contrib/examples/*.c -+ -+Version 1.6.10rc01 [February 27, 2014] -+ Fixed typos in the manual and in scripts/pnglibconf.dfa (CFLAGS -> CPPFLAGS -+ and PNG_USR_CONFIG -> PNG_USER_CONFIG). -+ -+Version 1.6.10rc02 [February 28, 2014] -+ Removed unreachable return statement after png_chunk_error() -+ in pngrutil.c -+ -+Version 1.6.10rc03 [March 4, 2014] -+ Un-deprecated png_data_freer(). -+ -+Version 1.6.10 [March 6, 2014] -+ No changes. -+ -+Version 1.6.11beta01 [March 17, 2014] -+ Use "if (value != 0)" instead of "if (value)" consistently. -+ Changed ZlibSrcDir from 1.2.5 to 1.2.8 in projects/vstudio. -+ Moved configuration information from the manual to the INSTALL file. -+ -+Version 1.6.11beta02 [April 6, 2014] -+ Removed #if/#else/#endif from inside two pow() calls in pngvalid.c because -+ they were handled improperly by Portland Group's PGI-14.1 - PGI-14.3 -+ when using its "__builtin_pow()" function. -+ Silence 'unused parameter' build warnings (Cosmin Truta). -+ $(CP) is now used alongside $(RM_F). Also, use 'copy' instead of 'cp' -+ where applicable, and applied other minor makefile changes (Cosmin). -+ Don't warn about invalid dimensions exceeding user limits (Cosmin). -+ Allow an easy replacement of the default pre-built configuration -+ header with a custom header, via the make PNGLIBCONF_H_PREBUILT -+ macro (Cosmin). -+ -+Version 1.6.11beta03 [April 6, 2014] -+ Fixed a typo in pngrutil.c, introduced in libpng-1.5.6, that interferes -+ with "blocky" expansion of sub-8-bit interlaced PNG files (Eric Huss). -+ Optionally use __builtin_bswap16() in png_do_swap(). -+ -+Version 1.6.11beta04 [April 19, 2014] -+ Made progressive reading of interlaced images consistent with the -+ behavior of the sequential reader and consistent with the manual, by -+ moving some code out of the PNG_READ_INTERLACING_SUPPORTED blocks. The -+ row_callback now receives the proper pass number and unexpanded rows, when -+ png_combine_row() isn't built or used, and png_set_interlace_handling() -+ is not called. -+ Allow PNG_sRGB_PROFILE_CHECKING = (-1) to mean no sRGB profile checking. -+ -+Version 1.6.11beta05 [April 26, 2014] -+ Do not reject ICC V2 profiles that lack padding (Kai-Uwe Behrmann). -+ Relocated closing bracket of the sRGB profile test loop to avoid getting -+ "Not recognizing known sRGB profile that has been edited" warning for -+ ICC V2 profiles that lack the MD5 signature in the profile header. -+ -+Version 1.6.11beta06 [May 19, 2014] -+ Added PNG_SKIP_sRGB_CHECK_PROFILE choice for png_set_option(). -+ -+Version 1.6.11rc01 [May 27, 2014] -+ No changes. -+ -+Version 1.6.11rc02 [June 3, 2014] -+ Test ZLIB_VERNUM instead of PNG_ZLIB_VERNUM in contrib/tools/pngfix.c -+ -+Version 1.6.11 [June 5, 2014] -+ No changes. -+ -+Version 1.6.12rc01 [June 6, 2014] -+ Relocated new code from 1.6.11beta06 in png.c to a point after the -+ declarations (Max Stepin). -+ -+Version 1.6.12rc02 [June 7, 2014] -+ Changed file permissions of contrib/tools/intgamma.sh, -+ test-driver, and compile from 0644 to 0755 (Cosmin). -+ -+Version 1.6.12rc03 [June 8, 2014] -+ Ensure "__has_attribute()" macro exists before trying to use it with -+ old clang compilers (MacPorts Ticket #43939). -+ -+Version 1.6.12 [June 12, 2014] -+ No changes. -+ -+Version 1.6.13beta01 [July 4, 2014] -+ Quieted -Wsign-compare and -Wclobber compiler warnings in -+ contrib/pngminus/*.c -+ Added "(void) png_ptr;" where needed in contrib/gregbook to quiet -+ compiler complaints about unused pointers. -+ Split a long output string in contrib/gregbook/rpng2-x.c. -+ Added "PNG_SET_OPTION" requirement for sRGB chunk support to pnglibconf.dfa, -+ Needed for write-only support (John Bowler). -+ Changed "if defined(__ARM_NEON__)" to -+ "if (defined(__ARM_NEON__) || defined(__ARM_NEON))" (James Wu). -+ Fixed clang no-warning builds: png_digit was defined but never used. -+ -+Version 1.6.13beta02 [July 21, 2014] -+ Fixed an incorrect separator ("/" should be "\") in scripts/makefile.vcwin32 -+ (bug report from Wolfgang S. Kechel). Bug was introduced in libpng-1.6.11. -+ Also fixed makefile.bc32, makefile.bor, makefile.msc, makefile.intel, and -+ makefile.tc3 similarly. -+ -+Version 1.6.13beta03 [August 3, 2014] -+ Removed scripts/makefile.elf. It has not worked since libpng-1.5.0beta14 -+ due to elimination of the PNG_FUNCTION_EXPORT and PNG_DATA_EXPORT -+ definitions from pngconf.h. -+ Ensure that CMakeLists.txt makes the target "lib" directory before making -+ symbolic link into it (SourceForge bug report #226 by Rolf Timmermans). -+ -+Version 1.6.13beta04 [August 8, 2014] -+ Added opinion that the ECCN (Export Control Classification Number) for -+ libpng is EAR99 to the README file. -+ Eliminated use of "$<" in makefile explicit rules, when copying -+ $PNGLIBCONF_H_PREBUILT. This does not work on some versions of make; -+ bug introduced in libpng version 1.6.11. -+ -+Version 1.6.13rc01 [August 14, 2014] -+ Made "ccopts" agree with "CFLAGS" in scripts/makefile.hp* and makefile.*sunu -+ -+Version 1.6.13 [August 21, 2014] -+ No changes. -+ -+Version 1.6.14beta01 [September 14, 2014] -+ Guard usage of png_ptr->options with #ifdef PNG_SET_OPTION_SUPPORTED. -+ Do not build contrib/tools/pngfix.c when PNG_SETJMP_NOT_SUPPORTED, -+ to allow "make" to complete without setjmp support (bug report by -+ Claudio Fontana) -+ Add "#include <setjmp.h>" to contrib/tools/pngfix.c (John Bowler) -+ -+Version 1.6.14beta02 [September 18, 2014] -+ Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c -+ because usleep() is deprecated. -+ Define usleep() in contrib/gregbook/rpng2-x.c if not already defined -+ in unistd.h and nanosleep() is not available; fixes error introduced -+ in libpng-1.6.13. -+ Disable floating point exception handling in pngvalid.c when -+ PNG_FLOATING_ARITHMETIC is not supported (bug report by "zootus -+ at users.sourceforge.net"). -+ -+Version 1.6.14beta03 [September 19, 2014] -+ Define FE_DIVBYZERO, FE_INVALID, and FE_OVERFLOW in pngvalid.c if not -+ already defined. Revert floating point exception handling in pngvalid.c -+ to version 1.6.14beta01 behavior. -+ -+Version 1.6.14beta04 [September 27, 2014] -+ Fixed incorrect handling of the iTXt compression flag in pngrutil.c -+ (bug report by Shunsaku Hirata). Bug was introduced in libpng-1.6.0. -+ -+Version 1.6.14beta05 [October 1, 2014] -+ Added "option READ_iCCP enables READ_COMPRESSED_TEXT" to pnglibconf.dfa -+ -+Version 1.6.14beta06 [October 5, 2014] -+ Removed unused "text_len" parameter from private function png_write_zTXt(). -+ Conditionally compile some code in png_deflate_claim(), when -+ PNG_WARNINGS_SUPPORTED and PNG_ERROR_TEXT_SUPPORTED are disabled. -+ Replaced repeated code in pngpread.c with PNG_PUSH_SAVE_BUFFER_IF_FULL. -+ Added "chunk iTXt enables TEXT" and "chunk zTXt enables TEXT" -+ to pnglibconf.dfa. -+ Removed "option READ_COMPRESSED_TEXT enables READ_TEXT" from pnglibconf.dfa, -+ to make it possible to configure a libpng that supports iCCP but not TEXT. -+ -+Version 1.6.14beta07 [October 7, 2014] -+ Removed "option WRITE_COMPRESSED_TEXT enables WRITE_TEXT" from pnglibconf.dfa -+ Only mark text chunks as written after successfully writing them. -+ -+Version 1.6.14rc01 [October 15, 2014] -+ Fixed some typos in comments. -+ -+Version 1.6.14rc02 [October 17, 2014] -+ Changed png_convert_to_rfc_1123() to png_convert_to_rfc_1123_buffer() -+ in the manual, to reflect the change made in libpng-1.6.0. -+ Updated README file to explain that direct access to the png_struct -+ and info_struct members has not been permitted since libpng-1.5.0. -+ -+Version 1.6.14 [October 23, 2014] -+ No changes. -+ -+Version 1.6.15beta01 [October 29, 2014] -+ Changed "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)" -+ Simplified png_free_data(). -+ Added missing "ptr = NULL" after some instances of png_free(). -+ -+Version 1.6.15beta02 [November 1, 2014] -+ Changed remaining "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)" -+ -+Version 1.6.15beta03 [November 3, 2014] -+ Added PNG_USE_ARM_NEON configuration flag (Marcin Juszkiewicz). -+ -+Version 1.6.15beta04 [November 4, 2014] -+ Removed new PNG_USE_ARM_NEON configuration flag and made a one-line -+ revision to configure.ac to support ARM on aarch64 instead (John Bowler). -+ -+Version 1.6.15beta05 [November 5, 2014] -+ Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in -+ example.c, pngtest.c, and applications in the contrib directory. -+ Avoid out-of-bounds memory access in png_user_version_check(). -+ Simplified and future-proofed png_user_version_check(). -+ Fixed GCC unsigned int->float warnings. Various versions of GCC -+ seem to generate warnings when an unsigned value is implicitly -+ converted to double. This is probably a GCC bug but this change -+ avoids the issue by explicitly converting to (int) where safe. -+ Free all allocated memory in pngimage. The file buffer cache was left -+ allocated at the end of the program, harmless but it causes memory -+ leak reports from clang. -+ Fixed array size calculations to avoid warnings. At various points -+ in the code the number of elements in an array is calculated using -+ sizeof. This generates a compile time constant of type (size_t) which -+ is then typically assigned to an (unsigned int) or (int). Some versions -+ of GCC on 64-bit systems warn about the apparent narrowing, even though -+ the same compiler does apparently generate the correct, in-range, -+ numeric constant. This adds appropriate, safe, casts to make the -+ warnings go away. -+ -+Version 1.6.15beta06 [November 6, 2014] -+ Reverted use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING -+ in the manual, example.c, pngtest.c, and applications in the contrib -+ directory. It was incorrect advice. -+ -+Version 1.6.15beta07 [November 7, 2014] -+ Removed #ifdef PNG_16BIT_SUPPORTED/#endif around png_product2(); it is -+ needed by png_reciprocal2(). -+ Added #ifdef PNG_16BIT_SUPPORTED/#endif around png_log16bit() and -+ png_do_swap(). -+ Changed all "#endif /* PNG_FEATURE_SUPPORTED */" to "#endif /* FEATURE */" -+ -+Version 1.6.15beta08 [November 8, 2014] -+ More housecleaning in *.h -+ -+Version 1.6.15rc01 [November 13, 2014] -+ -+Version 1.6.15rc02 [November 14, 2014] -+ The macros passed in the command line to Borland make were ignored if -+ similarly-named macros were already defined in makefiles. This behavior -+ is different from POSIX make and other make programs. Surround the -+ macro definitions with ifndef guards (Cosmin). -+ -+Version 1.6.15rc03 [November 16, 2014] -+ Added "-D_CRT_SECURE_NO_WARNINGS" to CFLAGS in scripts/makefile.vcwin32. -+ Removed the obsolete $ARCH variable from scripts/makefile.darwin. -+ -+Version 1.6.15 [November 20, 2014] -+ No changes. -+ -+Version 1.6.16beta01 [December 14, 2014] -+ Added ".align 2" to arm/filter_neon.S to support old GAS assemblers that -+ don't do alignment correctly. -+ Revised Makefile.am and scripts/symbols.dfn to work with MinGW/MSYS -+ (Bob Friesenhahn). -+ -+Version 1.6.16beta02 [December 15, 2014] -+ Revised Makefile.am and scripts/*.dfn again to work with MinGW/MSYS; -+ renamed scripts/*.dfn to scripts/*.c (John Bowler). -+ -+Version 1.6.16beta03 [December 21, 2014] -+ Quiet a "comparison always true" warning in pngstest.c (John Bowler). -+ -+Version 1.6.16rc01 [December 21, 2014] -+ Restored a test on width that was removed from png.c at libpng-1.6.9 -+ (Bug report by Alex Eubanks). -+ -+Version 1.6.16rc02 [December 21, 2014] -+ Undid the update to pngrutil.c in 1.6.16rc01. -+ -+Version 1.6.16rc03 [December 21, 2014] -+ Fixed an overflow in png_combine_row with very wide interlaced images. -+ -+Version 1.6.16 [December 22, 2014] -+ No changes. - - Send comments/corrections/commendations to png-mng-implement at lists.sf.net - (subscription required; visit -@@ -3540,5 +5156,3 @@ - or to glennrp at users.sourceforge.net - - Glenn R-P --*/ } --#endif ---- ./jdk/src/share/native/sun/awt/libpng/LICENSE Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/LICENSE Thu Feb 05 13:00:26 2015 +0100 -@@ -10,8 +10,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -108,4 +108,4 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 ---- ./jdk/src/share/native/sun/awt/libpng/README Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/README Thu Feb 05 13:00:26 2015 +0100 -@@ -1,11 +1,11 @@ --README for libpng version 1.5.4 - July 7, 2011 (shared library 15.0) -+README for libpng version 1.6.16 - December 22, 2014 (shared library 16.0) - See the note about version numbers near the top of png.h - - See INSTALL for instructions on how to install libpng. - --Libpng comes in several distribution formats. Get libpng-*.tar.gz, --libpng-*.tar.xz or libpng-*.tar.bz2 if you want UNIX-style line endings --in the text files, or lpng*.zip if you want DOS-style line endings. -+Libpng comes in several distribution formats. Get libpng-*.tar.gz or -+libpng-*.tar.xz or if you want UNIX-style line endings in the text files, -+or lpng*.7z or lpng*.zip if you want DOS-style line endings. - - Version 0.89 was the first official release of libpng. Don't let the - fact that it's the first release fool you. The libpng library has been in -@@ -23,18 +23,25 @@ - png_uint_32, which will affect shared-library applications that use - this function. - --To avoid problems with changes to the internals of png_info_struct, -+To avoid problems with changes to the internals of png info_struct, - new APIs have been made available in 0.95 to avoid direct application - access to info_ptr. These functions are the png_set_<chunk> and - png_get_<chunk> functions. These functions should be used when - accessing/storing the info_struct data, rather than manipulating it - directly, to avoid such problems in the future. - --It is important to note that the APIs do not make current programs -+It is important to note that the APIs did not make current programs - that access the info struct directly incompatible with the new --library. However, it is strongly suggested that new programs use --the new APIs (as shown in example.c and pngtest.c), and older programs --be converted to the new format, to facilitate upgrades in the future. -+library, through libpng-1.2.x. In libpng-1.4.x, which was meant to -+be a transitional release, members of the png_struct and the -+info_struct can still be accessed, but the compiler will issue a -+warning about deprecated usage. Since libpng-1.5.0, direct access -+to these structs is not allowed, and the definitions of the structs -+reside in private pngstruct.h and pnginfo.h header files that are not -+accessible to applications. It is strongly suggested that new -+programs use the new APIs (as shown in example.c and pngtest.c), and -+older programs be converted to the new format, to facilitate upgrades -+in the future. - **** - - Additions since 0.90 include the ability to compile libpng as a -@@ -77,17 +84,21 @@ - You can use zlib as a drop-in replacement for fread() and fwrite() if - you are so inclined. - --zlib should be available at the same place that libpng is, or at. --ftp://ftp.info-zip.org/pub/infozip/zlib -+zlib should be available at the same place that libpng is, or at zlib.net. - - You may also want a copy of the PNG specification. It is available - as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find - these at http://www.libpng.org/pub/png/documents/ - - This code is currently being archived at libpng.sf.net in the --[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT) --at GO GRAPHSUP. If you can't find it in any of those places, --e-mail me, and I'll help you find it. -+[DOWNLOAD] area, and at ftp://ftp.simplesystems.org. If you can't find it -+in any of those places, e-mail me, and I'll help you find it. -+ -+I am not a lawyer, but I believe that the Export Control Classification -+Number (ECCN) for libpng is EAR99, which means not subject to export -+controls or International Traffic in Arms Regulations (ITAR) because it -+is open source, publicly available software, that does not contain any -+encryption software. See the EAR, paragraphs 734.3(b)(3) and 734.7(b). - - If you have any code changes, requests, problems, etc., please e-mail - them to me. Also, I'd appreciate any make files or project files, -@@ -105,7 +116,7 @@ - development group. - - Send comments/corrections/commendations to png-mng-implement at --lists.sourceforge.net (subscription required; visit -+lists.sourceforge.net (subscription required; visit - https://lists.sourceforge.net/lists/listinfo/png-mng-implement - to subscribe) or to glennrp at users.sourceforge.net - -@@ -123,7 +134,7 @@ - to others, if necessary. - - Please do not send suggestions on how to change PNG. We have --been discussing PNG for sixteen years now, and it is official and -+been discussing PNG for nineteen years now, and it is official and - finished. If you have suggestions for libpng, however, I'll - gladly listen. Even if your suggestion is not used immediately, - it may be used later. -@@ -167,23 +178,25 @@ - pngwrite.c => High-level write functions - pngwtran.c => Write data transformations - pngwutil.c => Write utility functions -+ arm => Contains optimized code for the ARM platform - contrib => Contributions -+ examples => Example programs - gregbook => source code for PNG reading and writing, from - Greg Roelofs' "PNG: The Definitive Guide", - O'Reilly, 1999 -- msvctest => Builds and runs pngtest using a MSVC workspace -- pngminus => Simple pnm2png and png2pnm programs -- pngsuite => Test images -- visupng => Contains a MSVC workspace for VisualPng -+ libtests => Test programs -+ pngminim => Minimal decoder, encoder, and progressive decoder -+ programs demonstrating use of pngusr.dfa -+ pngminus => Simple pnm2png and png2pnm programs -+ pngsuite => Test images -+ tools => Various tools -+ visupng => Contains a MSVC workspace for VisualPng - projects => Contains project files and workspaces for - building a DLL -- cbuilder5 => Contains a Borland workspace for building -- libpng and zlib -- visualc6 => Contains a Microsoft Visual C++ (MSVC) -- workspace for building libpng and zlib -+ owatcom => Contains a WATCOM project for building libpng - visualc71 => Contains a Microsoft Visual C++ (MSVC) - workspace for building libpng and zlib -- xcode => Contains an Apple xcode -+ vstudio => Contains a Microsoft Visual C++ (MSVC) - workspace for building libpng and zlib - scripts => Directory containing scripts for building libpng: - (see scripts/README.txt for the list of scripts) ---- ./jdk/src/share/native/sun/awt/libpng/png.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/png.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.16 [December 22, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -42,7 +42,7 @@ - #include "pngpriv.h" - - /* Generate a compiler error if there is an old png.h in the search path. */ --typedef png_libpng_version_1_5_4 Your_png_h_is_not_version_1_5_4; -+typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16; - - /* Tells libpng that we have already handled the first "num_bytes" bytes - * of the PNG file signature. If the PNG data is embedded into another -@@ -52,7 +52,7 @@ - - #ifdef PNG_READ_SUPPORTED - void PNGAPI --png_set_sig_bytes(png_structp png_ptr, int num_bytes) -+png_set_sig_bytes(png_structrp png_ptr, int num_bytes) - { - png_debug(1, "in png_set_sig_bytes"); - -@@ -71,7 +71,7 @@ - * can simply check the remaining bytes for extra assurance. Returns - * an integer less than, equal to, or greater than zero if sig is found, - * respectively, to be less than, to match, or be greater than the correct -- * PNG signature (this is the same behaviour as strcmp, memcmp, etc). -+ * PNG signature (this is the same behavior as strcmp, memcmp, etc). - */ - int PNGAPI - png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) -@@ -90,52 +90,47 @@ - if (start + num_to_check > 8) - num_to_check = 8 - start; - -- return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); -+ return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); - } - --#endif /* PNG_READ_SUPPORTED */ -+#endif /* READ */ - - #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - /* Function to allocate memory for zlib */ - PNG_FUNCTION(voidpf /* PRIVATE */, - png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) - { -- png_voidp ptr; -- png_structp p=(png_structp)png_ptr; -- png_uint_32 save_flags=p->flags; -- png_alloc_size_t num_bytes; -+ png_alloc_size_t num_bytes = size; - - if (png_ptr == NULL) -- return (NULL); -- -- if (items > PNG_UINT_32_MAX/size) -+ return NULL; -+ -+ if (items >= (~(png_alloc_size_t)0)/size) - { -- png_warning (p, "Potential overflow in png_zalloc()"); -- return (NULL); -+ png_warning (png_voidcast(png_structrp, png_ptr), -+ "Potential overflow in png_zalloc()"); -+ return NULL; - } -- num_bytes = (png_alloc_size_t)items * size; -- -- p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; -- ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); -- p->flags=save_flags; -- -- return ((voidpf)ptr); -+ -+ num_bytes *= items; -+ return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); - } - - /* Function to free memory for zlib */ - void /* PRIVATE */ - png_zfree(voidpf png_ptr, voidpf ptr) - { -- png_free((png_structp)png_ptr, (png_voidp)ptr); -+ png_free(png_voidcast(png_const_structrp,png_ptr), ptr); - } - - /* Reset the CRC variable to 32 bits of 1's. Care must be taken - * in case CRC is > 32 bits to leave the top bits 0. - */ - void /* PRIVATE */ --png_reset_crc(png_structp png_ptr) -+png_reset_crc(png_structrp png_ptr) - { -- png_ptr->crc = crc32(0, Z_NULL, 0); -+ /* The cast is safe because the crc is a 32 bit value. */ -+ png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); - } - - /* Calculate the CRC over a section of data. We can only pass as -@@ -144,119 +139,254 @@ - * trouble of calculating it. - */ - void /* PRIVATE */ --png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length) -+png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length) - { - int need_crc = 1; - -- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ -+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - -- else /* critical */ -+ else /* critical */ - { -- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) -+ if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) - need_crc = 0; - } - -- if (need_crc) -- png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length); -+ /* 'uLong' is defined in zlib.h as unsigned long; this means that on some -+ * systems it is a 64 bit value. crc32, however, returns 32 bits so the -+ * following cast is safe. 'uInt' may be no more than 16 bits, so it is -+ * necessary to perform a loop here. -+ */ -+ if (need_crc != 0 && length > 0) -+ { -+ uLong crc = png_ptr->crc; /* Should never issue a warning */ -+ -+ do -+ { -+ uInt safe_length = (uInt)length; -+ if (safe_length == 0) -+ safe_length = (uInt)-1; /* evil, but safe */ -+ -+ crc = crc32(crc, ptr, safe_length); -+ -+ /* The following should never issue compiler warnings; if they do the -+ * target system has characteristics that will probably violate other -+ * assumptions within the libpng code. -+ */ -+ ptr += safe_length; -+ length -= safe_length; -+ } -+ while (length > 0); -+ -+ /* And the following is always safe because the crc is only 32 bits. */ -+ png_ptr->crc = (png_uint_32)crc; -+ } - } - - /* Check a user supplied version number, called from both read and write -- * functions that create a png_struct -+ * functions that create a png_struct. - */ - int --png_user_version_check(png_structp png_ptr, png_const_charp user_png_ver) -+png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) - { -- if (user_png_ver) -+ /* Libpng versions 1.0.0 and later are binary compatible if the version -+ * string matches through the second '.'; we must recompile any -+ * applications that use any older library version. -+ */ -+ -+ if (user_png_ver != NULL) - { -- int i = 0; -+ int i = -1; -+ int found_dots = 0; - - do - { -- if (user_png_ver[i] != png_libpng_ver[i]) -+ i++; -+ if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i]) - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; -- } while (png_libpng_ver[i++]); -+ if (user_png_ver[i] == '.') -+ found_dots++; -+ } while (found_dots < 2 && user_png_ver[i] != 0 && -+ PNG_LIBPNG_VER_STRING[i] != 0); - } - - else - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - -- if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) -+ if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0) - { -- /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so -- * we must recompile any applications that use any older library version. -- * For versions after libpng 1.0, we will be compatible, so we need -- * only check the first digit. -- */ -- if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || -- (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || -- (user_png_ver[0] == '0' && user_png_ver[2] < '9')) -- { - #ifdef PNG_WARNINGS_SUPPORTED -- size_t pos = 0; -- char m[128]; -- -- pos = png_safecat(m, sizeof m, pos, "Application built with libpng-"); -- pos = png_safecat(m, sizeof m, pos, user_png_ver); -- pos = png_safecat(m, sizeof m, pos, " but running with "); -- pos = png_safecat(m, sizeof m, pos, png_libpng_ver); -- -- png_warning(png_ptr, m); -+ size_t pos = 0; -+ char m[128]; -+ -+ pos = png_safecat(m, (sizeof m), pos, -+ "Application built with libpng-"); -+ pos = png_safecat(m, (sizeof m), pos, user_png_ver); -+ pos = png_safecat(m, (sizeof m), pos, " but running with "); -+ pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING); -+ PNG_UNUSED(pos) -+ -+ png_warning(png_ptr, m); - #endif - - #ifdef PNG_ERROR_NUMBERS_SUPPORTED -- png_ptr->flags = 0; -+ png_ptr->flags = 0; - #endif - -- return 0; -- } -+ return 0; - } - - /* Success return. */ - return 1; - } - --/* Allocate the memory for an info_struct for the application. We don't -- * really need the png_ptr, but it could potentially be useful in the -- * future. This should be used in favour of malloc(png_sizeof(png_info)) -- * and png_info_init() so that applications that want to use a shared -- * libpng don't have to be recompiled if png_info changes size. -+/* Generic function to create a png_struct for either read or write - this -+ * contains the common initialization. - */ -+PNG_FUNCTION(png_structp /* PRIVATE */, -+png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, -+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, -+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -+{ -+ png_struct create_struct; -+# ifdef PNG_SETJMP_SUPPORTED -+ jmp_buf create_jmp_buf; -+# endif -+ -+ /* This temporary stack-allocated structure is used to provide a place to -+ * build enough context to allow the user provided memory allocator (if any) -+ * to be called. -+ */ -+ memset(&create_struct, 0, (sizeof create_struct)); -+ -+ /* Added at libpng-1.2.6 */ -+# ifdef PNG_USER_LIMITS_SUPPORTED -+ create_struct.user_width_max = PNG_USER_WIDTH_MAX; -+ create_struct.user_height_max = PNG_USER_HEIGHT_MAX; -+ -+# ifdef PNG_USER_CHUNK_CACHE_MAX -+ /* Added at libpng-1.2.43 and 1.4.0 */ -+ create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; -+# endif -+ -+# ifdef PNG_USER_CHUNK_MALLOC_MAX -+ /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists -+ * in png_struct regardless. -+ */ -+ create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; -+# endif -+# endif -+ -+ /* The following two API calls simply set fields in png_struct, so it is safe -+ * to do them now even though error handling is not yet set up. -+ */ -+# ifdef PNG_USER_MEM_SUPPORTED -+ png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); -+# else -+ PNG_UNUSED(mem_ptr) -+ PNG_UNUSED(malloc_fn) -+ PNG_UNUSED(free_fn) -+# endif -+ -+ /* (*error_fn) can return control to the caller after the error_ptr is set, -+ * this will result in a memory leak unless the error_fn does something -+ * extremely sophisticated. The design lacks merit but is implicit in the -+ * API. -+ */ -+ png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); -+ -+# ifdef PNG_SETJMP_SUPPORTED -+ if (!setjmp(create_jmp_buf)) -+ { -+ /* Temporarily fake out the longjmp information until we have -+ * successfully completed this function. This only works if we have -+ * setjmp() support compiled in, but it is safe - this stuff should -+ * never happen. -+ */ -+ create_struct.jmp_buf_ptr = &create_jmp_buf; -+ create_struct.jmp_buf_size = 0; /*stack allocation*/ -+ create_struct.longjmp_fn = longjmp; -+# else -+ { -+# endif -+ /* Call the general version checker (shared with read and write code): -+ */ -+ if (png_user_version_check(&create_struct, user_png_ver) != 0) -+ { -+ png_structrp png_ptr = png_voidcast(png_structrp, -+ png_malloc_warn(&create_struct, (sizeof *png_ptr))); -+ -+ if (png_ptr != NULL) -+ { -+ /* png_ptr->zstream holds a back-pointer to the png_struct, so -+ * this can only be done now: -+ */ -+ create_struct.zstream.zalloc = png_zalloc; -+ create_struct.zstream.zfree = png_zfree; -+ create_struct.zstream.opaque = png_ptr; -+ -+# ifdef PNG_SETJMP_SUPPORTED -+ /* Eliminate the local error handling: */ -+ create_struct.jmp_buf_ptr = NULL; -+ create_struct.jmp_buf_size = 0; -+ create_struct.longjmp_fn = 0; -+# endif -+ -+ *png_ptr = create_struct; -+ -+ /* This is the successful return point */ -+ return png_ptr; -+ } -+ } -+ } -+ -+ /* A longjmp because of a bug in the application storage allocator or a -+ * simple failure to allocate the png_struct. -+ */ -+ return NULL; -+} -+ -+/* Allocate the memory for an info_struct for the application. */ - PNG_FUNCTION(png_infop,PNGAPI --png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED) -+png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) - { -- png_infop info_ptr; -+ png_inforp info_ptr; - - png_debug(1, "in png_create_info_struct"); - - if (png_ptr == NULL) -- return (NULL); -- --#ifdef PNG_USER_MEM_SUPPORTED -- info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, -- png_ptr->malloc_fn, png_ptr->mem_ptr); --#else -- info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); --#endif -+ return NULL; -+ -+ /* Use the internal API that does not (or at least should not) error out, so -+ * that this call always returns ok. The application typically sets up the -+ * error handling *after* creating the info_struct because this is the way it -+ * has always been done in 'example.c'. -+ */ -+ info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, -+ (sizeof *info_ptr))); -+ - if (info_ptr != NULL) -- png_info_init_3(&info_ptr, png_sizeof(png_info)); -- -- return (info_ptr); -+ memset(info_ptr, 0, (sizeof *info_ptr)); -+ -+ return info_ptr; - } - - /* This function frees the memory associated with a single info struct. - * Normally, one would use either png_destroy_read_struct() or - * png_destroy_write_struct() to free an info struct, but this may be -- * useful for some applications. -+ * useful for some applications. From libpng 1.6.0 this function is also used -+ * internally to implement the png_info release part of the 'struct' destroy -+ * APIs. This ensures that all possible approaches free the same data (all of -+ * it). - */ - void PNGAPI --png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) -+png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) - { -- png_infop info_ptr = NULL; -+ png_inforp info_ptr = NULL; - - png_debug(1, "in png_destroy_info_struct"); - -@@ -268,46 +398,57 @@ - - if (info_ptr != NULL) - { -- png_info_destroy(png_ptr, info_ptr); -- --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn, -- png_ptr->mem_ptr); --#else -- png_destroy_struct((png_voidp)info_ptr); --#endif -+ /* Do this first in case of an error below; if the app implements its own -+ * memory management this can lead to png_free calling png_error, which -+ * will abort this routine and return control to the app error handler. -+ * An infinite loop may result if it then tries to free the same info -+ * ptr. -+ */ - *info_ptr_ptr = NULL; -+ -+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); -+ memset(info_ptr, 0, (sizeof *info_ptr)); -+ png_free(png_ptr, info_ptr); - } - } - - /* Initialize the info structure. This is now an internal function (0.89) - * and applications using it are urged to use png_create_info_struct() -- * instead. -+ * instead. Use deprecated in 1.6.0, internal use removed (used internally it -+ * is just a memset). -+ * -+ * NOTE: it is almost inconceivable that this API is used because it bypasses -+ * the user-memory mechanism and the user error handling/warning mechanisms in -+ * those cases where it does anything other than a memset. - */ -- --void PNGAPI --png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) -+PNG_FUNCTION(void,PNGAPI -+png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), -+ PNG_DEPRECATED) - { -- png_infop info_ptr = *ptr_ptr; -+ png_inforp info_ptr = *ptr_ptr; - - png_debug(1, "in png_info_init_3"); - - if (info_ptr == NULL) - return; - -- if (png_sizeof(png_info) > png_info_struct_size) -+ if ((sizeof (png_info)) > png_info_struct_size) - { -- png_destroy_struct(info_ptr); -- info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); -+ *ptr_ptr = NULL; -+ /* The following line is why this API should not be used: */ -+ free(info_ptr); -+ info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, -+ (sizeof *info_ptr))); - *ptr_ptr = info_ptr; - } - - /* Set everything to 0 */ -- png_memset(info_ptr, 0, png_sizeof(png_info)); -+ memset(info_ptr, 0, (sizeof *info_ptr)); - } - -+/* The following API is not called internally */ - void PNGAPI --png_data_freer(png_structp png_ptr, png_infop info_ptr, -+png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, - int freer, png_uint_32 mask) - { - png_debug(1, "in png_data_freer"); -@@ -322,12 +463,11 @@ - info_ptr->free_me &= ~mask; - - else -- png_warning(png_ptr, -- "Unknown freer parameter in png_data_freer"); -+ png_error(png_ptr, "Unknown freer parameter in png_data_freer"); - } - - void PNGAPI --png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, -+png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, - int num) - { - png_debug(1, "in png_free_data"); -@@ -337,32 +477,32 @@ - - #ifdef PNG_TEXT_SUPPORTED - /* Free text item num or (if num == -1) all text items */ -- if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) -+ if (info_ptr->text != 0 && -+ ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0) - { - if (num != -1) - { -- if (info_ptr->text && info_ptr->text[num].key) -- { -- png_free(png_ptr, info_ptr->text[num].key); -- info_ptr->text[num].key = NULL; -- } -+ png_free(png_ptr, info_ptr->text[num].key); -+ info_ptr->text[num].key = NULL; - } - - else - { - int i; -+ - for (i = 0; i < info_ptr->num_text; i++) -- png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); -+ png_free(png_ptr, info_ptr->text[i].key); -+ - png_free(png_ptr, info_ptr->text); - info_ptr->text = NULL; -- info_ptr->num_text=0; -+ info_ptr->num_text = 0; - } - } - #endif - - #ifdef PNG_tRNS_SUPPORTED - /* Free any tRNS entry */ -- if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) -+ if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->trans_alpha); - info_ptr->trans_alpha = NULL; -@@ -372,7 +512,7 @@ - - #ifdef PNG_sCAL_SUPPORTED - /* Free any sCAL entry */ -- if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) -+ if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->scal_s_width); - png_free(png_ptr, info_ptr->scal_s_height); -@@ -384,20 +524,20 @@ - - #ifdef PNG_pCAL_SUPPORTED - /* Free any pCAL entry */ -- if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) -+ if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->pcal_purpose); - png_free(png_ptr, info_ptr->pcal_units); - info_ptr->pcal_purpose = NULL; - info_ptr->pcal_units = NULL; -+ - if (info_ptr->pcal_params != NULL) - { - int i; -- for (i = 0; i < (int)info_ptr->pcal_nparams; i++) -- { -+ -+ for (i = 0; i < info_ptr->pcal_nparams; i++) - png_free(png_ptr, info_ptr->pcal_params[i]); -- info_ptr->pcal_params[i] = NULL; -- } -+ - png_free(png_ptr, info_ptr->pcal_params); - info_ptr->pcal_params = NULL; - } -@@ -406,8 +546,8 @@ - #endif - - #ifdef PNG_iCCP_SUPPORTED -- /* Free any iCCP entry */ -- if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) -+ /* Free any profile entry */ -+ if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->iccp_name); - png_free(png_ptr, info_ptr->iccp_profile); -@@ -419,26 +559,28 @@ - - #ifdef PNG_sPLT_SUPPORTED - /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ -- if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) -+ if (info_ptr->splt_palettes != 0 && -+ ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0) - { - if (num != -1) - { -- if (info_ptr->splt_palettes) -- { -- png_free(png_ptr, info_ptr->splt_palettes[num].name); -- png_free(png_ptr, info_ptr->splt_palettes[num].entries); -- info_ptr->splt_palettes[num].name = NULL; -- info_ptr->splt_palettes[num].entries = NULL; -- } -+ png_free(png_ptr, info_ptr->splt_palettes[num].name); -+ png_free(png_ptr, info_ptr->splt_palettes[num].entries); -+ info_ptr->splt_palettes[num].name = NULL; -+ info_ptr->splt_palettes[num].entries = NULL; - } - - else - { -- if (info_ptr->splt_palettes_num) -+ if (info_ptr->splt_palettes_num != 0) - { - int i; -- for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) -- png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); -+ -+ for (i = 0; i < info_ptr->splt_palettes_num; i++) -+ { -+ png_free(png_ptr, info_ptr->splt_palettes[i].name); -+ png_free(png_ptr, info_ptr->splt_palettes[i].entries); -+ } - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = NULL; -@@ -449,32 +591,24 @@ - } - #endif - --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -- if (png_ptr->unknown_chunk.data) -- { -- png_free(png_ptr, png_ptr->unknown_chunk.data); -- png_ptr->unknown_chunk.data = NULL; -- } -- -- if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) -+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -+ if (info_ptr->unknown_chunks != 0 && -+ ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0) - { - if (num != -1) - { -- if (info_ptr->unknown_chunks) -- { -- png_free(png_ptr, info_ptr->unknown_chunks[num].data); -- info_ptr->unknown_chunks[num].data = NULL; -- } -+ png_free(png_ptr, info_ptr->unknown_chunks[num].data); -+ info_ptr->unknown_chunks[num].data = NULL; - } - - else - { - int i; - -- if (info_ptr->unknown_chunks_num) -+ if (info_ptr->unknown_chunks_num != 0) - { - for (i = 0; i < info_ptr->unknown_chunks_num; i++) -- png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); -+ png_free(png_ptr, info_ptr->unknown_chunks[i].data); - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = NULL; -@@ -486,7 +620,7 @@ - - #ifdef PNG_hIST_SUPPORTED - /* Free any hIST entry */ -- if ((mask & PNG_FREE_HIST) & info_ptr->free_me) -+ if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->hist); - info_ptr->hist = NULL; -@@ -495,9 +629,9 @@ - #endif - - /* Free any PLTE entry that was internally allocated */ -- if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) -+ if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0) - { -- png_zfree(png_ptr, info_ptr->palette); -+ png_free(png_ptr, info_ptr->palette); - info_ptr->palette = NULL; - info_ptr->valid &= ~PNG_INFO_PLTE; - info_ptr->num_palette = 0; -@@ -505,16 +639,14 @@ - - #ifdef PNG_INFO_IMAGE_SUPPORTED - /* Free any image bits attached to the info structure */ -- if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) -+ if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0) - { -- if (info_ptr->row_pointers) -+ if (info_ptr->row_pointers != 0) - { -- int row; -- for (row = 0; row < (int)info_ptr->height; row++) -- { -+ png_uint_32 row; -+ for (row = 0; row < info_ptr->height; row++) - png_free(png_ptr, info_ptr->row_pointers[row]); -- info_ptr->row_pointers[row] = NULL; -- } -+ - png_free(png_ptr, info_ptr->row_pointers); - info_ptr->row_pointers = NULL; - } -@@ -527,37 +659,14 @@ - - info_ptr->free_me &= ~mask; - } -- --/* This is an internal routine to free any memory that the info struct is -- * pointing to before re-using it or freeing the struct itself. Recall -- * that png_free() checks for NULL pointers for us. -- */ --void /* PRIVATE */ --png_info_destroy(png_structp png_ptr, png_infop info_ptr) --{ -- png_debug(1, "in png_info_destroy"); -- -- png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); -- --#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- if (png_ptr->num_chunk_list) -- { -- png_free(png_ptr, png_ptr->chunk_list); -- png_ptr->chunk_list = NULL; -- png_ptr->num_chunk_list = 0; -- } --#endif -- -- png_info_init_3(&info_ptr, png_sizeof(png_info)); --} --#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ -+#endif /* READ || WRITE */ - - /* This function returns a pointer to the io_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy() or png_read_destroy() are called. - */ - png_voidp PNGAPI --png_get_io_ptr(png_structp png_ptr) -+png_get_io_ptr(png_const_structrp png_ptr) - { - if (png_ptr == NULL) - return (NULL); -@@ -570,11 +679,11 @@ - /* Initialize the default input/output functions for the PNG file. If you - * use your own read or write routines, you can call either png_set_read_fn() - * or png_set_write_fn() instead of png_init_io(). If you have defined -- * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't -- * necessarily available. -+ * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a -+ * function of your own because "FILE *" isn't necessarily available. - */ - void PNGAPI --png_init_io(png_structp png_ptr, png_FILE_p fp) -+png_init_io(png_structrp png_ptr, png_FILE_p fp) - { - png_debug(1, "in png_init_io"); - -@@ -585,44 +694,64 @@ - } - # endif - -+#ifdef PNG_SAVE_INT_32_SUPPORTED -+/* The png_save_int_32 function assumes integers are stored in two's -+ * complement format. If this isn't the case, then this routine needs to -+ * be modified to write data in two's complement format. Note that, -+ * the following works correctly even if png_int_32 has more than 32 bits -+ * (compare the more complex code required on read for sign extension.) -+ */ -+void PNGAPI -+png_save_int_32(png_bytep buf, png_int_32 i) -+{ -+ buf[0] = (png_byte)((i >> 24) & 0xff); -+ buf[1] = (png_byte)((i >> 16) & 0xff); -+ buf[2] = (png_byte)((i >> 8) & 0xff); -+ buf[3] = (png_byte)(i & 0xff); -+} -+#endif -+ - # ifdef PNG_TIME_RFC1123_SUPPORTED - /* Convert the supplied time into an RFC 1123 string suitable for use in - * a "Creation Time" or other text-based time string. - */ --png_const_charp PNGAPI --png_convert_to_rfc1123(png_structp png_ptr, png_const_timep ptime) -+int PNGAPI -+png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) - { - static PNG_CONST char short_months[12][4] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - -- if (png_ptr == NULL) -- return (NULL); -+ if (out == NULL) -+ return 0; -+ -+ if (ptime->year > 9999 /* RFC1123 limitation */ || -+ ptime->month == 0 || ptime->month > 12 || -+ ptime->day == 0 || ptime->day > 31 || -+ ptime->hour > 23 || ptime->minute > 59 || -+ ptime->second > 60) -+ return 0; - - { - size_t pos = 0; -- char number_buf[5]; /* enough for a four digit year */ -- --# define APPEND_STRING(string)\ -- pos = png_safecat(png_ptr->time_buffer, sizeof png_ptr->time_buffer,\ -- pos, (string)) -+ char number_buf[5]; /* enough for a four-digit year */ -+ -+# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) - # define APPEND_NUMBER(format, value)\ - APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) --# define APPEND(ch)\ -- if (pos < (sizeof png_ptr->time_buffer)-1)\ -- png_ptr->time_buffer[pos++] = (ch) -- -- APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day % 32); -+# define APPEND(ch) if (pos < 28) out[pos++] = (ch) -+ -+ APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); - APPEND(' '); -- APPEND_STRING(short_months[(ptime->month - 1) % 12]); -+ APPEND_STRING(short_months[(ptime->month - 1)]); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); - APPEND(' '); -- APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour % 24); -+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); - APPEND(':'); -- APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute % 60); -+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); - APPEND(':'); -- APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second % 61); -+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); - APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ - - # undef APPEND -@@ -630,14 +759,37 @@ - # undef APPEND_STRING - } - -- return png_ptr->time_buffer; -+ return 1; - } --# endif /* PNG_TIME_RFC1123_SUPPORTED */ -- --#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ -- -+ -+# if PNG_LIBPNG_VER < 10700 -+/* To do: remove the following from libpng-1.7 */ -+/* Original API that uses a private buffer in png_struct. -+ * Deprecated because it causes png_struct to carry a spurious temporary -+ * buffer (png_struct::time_buffer), better to have the caller pass this in. -+ */ - png_const_charp PNGAPI --png_get_copyright(png_const_structp png_ptr) -+png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime) -+{ -+ if (png_ptr != NULL) -+ { -+ /* The only failure above if png_ptr != NULL is from an invalid ptime */ -+ if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0) -+ png_warning(png_ptr, "Ignoring invalid time value"); -+ -+ else -+ return png_ptr->time_buffer; -+ } -+ -+ return NULL; -+} -+# endif -+# endif /* TIME_RFC1123 */ -+ -+#endif /* READ || WRITE */ -+ -+png_const_charp PNGAPI -+png_get_copyright(png_const_structrp png_ptr) - { - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ - #ifdef PNG_STRING_COPYRIGHT -@@ -645,14 +797,14 @@ - #else - # ifdef __STDC__ - return PNG_STRING_NEWLINE \ -- "libpng version 1.5.4 - July 7, 2011" PNG_STRING_NEWLINE \ -- "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ -+ "libpng version 1.6.16 - December 22, 2014" PNG_STRING_NEWLINE \ -+ "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ - "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ - "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ - PNG_STRING_NEWLINE; - # else -- return "libpng version 1.5.4 - July 7, 2011\ -- Copyright (c) 1998-2011 Glenn Randers-Pehrson\ -+ return "libpng version 1.6.16 - December 22, 2014\ -+ Copyright (c) 1998-2014 Glenn Randers-Pehrson\ - Copyright (c) 1996-1997 Andreas Dilger\ - Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; - # endif -@@ -668,14 +820,14 @@ - * it is guaranteed that png.c uses the correct version of png.h. - */ - png_const_charp PNGAPI --png_get_libpng_ver(png_const_structp png_ptr) -+png_get_libpng_ver(png_const_structrp png_ptr) - { - /* Version of *.c files used when building libpng */ - return png_get_header_ver(png_ptr); - } - - png_const_charp PNGAPI --png_get_header_ver(png_const_structp png_ptr) -+png_get_header_ver(png_const_structrp png_ptr) - { - /* Version of *.h files used when building libpng */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -@@ -683,7 +835,7 @@ - } - - png_const_charp PNGAPI --png_get_header_version(png_const_structp png_ptr) -+png_get_header_version(png_const_structrp png_ptr) - { - /* Returns longer string containing both version and date */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -@@ -698,37 +850,122 @@ - #endif - } - --#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) --# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -+/* NOTE: this routine is not used internally! */ -+/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth -+ * large of png_color. This lets grayscale images be treated as -+ * paletted. Most useful for gamma correction and simplification -+ * of code. This API is not used internally. -+ */ -+void PNGAPI -+png_build_grayscale_palette(int bit_depth, png_colorp palette) -+{ -+ int num_palette; -+ int color_inc; -+ int i; -+ int v; -+ -+ png_debug(1, "in png_do_build_grayscale_palette"); -+ -+ if (palette == NULL) -+ return; -+ -+ switch (bit_depth) -+ { -+ case 1: -+ num_palette = 2; -+ color_inc = 0xff; -+ break; -+ -+ case 2: -+ num_palette = 4; -+ color_inc = 0x55; -+ break; -+ -+ case 4: -+ num_palette = 16; -+ color_inc = 0x11; -+ break; -+ -+ case 8: -+ num_palette = 256; -+ color_inc = 1; -+ break; -+ -+ default: -+ num_palette = 0; -+ color_inc = 0; -+ break; -+ } -+ -+ for (i = 0, v = 0; i < num_palette; i++, v += color_inc) -+ { -+ palette[i].red = (png_byte)v; -+ palette[i].green = (png_byte)v; -+ palette[i].blue = (png_byte)v; -+ } -+} -+#endif -+ -+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - int PNGAPI --png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) -+png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) - { - /* Check chunk_name and return "keep" value if it's on the list, else 0 */ -- int i; -- png_bytep p; -- if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0) -- return 0; -- -- p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5; -- for (i = png_ptr->num_chunk_list; i; i--, p -= 5) -- if (!png_memcmp(chunk_name, p, 4)) -- return ((int)*(p + 4)); -- return 0; -+ png_const_bytep p, p_end; -+ -+ if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0) -+ return PNG_HANDLE_CHUNK_AS_DEFAULT; -+ -+ p_end = png_ptr->chunk_list; -+ p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ -+ -+ /* The code is the fifth byte after each four byte string. Historically this -+ * code was always searched from the end of the list, this is no longer -+ * necessary because the 'set' routine handles duplicate entries correcty. -+ */ -+ do /* num_chunk_list > 0, so at least one */ -+ { -+ p -= 5; -+ -+ if (memcmp(chunk_name, p, 4) == 0) -+ return p[4]; -+ } -+ while (p > p_end); -+ -+ /* This means that known chunks should be processed and unknown chunks should -+ * be handled according to the value of png_ptr->unknown_default; this can be -+ * confusing because, as a result, there are two levels of defaulting for -+ * unknown chunks. -+ */ -+ return PNG_HANDLE_CHUNK_AS_DEFAULT; - } --# endif --#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ -+ -+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ -+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -+int /* PRIVATE */ -+png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) -+{ -+ png_byte chunk_string[5]; -+ -+ PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); -+ return png_handle_as_unknown(png_ptr, chunk_string); -+} -+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ -+#endif /* SET_UNKNOWN_CHUNKS */ - - #ifdef PNG_READ_SUPPORTED - /* This function, added to libpng-1.0.6g, is untested. */ - int PNGAPI --png_reset_zstream(png_structp png_ptr) -+png_reset_zstream(png_structrp png_ptr) - { - if (png_ptr == NULL) - return Z_STREAM_ERROR; - -+ /* WARNING: this resets the window bits to the maximum! */ - return (inflateReset(&png_ptr->zstream)); - } --#endif /* PNG_READ_SUPPORTED */ -+#endif /* READ */ - - /* This function was added to libpng-1.0.7 */ - png_uint_32 PNGAPI -@@ -741,93 +978,1530 @@ - - - #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) --# ifdef PNG_SIZE_T --/* Added at libpng version 1.2.6 */ -- PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); --png_size_t PNGAPI --png_convert_size(size_t size) -+/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. -+ * If it doesn't 'ret' is used to set it to something appropriate, even in cases -+ * like Z_OK or Z_STREAM_END where the error code is apparently a success code. -+ */ -+void /* PRIVATE */ -+png_zstream_error(png_structrp png_ptr, int ret) - { -- if (size > (png_size_t)-1) -- PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */ -- -- return ((png_size_t)size); -+ /* Translate 'ret' into an appropriate error string, priority is given to the -+ * one in zstream if set. This always returns a string, even in cases like -+ * Z_OK or Z_STREAM_END where the error code is a success code. -+ */ -+ if (png_ptr->zstream.msg == NULL) switch (ret) -+ { -+ default: -+ case Z_OK: -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); -+ break; -+ -+ case Z_STREAM_END: -+ /* Normal exit */ -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); -+ break; -+ -+ case Z_NEED_DICT: -+ /* This means the deflate stream did not have a dictionary; this -+ * indicates a bogus PNG. -+ */ -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); -+ break; -+ -+ case Z_ERRNO: -+ /* gz APIs only: should not happen */ -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); -+ break; -+ -+ case Z_STREAM_ERROR: -+ /* internal libpng error */ -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); -+ break; -+ -+ case Z_DATA_ERROR: -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); -+ break; -+ -+ case Z_MEM_ERROR: -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); -+ break; -+ -+ case Z_BUF_ERROR: -+ /* End of input or output; not a problem if the caller is doing -+ * incremental read or write. -+ */ -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); -+ break; -+ -+ case Z_VERSION_ERROR: -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); -+ break; -+ -+ case PNG_UNEXPECTED_ZLIB_RETURN: -+ /* Compile errors here mean that zlib now uses the value co-opted in -+ * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above -+ * and change pngpriv.h. Note that this message is "... return", -+ * whereas the default/Z_OK one is "... return code". -+ */ -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); -+ break; -+ } - } --# endif /* PNG_SIZE_T */ -+ -+/* png_convert_size: a PNGAPI but no longer in png.h, so deleted -+ * at libpng 1.5.5! -+ */ - - /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ --# ifdef PNG_CHECK_cHRM_SUPPORTED -+#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ -+static int -+png_colorspace_check_gamma(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_fixed_point gAMA, int from) -+ /* This is called to check a new gamma value against an existing one. The -+ * routine returns false if the new gamma value should not be written. -+ * -+ * 'from' says where the new gamma value comes from: -+ * -+ * 0: the new gamma value is the libpng estimate for an ICC profile -+ * 1: the new gamma value comes from a gAMA chunk -+ * 2: the new gamma value comes from an sRGB chunk -+ */ -+{ -+ png_fixed_point gtest; -+ -+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && -+ (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || -+ png_gamma_significant(gtest) != 0)) -+ { -+ /* Either this is an sRGB image, in which case the calculated gamma -+ * approximation should match, or this is an image with a profile and the -+ * value libpng calculates for the gamma of the profile does not match the -+ * value recorded in the file. The former, sRGB, case is an error, the -+ * latter is just a warning. -+ */ -+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) -+ { -+ png_chunk_report(png_ptr, "gamma value does not match sRGB", -+ PNG_CHUNK_ERROR); -+ /* Do not overwrite an sRGB value */ -+ return from == 2; -+ } -+ -+ else /* sRGB tag not involved */ -+ { -+ png_chunk_report(png_ptr, "gamma value does not match libpng estimate", -+ PNG_CHUNK_WARNING); -+ return from == 1; -+ } -+ } -+ -+ return 1; -+} -+ -+void /* PRIVATE */ -+png_colorspace_set_gamma(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_fixed_point gAMA) -+{ -+ /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't -+ * occur. Since the fixed point representation is asymetrical it is -+ * possible for 1/gamma to overflow the limit of 21474 and this means the -+ * gamma value must be at least 5/100000 and hence at most 20000.0. For -+ * safety the limits here are a little narrower. The values are 0.00016 to -+ * 6250.0, which are truly ridiculous gamma values (and will produce -+ * displays that are all black or all white.) -+ * -+ * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk -+ * handling code, which only required the value to be >0. -+ */ -+ png_const_charp errmsg; -+ -+ if (gAMA < 16 || gAMA > 625000000) -+ errmsg = "gamma value out of range"; -+ -+# ifdef PNG_READ_gAMA_SUPPORTED -+ /* Allow the application to set the gamma value more than once */ -+ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && -+ (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) -+ errmsg = "duplicate"; -+# endif -+ -+ /* Do nothing if the colorspace is already invalid */ -+ else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) -+ return; -+ -+ else -+ { -+ if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, -+ 1/*from gAMA*/) != 0) -+ { -+ /* Store this gamma value. */ -+ colorspace->gamma = gAMA; -+ colorspace->flags |= -+ (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); -+ } -+ -+ /* At present if the check_gamma test fails the gamma of the colorspace is -+ * not updated however the colorspace is not invalidated. This -+ * corresponds to the case where the existing gamma comes from an sRGB -+ * chunk or profile. An error message has already been output. -+ */ -+ return; -+ } -+ -+ /* Error exit - errmsg has been set. */ -+ colorspace->flags |= PNG_COLORSPACE_INVALID; -+ png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); -+} -+ -+void /* PRIVATE */ -+png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) -+{ -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) -+ { -+ /* Everything is invalid */ -+ info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| -+ PNG_INFO_iCCP); -+ -+# ifdef PNG_COLORSPACE_SUPPORTED -+ /* Clean up the iCCP profile now if it won't be used. */ -+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); -+# else -+ PNG_UNUSED(png_ptr) -+# endif -+ } -+ -+ else -+ { -+# ifdef PNG_COLORSPACE_SUPPORTED -+ /* Leave the INFO_iCCP flag set if the pngset.c code has already set -+ * it; this allows a PNG to contain a profile which matches sRGB and -+ * yet still have that profile retrievable by the application. -+ */ -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) -+ info_ptr->valid |= PNG_INFO_sRGB; -+ -+ else -+ info_ptr->valid &= ~PNG_INFO_sRGB; -+ -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) -+ info_ptr->valid |= PNG_INFO_cHRM; -+ -+ else -+ info_ptr->valid &= ~PNG_INFO_cHRM; -+# endif -+ -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) -+ info_ptr->valid |= PNG_INFO_gAMA; -+ -+ else -+ info_ptr->valid &= ~PNG_INFO_gAMA; -+ } -+} -+ -+#ifdef PNG_READ_SUPPORTED -+void /* PRIVATE */ -+png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) -+{ -+ if (info_ptr == NULL) /* reduce code size; check here not in the caller */ -+ return; -+ -+ info_ptr->colorspace = png_ptr->colorspace; -+ png_colorspace_sync_info(png_ptr, info_ptr); -+} -+#endif -+#endif -+ -+#ifdef PNG_COLORSPACE_SUPPORTED -+/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for -+ * cHRM, as opposed to using chromaticities. These internal APIs return -+ * non-zero on a parameter error. The X, Y and Z values are required to be -+ * positive and less than 1.0. -+ */ -+static int -+png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) -+{ -+ png_int_32 d, dwhite, whiteX, whiteY; -+ -+ d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; -+ if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0) -+ return 1; -+ if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0) -+ return 1; -+ dwhite = d; -+ whiteX = XYZ->red_X; -+ whiteY = XYZ->red_Y; -+ -+ d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; -+ if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0) -+ return 1; -+ if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0) -+ return 1; -+ dwhite += d; -+ whiteX += XYZ->green_X; -+ whiteY += XYZ->green_Y; -+ -+ d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; -+ if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0) -+ return 1; -+ if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0) -+ return 1; -+ dwhite += d; -+ whiteX += XYZ->blue_X; -+ whiteY += XYZ->blue_Y; -+ -+ /* The reference white is simply the sum of the end-point (X,Y,Z) vectors, -+ * thus: -+ */ -+ if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) -+ return 1; -+ if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) -+ return 1; -+ -+ return 0; -+} -+ -+static int -+png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) -+{ -+ png_fixed_point red_inverse, green_inverse, blue_scale; -+ png_fixed_point left, right, denominator; -+ -+ /* Check xy and, implicitly, z. Note that wide gamut color spaces typically -+ * have end points with 0 tristimulus values (these are impossible end -+ * points, but they are used to cover the possible colors.) -+ */ -+ if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; -+ if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; -+ if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; -+ if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; -+ if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; -+ if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; -+ if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; -+ if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1; -+ -+ /* The reverse calculation is more difficult because the original tristimulus -+ * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 -+ * derived values were recorded in the cHRM chunk; -+ * (red,green,blue,white)x(x,y). This loses one degree of freedom and -+ * therefore an arbitrary ninth value has to be introduced to undo the -+ * original transformations. -+ * -+ * Think of the original end-points as points in (X,Y,Z) space. The -+ * chromaticity values (c) have the property: -+ * -+ * C -+ * c = --------- -+ * X + Y + Z -+ * -+ * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the -+ * three chromaticity values (x,y,z) for each end-point obey the -+ * relationship: -+ * -+ * x + y + z = 1 -+ * -+ * This describes the plane in (X,Y,Z) space that intersects each axis at the -+ * value 1.0; call this the chromaticity plane. Thus the chromaticity -+ * calculation has scaled each end-point so that it is on the x+y+z=1 plane -+ * and chromaticity is the intersection of the vector from the origin to the -+ * (X,Y,Z) value with the chromaticity plane. -+ * -+ * To fully invert the chromaticity calculation we would need the three -+ * end-point scale factors, (red-scale, green-scale, blue-scale), but these -+ * were not recorded. Instead we calculated the reference white (X,Y,Z) and -+ * recorded the chromaticity of this. The reference white (X,Y,Z) would have -+ * given all three of the scale factors since: -+ * -+ * color-C = color-c * color-scale -+ * white-C = red-C + green-C + blue-C -+ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale -+ * -+ * But cHRM records only white-x and white-y, so we have lost the white scale -+ * factor: -+ * -+ * white-C = white-c*white-scale -+ * -+ * To handle this the inverse transformation makes an arbitrary assumption -+ * about white-scale: -+ * -+ * Assume: white-Y = 1.0 -+ * Hence: white-scale = 1/white-y -+ * Or: red-Y + green-Y + blue-Y = 1.0 -+ * -+ * Notice the last statement of the assumption gives an equation in three of -+ * the nine values we want to calculate. 8 more equations come from the -+ * above routine as summarised at the top above (the chromaticity -+ * calculation): -+ * -+ * Given: color-x = color-X / (color-X + color-Y + color-Z) -+ * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 -+ * -+ * This is 9 simultaneous equations in the 9 variables "color-C" and can be -+ * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix -+ * determinants, however this is not as bad as it seems because only 28 of -+ * the total of 90 terms in the various matrices are non-zero. Nevertheless -+ * Cramer's rule is notoriously numerically unstable because the determinant -+ * calculation involves the difference of large, but similar, numbers. It is -+ * difficult to be sure that the calculation is stable for real world values -+ * and it is certain that it becomes unstable where the end points are close -+ * together. -+ * -+ * So this code uses the perhaps slightly less optimal but more -+ * understandable and totally obvious approach of calculating color-scale. -+ * -+ * This algorithm depends on the precision in white-scale and that is -+ * (1/white-y), so we can immediately see that as white-y approaches 0 the -+ * accuracy inherent in the cHRM chunk drops off substantially. -+ * -+ * libpng arithmetic: a simple inversion of the above equations -+ * ------------------------------------------------------------ -+ * -+ * white_scale = 1/white-y -+ * white-X = white-x * white-scale -+ * white-Y = 1.0 -+ * white-Z = (1 - white-x - white-y) * white_scale -+ * -+ * white-C = red-C + green-C + blue-C -+ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale -+ * -+ * This gives us three equations in (red-scale,green-scale,blue-scale) where -+ * all the coefficients are now known: -+ * -+ * red-x*red-scale + green-x*green-scale + blue-x*blue-scale -+ * = white-x/white-y -+ * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 -+ * red-z*red-scale + green-z*green-scale + blue-z*blue-scale -+ * = (1 - white-x - white-y)/white-y -+ * -+ * In the last equation color-z is (1 - color-x - color-y) so we can add all -+ * three equations together to get an alternative third: -+ * -+ * red-scale + green-scale + blue-scale = 1/white-y = white-scale -+ * -+ * So now we have a Cramer's rule solution where the determinants are just -+ * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve -+ * multiplication of three coefficients so we can't guarantee to avoid -+ * overflow in the libpng fixed point representation. Using Cramer's rule in -+ * floating point is probably a good choice here, but it's not an option for -+ * fixed point. Instead proceed to simplify the first two equations by -+ * eliminating what is likely to be the largest value, blue-scale: -+ * -+ * blue-scale = white-scale - red-scale - green-scale -+ * -+ * Hence: -+ * -+ * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = -+ * (white-x - blue-x)*white-scale -+ * -+ * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = -+ * 1 - blue-y*white-scale -+ * -+ * And now we can trivially solve for (red-scale,green-scale): -+ * -+ * green-scale = -+ * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale -+ * ----------------------------------------------------------- -+ * green-x - blue-x -+ * -+ * red-scale = -+ * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale -+ * --------------------------------------------------------- -+ * red-y - blue-y -+ * -+ * Hence: -+ * -+ * red-scale = -+ * ( (green-x - blue-x) * (white-y - blue-y) - -+ * (green-y - blue-y) * (white-x - blue-x) ) / white-y -+ * ------------------------------------------------------------------------- -+ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) -+ * -+ * green-scale = -+ * ( (red-y - blue-y) * (white-x - blue-x) - -+ * (red-x - blue-x) * (white-y - blue-y) ) / white-y -+ * ------------------------------------------------------------------------- -+ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) -+ * -+ * Accuracy: -+ * The input values have 5 decimal digits of accuracy. The values are all in -+ * the range 0 < value < 1, so simple products are in the same range but may -+ * need up to 10 decimal digits to preserve the original precision and avoid -+ * underflow. Because we are using a 32-bit signed representation we cannot -+ * match this; the best is a little over 9 decimal digits, less than 10. -+ * -+ * The approach used here is to preserve the maximum precision within the -+ * signed representation. Because the red-scale calculation above uses the -+ * difference between two products of values that must be in the range -1..+1 -+ * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The -+ * factor is irrelevant in the calculation because it is applied to both -+ * numerator and denominator. -+ * -+ * Note that the values of the differences of the products of the -+ * chromaticities in the above equations tend to be small, for example for -+ * the sRGB chromaticities they are: -+ * -+ * red numerator: -0.04751 -+ * green numerator: -0.08788 -+ * denominator: -0.2241 (without white-y multiplication) -+ * -+ * The resultant Y coefficients from the chromaticities of some widely used -+ * color space definitions are (to 15 decimal places): -+ * -+ * sRGB -+ * 0.212639005871510 0.715168678767756 0.072192315360734 -+ * Kodak ProPhoto -+ * 0.288071128229293 0.711843217810102 0.000085653960605 -+ * Adobe RGB -+ * 0.297344975250536 0.627363566255466 0.075291458493998 -+ * Adobe Wide Gamut RGB -+ * 0.258728243040113 0.724682314948566 0.016589442011321 -+ */ -+ /* By the argument, above overflow should be impossible here. The return -+ * value of 2 indicates an internal error to the caller. -+ */ -+ if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0) -+ return 2; -+ if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0) -+ return 2; -+ denominator = left - right; -+ -+ /* Now find the red numerator. */ -+ if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) -+ return 2; -+ if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0) -+ return 2; -+ -+ /* Overflow is possible here and it indicates an extreme set of PNG cHRM -+ * chunk values. This calculation actually returns the reciprocal of the -+ * scale value because this allows us to delay the multiplication of white-y -+ * into the denominator, which tends to produce a small number. -+ */ -+ if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 || -+ red_inverse <= xy->whitey /* r+g+b scales = white scale */) -+ return 1; -+ -+ /* Similarly for green_inverse: */ -+ if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0) -+ return 2; -+ if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) -+ return 2; -+ if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 || -+ green_inverse <= xy->whitey) -+ return 1; -+ -+ /* And the blue scale, the checks above guarantee this can't overflow but it -+ * can still produce 0 for extreme cHRM values. -+ */ -+ blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - -+ png_reciprocal(green_inverse); -+ if (blue_scale <= 0) -+ return 1; -+ -+ -+ /* And fill in the png_XYZ: */ -+ if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, -+ red_inverse) == 0) -+ return 1; -+ -+ if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, -+ green_inverse) == 0) -+ return 1; -+ -+ if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, -+ PNG_FP_1) == 0) -+ return 1; -+ -+ return 0; /*success*/ -+} -+ -+static int -+png_XYZ_normalize(png_XYZ *XYZ) -+{ -+ png_int_32 Y; -+ -+ if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 || -+ XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 || -+ XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0) -+ return 1; -+ -+ /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. -+ * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore -+ * relying on addition of two positive values producing a negative one is not -+ * safe. -+ */ -+ Y = XYZ->red_Y; -+ if (0x7fffffff - Y < XYZ->green_X) -+ return 1; -+ Y += XYZ->green_Y; -+ if (0x7fffffff - Y < XYZ->blue_X) -+ return 1; -+ Y += XYZ->blue_Y; -+ -+ if (Y != PNG_FP_1) -+ { -+ if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0) -+ return 1; -+ -+ if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0) -+ return 1; -+ -+ if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0) -+ return 1; -+ if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int -+png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) -+{ -+ /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ -+ if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || -+ PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || -+ PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || -+ PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || -+ PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || -+ PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || -+ PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || -+ PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) -+ return 0; -+ return 1; -+} -+ -+/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM -+ * chunk chromaticities. Earlier checks used to simply look for the overflow -+ * condition (where the determinant of the matrix to solve for XYZ ends up zero -+ * because the chromaticity values are not all distinct.) Despite this it is -+ * theoretically possible to produce chromaticities that are apparently valid -+ * but that rapidly degrade to invalid, potentially crashing, sets because of -+ * arithmetic inaccuracies when calculations are performed on them. The new -+ * check is to round-trip xy -> XYZ -> xy and then check that the result is -+ * within a small percentage of the original. -+ */ -+static int -+png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) -+{ -+ int result; -+ png_xy xy_test; -+ -+ /* As a side-effect this routine also returns the XYZ endpoints. */ -+ result = png_XYZ_from_xy(XYZ, xy); -+ if (result != 0) -+ return result; -+ -+ result = png_xy_from_XYZ(&xy_test, XYZ); -+ if (result != 0) -+ return result; -+ -+ if (png_colorspace_endpoints_match(xy, &xy_test, -+ 5/*actually, the math is pretty accurate*/) != 0) -+ return 0; -+ -+ /* Too much slip */ -+ return 1; -+} -+ -+/* This is the check going the other way. The XYZ is modified to normalize it -+ * (another side-effect) and the xy chromaticities are returned. -+ */ -+static int -+png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) -+{ -+ int result; -+ png_XYZ XYZtemp; -+ -+ result = png_XYZ_normalize(XYZ); -+ if (result != 0) -+ return result; -+ -+ result = png_xy_from_XYZ(xy, XYZ); -+ if (result != 0) -+ return result; -+ -+ XYZtemp = *XYZ; -+ return png_colorspace_check_xy(&XYZtemp, xy); -+} -+ -+/* Used to check for an endpoint match against sRGB */ -+static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ -+{ -+ /* color x y */ -+ /* red */ 64000, 33000, -+ /* green */ 30000, 60000, -+ /* blue */ 15000, 6000, -+ /* white */ 31270, 32900 -+}; -+ -+static int -+png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, -+ int preferred) -+{ -+ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) -+ return 0; -+ -+ /* The consistency check is performed on the chromaticities; this factors out -+ * variations because of the normalization (or not) of the end point Y -+ * values. -+ */ -+ if (preferred < 2 && -+ (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) -+ { -+ /* The end points must be reasonably close to any we already have. The -+ * following allows an error of up to +/-.001 -+ */ -+ if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, -+ 100) == 0) -+ { -+ colorspace->flags |= PNG_COLORSPACE_INVALID; -+ png_benign_error(png_ptr, "inconsistent chromaticities"); -+ return 0; /* failed */ -+ } -+ -+ /* Only overwrite with preferred values */ -+ if (preferred == 0) -+ return 1; /* ok, but no change */ -+ } -+ -+ colorspace->end_points_xy = *xy; -+ colorspace->end_points_XYZ = *XYZ; -+ colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; -+ -+ /* The end points are normally quoted to two decimal digits, so allow +/-0.01 -+ * on this test. -+ */ -+ if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) -+ colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; -+ -+ else -+ colorspace->flags &= PNG_COLORSPACE_CANCEL( -+ PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); -+ -+ return 2; /* ok and changed */ -+} - - int /* PRIVATE */ --png_check_cHRM_fixed(png_structp png_ptr, -- png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, -- png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, -- png_fixed_point blue_x, png_fixed_point blue_y) -+png_colorspace_set_chromaticities(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, const png_xy *xy, int preferred) - { -- int ret = 1; -- unsigned long xy_hi,xy_lo,yx_hi,yx_lo; -- -- png_debug(1, "in function png_check_cHRM_fixed"); -- -- if (png_ptr == NULL) -+ /* We must check the end points to ensure they are reasonable - in the past -+ * color management systems have crashed as a result of getting bogus -+ * colorant values, while this isn't the fault of libpng it is the -+ * responsibility of libpng because PNG carries the bomb and libpng is in a -+ * position to protect against it. -+ */ -+ png_XYZ XYZ; -+ -+ switch (png_colorspace_check_xy(&XYZ, xy)) -+ { -+ case 0: /* success */ -+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, -+ preferred); -+ -+ case 1: -+ /* We can't invert the chromaticities so we can't produce value XYZ -+ * values. Likely as not a color management system will fail too. -+ */ -+ colorspace->flags |= PNG_COLORSPACE_INVALID; -+ png_benign_error(png_ptr, "invalid chromaticities"); -+ break; -+ -+ default: -+ /* libpng is broken; this should be a warning but if it happens we -+ * want error reports so for the moment it is an error. -+ */ -+ colorspace->flags |= PNG_COLORSPACE_INVALID; -+ png_error(png_ptr, "internal error checking chromaticities"); -+ break; -+ } -+ -+ return 0; /* failed */ -+} -+ -+int /* PRIVATE */ -+png_colorspace_set_endpoints(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) -+{ -+ png_XYZ XYZ = *XYZ_in; -+ png_xy xy; -+ -+ switch (png_colorspace_check_XYZ(&xy, &XYZ)) -+ { -+ case 0: -+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, -+ preferred); -+ -+ case 1: -+ /* End points are invalid. */ -+ colorspace->flags |= PNG_COLORSPACE_INVALID; -+ png_benign_error(png_ptr, "invalid end points"); -+ break; -+ -+ default: -+ colorspace->flags |= PNG_COLORSPACE_INVALID; -+ png_error(png_ptr, "internal error checking chromaticities"); -+ break; -+ } -+ -+ return 0; /* failed */ -+} -+ -+#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) -+/* Error message generation */ -+static char -+png_icc_tag_char(png_uint_32 byte) -+{ -+ byte &= 0xff; -+ if (byte >= 32 && byte <= 126) -+ return (char)byte; -+ else -+ return '?'; -+} -+ -+static void -+png_icc_tag_name(char *name, png_uint_32 tag) -+{ -+ name[0] = '\''; -+ name[1] = png_icc_tag_char(tag >> 24); -+ name[2] = png_icc_tag_char(tag >> 16); -+ name[3] = png_icc_tag_char(tag >> 8); -+ name[4] = png_icc_tag_char(tag ); -+ name[5] = '\''; -+} -+ -+static int -+is_ICC_signature_char(png_alloc_size_t it) -+{ -+ return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || -+ (it >= 97 && it <= 122); -+} -+ -+static int -+is_ICC_signature(png_alloc_size_t it) -+{ -+ return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && -+ is_ICC_signature_char((it >> 16) & 0xff) && -+ is_ICC_signature_char((it >> 8) & 0xff) && -+ is_ICC_signature_char(it & 0xff); -+} -+ -+static int -+png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, -+ png_const_charp name, png_alloc_size_t value, png_const_charp reason) -+{ -+ size_t pos; -+ char message[196]; /* see below for calculation */ -+ -+ if (colorspace != NULL) -+ colorspace->flags |= PNG_COLORSPACE_INVALID; -+ -+ pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ -+ pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ -+ pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ -+ if (is_ICC_signature(value) != 0) -+ { -+ /* So 'value' is at most 4 bytes and the following cast is safe */ -+ png_icc_tag_name(message+pos, (png_uint_32)value); -+ pos += 6; /* total +8; less than the else clause */ -+ message[pos++] = ':'; -+ message[pos++] = ' '; -+ } -+# ifdef PNG_WARNINGS_SUPPORTED -+ else -+ { -+ char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ -+ -+ pos = png_safecat(message, (sizeof message), pos, -+ png_format_number(number, number+(sizeof number), -+ PNG_NUMBER_FORMAT_x, value)); -+ pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ -+ } -+# endif -+ /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ -+ pos = png_safecat(message, (sizeof message), pos, reason); -+ PNG_UNUSED(pos) -+ -+ /* This is recoverable, but make it unconditionally an app_error on write to -+ * avoid writing invalid ICC profiles into PNG files (i.e., we handle them -+ * on read, with a warning, but on write unless the app turns off -+ * application errors the PNG won't be written.) -+ */ -+ png_chunk_report(png_ptr, message, -+ (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); -+ -+ return 0; -+} -+#endif /* sRGB || iCCP */ -+ -+#ifdef PNG_sRGB_SUPPORTED -+int /* PRIVATE */ -+png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, -+ int intent) -+{ -+ /* sRGB sets known gamma, end points and (from the chunk) intent. */ -+ /* IMPORTANT: these are not necessarily the values found in an ICC profile -+ * because ICC profiles store values adapted to a D50 environment; it is -+ * expected that the ICC profile mediaWhitePointTag will be D50; see the -+ * checks and code elsewhere to understand this better. -+ * -+ * These XYZ values, which are accurate to 5dp, produce rgb to gray -+ * coefficients of (6968,23435,2366), which are reduced (because they add up -+ * to 32769 not 32768) to (6968,23434,2366). These are the values that -+ * libpng has traditionally used (and are the best values given the 15bit -+ * algorithm used by the rgb to gray code.) -+ */ -+ static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ -+ { -+ /* color X Y Z */ -+ /* red */ 41239, 21264, 1933, -+ /* green */ 35758, 71517, 11919, -+ /* blue */ 18048, 7219, 95053 -+ }; -+ -+ /* Do nothing if the colorspace is already invalidated. */ -+ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - -- /* (x,y,z) values are first limited to 0..100000 (PNG_FP_1), the white -- * y must also be greater than 0. To test for the upper limit calculate -- * (PNG_FP_1-y) - x must be <= to this for z to be >= 0 (and the expression -- * cannot overflow.) At this point we know x and y are >= 0 and (x+y) is -- * <= PNG_FP_1. The previous test on PNG_MAX_UINT_31 is removed because it -- * pointless (and it produces compiler warnings!) -+ /* Check the intent, then check for existing settings. It is valid for the -+ * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must -+ * be consistent with the correct values. If, however, this function is -+ * called below because an iCCP chunk matches sRGB then it is quite -+ * conceivable that an older app recorded incorrect gAMA and cHRM because of -+ * an incorrect calculation based on the values in the profile - this does -+ * *not* invalidate the profile (though it still produces an error, which can -+ * be ignored.) - */ -- if (white_x < 0 || white_y <= 0 || -- red_x < 0 || red_y < 0 || -- green_x < 0 || green_y < 0 || -- blue_x < 0 || blue_y < 0) -+ if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) -+ return png_icc_profile_error(png_ptr, colorspace, "sRGB", -+ (unsigned)intent, "invalid sRGB rendering intent"); -+ -+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && -+ colorspace->rendering_intent != intent) -+ return png_icc_profile_error(png_ptr, colorspace, "sRGB", -+ (unsigned)intent, "inconsistent rendering intents"); -+ -+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) - { -- png_warning(png_ptr, -- "Ignoring attempt to set negative chromaticity value"); -- ret = 0; -+ png_benign_error(png_ptr, "duplicate sRGB information ignored"); -+ return 0; - } -- /* And (x+y) must be <= PNG_FP_1 (so z is >= 0) */ -- if (white_x > PNG_FP_1 - white_y) -+ -+ /* If the standard sRGB cHRM chunk does not match the one from the PNG file -+ * warn but overwrite the value with the correct one. -+ */ -+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && -+ !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, -+ 100)) -+ png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", -+ PNG_CHUNK_ERROR); -+ -+ /* This check is just done for the error reporting - the routine always -+ * returns true when the 'from' argument corresponds to sRGB (2). -+ */ -+ (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, -+ 2/*from sRGB*/); -+ -+ /* intent: bugs in GCC force 'int' to be used as the parameter type. */ -+ colorspace->rendering_intent = (png_uint_16)intent; -+ colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; -+ -+ /* endpoints */ -+ colorspace->end_points_xy = sRGB_xy; -+ colorspace->end_points_XYZ = sRGB_XYZ; -+ colorspace->flags |= -+ (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); -+ -+ /* gamma */ -+ colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; -+ colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; -+ -+ /* Finally record that we have an sRGB profile */ -+ colorspace->flags |= -+ (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); -+ -+ return 1; /* set */ -+} -+#endif /* sRGB */ -+ -+#ifdef PNG_iCCP_SUPPORTED -+/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value -+ * is XYZ(0.9642,1.0,0.8249), which scales to: -+ * -+ * (63189.8112, 65536, 54060.6464) -+ */ -+static const png_byte D50_nCIEXYZ[12] = -+ { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; -+ -+int /* PRIVATE */ -+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, -+ png_const_charp name, png_uint_32 profile_length) -+{ -+ if (profile_length < 132) -+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length, -+ "too short"); -+ -+ return 1; -+} -+ -+int /* PRIVATE */ -+png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, -+ png_const_charp name, png_uint_32 profile_length, -+ png_const_bytep profile/* first 132 bytes only */, int color_type) -+{ -+ png_uint_32 temp; -+ -+ /* Length check; this cannot be ignored in this code because profile_length -+ * is used later to check the tag table, so even if the profile seems over -+ * long profile_length from the caller must be correct. The caller can fix -+ * this up on read or write by just passing in the profile header length. -+ */ -+ temp = png_get_uint_32(profile); -+ if (temp != profile_length) -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "length does not match profile"); -+ -+ temp = (png_uint_32) (*(profile+8)); -+ if (temp > 3 && (profile_length & 3)) -+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length, -+ "invalid length"); -+ -+ temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ -+ if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ -+ profile_length < 132+12*temp) /* truncated tag table */ -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "tag count too large"); -+ -+ /* The 'intent' must be valid or we can't store it, ICC limits the intent to -+ * 16 bits. -+ */ -+ temp = png_get_uint_32(profile+64); -+ if (temp >= 0xffff) /* The ICC limit */ -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "invalid rendering intent"); -+ -+ /* This is just a warning because the profile may be valid in future -+ * versions. -+ */ -+ if (temp >= PNG_sRGB_INTENT_LAST) -+ (void)png_icc_profile_error(png_ptr, NULL, name, temp, -+ "intent outside defined range"); -+ -+ /* At this point the tag table can't be checked because it hasn't necessarily -+ * been loaded; however, various header fields can be checked. These checks -+ * are for values permitted by the PNG spec in an ICC profile; the PNG spec -+ * restricts the profiles that can be passed in an iCCP chunk (they must be -+ * appropriate to processing PNG data!) -+ */ -+ -+ /* Data checks (could be skipped). These checks must be independent of the -+ * version number; however, the version number doesn't accomodate changes in -+ * the header fields (just the known tags and the interpretation of the -+ * data.) -+ */ -+ temp = png_get_uint_32(profile+36); /* signature 'ascp' */ -+ if (temp != 0x61637370) -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "invalid signature"); -+ -+ /* Currently the PCS illuminant/adopted white point (the computational -+ * white point) are required to be D50, -+ * however the profile contains a record of the illuminant so perhaps ICC -+ * expects to be able to change this in the future (despite the rationale in -+ * the introduction for using a fixed PCS adopted white.) Consequently the -+ * following is just a warning. -+ */ -+ if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) -+ (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, -+ "PCS illuminant is not D50"); -+ -+ /* The PNG spec requires this: -+ * "If the iCCP chunk is present, the image samples conform to the colour -+ * space represented by the embedded ICC profile as defined by the -+ * International Color Consortium [ICC]. The colour space of the ICC profile -+ * shall be an RGB colour space for colour images (PNG colour types 2, 3, and -+ * 6), or a greyscale colour space for greyscale images (PNG colour types 0 -+ * and 4)." -+ * -+ * This checking code ensures the embedded profile (on either read or write) -+ * conforms to the specification requirements. Notice that an ICC 'gray' -+ * color-space profile contains the information to transform the monochrome -+ * data to XYZ or L*a*b (according to which PCS the profile uses) and this -+ * should be used in preference to the standard libpng K channel replication -+ * into R, G and B channels. -+ * -+ * Previously it was suggested that an RGB profile on grayscale data could be -+ * handled. However it it is clear that using an RGB profile in this context -+ * must be an error - there is no specification of what it means. Thus it is -+ * almost certainly more correct to ignore the profile. -+ */ -+ temp = png_get_uint_32(profile+16); /* data colour space field */ -+ switch (temp) - { -- png_warning(png_ptr, "Invalid cHRM white point"); -- ret = 0; -+ case 0x52474220: /* 'RGB ' */ -+ if ((color_type & PNG_COLOR_MASK_COLOR) == 0) -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "RGB color space not permitted on grayscale PNG"); -+ break; -+ -+ case 0x47524159: /* 'GRAY' */ -+ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "Gray color space not permitted on RGB PNG"); -+ break; -+ -+ default: -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "invalid ICC profile color space"); - } - -- if (red_x > PNG_FP_1 - red_y) -+ /* It is up to the application to check that the profile class matches the -+ * application requirements; the spec provides no guidance, but it's pretty -+ * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer -+ * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these -+ * cases. Issue an error for device link or abstract profiles - these don't -+ * contain the records necessary to transform the color-space to anything -+ * other than the target device (and not even that for an abstract profile). -+ * Profiles of these classes may not be embedded in images. -+ */ -+ temp = png_get_uint_32(profile+12); /* profile/device class */ -+ switch (temp) - { -- png_warning(png_ptr, "Invalid cHRM red point"); -- ret = 0; -+ case 0x73636E72: /* 'scnr' */ -+ case 0x6D6E7472: /* 'mntr' */ -+ case 0x70727472: /* 'prtr' */ -+ case 0x73706163: /* 'spac' */ -+ /* All supported */ -+ break; -+ -+ case 0x61627374: /* 'abst' */ -+ /* May not be embedded in an image */ -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "invalid embedded Abstract ICC profile"); -+ -+ case 0x6C696E6B: /* 'link' */ -+ /* DeviceLink profiles cannot be interpreted in a non-device specific -+ * fashion, if an app uses the AToB0Tag in the profile the results are -+ * undefined unless the result is sent to the intended device, -+ * therefore a DeviceLink profile should not be found embedded in a -+ * PNG. -+ */ -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "unexpected DeviceLink ICC profile class"); -+ -+ case 0x6E6D636C: /* 'nmcl' */ -+ /* A NamedColor profile is also device specific, however it doesn't -+ * contain an AToB0 tag that is open to misinterpretation. Almost -+ * certainly it will fail the tests below. -+ */ -+ (void)png_icc_profile_error(png_ptr, NULL, name, temp, -+ "unexpected NamedColor ICC profile class"); -+ break; -+ -+ default: -+ /* To allow for future enhancements to the profile accept unrecognized -+ * profile classes with a warning, these then hit the test below on the -+ * tag content to ensure they are backward compatible with one of the -+ * understood profiles. -+ */ -+ (void)png_icc_profile_error(png_ptr, NULL, name, temp, -+ "unrecognized ICC profile class"); -+ break; - } - -- if (green_x > PNG_FP_1 - green_y) -+ /* For any profile other than a device link one the PCS must be encoded -+ * either in XYZ or Lab. -+ */ -+ temp = png_get_uint_32(profile+20); -+ switch (temp) - { -- png_warning(png_ptr, "Invalid cHRM green point"); -- ret = 0; -+ case 0x58595A20: /* 'XYZ ' */ -+ case 0x4C616220: /* 'Lab ' */ -+ break; -+ -+ default: -+ return png_icc_profile_error(png_ptr, colorspace, name, temp, -+ "unexpected ICC PCS encoding"); - } - -- if (blue_x > PNG_FP_1 - blue_y) -+ return 1; -+} -+ -+int /* PRIVATE */ -+png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, -+ png_const_charp name, png_uint_32 profile_length, -+ png_const_bytep profile /* header plus whole tag table */) -+{ -+ png_uint_32 tag_count = png_get_uint_32(profile+128); -+ png_uint_32 itag; -+ png_const_bytep tag = profile+132; /* The first tag */ -+ -+ /* First scan all the tags in the table and add bits to the icc_info value -+ * (temporarily in 'tags'). -+ */ -+ for (itag=0; itag < tag_count; ++itag, tag += 12) - { -- png_warning(png_ptr, "Invalid cHRM blue point"); -- ret = 0; -+ png_uint_32 tag_id = png_get_uint_32(tag+0); -+ png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ -+ png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ -+ -+ /* The ICC specification does not exclude zero length tags, therefore the -+ * start might actually be anywhere if there is no data, but this would be -+ * a clear abuse of the intent of the standard so the start is checked for -+ * being in range. All defined tag types have an 8 byte header - a 4 byte -+ * type signature then 0. -+ */ -+ if ((tag_start & 3) != 0) -+ { -+ /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is -+ * only a warning here because libpng does not care about the -+ * alignment. -+ */ -+ (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, -+ "ICC profile tag start not a multiple of 4"); -+ } -+ -+ /* This is a hard error; potentially it can cause read outside the -+ * profile. -+ */ -+ if (tag_start > profile_length || tag_length > profile_length - tag_start) -+ return png_icc_profile_error(png_ptr, colorspace, name, tag_id, -+ "ICC profile tag outside profile"); - } - -- png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo); -- png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); -- -- if (xy_hi == yx_hi && xy_lo == yx_lo) -+ return 1; /* success, maybe with warnings */ -+} -+ -+#if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 -+/* Information about the known ICC sRGB profiles */ -+static const struct -+{ -+ png_uint_32 adler, crc, length; -+ png_uint_32 md5[4]; -+ png_byte have_md5; -+ png_byte is_broken; -+ png_uint_16 intent; -+ -+# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) -+# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ -+ { adler, crc, length, md5, broke, intent }, -+ -+} png_sRGB_checks[] = -+{ -+ /* This data comes from contrib/tools/checksum-icc run on downloads of -+ * all four ICC sRGB profiles from www.color.org. -+ */ -+ /* adler32, crc32, MD5[4], intent, date, length, file-name */ -+ PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, -+ PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, -+ "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") -+ -+ /* ICC sRGB v2 perceptual no black-compensation: */ -+ PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, -+ PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, -+ "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") -+ -+ PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, -+ PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, -+ "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") -+ -+ /* ICC sRGB v4 perceptual */ -+ PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, -+ PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, -+ "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") -+ -+ /* The following profiles have no known MD5 checksum. If there is a match -+ * on the (empty) MD5 the other fields are used to attempt a match and -+ * a warning is produced. The first two of these profiles have a 'cprt' tag -+ * which suggests that they were also made by Hewlett Packard. -+ */ -+ PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, -+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, -+ "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") -+ -+ /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not -+ * match the D50 PCS illuminant in the header (it is in fact the D65 values, -+ * so the white point is recorded as the un-adapted value.) The profiles -+ * below only differ in one byte - the intent - and are basically the same as -+ * the previous profile except for the mediaWhitePointTag error and a missing -+ * chromaticAdaptationTag. -+ */ -+ PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, -+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, -+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") -+ -+ PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, -+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, -+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") -+}; -+ -+static int -+png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, -+ png_const_bytep profile, uLong adler) -+{ -+ /* The quick check is to verify just the MD5 signature and trust the -+ * rest of the data. Because the profile has already been verified for -+ * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' -+ * field too, so if the profile has been edited with an intent not defined -+ * by sRGB (but maybe defined by a later ICC specification) the read of -+ * the profile will fail at that point. -+ */ -+ -+ png_uint_32 length = 0; -+ png_uint_32 intent = 0x10000; /* invalid */ -+#if PNG_sRGB_PROFILE_CHECKS > 1 -+ uLong crc = 0; /* the value for 0 length data */ -+#endif -+ unsigned int i; -+ -+#ifdef PNG_SET_OPTION_SUPPORTED -+ /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */ -+ if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) == -+ PNG_OPTION_ON) -+ return 0; -+#endif -+ -+ for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) - { -- png_warning(png_ptr, -- "Ignoring attempt to set cHRM RGB triangle with zero area"); -- ret = 0; -+ if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && -+ png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && -+ png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && -+ png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) -+ { -+ /* This may be one of the old HP profiles without an MD5, in that -+ * case we can only use the length and Adler32 (note that these -+ * are not used by default if there is an MD5!) -+ */ -+# if PNG_sRGB_PROFILE_CHECKS == 0 -+ if (png_sRGB_checks[i].have_md5 != 0) -+ return 1+png_sRGB_checks[i].is_broken; -+# endif -+ -+ /* Profile is unsigned or more checks have been configured in. */ -+ if (length == 0) -+ { -+ length = png_get_uint_32(profile); -+ intent = png_get_uint_32(profile+64); -+ } -+ -+ /* Length *and* intent must match */ -+ if (length == png_sRGB_checks[i].length && -+ intent == png_sRGB_checks[i].intent) -+ { -+ /* Now calculate the adler32 if not done already. */ -+ if (adler == 0) -+ { -+ adler = adler32(0, NULL, 0); -+ adler = adler32(adler, profile, length); -+ } -+ -+ if (adler == png_sRGB_checks[i].adler) -+ { -+ /* These basic checks suggest that the data has not been -+ * modified, but if the check level is more than 1 perform -+ * our own crc32 checksum on the data. -+ */ -+# if PNG_sRGB_PROFILE_CHECKS > 1 -+ if (crc == 0) -+ { -+ crc = crc32(0, NULL, 0); -+ crc = crc32(crc, profile, length); -+ } -+ -+ /* So this check must pass for the 'return' below to happen. -+ */ -+ if (crc == png_sRGB_checks[i].crc) -+# endif -+ { -+ if (png_sRGB_checks[i].is_broken != 0) -+ { -+ /* These profiles are known to have bad data that may cause -+ * problems if they are used, therefore attempt to -+ * discourage their use, skip the 'have_md5' warning below, -+ * which is made irrelevant by this error. -+ */ -+ png_chunk_report(png_ptr, "known incorrect sRGB profile", -+ PNG_CHUNK_ERROR); -+ } -+ -+ /* Warn that this being done; this isn't even an error since -+ * the profile is perfectly valid, but it would be nice if -+ * people used the up-to-date ones. -+ */ -+ else if (png_sRGB_checks[i].have_md5 == 0) -+ { -+ png_chunk_report(png_ptr, "out-of-date sRGB profile with" -+ " no signature", -+ PNG_CHUNK_WARNING); -+ } -+ -+ return 1+png_sRGB_checks[i].is_broken; -+ } -+ } -+ -+# if PNG_sRGB_PROFILE_CHECKS > 0 -+ /* The signature matched, but the profile had been changed in some -+ * way. This probably indicates a data error or uninformed hacking. -+ * Fall through to "no match". -+ */ -+ png_chunk_report(png_ptr, "Not recognizing known sRGB profile that" -+ " has been edited", -+ PNG_CHUNK_WARNING); -+ break; -+# endif -+ } -+ } - } - -- return ret; -+ return 0; /* no match */ - } --# endif /* PNG_CHECK_cHRM_SUPPORTED */ -- -+#endif -+ -+#ifdef PNG_sRGB_SUPPORTED - void /* PRIVATE */ --png_check_IHDR(png_structp png_ptr, -+png_icc_set_sRGB(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_const_bytep profile, uLong adler) -+{ -+ /* Is this profile one of the known ICC sRGB profiles? If it is, just set -+ * the sRGB information. -+ */ -+#if PNG_sRGB_PROFILE_CHECKS >= 0 -+ if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) -+#endif -+ (void)png_colorspace_set_sRGB(png_ptr, colorspace, -+ (int)/*already checked*/png_get_uint_32(profile+64)); -+} -+#endif /* READ_sRGB */ -+ -+int /* PRIVATE */ -+png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, -+ png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, -+ int color_type) -+{ -+ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) -+ return 0; -+ -+ if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && -+ png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, -+ color_type) != 0 && -+ png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, -+ profile) != 0) -+ { -+# ifdef PNG_sRGB_SUPPORTED -+ /* If no sRGB support, don't try storing sRGB information */ -+ png_icc_set_sRGB(png_ptr, colorspace, profile, 0); -+# endif -+ return 1; -+ } -+ -+ /* Failure case */ -+ return 0; -+} -+#endif /* iCCP */ -+ -+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -+void /* PRIVATE */ -+png_colorspace_set_rgb_coefficients(png_structrp png_ptr) -+{ -+ /* Set the rgb_to_gray coefficients from the colorspace. */ -+ if (png_ptr->rgb_to_gray_coefficients_set == 0 && -+ (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) -+ { -+ /* png_set_background has not been called, get the coefficients from the Y -+ * values of the colorspace colorants. -+ */ -+ png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; -+ png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; -+ png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; -+ png_fixed_point total = r+g+b; -+ -+ if (total > 0 && -+ r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && -+ g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && -+ b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && -+ r+g+b <= 32769) -+ { -+ /* We allow 0 coefficients here. r+g+b may be 32769 if two or -+ * all of the coefficients were rounded up. Handle this by -+ * reducing the *largest* coefficient by 1; this matches the -+ * approach used for the default coefficients in pngrtran.c -+ */ -+ int add = 0; -+ -+ if (r+g+b > 32768) -+ add = -1; -+ else if (r+g+b < 32768) -+ add = 1; -+ -+ if (add != 0) -+ { -+ if (g >= r && g >= b) -+ g += add; -+ else if (r >= g && r >= b) -+ r += add; -+ else -+ b += add; -+ } -+ -+ /* Check for an internal error. */ -+ if (r+g+b != 32768) -+ png_error(png_ptr, -+ "internal error handling cHRM coefficients"); -+ -+ else -+ { -+ png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; -+ png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; -+ } -+ } -+ -+ /* This is a png_error at present even though it could be ignored - -+ * it should never happen, but it is important that if it does, the -+ * bug is fixed. -+ */ -+ else -+ png_error(png_ptr, "internal error handling cHRM->XYZ"); -+ } -+} -+#endif -+ -+#endif /* COLORSPACE */ -+ -+#ifdef __GNUC__ -+/* This exists solely to work round a warning from GNU C. */ -+static int /* PRIVATE */ -+png_gt(size_t a, size_t b) -+{ -+ return a > b; -+} -+#else -+# define png_gt(a,b) ((a) > (b)) -+#endif -+ -+void /* PRIVATE */ -+png_check_IHDR(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -@@ -840,53 +2514,68 @@ - png_warning(png_ptr, "Image width is zero in IHDR"); - error = 1; - } -+ else if (width > PNG_UINT_31_MAX) -+ { -+ png_warning(png_ptr, "Invalid image width in IHDR"); -+ error = 1; -+ } -+ -+ else if (png_gt(width, -+ (PNG_SIZE_MAX >> 3) /* 8-byte RGBA pixels */ -+ - 48 /* big_row_buf hack */ -+ - 1 /* filter byte */ -+ - 7*8 /* rounding width to multiple of 8 pix */ -+ - 8)) /* extra max_pixel_depth pad */ -+ { -+ /* The size of the row must be within the limits of this architecture. -+ * Because the read code can perform arbitrary transformations the -+ * maximum size is checked here. Because the code in png_read_start_row -+ * adds extra space "for safety's sake" in several places a conservative -+ * limit is used here. -+ * -+ * NOTE: it would be far better to check the size that is actually used, -+ * but the effect in the real world is minor and the changes are more -+ * extensive, therefore much more dangerous and much more difficult to -+ * write in a way that avoids compiler warnings. -+ */ -+ png_warning(png_ptr, "Image width is too large for this architecture"); -+ error = 1; -+ } -+ else -+ { -+# ifdef PNG_SET_USER_LIMITS_SUPPORTED -+ if (width > png_ptr->user_width_max) -+# else -+ if (width > PNG_USER_WIDTH_MAX) -+# endif -+ { -+ png_warning(png_ptr, "Image width exceeds user limit in IHDR"); -+ error = 1; -+ } -+ } - - if (height == 0) - { - png_warning(png_ptr, "Image height is zero in IHDR"); - error = 1; - } -- --# ifdef PNG_SET_USER_LIMITS_SUPPORTED -- if (width > png_ptr->user_width_max) -- --# else -- if (width > PNG_USER_WIDTH_MAX) --# endif -- { -- png_warning(png_ptr, "Image width exceeds user limit in IHDR"); -- error = 1; -- } -- --# ifdef PNG_SET_USER_LIMITS_SUPPORTED -- if (height > png_ptr->user_height_max) --# else -- if (height > PNG_USER_HEIGHT_MAX) --# endif -- { -- png_warning(png_ptr, "Image height exceeds user limit in IHDR"); -- error = 1; -- } -- -- if (width > PNG_UINT_31_MAX) -- { -- png_warning(png_ptr, "Invalid image width in IHDR"); -- error = 1; -- } -- -- if (height > PNG_UINT_31_MAX) -+ else if (height > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image height in IHDR"); - error = 1; - } -- -- if (width > (PNG_UINT_32_MAX -- >> 3) /* 8-byte RGBA pixels */ -- - 48 /* bigrowbuf hack */ -- - 1 /* filter byte */ -- - 7*8 /* rounding of width to multiple of 8 pixels */ -- - 8) /* extra max_pixel_depth pad */ -- png_warning(png_ptr, "Width is too large for libpng to process pixels"); -+ else -+ { -+# ifdef PNG_SET_USER_LIMITS_SUPPORTED -+ if (height > png_ptr->user_height_max) -+# else -+ if (height > PNG_USER_HEIGHT_MAX) -+# endif -+ { -+ png_warning(png_ptr, "Image height exceeds user limit in IHDR"); -+ error = 1; -+ } -+ } - - /* Check other values */ - if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && -@@ -934,13 +2623,13 @@ - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ -- if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && -- png_ptr->mng_features_permitted) -+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && -+ png_ptr->mng_features_permitted != 0) - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - - if (filter_type != PNG_FILTER_TYPE_BASE) - { -- if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && -+ if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || -@@ -950,7 +2639,7 @@ - error = 1; - } - -- if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) -+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0) - { - png_warning(png_ptr, "Invalid filter method in IHDR"); - error = 1; -@@ -1010,7 +2699,7 @@ - switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) - { - case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: -- if (state & PNG_FP_SAW_ANY) -+ if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, type); -@@ -1018,10 +2707,10 @@ - - case PNG_FP_INTEGER + PNG_FP_SAW_DOT: - /* Ok as trailer, ok as lead of fraction. */ -- if (state & PNG_FP_SAW_DOT) /* two dots */ -+ if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ - goto PNG_FP_End; - -- else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ -+ else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ - png_fp_add(state, type); - - else -@@ -1030,7 +2719,7 @@ - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: -- if (state & PNG_FP_SAW_DOT) /* delayed fraction */ -+ if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ - png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); - - png_fp_add(state, type | PNG_FP_WAS_VALID); -@@ -1068,7 +2757,7 @@ - break; - - case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: -- if (state & PNG_FP_SAW_ANY) -+ if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, PNG_FP_SAW_SIGN); -@@ -1111,15 +2800,15 @@ - int state=0; - png_size_t char_index=0; - -- if (png_check_fp_number(string, size, &state, &char_index) && -+ if (png_check_fp_number(string, size, &state, &char_index) != 0 && - (char_index == size || string[char_index] == 0)) - return state /* must be non-zero - see above */; - - return 0; /* i.e. fail */ - } --#endif /* pCAL or sCAL */ -- --#ifdef PNG_READ_sCAL_SUPPORTED -+#endif /* pCAL || sCAL */ -+ -+#ifdef PNG_sCAL_SUPPORTED - # ifdef PNG_FLOATING_POINT_SUPPORTED - /* Utility used below - a simple accurate power of ten from an integral - * exponent. -@@ -1151,7 +2840,7 @@ - } - while (power > 0); - -- if (recip) d = 1/d; -+ if (recip != 0) d = 1/d; - } - /* else power is 0 and d is 1 */ - -@@ -1162,7 +2851,7 @@ - * precision. - */ - void /* PRIVATE */ --png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, -+png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, - double fp, unsigned int precision) - { - /* We use standard functions from math.h, but not printf because -@@ -1365,8 +3054,9 @@ - - if (exp_b10 != (-1)) - { -- if (exp_b10 == 0) *ascii++ = 46, --size; /* counted -- above */ -+ if (exp_b10 == 0) -+ *ascii++ = 46, --size; /* counted above */ -+ - --exp_b10; - } - *ascii++ = (char)(48 + (int)d), ++cdigits; -@@ -1411,18 +3101,30 @@ - size -= cdigits; - - *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ -- if (exp_b10 < 0) -+ -+ /* The following use of an unsigned temporary avoids ambiguities in -+ * the signed arithmetic on exp_b10 and permits GCC at least to do -+ * better optimization. -+ */ - { -- *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ -- exp_b10 = -exp_b10; -- } -- -- cdigits = 0; -- -- while (exp_b10 > 0) -- { -- exponent[cdigits++] = (char)(48 + exp_b10 % 10); -- exp_b10 /= 10; -+ unsigned int uexp_b10; -+ -+ if (exp_b10 < 0) -+ { -+ *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ -+ uexp_b10 = -exp_b10; -+ } -+ -+ else -+ uexp_b10 = exp_b10; -+ -+ cdigits = 0; -+ -+ while (uexp_b10 > 0) -+ { -+ exponent[cdigits++] = (char)(48 + uexp_b10 % 10); -+ uexp_b10 /= 10; -+ } - } - - /* Need another size check here for the exponent digits, so -@@ -1464,8 +3166,8 @@ - /* Function to format a fixed point value in ASCII. - */ - void /* PRIVATE */ --png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, -- png_fixed_point fp) -+png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, -+ png_size_t size, png_fixed_point fp) - { - /* Require space for 10 decimal digits, a decimal point, a minus sign and a - * trailing \0, 13 characters: -@@ -1480,7 +3182,7 @@ - else - num = fp; - -- if (num <= 0x80000000U) /* else overflowed */ -+ if (num <= 0x80000000) /* else overflowed */ - { - unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10]; -@@ -1535,21 +3237,30 @@ - #endif /* READ_SCAL */ - - #if defined(PNG_FLOATING_POINT_SUPPORTED) && \ -- !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) -+ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ -+ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ -+ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ -+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ -+ (defined(PNG_sCAL_SUPPORTED) && \ -+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) - png_fixed_point --png_fixed(png_structp png_ptr, double fp, png_const_charp text) -+png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) - { - double r = floor(100000 * fp + .5); - - if (r > 2147483647. || r < -2147483648.) - png_fixed_error(png_ptr, text); - -+# ifndef PNG_ERROR_TEXT_SUPPORTED -+ PNG_UNUSED(text) -+# endif -+ - return (png_fixed_point)r; - } - #endif - --#if defined(PNG_READ_GAMMA_SUPPORTED) || \ -- defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) -+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ -+ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) - /* muldiv functions */ - /* This API takes signed arguments and rounds the result to the nearest - * integer (or, for a fixed point number - the standard argument - to -@@ -1653,11 +3364,12 @@ - if (s00 >= (D >> 1)) - ++result; - -- if (negative) -+ if (negative != 0) - result = -result; - - /* Check for overflow. */ -- if ((negative && result <= 0) || (!negative && result >= 0)) -+ if ((negative != 0 && result <= 0) || -+ (negative == 0 && result >= 0)) - { - *res = result; - return 1; -@@ -1676,12 +3388,12 @@ - * result. - */ - png_fixed_point --png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, -+png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times, - png_int_32 divisor) - { - png_fixed_point result; - -- if (png_muldiv(&result, a, times, divisor)) -+ if (png_muldiv(&result, a, times, divisor) != 0) - return result; - - png_warning(png_ptr, "fixed point overflow ignored"); -@@ -1689,7 +3401,7 @@ - } - #endif - --#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gammma */ -+#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ - /* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ - png_fixed_point - png_reciprocal(png_fixed_point a) -@@ -1702,34 +3414,48 @@ - #else - png_fixed_point res; - -- if (png_muldiv(&res, 100000, 100000, a)) -+ if (png_muldiv(&res, 100000, 100000, a) != 0) - return res; - #endif - - return 0; /* error/overflow */ - } - -+/* This is the shared test on whether a gamma value is 'significant' - whether -+ * it is worth doing gamma correction. -+ */ -+int /* PRIVATE */ -+png_gamma_significant(png_fixed_point gamma_val) -+{ -+ return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || -+ gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; -+} -+#endif -+ -+#ifdef PNG_READ_GAMMA_SUPPORTED -+#if defined(PNG_16BIT_SUPPORTED) || !defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - /* A local convenience routine. */ - static png_fixed_point - png_product2(png_fixed_point a, png_fixed_point b) - { - /* The required result is 1/a * 1/b; the following preserves accuracy. */ --#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a * 1E-5; - r *= b; - r = floor(r+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; --#else -+# else - png_fixed_point res; - -- if (png_muldiv(&res, a, b, 100000)) -+ if (png_muldiv(&res, a, b, 100000) != 0) - return res; --#endif -+# endif - - return 0; /* overflow */ - } -+#endif /* 16BIT || !FLOATING_ARITHMETIC */ - - /* The inverse of the above. */ - png_fixed_point -@@ -1759,73 +3485,28 @@ - } - #endif /* READ_GAMMA */ - --#ifdef PNG_CHECK_cHRM_SUPPORTED --/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, -- * 2010: moved from pngset.c) */ --/* -- * Multiply two 32-bit numbers, V1 and V2, using 32-bit -- * arithmetic, to produce a 64-bit result in the HI/LO words. -- * -- * A B -- * x C D -- * ------ -- * AD || BD -- * AC || CB || 0 -- * -- * where A and B are the high and low 16-bit words of V1, -- * C and D are the 16-bit words of V2, AD is the product of -- * A and D, and X || Y is (X << 16) + Y. --*/ -- --void /* PRIVATE */ --png_64bit_product (long v1, long v2, unsigned long *hi_product, -- unsigned long *lo_product) --{ -- int a, b, c, d; -- long lo, hi, x, y; -- -- a = (v1 >> 16) & 0xffff; -- b = v1 & 0xffff; -- c = (v2 >> 16) & 0xffff; -- d = v2 & 0xffff; -- -- lo = b * d; /* BD */ -- x = a * d + c * b; /* AD + CB */ -- y = ((lo >> 16) & 0xffff) + x; -- -- lo = (lo & 0xffff) | ((y & 0xffff) << 16); -- hi = (y >> 16) & 0xffff; -- -- hi += a * c; /* AC */ -- -- *hi_product = (unsigned long)hi; -- *lo_product = (unsigned long)lo; --} --#endif /* CHECK_cHRM */ -- - #ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ - #ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* Fixed point gamma. - * -+ * The code to calculate the tables used below can be found in the shell script -+ * contrib/tools/intgamma.sh -+ * - * To calculate gamma this code implements fast log() and exp() calls using only - * fixed point arithmetic. This code has sufficient precision for either 8-bit - * or 16-bit sample values. - * - * The tables used here were calculated using simple 'bc' programs, but C double -- * precision floating point arithmetic would work fine. The programs are given -- * at the head of each table. -+ * precision floating point arithmetic would work fine. - * - * 8-bit log table - * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to - * 255, so it's the base 2 logarithm of a normalized 8-bit floating point - * mantissa. The numbers are 32-bit fractions. - */ --static png_uint_32 -+static const png_uint_32 - png_8bit_l2[128] = - { --# if PNG_DO_BC -- for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } --# endif - 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, - 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, - 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, -@@ -1848,6 +3529,7 @@ - 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, - 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, - 24347096U, 0U -+ - #if 0 - /* The following are the values for 16-bit tables - these work fine for the - * 8-bit conversions but produce very slightly larger errors in the 16-bit -@@ -1869,18 +3551,18 @@ - #endif - }; - --PNG_STATIC png_int_32 -+static png_int_32 - png_log8bit(unsigned int x) - { - unsigned int lg2 = 0; - /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, - * because the log is actually negate that means adding 1. The final - * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 -- * input), return 7.99998 for the overflow (log 0) case - so the result is -+ * input), return -1 for the overflow (log 0) case, - so the result is - * always at most 19 bits. - */ - if ((x &= 0xff) == 0) -- return 0xffffffff; -+ return -1; - - if ((x & 0xf0) == 0) - lg2 = 4, x <<= 4; -@@ -1925,14 +3607,15 @@ - * Zero (257): 0 - * End (258): 23499 - */ --PNG_STATIC png_int_32 -+#ifdef PNG_16BIT_SUPPORTED -+static png_int_32 - png_log16bit(png_uint_32 x) - { - unsigned int lg2 = 0; - - /* As above, but now the input has 16 bits. */ - if ((x &= 0xffff) == 0) -- return 0xffffffff; -+ return -1; - - if ((x & 0xff00) == 0) - lg2 = 8, x <<= 8; -@@ -1975,14 +3658,15 @@ - /* Safe, because the result can't have more than 20 bits: */ - return (png_int_32)((lg2 + 2048) >> 12); - } -+#endif /* 16BIT */ - - /* The 'exp()' case must invert the above, taking a 20-bit fixed point - * logarithmic value and returning a 16 or 8-bit number as appropriate. In - * each case only the low 16 bits are relevant - the fraction - since the - * integer bits (the top 4) simply determine a shift. - * -- * The worst case is the 16-bit distinction between 65535 and 65534, this -- * requires perhaps spurious accuracty in the decoding of the logarithm to -+ * The worst case is the 16-bit distinction between 65535 and 65534. This -+ * requires perhaps spurious accuracy in the decoding of the logarithm to - * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance - * of getting this accuracy in practice. - * -@@ -1990,12 +3674,9 @@ - * frational part of the logarithm by using an accurate 32-bit value from the - * top four fractional bits then multiplying in the remaining bits. - */ --static png_uint_32 -+static const png_uint_32 - png_32bit_exp[16] = - { --# if PNG_DO_BC -- for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } --# endif - /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ - 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, - 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, -@@ -2003,7 +3684,7 @@ - }; - - /* Adjustment table; provided to explain the numbers in the code below. */ --#if PNG_DO_BC -+#if 0 - for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} - 11 44937.64284865548751208448 - 10 45180.98734845585101160448 -@@ -2019,7 +3700,7 @@ - 0 45425.85339951654943850496 - #endif - --PNG_STATIC png_uint_32 -+static png_uint_32 - png_exp(png_fixed_point x) - { - if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ -@@ -2067,13 +3748,13 @@ - return 0; - } - --PNG_STATIC png_byte -+static png_byte - png_exp8bit(png_fixed_point lg2) - { - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - -- /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the -+ /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the - * second, rounding, step can't overflow because of the first, subtraction, - * step. - */ -@@ -2081,7 +3762,8 @@ - return (png_byte)((x + 0x7fffffU) >> 24); - } - --PNG_STATIC png_uint_16 -+#ifdef PNG_16BIT_SUPPORTED -+static png_uint_16 - png_exp16bit(png_fixed_point lg2) - { - /* Get a 32-bit value: */ -@@ -2091,6 +3773,7 @@ - x -= x >> 16; - return (png_uint_16)((x + 32767U) >> 16); - } -+#endif /* 16BIT */ - #endif /* FLOATING_ARITHMETIC */ - - png_byte -@@ -2099,13 +3782,37 @@ - if (value > 0 && value < 255) - { - # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -- double r = floor(255*pow(value/255.,gamma_val*.00001)+.5); -+ /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly -+ * convert this to a floating point value. This includes values that -+ * would overflow if 'value' were to be converted to 'int'. -+ * -+ * Apparently GCC, however, does an intermediate conversion to (int) -+ * on some (ARM) but not all (x86) platforms, possibly because of -+ * hardware FP limitations. (E.g. if the hardware conversion always -+ * assumes the integer register contains a signed value.) This results -+ * in ANSI-C undefined behavior for large values. -+ * -+ * Other implementations on the same machine might actually be ANSI-C90 -+ * conformant and therefore compile spurious extra code for the large -+ * values. -+ * -+ * We can be reasonably sure that an unsigned to float conversion -+ * won't be faster than an int to float one. Therefore this code -+ * assumes responsibility for the undefined behavior, which it knows -+ * can't happen because of the check above. -+ * -+ * Note the argument to this routine is an (unsigned int) because, on -+ * 16-bit platforms, it is assigned a value which might be out of -+ * range for an (int); that would result in undefined behavior in the -+ * caller if the *argument* ('value') were to be declared (int). -+ */ -+ double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5); - return (png_byte)r; - # else - png_int_32 lg2 = png_log8bit(value); - png_fixed_point res; - -- if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) -+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) - return png_exp8bit(res); - - /* Overflow. */ -@@ -2116,19 +3823,26 @@ - return (png_byte)value; - } - -+#ifdef PNG_16BIT_SUPPORTED - png_uint_16 - png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) - { - if (value > 0 && value < 65535) - { - # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -- double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5); -+ /* The same (unsigned int)->(double) constraints apply here as above, -+ * however in this case the (unsigned int) to (int) conversion can -+ * overflow on an ANSI-C90 compliant system so the cast needs to ensure -+ * that this is not possible. -+ */ -+ double r = floor(65535*pow((png_int_32)value/65535., -+ gamma_val*.00001)+.5); - return (png_uint_16)r; - # else - png_int_32 lg2 = png_log16bit(value); - png_fixed_point res; - -- if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) -+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) - return png_exp16bit(res); - - /* Overflow. */ -@@ -2138,6 +3852,7 @@ - - return (png_uint_16)value; - } -+#endif /* 16BIT */ - - /* This does the right thing based on the bit_depth field of the - * png_struct, interpreting values as 8-bit or 16-bit. While the result -@@ -2145,26 +3860,22 @@ - * 8-bit (as are the arguments.) - */ - png_uint_16 /* PRIVATE */ --png_gamma_correct(png_structp png_ptr, unsigned int value, -+png_gamma_correct(png_structrp png_ptr, unsigned int value, - png_fixed_point gamma_val) - { - if (png_ptr->bit_depth == 8) - return png_gamma_8bit_correct(value, gamma_val); - -+#ifdef PNG_16BIT_SUPPORTED - else - return png_gamma_16bit_correct(value, gamma_val); -+#else -+ /* should not reach this */ -+ return 0; -+#endif /* 16BIT */ - } - --/* This is the shared test on whether a gamma value is 'significant' - whether -- * it is worth doing gamma correction. -- */ --int /* PRIVATE */ --png_gamma_significant(png_fixed_point gamma_val) --{ -- return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || -- gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; --} -- -+#ifdef PNG_16BIT_SUPPORTED - /* Internal function to build a single 16-bit table - the table consists of - * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount - * to shift the input values right (or 16-number_of_signifiant_bits). -@@ -2174,27 +3885,33 @@ - * should be somewhere that will be cleaned. - */ - static void --png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, -+png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) - { - /* Various values derived from 'shift': */ - PNG_CONST unsigned int num = 1U << (8U - shift); -+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -+ /* CSE the division and work round wacky GCC warnings (see the comments -+ * in png_gamma_8bit_correct for where these come from.) -+ */ -+ PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1); -+#endif - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; - PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); - unsigned int i; - - png_uint_16pp table = *ptable = -- (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); -+ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); - - for (i = 0; i < num; i++) - { - png_uint_16p sub_table = table[i] = -- (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); -+ (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); - - /* The 'threshold' test is repeated here because it can arise for one of - * the 16-bit tables even if the others don't hit it. - */ -- if (png_gamma_significant(gamma_val)) -+ if (png_gamma_significant(gamma_val) != 0) - { - /* The old code would overflow at the end and this would cause the - * 'pow' function to return a result >1, resulting in an -@@ -2210,10 +3927,13 @@ - png_uint_32 ig = (j << (8-shift)) + i; - # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* Inline the 'max' scaling operation: */ -- double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); -+ /* See png_gamma_8bit_correct for why the cast to (int) is -+ * required here. -+ */ -+ double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5); - sub_table[j] = (png_uint_16)d; - # else -- if (shift) -+ if (shift != 0) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); -@@ -2229,7 +3949,7 @@ - { - png_uint_32 ig = (j << (8-shift)) + i; - -- if (shift) -+ if (shift != 0) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = (png_uint_16)ig; -@@ -2242,7 +3962,7 @@ - * required. - */ - static void --png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, -+png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) - { - PNG_CONST unsigned int num = 1U << (8U - shift); -@@ -2251,15 +3971,15 @@ - png_uint_32 last; - - png_uint_16pp table = *ptable = -- (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); -+ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); - - /* 'num' is the number of tables and also the number of low bits of low - * bits of the input 16-bit value used to select a table. Each table is -- * itself index by the high 8 bits of the value. -+ * itself indexed by the high 8 bits of the value. - */ - for (i = 0; i < num; i++) - table[i] = (png_uint_16p)png_malloc(png_ptr, -- 256 * png_sizeof(png_uint_16)); -+ 256 * (sizeof (png_uint_16))); - - /* 'gamma_val' is set to the reciprocal of the value calculated above, so - * pow(out,g) is an *input* value. 'last' is the last input value set. -@@ -2303,23 +4023,84 @@ - last++; - } - } -+#endif /* 16BIT */ - - /* Build a single 8-bit table: same as the 16-bit case but much simpler (and - * typically much faster). Note that libpng currently does no sBIT processing -- * (apparently contrary to the spec) so a 256 entry table is always generated. -+ * (apparently contrary to the spec) so a 256-entry table is always generated. - */ - static void --png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, -+png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, - PNG_CONST png_fixed_point gamma_val) - { - unsigned int i; - png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); - -- if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++) -- table[i] = png_gamma_8bit_correct(i, gamma_val); -- -- else for (i=0; i<256; ++i) -- table[i] = (png_byte)i; -+ if (png_gamma_significant(gamma_val) != 0) -+ for (i=0; i<256; i++) -+ table[i] = png_gamma_8bit_correct(i, gamma_val); -+ -+ else -+ for (i=0; i<256; ++i) -+ table[i] = (png_byte)i; -+} -+ -+/* Used from png_read_destroy and below to release the memory used by the gamma -+ * tables. -+ */ -+void /* PRIVATE */ -+png_destroy_gamma_table(png_structrp png_ptr) -+{ -+ png_free(png_ptr, png_ptr->gamma_table); -+ png_ptr->gamma_table = NULL; -+ -+#ifdef PNG_16BIT_SUPPORTED -+ if (png_ptr->gamma_16_table != NULL) -+ { -+ int i; -+ int istop = (1 << (8 - png_ptr->gamma_shift)); -+ for (i = 0; i < istop; i++) -+ { -+ png_free(png_ptr, png_ptr->gamma_16_table[i]); -+ } -+ png_free(png_ptr, png_ptr->gamma_16_table); -+ png_ptr->gamma_16_table = NULL; -+ } -+#endif /* 16BIT */ -+ -+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ -+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ -+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) -+ png_free(png_ptr, png_ptr->gamma_from_1); -+ png_ptr->gamma_from_1 = NULL; -+ png_free(png_ptr, png_ptr->gamma_to_1); -+ png_ptr->gamma_to_1 = NULL; -+ -+#ifdef PNG_16BIT_SUPPORTED -+ if (png_ptr->gamma_16_from_1 != NULL) -+ { -+ int i; -+ int istop = (1 << (8 - png_ptr->gamma_shift)); -+ for (i = 0; i < istop; i++) -+ { -+ png_free(png_ptr, png_ptr->gamma_16_from_1[i]); -+ } -+ png_free(png_ptr, png_ptr->gamma_16_from_1); -+ png_ptr->gamma_16_from_1 = NULL; -+ } -+ if (png_ptr->gamma_16_to_1 != NULL) -+ { -+ int i; -+ int istop = (1 << (8 - png_ptr->gamma_shift)); -+ for (i = 0; i < istop; i++) -+ { -+ png_free(png_ptr, png_ptr->gamma_16_to_1[i]); -+ } -+ png_free(png_ptr, png_ptr->gamma_16_to_1); -+ png_ptr->gamma_16_to_1 = NULL; -+ } -+#endif /* 16BIT */ -+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } - - /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit -@@ -2328,35 +4109,48 @@ - * we don't need to allocate > 64K chunks for a full 16-bit table. - */ - void /* PRIVATE */ --png_build_gamma_table(png_structp png_ptr, int bit_depth) -+png_build_gamma_table(png_structrp png_ptr, int bit_depth) - { - png_debug(1, "in png_build_gamma_table"); - -+ /* Remove any existing table; this copes with multiple calls to -+ * png_read_update_info. The warning is because building the gamma tables -+ * multiple times is a performance hit - it's harmless but the ability to call -+ * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible -+ * to warn if the app introduces such a hit. -+ */ -+ if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) -+ { -+ png_warning(png_ptr, "gamma table being rebuilt"); -+ png_destroy_gamma_table(png_ptr); -+ } -+ - if (bit_depth <= 8) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_table, -- png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, -+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - - #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) -- if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) -+ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, -- png_reciprocal(png_ptr->gamma)); -+ png_reciprocal(png_ptr->colorspace.gamma)); - - png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : -- png_ptr->gamma/* Probably doing rgb_to_gray */); -+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } - #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } -+#ifdef PNG_16BIT_SUPPORTED - else - { - png_byte shift, sig_bit; - -- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) -+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - sig_bit = png_ptr->sig_bit.red; - -@@ -2376,7 +4170,7 @@ - * Where 'iv' is the input color value and 'ov' is the output value - - * pow(iv, gamma). - * -- * Thus the gamma table consists of up to 256 256 entry tables. The table -+ * Thus the gamma table consists of up to 256 256-entry tables. The table - * is selected by the (8-gamma_shift) most significant of the low 8 bits of - * the color value then indexed by the upper 8 bits: - * -@@ -2393,7 +4187,7 @@ - else - shift = 0; /* keep all 16 bits */ - -- if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) -+ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - { - /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively - * the significant bits in the *input* when the output will -@@ -2408,32 +4202,28 @@ - - png_ptr->gamma_shift = shift; - --#ifdef PNG_16BIT_SUPPORTED - /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now - * PNG_COMPOSE). This effectively smashed the background calculation for - * 16-bit output because the 8-bit table assumes the result will be reduced - * to 8 bits. - */ -- if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) --#endif -+ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, -- png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, -+ png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - --#ifdef PNG_16BIT_SUPPORTED - else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, -- png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, -+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); --#endif - - #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) -- if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) -+ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, -- png_reciprocal(png_ptr->gamma)); -+ png_reciprocal(png_ptr->colorspace.gamma)); - - /* Notice that the '16 from 1' table should be full precision, however - * the lookup on this table still uses gamma_shift, so it can't be. -@@ -2441,10 +4231,291 @@ - */ - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : -- png_ptr->gamma/* Probably doing rgb_to_gray */); -+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } - #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } -+#endif /* 16BIT */ - } - #endif /* READ_GAMMA */ --#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ -+ -+/* HARDWARE OR SOFTWARE OPTION SUPPORT */ -+#ifdef PNG_SET_OPTION_SUPPORTED -+int PNGAPI -+png_set_option(png_structrp png_ptr, int option, int onoff) -+{ -+ if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && -+ (option & 1) == 0) -+ { -+ int mask = 3 << option; -+ int setting = (2 + (onoff != 0)) << option; -+ int current = png_ptr->options; -+ -+ png_ptr->options = (png_byte)((current & ~mask) | setting); -+ -+ return (current & mask) >> option; -+ } -+ -+ return PNG_OPTION_INVALID; -+} -+#endif -+ -+/* sRGB support */ -+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ -+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -+/* sRGB conversion tables; these are machine generated with the code in -+ * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the -+ * specification (see the article at http://en.wikipedia.org/wiki/SRGB) -+ * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. -+ * The sRGB to linear table is exact (to the nearest 16 bit linear fraction). -+ * The inverse (linear to sRGB) table has accuracies as follows: -+ * -+ * For all possible (255*65535+1) input values: -+ * -+ * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact -+ * -+ * For the input values corresponding to the 65536 16-bit values: -+ * -+ * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact -+ * -+ * In all cases the inexact readings are only off by one. -+ */ -+ -+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -+/* The convert-to-sRGB table is only currently required for read. */ -+const png_uint_16 png_sRGB_table[256] = -+{ -+ 0,20,40,60,80,99,119,139, -+ 159,179,199,219,241,264,288,313, -+ 340,367,396,427,458,491,526,562, -+ 599,637,677,718,761,805,851,898, -+ 947,997,1048,1101,1156,1212,1270,1330, -+ 1391,1453,1517,1583,1651,1720,1790,1863, -+ 1937,2013,2090,2170,2250,2333,2418,2504, -+ 2592,2681,2773,2866,2961,3058,3157,3258, -+ 3360,3464,3570,3678,3788,3900,4014,4129, -+ 4247,4366,4488,4611,4736,4864,4993,5124, -+ 5257,5392,5530,5669,5810,5953,6099,6246, -+ 6395,6547,6700,6856,7014,7174,7335,7500, -+ 7666,7834,8004,8177,8352,8528,8708,8889, -+ 9072,9258,9445,9635,9828,10022,10219,10417, -+ 10619,10822,11028,11235,11446,11658,11873,12090, -+ 12309,12530,12754,12980,13209,13440,13673,13909, -+ 14146,14387,14629,14874,15122,15371,15623,15878, -+ 16135,16394,16656,16920,17187,17456,17727,18001, -+ 18277,18556,18837,19121,19407,19696,19987,20281, -+ 20577,20876,21177,21481,21787,22096,22407,22721, -+ 23038,23357,23678,24002,24329,24658,24990,25325, -+ 25662,26001,26344,26688,27036,27386,27739,28094, -+ 28452,28813,29176,29542,29911,30282,30656,31033, -+ 31412,31794,32179,32567,32957,33350,33745,34143, -+ 34544,34948,35355,35764,36176,36591,37008,37429, -+ 37852,38278,38706,39138,39572,40009,40449,40891, -+ 41337,41785,42236,42690,43147,43606,44069,44534, -+ 45002,45473,45947,46423,46903,47385,47871,48359, -+ 48850,49344,49841,50341,50844,51349,51858,52369, -+ 52884,53401,53921,54445,54971,55500,56032,56567, -+ 57105,57646,58190,58737,59287,59840,60396,60955, -+ 61517,62082,62650,63221,63795,64372,64952,65535 -+}; -+#endif /* SIMPLIFIED_READ */ -+ -+/* The base/delta tables are required for both read and write (but currently -+ * only the simplified versions.) -+ */ -+const png_uint_16 png_sRGB_base[512] = -+{ -+ 128,1782,3383,4644,5675,6564,7357,8074, -+ 8732,9346,9921,10463,10977,11466,11935,12384, -+ 12816,13233,13634,14024,14402,14769,15125,15473, -+ 15812,16142,16466,16781,17090,17393,17690,17981, -+ 18266,18546,18822,19093,19359,19621,19879,20133, -+ 20383,20630,20873,21113,21349,21583,21813,22041, -+ 22265,22487,22707,22923,23138,23350,23559,23767, -+ 23972,24175,24376,24575,24772,24967,25160,25352, -+ 25542,25730,25916,26101,26284,26465,26645,26823, -+ 27000,27176,27350,27523,27695,27865,28034,28201, -+ 28368,28533,28697,28860,29021,29182,29341,29500, -+ 29657,29813,29969,30123,30276,30429,30580,30730, -+ 30880,31028,31176,31323,31469,31614,31758,31902, -+ 32045,32186,32327,32468,32607,32746,32884,33021, -+ 33158,33294,33429,33564,33697,33831,33963,34095, -+ 34226,34357,34486,34616,34744,34873,35000,35127, -+ 35253,35379,35504,35629,35753,35876,35999,36122, -+ 36244,36365,36486,36606,36726,36845,36964,37083, -+ 37201,37318,37435,37551,37668,37783,37898,38013, -+ 38127,38241,38354,38467,38580,38692,38803,38915, -+ 39026,39136,39246,39356,39465,39574,39682,39790, -+ 39898,40005,40112,40219,40325,40431,40537,40642, -+ 40747,40851,40955,41059,41163,41266,41369,41471, -+ 41573,41675,41777,41878,41979,42079,42179,42279, -+ 42379,42478,42577,42676,42775,42873,42971,43068, -+ 43165,43262,43359,43456,43552,43648,43743,43839, -+ 43934,44028,44123,44217,44311,44405,44499,44592, -+ 44685,44778,44870,44962,45054,45146,45238,45329, -+ 45420,45511,45601,45692,45782,45872,45961,46051, -+ 46140,46229,46318,46406,46494,46583,46670,46758, -+ 46846,46933,47020,47107,47193,47280,47366,47452, -+ 47538,47623,47709,47794,47879,47964,48048,48133, -+ 48217,48301,48385,48468,48552,48635,48718,48801, -+ 48884,48966,49048,49131,49213,49294,49376,49458, -+ 49539,49620,49701,49782,49862,49943,50023,50103, -+ 50183,50263,50342,50422,50501,50580,50659,50738, -+ 50816,50895,50973,51051,51129,51207,51285,51362, -+ 51439,51517,51594,51671,51747,51824,51900,51977, -+ 52053,52129,52205,52280,52356,52432,52507,52582, -+ 52657,52732,52807,52881,52956,53030,53104,53178, -+ 53252,53326,53400,53473,53546,53620,53693,53766, -+ 53839,53911,53984,54056,54129,54201,54273,54345, -+ 54417,54489,54560,54632,54703,54774,54845,54916, -+ 54987,55058,55129,55199,55269,55340,55410,55480, -+ 55550,55620,55689,55759,55828,55898,55967,56036, -+ 56105,56174,56243,56311,56380,56448,56517,56585, -+ 56653,56721,56789,56857,56924,56992,57059,57127, -+ 57194,57261,57328,57395,57462,57529,57595,57662, -+ 57728,57795,57861,57927,57993,58059,58125,58191, -+ 58256,58322,58387,58453,58518,58583,58648,58713, -+ 58778,58843,58908,58972,59037,59101,59165,59230, -+ 59294,59358,59422,59486,59549,59613,59677,59740, -+ 59804,59867,59930,59993,60056,60119,60182,60245, -+ 60308,60370,60433,60495,60558,60620,60682,60744, -+ 60806,60868,60930,60992,61054,61115,61177,61238, -+ 61300,61361,61422,61483,61544,61605,61666,61727, -+ 61788,61848,61909,61969,62030,62090,62150,62211, -+ 62271,62331,62391,62450,62510,62570,62630,62689, -+ 62749,62808,62867,62927,62986,63045,63104,63163, -+ 63222,63281,63340,63398,63457,63515,63574,63632, -+ 63691,63749,63807,63865,63923,63981,64039,64097, -+ 64155,64212,64270,64328,64385,64443,64500,64557, -+ 64614,64672,64729,64786,64843,64900,64956,65013, -+ 65070,65126,65183,65239,65296,65352,65409,65465 -+}; -+ -+const png_byte png_sRGB_delta[512] = -+{ -+ 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, -+ 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, -+ 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, -+ 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, -+ 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, -+ 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, -+ 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, -+ 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, -+ 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, -+ 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, -+ 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, -+ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, -+ 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, -+ 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, -+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, -+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, -+ 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, -+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, -+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, -+ 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, -+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, -+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, -+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, -+ 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -+ 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7, -+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, -+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, -+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -+}; -+#endif /* SIMPLIFIED READ/WRITE sRGB support */ -+ -+/* SIMPLIFIED READ/WRITE SUPPORT */ -+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ -+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -+static int -+png_image_free_function(png_voidp argument) -+{ -+ png_imagep image = png_voidcast(png_imagep, argument); -+ png_controlp cp = image->opaque; -+ png_control c; -+ -+ /* Double check that we have a png_ptr - it should be impossible to get here -+ * without one. -+ */ -+ if (cp->png_ptr == NULL) -+ return 0; -+ -+ /* First free any data held in the control structure. */ -+# ifdef PNG_STDIO_SUPPORTED -+ if (cp->owned_file != 0) -+ { -+ FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); -+ cp->owned_file = 0; -+ -+ /* Ignore errors here. */ -+ if (fp != NULL) -+ { -+ cp->png_ptr->io_ptr = NULL; -+ (void)fclose(fp); -+ } -+ } -+# endif -+ -+ /* Copy the control structure so that the original, allocated, version can be -+ * safely freed. Notice that a png_error here stops the remainder of the -+ * cleanup, but this is probably fine because that would indicate bad memory -+ * problems anyway. -+ */ -+ c = *cp; -+ image->opaque = &c; -+ png_free(c.png_ptr, cp); -+ -+ /* Then the structures, calling the correct API. */ -+ if (c.for_write != 0) -+ { -+# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -+ png_destroy_write_struct(&c.png_ptr, &c.info_ptr); -+# else -+ png_error(c.png_ptr, "simplified write not supported"); -+# endif -+ } -+ else -+ { -+# ifdef PNG_SIMPLIFIED_READ_SUPPORTED -+ png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); -+# else -+ png_error(c.png_ptr, "simplified read not supported"); -+# endif -+ } -+ -+ /* Success. */ -+ return 1; -+} -+ -+void PNGAPI -+png_image_free(png_imagep image) -+{ -+ /* Safely call the real function, but only if doing so is safe at this point -+ * (if not inside an error handling context). Otherwise assume -+ * png_safe_execute will call this API after the return. -+ */ -+ if (image != NULL && image->opaque != NULL && -+ image->opaque->error_buf == NULL) -+ { -+ /* Ignore errors here: */ -+ (void)png_safe_execute(image, png_image_free_function, image); -+ image->opaque = NULL; -+ } -+} -+ -+int /* PRIVATE */ -+png_image_error(png_imagep image, png_const_charp error_message) -+{ -+ /* Utility to log an error. */ -+ png_safecat(image->message, (sizeof image->message), 0, error_message); -+ image->warning_or_error |= PNG_IMAGE_ERROR; -+ png_image_free(image); -+ return 0; -+} -+ -+#endif /* SIMPLIFIED READ/WRITE */ -+#endif /* READ || WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/png.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/png.h Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * libpng version 1.5.4 - July 7, 2011 -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * libpng version 1.6.16, December 22, 2014 -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -39,7 +39,7 @@ - * Authors and maintainers: - * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat - * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger -- * libpng versions 0.97, January 1998, through 1.5.4 - July 7, 2011: Glenn -+ * libpng versions 0.97, January 1998, through 1.6.16, December 22, 2014: Glenn - * See also "Contributing Authors", below. - * - * Note about libpng version numbers: -@@ -185,6 +185,61 @@ - * 1.5.4beta01-08 15 10504 15.so.15.4[.0] - * 1.5.4rc01 15 10504 15.so.15.4[.0] - * 1.5.4 15 10504 15.so.15.4[.0] -+ * 1.5.5beta01-08 15 10505 15.so.15.5[.0] -+ * 1.5.5rc01 15 10505 15.so.15.5[.0] -+ * 1.5.5 15 10505 15.so.15.5[.0] -+ * 1.5.6beta01-07 15 10506 15.so.15.6[.0] -+ * 1.5.6rc01-03 15 10506 15.so.15.6[.0] -+ * 1.5.6 15 10506 15.so.15.6[.0] -+ * 1.5.7beta01-05 15 10507 15.so.15.7[.0] -+ * 1.5.7rc01-03 15 10507 15.so.15.7[.0] -+ * 1.5.7 15 10507 15.so.15.7[.0] -+ * 1.6.0beta01-40 16 10600 16.so.16.0[.0] -+ * 1.6.0rc01-08 16 10600 16.so.16.0[.0] -+ * 1.6.0 16 10600 16.so.16.0[.0] -+ * 1.6.1beta01-09 16 10601 16.so.16.1[.0] -+ * 1.6.1rc01 16 10601 16.so.16.1[.0] -+ * 1.6.1 16 10601 16.so.16.1[.0] -+ * 1.6.2beta01 16 10602 16.so.16.2[.0] -+ * 1.6.2rc01-06 16 10602 16.so.16.2[.0] -+ * 1.6.2 16 10602 16.so.16.2[.0] -+ * 1.6.3beta01-11 16 10603 16.so.16.3[.0] -+ * 1.6.3rc01 16 10603 16.so.16.3[.0] -+ * 1.6.3 16 10603 16.so.16.3[.0] -+ * 1.6.4beta01-02 16 10604 16.so.16.4[.0] -+ * 1.6.4rc01 16 10604 16.so.16.4[.0] -+ * 1.6.4 16 10604 16.so.16.4[.0] -+ * 1.6.5 16 10605 16.so.16.5[.0] -+ * 1.6.6 16 10606 16.so.16.6[.0] -+ * 1.6.7beta01-04 16 10607 16.so.16.7[.0] -+ * 1.6.7rc01-03 16 10607 16.so.16.7[.0] -+ * 1.6.7 16 10607 16.so.16.7[.0] -+ * 1.6.8beta01-02 16 10608 16.so.16.8[.0] -+ * 1.6.8rc01-02 16 10608 16.so.16.8[.0] -+ * 1.6.8 16 10608 16.so.16.8[.0] -+ * 1.6.9beta01-04 16 10609 16.so.16.9[.0] -+ * 1.6.9rc01-02 16 10609 16.so.16.9[.0] -+ * 1.6.9 16 10609 16.so.16.9[.0] -+ * 1.6.10beta01-03 16 10610 16.so.16.10[.0] -+ * 1.6.10rc01-03 16 10610 16.so.16.10[.0] -+ * 1.6.10 16 10610 16.so.16.10[.0] -+ * 1.6.11beta01-06 16 10611 16.so.16.11[.0] -+ * 1.6.11rc01-02 16 10611 16.so.16.11[.0] -+ * 1.6.11 16 10611 16.so.16.11[.0] -+ * 1.6.12rc01-03 16 10612 16.so.16.12[.0] -+ * 1.6.12 16 10612 16.so.16.12[.0] -+ * 1.6.13beta01-04 16 10613 16.so.16.13[.0] -+ * 1.6.13rc01-02 16 10613 16.so.16.13[.0] -+ * 1.6.13 16 10613 16.so.16.13[.0] -+ * 1.6.14beta01-07 16 10614 16.so.16.14[.0] -+ * 1.6.14rc01-02 16 10614 16.so.16.14[.0] -+ * 1.6.14 16 10614 16.so.16.14[.0] -+ * 1.6.15beta01-08 16 10615 16.so.16.15[.0] -+ * 1.6.15rc01-03 16 10615 16.so.16.15[.0] -+ * 1.6.15 16 10615 16.so.16.15[.0] -+ * 1.6.16beta01-03 16 10616 16.so.16.16[.0] -+ * 1.6.16rc01-02 16 10616 16.so.16.16[.0] -+ * 1.6.16 16 10616 16.so.16.16[.0] - * - * Henceforth the source version will match the shared-library major - * and minor numbers; the shared-library major version number will be -@@ -194,7 +249,7 @@ - * to the source version x.y.z (leading zeros in y and z). Beta versions - * were given the previous public release number plus a letter, until - * version 1.0.6j; from then on they were given the upcoming public -- * release number plus "betaNN" or "rcN". -+ * release number plus "betaNN" or "rcNN". - * - * Binary incompatibility exists only when applications make direct access - * to the info_ptr or png_ptr members through png.h, and the compiled -@@ -216,8 +271,8 @@ - * - * This code is released under the libpng license. - * -- * libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are -- * Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+ * libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+ * Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - * distributed according to the same disclaimer and license as libpng-1.2.5 - * with the following individual added to the list of Contributing Authors: - * -@@ -328,28 +383,30 @@ - * Y2K compliance in libpng: - * ========================= - * -- * July 7, 2011 -+ * December 22, 2014 - * - * Since the PNG Development group is an ad-hoc body, we can't make - * an official declaration. - * - * This is your unofficial assurance that libpng from version 0.71 and -- * upward through 1.5.4 are Y2K compliant. It is my belief that -+ * upward through 1.6.16 are Y2K compliant. It is my belief that - * earlier versions were also Y2K compliant. - * - * Libpng only has two year fields. One is a 2-byte unsigned integer -- * that will hold years up to 65535. The other holds the date in text -- * format, and will hold years up to 9999. -+ * that will hold years up to 65535. The other, which is deprecated, -+ * holds the date in text format, and will hold years up to 9999. - * - * The integer is - * "png_uint_16 year" in png_time_struct. - * - * The string is -- * "png_char time_buffer" in png_struct -+ * "char time_buffer[29]" in png_struct. This is no longer used -+ * in libpng-1.6.x and will be removed from libpng-1.7.0. - * - * There are seven time-related functions: -- * png.c: png_convert_to_rfc_1123() in png.c -- * (formerly png_convert_to_rfc_1152() in error) -+ * png.c: png_convert_to_rfc_1123_buffer() in png.c -+ * (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and -+ * png_convert_to_rfc_1152() in error prior to libpng-0.98) - * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c - * png_convert_from_time_t() in pngwrite.c - * png_get_tIME() in pngget.c -@@ -360,8 +417,8 @@ - * All handle dates properly in a Y2K environment. The - * png_convert_from_time_t() function calls gmtime() to convert from system - * clock time, which returns (year - 1900), which we properly convert to -- * the full 4-digit year. There is a possibility that applications using -- * libpng are not passing 4-digit years into the png_convert_to_rfc_1123() -+ * the full 4-digit year. There is a possibility that libpng applications -+ * are not passing 4-digit years into the png_convert_to_rfc_1123_buffer() - * function, or that they are incorrectly passing only a 2-digit year - * instead of "year - 1900" into the png_convert_from_struct_tm() function, - * but this is not under our control. The libpng documentation has always -@@ -385,21 +442,27 @@ - /* This is not the place to learn how to use libpng. The file libpng-manual.txt - * describes how to use libpng, and the file example.c summarizes it - * with some code on which to build. This file is useful for looking -- * at the actual function definitions and structure components. -+ * at the actual function definitions and structure components. If that -+ * file has been stripped from your copy of libpng, you can find it at -+ * <http://www.libpng.org/pub/png/libpng-manual.txt> -+ * -+ * If you just need to read a PNG file and don't want to read the documentation -+ * skip to the end of this file and read the section entitled 'simplified API'. - */ - - /* Version information for png.h - this should match the version in png.c */ --#define PNG_LIBPNG_VER_STRING "1.5.4" -+#define PNG_LIBPNG_VER_STRING "1.6.16" - #define PNG_HEADER_VERSION_STRING \ -- " libpng version 1.5.4 - July 7, 2011\n" -- --#define PNG_LIBPNG_VER_SONUM 15 --#define PNG_LIBPNG_VER_DLLNUM 15 -+ " libpng version 1.6.16 - December 22, 2014\n" -+ -+#define PNG_LIBPNG_VER_SONUM 16 -+#define PNG_LIBPNG_VER_DLLNUM 16 - - /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ - #define PNG_LIBPNG_VER_MAJOR 1 --#define PNG_LIBPNG_VER_MINOR 5 --#define PNG_LIBPNG_VER_RELEASE 4 -+#define PNG_LIBPNG_VER_MINOR 6 -+#define PNG_LIBPNG_VER_RELEASE 16 -+ - /* This should match the numeric part of the final component of - * PNG_LIBPNG_VER_STRING, omitting any leading zero: - */ -@@ -421,7 +484,7 @@ - #define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with - PNG_LIBPNG_BUILD_PRIVATE */ - --#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA -+#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE - - /* Careful here. At one time, Guy wanted to use 082, but that would be octal. - * We must not include leading zeros. -@@ -429,7 +492,7 @@ - * version 1.0.0 was mis-numbered 100 instead of 10000). From - * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release - */ --#define PNG_LIBPNG_VER 10504 /* 1.5.4 */ -+#define PNG_LIBPNG_VER 10616 /* 1.6.16 */ - - /* Library configuration: these options cannot be changed after - * the library has been built. -@@ -442,25 +505,7 @@ - #endif - - #ifndef PNG_VERSION_INFO_ONLY --# ifndef PNG_BUILDING_SYMBOL_TABLE -- /* -- * Standard header files (not needed for the version info or while -- * building symbol table -- see scripts/pnglibconf.dfa) -- */ --# ifdef PNG_SETJMP_SUPPORTED --# include <setjmp.h> --# endif -- -- /* Need the time information for converting tIME chunks, it -- * defines struct tm: -- */ --# ifdef PNG_CONVERT_tIME_SUPPORTED -- /* "time.h" functions are not supported on all operating systems */ --# include <time.h> --# endif --# endif -- --/* Machine specific configuration. */ -+ /* Machine specific configuration. */ - # include "pngconf.h" - #endif - -@@ -509,6 +554,7 @@ - * 2. Type definitions (base types are defined in pngconf.h), structure - * definitions. - * 3. Exported library functions. -+ * 4. Simplified API. - * - * The library source code has additional files (principally pngpriv.h) that - * allow configuration of the library. -@@ -551,7 +597,48 @@ - /* This triggers a compiler error in png.c, if png.c and png.h - * do not agree upon the version number. - */ --typedef char* png_libpng_version_1_5_4; -+typedef char* png_libpng_version_1_6_16; -+ -+/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. -+ * -+ * png_struct is the cache of information used while reading or writing a single -+ * PNG file. One of these is always required, although the simplified API -+ * (below) hides the creation and destruction of it. -+ */ -+typedef struct png_struct_def png_struct; -+typedef const png_struct * png_const_structp; -+typedef png_struct * png_structp; -+typedef png_struct * * png_structpp; -+ -+/* png_info contains information read from or to be written to a PNG file. One -+ * or more of these must exist while reading or creating a PNG file. The -+ * information is not used by libpng during read but is used to control what -+ * gets written when a PNG file is created. "png_get_" function calls read -+ * information during read and "png_set_" functions calls write information -+ * when creating a PNG. -+ * been moved into a separate header file that is not accessible to -+ * applications. Read libpng-manual.txt or libpng.3 for more info. -+ */ -+typedef struct png_info_def png_info; -+typedef png_info * png_infop; -+typedef const png_info * png_const_infop; -+typedef png_info * * png_infopp; -+ -+/* Types with names ending 'p' are pointer types. The corresponding types with -+ * names ending 'rp' are identical pointer types except that the pointer is -+ * marked 'restrict', which means that it is the only pointer to the object -+ * passed to the function. Applications should not use the 'restrict' types; -+ * it is always valid to pass 'p' to a pointer with a function argument of the -+ * corresponding 'rp' type. Different compilers have different rules with -+ * regard to type matching in the presence of 'restrict'. For backward -+ * compatibility libpng callbacks never have 'restrict' in their parameters and, -+ * consequentially, writing portable application code is extremely difficult if -+ * an attempt is made to use 'restrict'. -+ */ -+typedef png_struct * PNG_RESTRICT png_structrp; -+typedef const png_struct * PNG_RESTRICT png_const_structrp; -+typedef png_info * PNG_RESTRICT png_inforp; -+typedef const png_info * PNG_RESTRICT png_const_inforp; - - /* Three color definitions. The order of the red, green, and blue, (and the - * exact size) is not important, although the size of the fields need to -@@ -563,9 +650,9 @@ - png_byte green; - png_byte blue; - } png_color; --typedef png_color FAR * png_colorp; --typedef PNG_CONST png_color FAR * png_const_colorp; --typedef png_color FAR * FAR * png_colorpp; -+typedef png_color * png_colorp; -+typedef const png_color * png_const_colorp; -+typedef png_color * * png_colorpp; - - typedef struct png_color_16_struct - { -@@ -575,9 +662,9 @@ - png_uint_16 blue; - png_uint_16 gray; /* for use in grayscale files */ - } png_color_16; --typedef png_color_16 FAR * png_color_16p; --typedef PNG_CONST png_color_16 FAR * png_const_color_16p; --typedef png_color_16 FAR * FAR * png_color_16pp; -+typedef png_color_16 * png_color_16p; -+typedef const png_color_16 * png_const_color_16p; -+typedef png_color_16 * * png_color_16pp; - - typedef struct png_color_8_struct - { -@@ -587,9 +674,9 @@ - png_byte gray; /* for use in grayscale files */ - png_byte alpha; /* for alpha channel files */ - } png_color_8; --typedef png_color_8 FAR * png_color_8p; --typedef PNG_CONST png_color_8 FAR * png_const_color_8p; --typedef png_color_8 FAR * FAR * png_color_8pp; -+typedef png_color_8 * png_color_8p; -+typedef const png_color_8 * png_const_color_8p; -+typedef png_color_8 * * png_color_8pp; - - /* - * The following two structures are used for the in-core representation -@@ -603,9 +690,9 @@ - png_uint_16 alpha; - png_uint_16 frequency; - } png_sPLT_entry; --typedef png_sPLT_entry FAR * png_sPLT_entryp; --typedef PNG_CONST png_sPLT_entry FAR * png_const_sPLT_entryp; --typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; -+typedef png_sPLT_entry * png_sPLT_entryp; -+typedef const png_sPLT_entry * png_const_sPLT_entryp; -+typedef png_sPLT_entry * * png_sPLT_entrypp; - - /* When the depth of the sPLT palette is 8 bits, the color and alpha samples - * occupy the LSB of their respective members, and the MSB of each member -@@ -619,18 +706,27 @@ - png_sPLT_entryp entries; /* palette entries */ - png_int_32 nentries; /* number of palette entries */ - } png_sPLT_t; --typedef png_sPLT_t FAR * png_sPLT_tp; --typedef PNG_CONST png_sPLT_t FAR * png_const_sPLT_tp; --typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; -+typedef png_sPLT_t * png_sPLT_tp; -+typedef const png_sPLT_t * png_const_sPLT_tp; -+typedef png_sPLT_t * * png_sPLT_tpp; - - #ifdef PNG_TEXT_SUPPORTED - /* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, - * and whether that contents is compressed or not. The "key" field -- * points to a regular zero-terminated C string. The "text", "lang", and -- * "lang_key" fields can be regular C strings, empty strings, or NULL pointers. -+ * points to a regular zero-terminated C string. The "text" fields can be a -+ * regular C string, an empty string, or a NULL pointer. - * However, the structure returned by png_get_text() will always contain -- * regular zero-terminated C strings (possibly empty), never NULL pointers, -- * so they can be safely used in printf() and other string-handling functions. -+ * the "text" field as a regular zero-terminated C string (possibly -+ * empty), never a NULL pointer, so it can be safely used in printf() and -+ * other string-handling functions. Note that the "itxt_length", "lang", and -+ * "lang_key" members of the structure only exist when the library is built -+ * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by -+ * default without iTXt support. Also note that when iTXt *is* supported, -+ * the "lang" and "lang_key" fields contain NULL pointers when the -+ * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or -+ * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the -+ * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" -+ * which is always 0 or 1, or its "compression method" which is always 0. - */ - typedef struct png_text_struct - { -@@ -649,9 +745,9 @@ - png_charp lang_key; /* keyword translated UTF-8 string, 0 or more - chars or a NULL pointer */ - } png_text; --typedef png_text FAR * png_textp; --typedef PNG_CONST png_text FAR * png_const_textp; --typedef png_text FAR * FAR * png_textpp; -+typedef png_text * png_textp; -+typedef const png_text * png_const_textp; -+typedef png_text * * png_textpp; - #endif - - /* Supported compression types for text in PNG files (tEXt, and zTXt). -@@ -679,49 +775,45 @@ - png_byte minute; /* minute of hour, 0 - 59 */ - png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ - } png_time; --typedef png_time FAR * png_timep; --typedef PNG_CONST png_time FAR * png_const_timep; --typedef png_time FAR * FAR * png_timepp; -- --#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ -- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -+typedef png_time * png_timep; -+typedef const png_time * png_const_timep; -+typedef png_time * * png_timepp; -+ -+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ -+ defined(PNG_USER_CHUNKS_SUPPORTED) - /* png_unknown_chunk is a structure to hold queued chunks for which there is - * no specific support. The idea is that we can use this to queue - * up private chunks for output even though the library doesn't actually - * know about their semantics. -+ * -+ * The data in the structure is set by libpng on read and used on write. - */ - typedef struct png_unknown_chunk_t - { -- png_byte name[5]; -- png_byte *data; -+ png_byte name[5]; /* Textual chunk name with '\0' terminator */ -+ png_byte *data; /* Data, should not be modified on read! */ - png_size_t size; - -- /* libpng-using applications should NOT directly modify this byte. */ -+ /* On write 'location' must be set using the flag values listed below. -+ * Notice that on read it is set by libpng however the values stored have -+ * more bits set than are listed below. Always treat the value as a -+ * bitmask. On write set only one bit - setting multiple bits may cause the -+ * chunk to be written in multiple places. -+ */ - png_byte location; /* mode of operation at read time */ - } -- -- - png_unknown_chunk; --typedef png_unknown_chunk FAR * png_unknown_chunkp; --typedef PNG_CONST png_unknown_chunk FAR * png_const_unknown_chunkp; --typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; -+ -+typedef png_unknown_chunk * png_unknown_chunkp; -+typedef const png_unknown_chunk * png_const_unknown_chunkp; -+typedef png_unknown_chunk * * png_unknown_chunkpp; - #endif - --/* Values for the unknown chunk location byte */ -- -+/* Flag values for the unknown chunk location byte. */ - #define PNG_HAVE_IHDR 0x01 - #define PNG_HAVE_PLTE 0x02 - #define PNG_AFTER_IDAT 0x08 - --/* The complete definition of png_info has, as of libpng-1.5.0, -- * been moved into a separate header file that is not accessible to -- * applications. Read libpng-manual.txt or libpng.3 for more info. -- */ --typedef struct png_info_def png_info; --typedef png_info FAR * png_infop; --typedef PNG_CONST png_info FAR * png_const_infop; --typedef png_info FAR * FAR * png_infopp; -- - /* Maximum positive integer used in PNG is (2^31)-1 */ - #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) - #define PNG_UINT_32_MAX ((png_uint_32)(-1)) -@@ -821,7 +913,7 @@ - #define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ - #define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ - #define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ --#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ -+#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ - - /* This is used for the transformation routines, as some of them - * change these values for the row. It also should enable using -@@ -837,16 +929,8 @@ - png_byte pixel_depth; /* bits per pixel (depth * channels) */ - } png_row_info; - --typedef png_row_info FAR * png_row_infop; --typedef png_row_info FAR * FAR * png_row_infopp; -- --/* The complete definition of png_struct has, as of libpng-1.5.0, -- * been moved into a separate header file that is not accessible to -- * applications. Read libpng-manual.txt or libpng.3 for more info. -- */ --typedef struct png_struct_def png_struct; --typedef PNG_CONST png_struct FAR * png_const_structp; --typedef png_struct FAR * png_structp; -+typedef png_row_info * png_row_infop; -+typedef png_row_info * * png_row_infopp; - - /* These are the function types for the I/O functions and for the functions - * that allow the user to override the default I/O functions with his or her -@@ -893,7 +977,8 @@ - png_unknown_chunkp)); - #endif - #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED --typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); -+/* not used anywhere */ -+/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ - #endif - - #ifdef PNG_SETJMP_SUPPORTED -@@ -949,8 +1034,6 @@ - png_alloc_size_t)); - typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); - --typedef png_struct FAR * FAR * png_structpp; -- - /* Section 3: exported functions - * Here are the function definitions most commonly used. This is not - * the place to find out how to use libpng. See libpng-manual.txt for the -@@ -986,7 +1069,7 @@ - /* Tell lib we have already handled the first <num_bytes> magic bytes. - * Handling more than 8 bytes from the beginning of the file is an error. - */ --PNG_EXPORT(2, void, png_set_sig_bytes, (png_structp png_ptr, int num_bytes)); -+PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); - - /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a - * PNG file. Returns zero if the supplied bytes match the 8-byte PNG -@@ -1014,9 +1097,9 @@ - PNG_ALLOCATED); - - PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, -- (png_const_structp png_ptr)); -- --PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structp png_ptr, -+ (png_const_structrp png_ptr)); -+ -+PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, - png_size_t size)); - - /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp -@@ -1030,10 +1113,10 @@ - * allocated by the library - the call will return NULL on a mismatch - * indicating an ABI mismatch. - */ --PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, -+PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, - png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); - # define png_jmpbuf(png_ptr) \ -- (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) -+ (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) - #else - # define png_jmpbuf(png_ptr) \ - (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) -@@ -1043,12 +1126,12 @@ - * will use it; otherwise it will call PNG_ABORT(). This function was - * added in libpng-1.5.0. - */ --PNG_EXPORTA(9, void, png_longjmp, (png_structp png_ptr, int val), -+PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), - PNG_NORETURN); - - #ifdef PNG_READ_SUPPORTED - /* Reset the compression stream */ --PNG_EXPORT(10, int, png_reset_zstream, (png_structp png_ptr)); -+PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); - #endif - - /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ -@@ -1066,91 +1149,107 @@ - #endif - - /* Write the PNG file signature. */ --PNG_EXPORT(13, void, png_write_sig, (png_structp png_ptr)); -+PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); - - /* Write a PNG chunk - size, type, (optional) data, CRC. */ --PNG_EXPORT(14, void, png_write_chunk, (png_structp png_ptr, png_const_bytep -+PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep - chunk_name, png_const_bytep data, png_size_t length)); - - /* Write the start of a PNG chunk - length and chunk name. */ --PNG_EXPORT(15, void, png_write_chunk_start, (png_structp png_ptr, -+PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, - png_const_bytep chunk_name, png_uint_32 length)); - - /* Write the data of a PNG chunk started with png_write_chunk_start(). */ --PNG_EXPORT(16, void, png_write_chunk_data, (png_structp png_ptr, -+PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, - png_const_bytep data, png_size_t length)); - - /* Finish a chunk started with png_write_chunk_start() (includes CRC). */ --PNG_EXPORT(17, void, png_write_chunk_end, (png_structp png_ptr)); -+PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); - - /* Allocate and initialize the info structure */ --PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_structp png_ptr), -+PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), - PNG_ALLOCATED); - --PNG_EXPORT(19, void, png_info_init_3, (png_infopp info_ptr, -- png_size_t png_info_struct_size)); -+/* DEPRECATED: this function allowed init structures to be created using the -+ * default allocation method (typically malloc). Use is deprecated in 1.6.0 and -+ * the API will be removed in the future. -+ */ -+PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, -+ png_size_t png_info_struct_size), PNG_DEPRECATED); - - /* Writes all the PNG information before the image. */ - PNG_EXPORT(20, void, png_write_info_before_PLTE, -- (png_structp png_ptr, png_infop info_ptr)); -+ (png_structrp png_ptr, png_const_inforp info_ptr)); - PNG_EXPORT(21, void, png_write_info, -- (png_structp png_ptr, png_infop info_ptr)); -+ (png_structrp png_ptr, png_const_inforp info_ptr)); - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read the information before the actual image data. */ - PNG_EXPORT(22, void, png_read_info, -- (png_structp png_ptr, png_infop info_ptr)); -+ (png_structrp png_ptr, png_inforp info_ptr)); - #endif - - #ifdef PNG_TIME_RFC1123_SUPPORTED --PNG_EXPORT(23, png_const_charp, png_convert_to_rfc1123, -- (png_structp png_ptr, -+ /* Convert to a US string format: there is no localization support in this -+ * routine. The original implementation used a 29 character buffer in -+ * png_struct, this will be removed in future versions. -+ */ -+#if PNG_LIBPNG_VER < 10700 -+/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ -+PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, -+ png_const_timep ptime),PNG_DEPRECATED); -+#endif -+PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], - png_const_timep ptime)); - #endif - - #ifdef PNG_CONVERT_tIME_SUPPORTED - /* Convert from a struct tm to png_time */ - PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, -- PNG_CONST struct tm FAR * ttime)); -+ const struct tm * ttime)); - - /* Convert from time_t to png_time. Uses gmtime() */ --PNG_EXPORT(25, void, png_convert_from_time_t, -- (png_timep ptime, time_t ttime)); --#endif /* PNG_CONVERT_tIME_SUPPORTED */ -+PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime)); -+#endif /* CONVERT_tIME */ - - #ifdef PNG_READ_EXPAND_SUPPORTED - /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ --PNG_EXPORT(26, void, png_set_expand, (png_structp png_ptr)); --PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structp png_ptr)); --PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structp png_ptr)); --PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structp png_ptr)); -+PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); -+PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); -+PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); -+PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); - #endif - - #ifdef PNG_READ_EXPAND_16_SUPPORTED - /* Expand to 16-bit channels, forces conversion of palette to RGB and expansion - * of a tRNS chunk if present. - */ --PNG_EXPORT(221, void, png_set_expand_16, (png_structp png_ptr)); -+PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) - /* Use blue, green, red order for pixels. */ --PNG_EXPORT(30, void, png_set_bgr, (png_structp png_ptr)); -+PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); - #endif - - #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* Expand the grayscale to 24-bit RGB if necessary. */ --PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structp png_ptr)); -+PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); - #endif - - #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Reduce RGB to grayscale. */ --PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structp png_ptr, -- int error_action, double red, double green)); --PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structp png_ptr, -- int error_action, png_fixed_point red, png_fixed_point green)); -- --PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structp -+#define PNG_ERROR_ACTION_NONE 1 -+#define PNG_ERROR_ACTION_WARN 2 -+#define PNG_ERROR_ACTION_ERROR 3 -+#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ -+ -+PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, -+ int error_action, double red, double green)) -+PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, -+ int error_action, png_fixed_point red, png_fixed_point green)) -+ -+PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp - png_ptr)); - #endif - -@@ -1160,9 +1259,9 @@ - #endif - - #ifdef PNG_READ_ALPHA_MODE_SUPPORTED --/* How the alpha channel is interpreted - this affects how the color channels of -- * a PNG file are returned when an alpha channel, or tRNS chunk in a palette -- * file, is present. -+/* How the alpha channel is interpreted - this affects how the color channels -+ * of a PNG file are returned to the calling application when an alpha channel, -+ * or a tRNS chunk in a palette file, is present. - * - * This has no effect on the way pixels are written into a PNG output - * datastream. The color samples in a PNG datastream are never premultiplied -@@ -1170,33 +1269,19 @@ - * - * The default is to return data according to the PNG specification: the alpha - * channel is a linear measure of the contribution of the pixel to the -- * corresponding composited pixel. The gamma encoded color channels must be -- * scaled according to the contribution and to do this it is necessary to undo -+ * corresponding composited pixel, and the color channels are unassociated -+ * (not premultiplied). The gamma encoded color channels must be scaled -+ * according to the contribution and to do this it is necessary to undo - * the encoding, scale the color values, perform the composition and reencode - * the values. This is the 'PNG' mode. - * - * The alternative is to 'associate' the alpha with the color information by -- * storing color channel values that have been scaled by the alpha. The -- * advantage is that the color channels can be resampled (the image can be -- * scaled) in this form. The disadvantage is that normal practice is to store -- * linear, not (gamma) encoded, values and this requires 16-bit channels for -- * still images rather than the 8-bit channels that are just about sufficient if -- * gamma encoding is used. In addition all non-transparent pixel values, -- * including completely opaque ones, must be gamma encoded to produce the final -- * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the -- * latter being the two common names for associated alpha color channels.) -+ * storing color channel values that have been scaled by the alpha. -+ * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes -+ * (the latter being the two common names for associated alpha color channels). - * -- * Since it is not necessary to perform arithmetic on opaque color values so -- * long as they are not to be resampled and are in the final color space it is -- * possible to optimize the handling of alpha by storing the opaque pixels in -- * the PNG format (adjusted for the output color space) while storing partially -- * opaque pixels in the standard, linear, format. The accuracy required for -- * standard alpha composition is relatively low, because the pixels are -- * isolated, therefore typically the accuracy loss in storing 8-bit linear -- * values is acceptable. (This is not true if the alpha channel is used to -- * simulate transparency over large areas - use 16 bits or the PNG mode in -- * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is -- * treated as opaque only if the alpha value is equal to the maximum value. -+ * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha -+ * value is equal to the maximum value. - * - * The final choice is to gamma encode the alpha channel as well. This is - * broken because, in practice, no implementation that uses this choice -@@ -1215,76 +1300,15 @@ - #define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ - #define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ - --PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structp png_ptr, int mode, -- double output_gamma)); --PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structp png_ptr, -- int mode, png_fixed_point output_gamma)); -+PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, -+ double output_gamma)) -+PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, -+ int mode, png_fixed_point output_gamma)) - #endif - --#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) -+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) - /* The output_gamma value is a screen gamma in libpng terminology: it expresses -- * how to decode the output values, not how they are encoded. The values used -- * correspond to the normal numbers used to describe the overall gamma of a -- * computer display system; for example 2.2 for an sRGB conformant system. The -- * values are scaled by 100000 in the _fixed version of the API (so 220000 for -- * sRGB.) -- * -- * The inverse of the value is always used to provide a default for the PNG file -- * encoding if it has no gAMA chunk and if png_set_gamma() has not been called -- * to override the PNG gamma information. -- * -- * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode -- * opaque pixels however pixels with lower alpha values are not encoded, -- * regardless of the output gamma setting. -- * -- * When the standard Porter Duff handling is requested with mode 1 the output -- * encoding is set to be linear and the output_gamma value is only relevant -- * as a default for input data that has no gamma information. The linear output -- * encoding will be overridden if png_set_gamma() is called - the results may be -- * highly unexpected! -- * -- * The following numbers are derived from the sRGB standard and the research -- * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of -- * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing -- * correction required to take account of any differences in the color -- * environment of the original scene and the intended display environment; the -- * value expresses how to *decode* the image for display, not how the original -- * data was *encoded*. -- * -- * sRGB provides a peg for the PNG standard by defining a viewing environment. -- * sRGB itself, and earlier TV standards, actually use a more complex transform -- * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is -- * limited to simple power laws.) By saying that an image for direct display on -- * an sRGB conformant system should be stored with a gAMA chunk value of 45455 -- * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification -- * makes it possible to derive values for other display systems and -- * environments. -- * -- * The Mac value is deduced from the sRGB based on an assumption that the actual -- * extra viewing correction used in early Mac display systems was implemented as -- * a power 1.45 lookup table. -- * -- * Any system where a programmable lookup table is used or where the behavior of -- * the final display device characteristics can be changed requires system -- * specific code to obtain the current characteristic. However this can be -- * difficult and most PNG gamma correction only requires an approximate value. -- * -- * By default, if png_set_alpha_mode() is not called, libpng assumes that all -- * values are unencoded, linear, values and that the output device also has a -- * linear characteristic. This is only very rarely correct - it is invariably -- * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the -- * default if you don't know what the right answer is! -- * -- * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS -- * 10.6) which used a correction table to implement a somewhat lower gamma on an -- * otherwise sRGB system. -- * -- * Both these values are reserved (not simple gamma values) in order to allow -- * more precise correction internally in the future. -- * -- * NOTE: the following values can be passed to either the fixed or floating -- * point APIs, but the floating point API will also accept floating point -- * values. -+ * how to decode the output values, not how they are encoded. - */ - #define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ - #define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ -@@ -1351,7 +1375,7 @@ - * - * When the default gamma of PNG files doesn't match the output gamma. - * If you have PNG files with no gamma information png_set_alpha_mode allows -- * you to provide a default gamma, but it also sets the output gamma to the -+ * you to provide a default gamma, but it also sets the ouput gamma to the - * matching value. If you know your PNG files have a gamma that doesn't - * match the output you can take advantage of the fact that - * png_set_alpha_mode always sets the output gamma but only sets the PNG -@@ -1369,51 +1393,50 @@ - */ - - #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED --PNG_EXPORT(36, void, png_set_strip_alpha, (png_structp png_ptr)); -+PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) --PNG_EXPORT(37, void, png_set_swap_alpha, (png_structp png_ptr)); -+PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) --PNG_EXPORT(38, void, png_set_invert_alpha, (png_structp png_ptr)); -+PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) - /* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ --PNG_EXPORT(39, void, png_set_filler, (png_structp png_ptr, png_uint_32 filler, -+PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, - int flags)); - /* The values of the PNG_FILLER_ defines should NOT be changed */ - # define PNG_FILLER_BEFORE 0 - # define PNG_FILLER_AFTER 1 - /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ --PNG_EXPORT(40, void, png_set_add_alpha, -- (png_structp png_ptr, png_uint_32 filler, -- int flags)); --#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ -+PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, -+ png_uint_32 filler, int flags)); -+#endif /* READ_FILLER || WRITE_FILLER */ - - #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) - /* Swap bytes in 16-bit depth files. */ --PNG_EXPORT(41, void, png_set_swap, (png_structp png_ptr)); -+PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) - /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ --PNG_EXPORT(42, void, png_set_packing, (png_structp png_ptr)); -+PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) - /* Swap packing order of pixels in bytes. */ --PNG_EXPORT(43, void, png_set_packswap, (png_structp png_ptr)); -+PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - /* Converts files to legal bit depths. */ --PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_color_8p -+PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p - true_bits)); - #endif - -@@ -1425,12 +1448,12 @@ - * necessary to call png_read_row or png_read_rows png_get_image_height - * times for each pass. - */ --PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr)); -+PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); - #endif - - #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) - /* Invert monochrome files */ --PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr)); -+PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); - #endif - - #ifdef PNG_READ_BACKGROUND_SUPPORTED -@@ -1439,12 +1462,12 @@ - * read. Doing so will result in unexpected behavior and possible warnings or - * errors if the PNG file contains a bKGD chunk. - */ --PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr, -+PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, -- int need_expand, double background_gamma)); --PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr, -+ int need_expand, double background_gamma)) -+PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, -- int need_expand, png_fixed_point background_gamma)); -+ int need_expand, png_fixed_point background_gamma)) - #endif - #ifdef PNG_READ_BACKGROUND_SUPPORTED - # define PNG_BACKGROUND_GAMMA_UNKNOWN 0 -@@ -1455,23 +1478,22 @@ - - #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - /* Scale a 16-bit depth file down to 8-bit, accurately. */ --PNG_EXPORT(229, void, png_set_scale_16, (png_structp png_ptr)); -+PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); - #endif - - #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - #define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ - /* Strip the second byte of information from a 16-bit depth file. */ --PNG_EXPORT(48, void, png_set_strip_16, (png_structp png_ptr)); -+PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); - #endif - - #ifdef PNG_READ_QUANTIZE_SUPPORTED - /* Turn on quantizing, and reduce the palette to the number of colors - * available. - */ --PNG_EXPORT(49, void, png_set_quantize, -- (png_structp png_ptr, png_colorp palette, -- int num_palette, int maximum_colors, png_const_uint_16p histogram, -- int full_quantize)); -+PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, -+ png_colorp palette, int num_palette, int maximum_colors, -+ png_const_uint_16p histogram, int full_quantize)); - #endif - - #ifdef PNG_READ_GAMMA_SUPPORTED -@@ -1491,71 +1513,69 @@ - * API (floating point or fixed.) Notice, however, that the 'file_gamma' value - * is the inverse of a 'screen gamma' value. - */ --PNG_FP_EXPORT(50, void, png_set_gamma, -- (png_structp png_ptr, double screen_gamma, -- double override_file_gamma)); --PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structp png_ptr, -- png_fixed_point screen_gamma, png_fixed_point override_file_gamma)); -+PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, -+ double screen_gamma, double override_file_gamma)) -+PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, -+ png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) - #endif - - #ifdef PNG_WRITE_FLUSH_SUPPORTED - /* Set how many lines between output flushes - 0 for no flushing */ --PNG_EXPORT(51, void, png_set_flush, (png_structp png_ptr, int nrows)); -+PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows)); - /* Flush the current PNG output buffer */ --PNG_EXPORT(52, void, png_write_flush, (png_structp png_ptr)); -+PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); - #endif - - /* Optional update palette with requested transformations */ --PNG_EXPORT(53, void, png_start_read_image, (png_structp png_ptr)); -+PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); - - /* Optional call to update the users info structure */ --PNG_EXPORT(54, void, png_read_update_info, -- (png_structp png_ptr, png_infop info_ptr)); -+PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, -+ png_inforp info_ptr)); - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read one or more rows of image data. */ --PNG_EXPORT(55, void, png_read_rows, (png_structp png_ptr, png_bytepp row, -+PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows)); - #endif - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read a row of data. */ --PNG_EXPORT(56, void, png_read_row, (png_structp png_ptr, png_bytep row, -+PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, - png_bytep display_row)); - #endif - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read the whole image into memory at once. */ --PNG_EXPORT(57, void, png_read_image, (png_structp png_ptr, png_bytepp image)); -+PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); - #endif - - /* Write a row of image data */ --PNG_EXPORT(58, void, png_write_row, -- (png_structp png_ptr, png_const_bytep row)); -+PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, -+ png_const_bytep row)); - - /* Write a few rows of image data: (*row) is not written; however, the type - * is declared as writeable to maintain compatibility with previous versions - * of libpng and to allow the 'display_row' array from read_rows to be passed - * unchanged to write_rows. - */ --PNG_EXPORT(59, void, png_write_rows, (png_structp png_ptr, png_bytepp row, -+PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, - png_uint_32 num_rows)); - - /* Write the image data */ --PNG_EXPORT(60, void, png_write_image, -- (png_structp png_ptr, png_bytepp image)); -+PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); - - /* Write the end of the PNG file. */ --PNG_EXPORT(61, void, png_write_end, -- (png_structp png_ptr, png_infop info_ptr)); -+PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, -+ png_inforp info_ptr)); - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read the end of the PNG file. */ --PNG_EXPORT(62, void, png_read_end, (png_structp png_ptr, png_infop info_ptr)); -+PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); - #endif - - /* Free any memory associated with the png_info_struct */ --PNG_EXPORT(63, void, png_destroy_info_struct, (png_structp png_ptr, -+PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, - png_infopp info_ptr_ptr)); - - /* Free any memory associated with the png_struct and the png_info_structs */ -@@ -1567,8 +1587,8 @@ - png_infopp info_ptr_ptr)); - - /* Set the libpng method of handling chunk CRC errors */ --PNG_EXPORT(66, void, png_set_crc_action, -- (png_structp png_ptr, int crit_action, int ancil_action)); -+PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, -+ int ancil_action)); - - /* Values for png_set_crc_action() say how to handle CRC errors in - * ancillary and critical chunks, and whether to use the data contained -@@ -1597,8 +1617,8 @@ - /* Set the filtering method(s) used by libpng. Currently, the only valid - * value for "method" is 0. - */ --PNG_EXPORT(67, void, png_set_filter, -- (png_structp png_ptr, int method, int filters)); -+PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, -+ int filters)); - - /* Flags for png_set_filter() to say which filters to use. The flags - * are chosen so that they don't conflict with real filter types -@@ -1653,14 +1673,14 @@ - * the weights and costs are set to 1.0, this degenerates the WEIGHTED method - * to the UNWEIGHTED method, but with added encoding time/computation. - */ --PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structp png_ptr, -+PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, - int heuristic_method, int num_weights, png_const_doublep filter_weights, -- png_const_doublep filter_costs)); -+ png_const_doublep filter_costs)) - PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, -- (png_structp png_ptr, -- int heuristic_method, int num_weights, png_const_fixed_point_p -- filter_weights, png_const_fixed_point_p filter_costs)); --#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ -+ (png_structrp png_ptr, int heuristic_method, int num_weights, -+ png_const_fixed_point_p filter_weights, -+ png_const_fixed_point_p filter_costs)) -+#endif /* WRITE_WEIGHTED_FILTER */ - - /* Heuristic used for row filter selection. These defines should NOT be - * changed. -@@ -1678,45 +1698,45 @@ - * for PNG images, and do considerably fewer caclulations. In the future, - * these values may not correspond directly to the zlib compression levels. - */ --PNG_EXPORT(69, void, png_set_compression_level, -- (png_structp png_ptr, int level)); -- --PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structp png_ptr, -+PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr, -+ int level)); -+ -+PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, - int mem_level)); - --PNG_EXPORT(71, void, png_set_compression_strategy, (png_structp png_ptr, -+PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr, - int strategy)); - - /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ --PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structp png_ptr, -+PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr, - int window_bits)); - --PNG_EXPORT(73, void, png_set_compression_method, (png_structp png_ptr, -+PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr, - int method)); - #endif - - #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - /* Also set zlib parameters for compressing non-IDAT chunks */ --PNG_EXPORT(222, void, png_set_text_compression_level, -- (png_structp png_ptr, int level)); -- --PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structp png_ptr, -+PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr, -+ int level)); -+ -+PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, - int mem_level)); - --PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structp png_ptr, -+PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, - int strategy)); - - /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ --PNG_EXPORT(225, void, png_set_text_compression_window_bits, (png_structp -- png_ptr, int window_bits)); -- --PNG_EXPORT(226, void, png_set_text_compression_method, (png_structp png_ptr, -+PNG_EXPORT(225, void, png_set_text_compression_window_bits, -+ (png_structrp png_ptr, int window_bits)); -+ -+PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, - int method)); --#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ -+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ - - /* These next functions are called for input/output, memory, and error - * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, -@@ -1729,7 +1749,7 @@ - - #ifdef PNG_STDIO_SUPPORTED - /* Initialize the input/output for the PNG file to the default functions. */ --PNG_EXPORT(74, void, png_init_io, (png_structp png_ptr, png_FILE_p fp)); -+PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); - #endif - - /* Replace the (error and abort), and warning functions with user -@@ -1740,12 +1760,11 @@ - * default function will be used. - */ - --PNG_EXPORT(75, void, png_set_error_fn, -- (png_structp png_ptr, png_voidp error_ptr, -- png_error_ptr error_fn, png_error_ptr warning_fn)); -+PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, -+ png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); - - /* Return the user pointer associated with the error functions */ --PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structp png_ptr)); -+PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); - - /* Replace the default data output functions with a user supplied one(s). - * If buffered output is not used, then output_flush_fn can be set to NULL. -@@ -1757,47 +1776,47 @@ - * default flush function, which uses the standard *FILE structure, will - * be used. - */ --PNG_EXPORT(77, void, png_set_write_fn, (png_structp png_ptr, png_voidp io_ptr, -+PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); - - /* Replace the default data input function with a user supplied one. */ --PNG_EXPORT(78, void, png_set_read_fn, (png_structp png_ptr, png_voidp io_ptr, -+PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn)); - - /* Return the user pointer associated with the I/O functions */ --PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_structp png_ptr)); -- --PNG_EXPORT(80, void, png_set_read_status_fn, (png_structp png_ptr, -+PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); -+ -+PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, - png_read_status_ptr read_row_fn)); - --PNG_EXPORT(81, void, png_set_write_status_fn, (png_structp png_ptr, -+PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, - png_write_status_ptr write_row_fn)); - - #ifdef PNG_USER_MEM_SUPPORTED - /* Replace the default memory allocation functions with user supplied one(s). */ --PNG_EXPORT(82, void, png_set_mem_fn, (png_structp png_ptr, png_voidp mem_ptr, -+PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn)); - /* Return the user pointer associated with the memory functions */ --PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structp png_ptr)); -+PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); - #endif - - #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED --PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structp png_ptr, -+PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr read_user_transform_fn)); - #endif - - #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED --PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structp png_ptr, -+PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr write_user_transform_fn)); - #endif - - #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED --PNG_EXPORT(86, void, png_set_user_transform_info, (png_structp png_ptr, -+PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, - png_voidp user_transform_ptr, int user_transform_depth, - int user_transform_channels)); - /* Return the user pointer associated with the user transform functions */ - PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - #endif - - #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -@@ -1812,31 +1831,53 @@ - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ --PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structp)); --PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structp)); -+PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); -+PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); - #endif - -+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -+/* This callback is called only for *unknown* chunks. If -+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known -+ * chunks to be treated as unknown, however in this case the callback must do -+ * any processing required by the chunk (e.g. by calling the appropriate -+ * png_set_ APIs.) -+ * -+ * There is no write support - on write, by default, all the chunks in the -+ * 'unknown' list are written in the specified position. -+ * -+ * The integer return from the callback function is interpreted thus: -+ * -+ * negative: An error occured, png_chunk_error will be called. -+ * zero: The chunk was not handled, the chunk will be saved. A critical -+ * chunk will cause an error at this point unless it is to be saved. -+ * positive: The chunk was handled, libpng will ignore/discard it. -+ * -+ * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about -+ * how this behavior will change in libpng 1.7 -+ */ -+PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, -+ png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); -+#endif -+ - #ifdef PNG_USER_CHUNKS_SUPPORTED --PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structp png_ptr, -- png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); --PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structp png_ptr)); -+PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); - #endif - - #ifdef PNG_PROGRESSIVE_READ_SUPPORTED - /* Sets the function callbacks for the push reader, and a pointer to a - * user-defined structure available to the callback functions. - */ --PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structp png_ptr, -+PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, - png_voidp progressive_ptr, png_progressive_info_ptr info_fn, - png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); - - /* Returns the user pointer associated with the push read functions */ --PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, (png_const_structp png_ptr)); -+PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, -+ (png_const_structrp png_ptr)); - - /* Function to be called when data becomes available */ --PNG_EXPORT(92, void, png_process_data, -- (png_structp png_ptr, png_infop info_ptr, -- png_bytep buffer, png_size_t buffer_size)); -+PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, -+ png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size)); - - /* A function which may be called *only* within png_process_data to stop the - * processing of any more data. The function returns the number of bytes -@@ -1845,7 +1886,7 @@ - * 'save' is set to true the routine will first save all the pending data and - * will always return 0. - */ --PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structp, int save)); -+PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save)); - - /* A function which may be called *only* outside (after) a call to - * png_process_data. It returns the number of bytes of data to skip in the -@@ -1853,40 +1894,43 @@ - * application must skip than number of bytes of input data and pass the - * following data to the next call to png_process_data. - */ --PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp)); -+PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); - - /* Function that combines rows. 'new_row' is a flag that should come from - * the callback and be non-NULL if anything needs to be done; the library - * stores its own version of the new data internally and ignores the passed - * in value. - */ --PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr, -+PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, - png_bytep old_row, png_const_bytep new_row)); --#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -- --PNG_EXPORTA(94, png_voidp, png_malloc, -- (png_structp png_ptr, png_alloc_size_t size), -- PNG_ALLOCATED); -+#endif /* PROGRESSIVE_READ */ -+ -+PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, -+ png_alloc_size_t size), PNG_ALLOCATED); - /* Added at libpng version 1.4.0 */ --PNG_EXPORTA(95, png_voidp, png_calloc, -- (png_structp png_ptr, png_alloc_size_t size), -- PNG_ALLOCATED); -+PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, -+ png_alloc_size_t size), PNG_ALLOCATED); - - /* Added at libpng version 1.2.4 */ --PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_structp png_ptr, -+PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - - /* Frees a pointer allocated by png_malloc() */ --PNG_EXPORT(97, void, png_free, (png_structp png_ptr, png_voidp ptr)); -+PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); - - /* Free data that was allocated internally */ --PNG_EXPORT(98, void, png_free_data, -- (png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); -+PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 free_me, int num)); - - /* Reassign responsibility for freeing existing data, whether allocated -- * by libpng or by the application */ --PNG_EXPORT(99, void, png_data_freer, -- (png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); -+ * by libpng or by the application; this works on the png_info structure passed -+ * in, it does not change the state for other png_info structures. -+ * -+ * It is unlikely that this function works correctly as of 1.6.0 and using it -+ * may result either in memory leaks or double free of allocated data. -+ */ -+PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, -+ png_inforp info_ptr, int freer, png_uint_32 mask)); - - /* Assignments for png_data_freer */ - #define PNG_DESTROY_WILL_FREE_DATA 1 -@@ -1899,8 +1943,10 @@ - #define PNG_FREE_ROWS 0x0040 - #define PNG_FREE_PCAL 0x0080 - #define PNG_FREE_SCAL 0x0100 --#define PNG_FREE_UNKN 0x0200 --#define PNG_FREE_LIST 0x0400 -+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -+# define PNG_FREE_UNKN 0x0200 -+#endif -+/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */ - #define PNG_FREE_PLTE 0x1000 - #define PNG_FREE_TRNS 0x2000 - #define PNG_FREE_TEXT 0x4000 -@@ -1908,50 +1954,55 @@ - #define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ - - #ifdef PNG_USER_MEM_SUPPORTED --PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_structp png_ptr, -- png_alloc_size_t size), PNG_ALLOCATED); --PNG_EXPORT(101, void, png_free_default, (png_structp png_ptr, png_voidp ptr)); -+PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, -+ png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); -+PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, -+ png_voidp ptr), PNG_DEPRECATED); - #endif - - #ifdef PNG_ERROR_TEXT_SUPPORTED - /* Fatal error in PNG image of libpng - can't continue */ --PNG_EXPORTA(102, void, png_error, -- (png_structp png_ptr, png_const_charp error_message), -- PNG_NORETURN); -+PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, -+ png_const_charp error_message), PNG_NORETURN); - - /* The same, but the chunk name is prepended to the error string. */ --PNG_EXPORTA(103, void, png_chunk_error, (png_structp png_ptr, -+PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, - png_const_charp error_message), PNG_NORETURN); - - #else - /* Fatal error in PNG image of libpng - can't continue */ --PNG_EXPORTA(104, void, png_err, (png_structp png_ptr), PNG_NORETURN); -+PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); -+# define png_error(s1,s2) png_err(s1) -+# define png_chunk_error(s1,s2) png_err(s1) - #endif - - #ifdef PNG_WARNINGS_SUPPORTED - /* Non-fatal error in libpng. Can continue, but may have a problem. */ --PNG_EXPORT(105, void, png_warning, (png_structp png_ptr, -+PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); - - /* Non-fatal error in libpng, chunk name is prepended to message. */ --PNG_EXPORT(106, void, png_chunk_warning, (png_structp png_ptr, -+PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); -+#else -+# define png_warning(s1,s2) ((void)(s1)) -+# define png_chunk_warning(s1,s2) ((void)(s1)) - #endif - - #ifdef PNG_BENIGN_ERRORS_SUPPORTED - /* Benign error in libpng. Can continue, but may have a problem. - * User can choose whether to handle as a fatal error or as a warning. */ --# undef png_benign_error --PNG_EXPORT(107, void, png_benign_error, (png_structp png_ptr, -+PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); - --/* Same, chunk name is prepended to message. */ --# undef png_chunk_benign_error --PNG_EXPORT(108, void, png_chunk_benign_error, (png_structp png_ptr, -+#ifdef PNG_READ_SUPPORTED -+/* Same, chunk name is prepended to message (only during read) */ -+PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); -+#endif - - PNG_EXPORT(109, void, png_set_benign_errors, -- (png_structp png_ptr, int allowed)); -+ (png_structrp png_ptr, int allowed)); - #else - # ifdef PNG_ALLOW_BENIGN_ERRORS - # define png_benign_error png_warning -@@ -1975,268 +2026,274 @@ - * png_info_struct. - */ - /* Returns "flag" if chunk data is valid in info_ptr. */ --PNG_EXPORT(110, png_uint_32, png_get_valid, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_uint_32 flag)); -+PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, png_uint_32 flag)); - - /* Returns number of bytes needed to hold a transformed row. */ --PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - #ifdef PNG_INFO_IMAGE_SUPPORTED - /* Returns row_pointers, which is an array of pointers to scanlines that was - * returned from png_read_png(). - */ --PNG_EXPORT(112, png_bytepp, png_get_rows, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); -+ - /* Set row_pointers, which is an array of pointers to scanlines for use - * by png_write_png(). - */ --PNG_EXPORT(113, void, png_set_rows, (png_structp png_ptr, -- png_infop info_ptr, png_bytepp row_pointers)); -+PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_bytepp row_pointers)); - #endif - - /* Returns number of color channels in image. */ --PNG_EXPORT(114, png_byte, png_get_channels, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - #ifdef PNG_EASY_ACCESS_SUPPORTED - /* Returns image width in pixels. */ --PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - /* Returns image height in pixels. */ --PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - /* Returns image bit_depth. */ --PNG_EXPORT(117, png_byte, png_get_bit_depth, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - /* Returns image color_type. */ --PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - /* Returns image filter_type. */ --PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - /* Returns image interlace_type. */ --PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - /* Returns image compression_type. */ --PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); - - /* Returns image resolution in pixels per meter, from pHYs chunk data. */ - PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - - /* Returns pixel aspect ratio, computed from pHYs chunk data. */ - PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)) - PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)) - - /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ - PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -- --#endif /* PNG_EASY_ACCESS_SUPPORTED */ -- -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); -+ -+#endif /* EASY_ACCESS */ -+ -+#ifdef PNG_READ_SUPPORTED - /* Returns pointer to signature string read from PNG header */ --PNG_EXPORT(130, png_const_bytep, png_get_signature, -- (png_const_structp png_ptr, png_infop info_ptr)); -+PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)); -+#endif - - #ifdef PNG_bKGD_SUPPORTED --PNG_EXPORT(131, png_uint_32, png_get_bKGD, -- (png_const_structp png_ptr, png_infop info_ptr, -- png_color_16p *background)); -+PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_color_16p *background)); - #endif - - #ifdef PNG_bKGD_SUPPORTED --PNG_EXPORT(132, void, png_set_bKGD, (png_structp png_ptr, png_infop info_ptr, -- png_const_color_16p background)); -+PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_color_16p background)); - #endif - - #ifdef PNG_cHRM_SUPPORTED --PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structp png_ptr, -- png_const_infop info_ptr, double *white_x, double *white_y, double *red_x, -+PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, - double *red_y, double *green_x, double *green_y, double *blue_x, -- double *blue_y)); --#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */ -+ double *blue_y)) -+PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, -+ double *green_X, double *green_Y, double *green_Z, double *blue_X, -+ double *blue_Y, double *blue_Z)) - PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, -- (png_const_structp png_ptr, -- png_const_infop info_ptr, png_fixed_point *int_white_x, -- png_fixed_point *int_white_y, png_fixed_point *int_red_x, -- png_fixed_point *int_red_y, png_fixed_point *int_green_x, -- png_fixed_point *int_green_y, png_fixed_point *int_blue_x, -- png_fixed_point *int_blue_y)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr, -+ png_fixed_point *int_white_x, png_fixed_point *int_white_y, -+ png_fixed_point *int_red_x, png_fixed_point *int_red_y, -+ png_fixed_point *int_green_x, png_fixed_point *int_green_y, -+ png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) -+PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, -+ (png_const_structrp png_ptr, png_const_inforp info_ptr, -+ png_fixed_point *int_red_X, png_fixed_point *int_red_Y, -+ png_fixed_point *int_red_Z, png_fixed_point *int_green_X, -+ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, -+ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, -+ png_fixed_point *int_blue_Z)) - #endif --#endif - - #ifdef PNG_cHRM_SUPPORTED --PNG_FP_EXPORT(135, void, png_set_cHRM, -- (png_structp png_ptr, png_infop info_ptr, -+PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, -+ png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, double green_x, -- double green_y, double blue_x, double blue_y)); --PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr, -- png_infop info_ptr, png_fixed_point int_white_x, -+ double green_y, double blue_x, double blue_y)) -+PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, -+ png_inforp info_ptr, double red_X, double red_Y, double red_Z, -+ double green_X, double green_Y, double green_Z, double blue_X, -+ double blue_Y, double blue_Z)) -+PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_fixed_point int_white_x, - png_fixed_point int_white_y, png_fixed_point int_red_x, - png_fixed_point int_red_y, png_fixed_point int_green_x, - png_fixed_point int_green_y, png_fixed_point int_blue_x, -- png_fixed_point int_blue_y)); -+ png_fixed_point int_blue_y)) -+PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, -+ png_fixed_point int_red_Z, png_fixed_point int_green_X, -+ png_fixed_point int_green_Y, png_fixed_point int_green_Z, -+ png_fixed_point int_blue_X, png_fixed_point int_blue_Y, -+ png_fixed_point int_blue_Z)) - #endif - - #ifdef PNG_gAMA_SUPPORTED --PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- double *file_gamma)); -+PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, double *file_gamma)) - PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_fixed_point *int_file_gamma)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr, -+ png_fixed_point *int_file_gamma)) - #endif - - #ifdef PNG_gAMA_SUPPORTED --PNG_FP_EXPORT(139, void, png_set_gAMA, (png_structp png_ptr, -- png_infop info_ptr, double file_gamma)); --PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_structp png_ptr, -- png_infop info_ptr, png_fixed_point int_file_gamma)); -+PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, -+ png_inforp info_ptr, double file_gamma)) -+PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_fixed_point int_file_gamma)) - #endif - - #ifdef PNG_hIST_SUPPORTED --PNG_EXPORT(141, png_uint_32, png_get_hIST, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_uint_16p *hist)); -+PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_uint_16p *hist)); - #endif - - #ifdef PNG_hIST_SUPPORTED --PNG_EXPORT(142, void, png_set_hIST, (png_structp png_ptr, -- png_infop info_ptr, png_const_uint_16p hist)); -+PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_uint_16p hist)); - #endif - --PNG_EXPORT(143, png_uint_32, png_get_IHDR, -- (png_structp png_ptr, png_infop info_ptr, -- png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, -- int *interlace_method, int *compression_method, int *filter_method)); -- --PNG_EXPORT(144, void, png_set_IHDR, -- (png_structp png_ptr, png_infop info_ptr, -- png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, -- int interlace_method, int compression_method, int filter_method)); -+PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, -+ int *bit_depth, int *color_type, int *interlace_method, -+ int *compression_method, int *filter_method)); -+ -+PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, -+ int color_type, int interlace_method, int compression_method, -+ int filter_method)); - - #ifdef PNG_oFFs_SUPPORTED --PNG_EXPORT(145, png_uint_32, png_get_oFFs, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); -+PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, -+ int *unit_type)); - #endif - - #ifdef PNG_oFFs_SUPPORTED --PNG_EXPORT(146, void, png_set_oFFs, -- (png_structp png_ptr, png_infop info_ptr, -- png_int_32 offset_x, png_int_32 offset_y, int unit_type)); -+PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, -+ int unit_type)); - #endif - - #ifdef PNG_pCAL_SUPPORTED --PNG_EXPORT(147, png_uint_32, png_get_pCAL, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, -- int *nparams, -- png_charp *units, png_charpp *params)); -+PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, -+ png_int_32 *X1, int *type, int *nparams, png_charp *units, -+ png_charpp *params)); - #endif - - #ifdef PNG_pCAL_SUPPORTED --PNG_EXPORT(148, void, png_set_pCAL, (png_structp png_ptr, -- png_infop info_ptr, -- png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, -- int nparams, png_const_charp units, png_charpp params)); -+PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, -+ int type, int nparams, png_const_charp units, png_charpp params)); - #endif - - #ifdef PNG_pHYs_SUPPORTED --PNG_EXPORT(149, png_uint_32, png_get_pHYs, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); -+PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, -+ int *unit_type)); - #endif - - #ifdef PNG_pHYs_SUPPORTED --PNG_EXPORT(150, void, png_set_pHYs, -- (png_structp png_ptr, png_infop info_ptr, -- png_uint_32 res_x, png_uint_32 res_y, int unit_type)); -+PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); - #endif - --PNG_EXPORT(151, png_uint_32, png_get_PLTE, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_colorp *palette, int *num_palette)); -- --PNG_EXPORT(152, void, png_set_PLTE, -- (png_structp png_ptr, png_infop info_ptr, -- png_const_colorp palette, int num_palette)); -+PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_colorp *palette, int *num_palette)); -+ -+PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, -+ png_inforp info_ptr, png_const_colorp palette, int num_palette)); - - #ifdef PNG_sBIT_SUPPORTED --PNG_EXPORT(153, png_uint_32, png_get_sBIT, -- (png_const_structp png_ptr, png_infop info_ptr, -- png_color_8p *sig_bit)); -+PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_color_8p *sig_bit)); - #endif - - #ifdef PNG_sBIT_SUPPORTED --PNG_EXPORT(154, void, png_set_sBIT, -- (png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit)); -+PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_color_8p sig_bit)); - #endif - - #ifdef PNG_sRGB_SUPPORTED --PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structp png_ptr, -- png_const_infop info_ptr, int *file_srgb_intent)); -+PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, int *file_srgb_intent)); - #endif - - #ifdef PNG_sRGB_SUPPORTED --PNG_EXPORT(156, void, png_set_sRGB, -- (png_structp png_ptr, png_infop info_ptr, int srgb_intent)); --PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_structp png_ptr, -- png_infop info_ptr, int srgb_intent)); -+PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, -+ png_inforp info_ptr, int srgb_intent)); -+PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, -+ png_inforp info_ptr, int srgb_intent)); - #endif - - #ifdef PNG_iCCP_SUPPORTED --PNG_EXPORT(158, png_uint_32, png_get_iCCP, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_charpp name, int *compression_type, png_bytepp profile, -- png_uint_32 *proflen)); -+PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_charpp name, int *compression_type, -+ png_bytepp profile, png_uint_32 *proflen)); - #endif - - #ifdef PNG_iCCP_SUPPORTED --PNG_EXPORT(159, void, png_set_iCCP, -- (png_structp png_ptr, png_infop info_ptr, -- png_const_charp name, int compression_type, png_const_bytep profile, -- png_uint_32 proflen)); -+PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_charp name, int compression_type, -+ png_const_bytep profile, png_uint_32 proflen)); - #endif - - #ifdef PNG_sPLT_SUPPORTED --PNG_EXPORT(160, png_uint_32, png_get_sPLT, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_sPLT_tpp entries)); -+PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_sPLT_tpp entries)); - #endif - - #ifdef PNG_sPLT_SUPPORTED --PNG_EXPORT(161, void, png_set_sPLT, -- (png_structp png_ptr, png_infop info_ptr, -- png_const_sPLT_tp entries, int nentries)); -+PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); - #endif - - #ifdef PNG_TEXT_SUPPORTED - /* png_get_text also returns the number of text chunks in *num_text */ --PNG_EXPORT(162, png_uint_32, png_get_text, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- png_textp *text_ptr, int *num_text)); -+PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_textp *text_ptr, int *num_text)); - #endif - - /* Note while png_set_text() will accept a structure whose text, -@@ -2247,116 +2304,220 @@ - */ - - #ifdef PNG_TEXT_SUPPORTED --PNG_EXPORT(163, void, png_set_text, -- (png_structp png_ptr, png_infop info_ptr, -- png_const_textp text_ptr, int num_text)); -+PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_textp text_ptr, int num_text)); - #endif - - #ifdef PNG_tIME_SUPPORTED --PNG_EXPORT(164, png_uint_32, png_get_tIME, -- (png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); -+PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_timep *mod_time)); - #endif - - #ifdef PNG_tIME_SUPPORTED --PNG_EXPORT(165, void, png_set_tIME, -- (png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)); -+PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_timep mod_time)); - #endif - - #ifdef PNG_tRNS_SUPPORTED --PNG_EXPORT(166, png_uint_32, png_get_tRNS, -- (png_const_structp png_ptr, png_infop info_ptr, -- png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)); -+PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, -+ png_color_16p *trans_color)); - #endif - - #ifdef PNG_tRNS_SUPPORTED --PNG_EXPORT(167, void, png_set_tRNS, -- (png_structp png_ptr, png_infop info_ptr, -- png_const_bytep trans_alpha, int num_trans, -+PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, -+ png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, - png_const_color_16p trans_color)); - #endif - - #ifdef PNG_sCAL_SUPPORTED --PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- int *unit, double *width, double *height)); --#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -+PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, int *unit, double *width, double *height)) -+#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ -+ defined(PNG_FLOATING_POINT_SUPPORTED) - /* NOTE: this API is currently implemented using floating point arithmetic, - * consequently it can only be used on systems with floating point support. - * In any case the range of values supported by png_fixed_point is small and it - * is highly recommended that png_get_sCAL_s be used instead. - */ - PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, -- (png_structp png_ptr, png_const_infop info_ptr, int *unit, -- png_fixed_point *width, -- png_fixed_point *height)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, -+ png_fixed_point *width, png_fixed_point *height)) - #endif - PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, -- (png_const_structp png_ptr, png_const_infop info_ptr, -- int *unit, png_charpp swidth, png_charpp sheight)); -- --PNG_FP_EXPORT(170, void, png_set_sCAL, -- (png_structp png_ptr, png_infop info_ptr, -- int unit, double width, double height)); --PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_structp png_ptr, -- png_infop info_ptr, int unit, png_fixed_point width, -- png_fixed_point height)); --PNG_EXPORT(171, void, png_set_sCAL_s, -- (png_structp png_ptr, png_infop info_ptr, -- int unit, png_const_charp swidth, png_const_charp sheight)); --#endif /* PNG_sCAL_SUPPORTED */ -- --#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED --/* Provide a list of chunks and how they are to be handled, if the built-in -- handling or default unknown chunk handling is not desired. Any chunks not -- listed will be handled in the default manner. The IHDR and IEND chunks -- must not be listed. -- keep = 0: follow default behaviour -- = 1: do not keep -- = 2: keep only if safe-to-copy -- = 3: keep even if unsafe-to-copy --*/ --PNG_EXPORT(172, void, png_set_keep_unknown_chunks, -- (png_structp png_ptr, int keep, -- png_const_bytep chunk_list, int num_chunks)); --PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, -+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, -+ png_charpp swidth, png_charpp sheight)); -+ -+PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, -+ png_inforp info_ptr, int unit, double width, double height)) -+PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, -+ png_inforp info_ptr, int unit, png_fixed_point width, -+ png_fixed_point height)) -+PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, -+ png_inforp info_ptr, int unit, -+ png_const_charp swidth, png_const_charp sheight)); -+#endif /* sCAL */ -+ -+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+/* Provide the default handling for all unknown chunks or, optionally, for -+ * specific unknown chunks. -+ * -+ * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was -+ * ignored and the default was used, the per-chunk setting only had an effect on -+ * write. If you wish to have chunk-specific handling on read in code that must -+ * work on earlier versions you must use a user chunk callback to specify the -+ * desired handling (keep or discard.) -+ * -+ * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The -+ * parameter is interpreted as follows: -+ * -+ * READ: -+ * PNG_HANDLE_CHUNK_AS_DEFAULT: -+ * Known chunks: do normal libpng processing, do not keep the chunk (but -+ * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -+ * Unknown chunks: for a specific chunk use the global default, when used -+ * as the default discard the chunk data. -+ * PNG_HANDLE_CHUNK_NEVER: -+ * Discard the chunk data. -+ * PNG_HANDLE_CHUNK_IF_SAFE: -+ * Keep the chunk data if the chunk is not critical else raise a chunk -+ * error. -+ * PNG_HANDLE_CHUNK_ALWAYS: -+ * Keep the chunk data. -+ * -+ * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, -+ * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent -+ * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks -+ * it simply resets the behavior to the libpng default. -+ * -+ * INTERACTION WTIH USER CHUNK CALLBACKS: -+ * The per-chunk handling is always used when there is a png_user_chunk_ptr -+ * callback and the callback returns 0; the chunk is then always stored *unless* -+ * it is critical and the per-chunk setting is other than ALWAYS. Notice that -+ * the global default is *not* used in this case. (In effect the per-chunk -+ * value is incremented to at least IF_SAFE.) -+ * -+ * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and -+ * per-chunk defaults will be honored. If you want to preserve the current -+ * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE -+ * as the default - if you don't do this libpng 1.6 will issue a warning. -+ * -+ * If you want unhandled unknown chunks to be discarded in libpng 1.6 and -+ * earlier simply return '1' (handled). -+ * -+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: -+ * If this is *not* set known chunks will always be handled by libpng and -+ * will never be stored in the unknown chunk list. Known chunks listed to -+ * png_set_keep_unknown_chunks will have no effect. If it is set then known -+ * chunks listed with a keep other than AS_DEFAULT will *never* be processed -+ * by libpng, in addition critical chunks must either be processed by the -+ * callback or saved. -+ * -+ * The IHDR and IEND chunks must not be listed. Because this turns off the -+ * default handling for chunks that would otherwise be recognized the -+ * behavior of libpng transformations may well become incorrect! -+ * -+ * WRITE: -+ * When writing chunks the options only apply to the chunks specified by -+ * png_set_unknown_chunks (below), libpng will *always* write known chunks -+ * required by png_set_ calls and will always write the core critical chunks -+ * (as required for PLTE). -+ * -+ * Each chunk in the png_set_unknown_chunks list is looked up in the -+ * png_set_keep_unknown_chunks list to find the keep setting, this is then -+ * interpreted as follows: -+ * -+ * PNG_HANDLE_CHUNK_AS_DEFAULT: -+ * Write safe-to-copy chunks and write other chunks if the global -+ * default is set to _ALWAYS, otherwise don't write this chunk. -+ * PNG_HANDLE_CHUNK_NEVER: -+ * Do not write the chunk. -+ * PNG_HANDLE_CHUNK_IF_SAFE: -+ * Write the chunk if it is safe-to-copy, otherwise do not write it. -+ * PNG_HANDLE_CHUNK_ALWAYS: -+ * Write the chunk. -+ * -+ * Note that the default behavior is effectively the opposite of the read case - -+ * in read unknown chunks are not stored by default, in write they are written -+ * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different -+ * - on write the safe-to-copy bit is checked, on read the critical bit is -+ * checked and on read if the chunk is critical an error will be raised. -+ * -+ * num_chunks: -+ * =========== -+ * If num_chunks is positive, then the "keep" parameter specifies the manner -+ * for handling only those chunks appearing in the chunk_list array, -+ * otherwise the chunk list array is ignored. -+ * -+ * If num_chunks is 0 the "keep" parameter specifies the default behavior for -+ * unknown chunks, as described above. -+ * -+ * If num_chunks is negative, then the "keep" parameter specifies the manner -+ * for handling all unknown chunks plus all chunks recognized by libpng -+ * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to -+ * be processed by libpng. -+ */ -+PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, -+ int keep, png_const_bytep chunk_list, int num_chunks)); -+ -+/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; -+ * the result is therefore true (non-zero) if special handling is required, -+ * false for the default handling. -+ */ -+PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, - png_const_bytep chunk_name)); - #endif --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED --PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structp png_ptr, -- png_infop info_ptr, png_const_unknown_chunkp unknowns, -+ -+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -+PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_unknown_chunkp unknowns, - int num_unknowns)); -+ /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added -+ * unknowns to the location currently stored in the png_struct. This is -+ * invariably the wrong value on write. To fix this call the following API -+ * for each chunk in the list with the correct location. If you know your -+ * code won't be compiled on earlier versions you can rely on -+ * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing -+ * the correct thing. -+ */ -+ - PNG_EXPORT(175, void, png_set_unknown_chunk_location, -- (png_structp png_ptr, png_infop info_ptr, int chunk, int location)); --PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structp png_ptr, -- png_const_infop info_ptr, png_unknown_chunkpp entries)); -+ (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); -+ -+PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, -+ png_inforp info_ptr, png_unknown_chunkpp entries)); - #endif - - /* Png_free_data() will turn off the "valid" flag for anything it frees. - * If you need to turn it off for a chunk that your application has freed, - * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); - */ --PNG_EXPORT(177, void, png_set_invalid, -- (png_structp png_ptr, png_infop info_ptr, int mask)); -+PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, -+ png_inforp info_ptr, int mask)); - - #ifdef PNG_INFO_IMAGE_SUPPORTED - /* The "params" pointer is currently not used and is for future expansion. */ --PNG_EXPORT(178, void, png_read_png, (png_structp png_ptr, png_infop info_ptr, -- int transforms, png_voidp params)); --PNG_EXPORT(179, void, png_write_png, (png_structp png_ptr, png_infop info_ptr, -+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, - int transforms, png_voidp params)); - #endif -+#ifdef PNG_WRITE_SUPPORTED -+PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, -+ int transforms, png_voidp params)); -+#endif -+#endif - - PNG_EXPORT(180, png_const_charp, png_get_copyright, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - PNG_EXPORT(181, png_const_charp, png_get_header_ver, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - PNG_EXPORT(182, png_const_charp, png_get_header_version, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - - #ifdef PNG_MNG_FEATURES_SUPPORTED --PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structp png_ptr, -+PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, - png_uint_32 mng_features_permitted)); - #endif - -@@ -2365,75 +2526,77 @@ - #define PNG_HANDLE_CHUNK_NEVER 1 - #define PNG_HANDLE_CHUNK_IF_SAFE 2 - #define PNG_HANDLE_CHUNK_ALWAYS 3 -+#define PNG_HANDLE_CHUNK_LAST 4 - - /* Strip the prepended error numbers ("#nnn ") from error and warning - * messages before passing them to the error or warning handler. - */ - #ifdef PNG_ERROR_NUMBERS_SUPPORTED --PNG_EXPORT(185, void, png_set_strip_error_numbers, -- (png_structp png_ptr, -+PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, - png_uint_32 strip_mode)); - #endif - - /* Added in libpng-1.2.6 */ - #ifdef PNG_SET_USER_LIMITS_SUPPORTED --PNG_EXPORT(186, void, png_set_user_limits, (png_structp png_ptr, -+PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, - png_uint_32 user_width_max, png_uint_32 user_height_max)); - PNG_EXPORT(187, png_uint_32, png_get_user_width_max, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - PNG_EXPORT(188, png_uint_32, png_get_user_height_max, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - /* Added in libpng-1.4.0 */ --PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structp png_ptr, -+PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, - png_uint_32 user_chunk_cache_max)); - PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - /* Added in libpng-1.4.1 */ --PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structp png_ptr, -+PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, - png_alloc_size_t user_chunk_cache_max)); - PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - #endif - - #if defined(PNG_INCH_CONVERSIONS_SUPPORTED) - PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - - PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - - PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)); - - PNG_FP_EXPORT(196, float, png_get_x_offset_inches, -- (png_const_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)) - #ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ - PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, -- (png_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)) - #endif - --PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structp png_ptr, -- png_const_infop info_ptr)); -+PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr)) - #ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ - PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, -- (png_structp png_ptr, png_const_infop info_ptr)); -+ (png_const_structrp png_ptr, png_const_inforp info_ptr)) - #endif - - # ifdef PNG_pHYs_SUPPORTED --PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structp png_ptr, -- png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, -+PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, -+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); --# endif /* PNG_pHYs_SUPPORTED */ --#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ -+# endif /* pHYs */ -+#endif /* INCH_CONVERSIONS */ - - /* Added in libpng-1.4.0 */ - #ifdef PNG_IO_STATE_SUPPORTED --PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_structp png_ptr)); -- --PNG_EXPORTA(200, png_const_bytep, png_get_io_chunk_name, -- (png_structp png_ptr), PNG_DEPRECATED); -+PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); -+ -+/* Removed from libpng 1.6; use png_get_io_chunk_type. */ -+PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), -+ PNG_DEPRECATED) -+ - PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, -- (png_const_structp png_ptr)); -+ (png_const_structrp png_ptr)); - - /* The flags returned by png_get_io_state() are the following: */ - # define PNG_IO_NONE 0x0000 /* no I/O at this moment */ -@@ -2445,7 +2608,7 @@ - # define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ - # define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ - # define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ --#endif /* ?PNG_IO_STATE_SUPPORTED */ -+#endif /* IO_STATE */ - - /* Interlace support. The following macros are always defined so that if - * libpng interlace handling is turned off the macros may be used to handle -@@ -2457,8 +2620,16 @@ - * full, image which appears in a given pass. 'pass' is in the range 0 - * to 6 and the result is in the range 0 to 7. - */ --#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) --#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) -+#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) -+#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) -+ -+/* A macro to return the offset between pixels in the output row for a pair of -+ * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that -+ * follows. Note that ROW_OFFSET is the offset from one row to the next whereas -+ * COL_OFFSET is from one column to the next, within a row. -+ */ -+#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) -+#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) - - /* Two macros to help evaluate the number of rows or columns in each - * pass. This is expressed as a shift - effectively log2 of the number or -@@ -2481,10 +2652,10 @@ - * necessary to find the row in the output image given a row in an interlaced - * image, so two more macros: - */ --#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ -- (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) --#define PNG_COL_FROM_PASS_COL(xIn, pass) \ -- (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) -+#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ -+ (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) -+#define PNG_COL_FROM_PASS_COL(x_in, pass) \ -+ (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) - - /* Two macros which return a boolean (0 or 1) saying whether the given row - * or column is in a particular pass. These use a common utility macro that -@@ -2493,8 +2664,8 @@ - * the tile. - */ - #define PNG_PASS_MASK(pass,off) ( \ -- ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \ -- ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) -+ ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \ -+ ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) - - #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ - ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) -@@ -2520,14 +2691,14 @@ - { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ - * (png_uint_16)(alpha) \ - + (png_uint_16)(bg)*(png_uint_16)(255 \ -- - (png_uint_16)(alpha)) + (png_uint_16)128); \ -+ - (png_uint_16)(alpha)) + 128); \ - (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } - - # define png_composite_16(composite, fg, alpha, bg) \ - { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ - * (png_uint_32)(alpha) \ -- + (png_uint_32)(bg)*(png_uint_32)(65535L \ -- - (png_uint_32)(alpha)) + (png_uint_32)32768L); \ -+ + (png_uint_32)(bg)*(65535 \ -+ - (png_uint_32)(alpha)) + 32768); \ - (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } - - #else /* Standard method using integer division */ -@@ -2535,13 +2706,13 @@ - # define png_composite(composite, fg, alpha, bg) \ - (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ - (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ -- (png_uint_16)127) / 255) -+ 127) / 255) - - # define png_composite_16(composite, fg, alpha, bg) \ - (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ -- (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ -- (png_uint_32)32767) / (png_uint_32)65535L) --#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ -+ (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ -+ 32767) / 65535) -+#endif /* READ_COMPOSITE_NODIV */ - - #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED - PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); -@@ -2549,7 +2720,7 @@ - PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); - #endif - --PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_structp png_ptr, -+PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, - png_const_bytep buf)); - /* No png_get_int_16 -- may be added if there's a real need for it. */ - -@@ -2575,7 +2746,7 @@ - * The png_get_int_32() routine assumes we are using two's complement - * format for negative values, which is almost certainly true. - */ --# define png_get_uint_32(buf) \ -+# define PNG_get_uint_32(buf) \ - (((png_uint_32)(*(buf)) << 24) + \ - ((png_uint_32)(*((buf) + 1)) << 16) + \ - ((png_uint_32)(*((buf) + 2)) << 8) + \ -@@ -2584,27 +2755,550 @@ - /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the - * function) incorrectly returned a value of type png_uint_32. - */ --# define png_get_uint_16(buf) \ -+# define PNG_get_uint_16(buf) \ - ((png_uint_16) \ - (((unsigned int)(*(buf)) << 8) + \ - ((unsigned int)(*((buf) + 1))))) - --# define png_get_int_32(buf) \ -+# define PNG_get_int_32(buf) \ - ((png_int_32)((*(buf) & 0x80) \ - ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ - : (png_int_32)png_get_uint_32(buf))) -+ -+ /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, -+ * but defining a macro name prefixed with PNG_PREFIX. -+ */ -+# ifndef PNG_PREFIX -+# define png_get_uint_32(buf) PNG_get_uint_32(buf) -+# define png_get_uint_16(buf) PNG_get_uint_16(buf) -+# define png_get_int_32(buf) PNG_get_int_32(buf) -+# endif -+#else -+# ifdef PNG_PREFIX -+ /* No macros; revert to the (redefined) function */ -+# define PNG_get_uint_32 (png_get_uint_32) -+# define PNG_get_uint_16 (png_get_uint_16) -+# define PNG_get_int_32 (png_get_int_32) -+# endif - #endif - --/* Maintainer: Put new public prototypes here ^, in libpng.3, and project -- * defs -+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ -+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -+/******************************************************************************* -+ * SIMPLIFIED API -+ ******************************************************************************* -+ * -+ * Please read the documentation in libpng-manual.txt (TODO: write said -+ * documentation) if you don't understand what follows. -+ * -+ * The simplified API hides the details of both libpng and the PNG file format -+ * itself. It allows PNG files to be read into a very limited number of -+ * in-memory bitmap formats or to be written from the same formats. If these -+ * formats do not accomodate your needs then you can, and should, use the more -+ * sophisticated APIs above - these support a wide variety of in-memory formats -+ * and a wide variety of sophisticated transformations to those formats as well -+ * as a wide variety of APIs to manipulate ancillary information. -+ * -+ * To read a PNG file using the simplified API: -+ * -+ * 1) Declare a 'png_image' structure (see below) on the stack and set the -+ * version field to PNG_IMAGE_VERSION. -+ * 2) Call the appropriate png_image_begin_read... function. -+ * 3) Set the png_image 'format' member to the required sample format. -+ * 4) Allocate a buffer for the image and, if required, the color-map. -+ * 5) Call png_image_finish_read to read the image and, if required, the -+ * color-map into your buffers. -+ * -+ * There are no restrictions on the format of the PNG input itself; all valid -+ * color types, bit depths, and interlace methods are acceptable, and the -+ * input image is transformed as necessary to the requested in-memory format -+ * during the png_image_finish_read() step. The only caveat is that if you -+ * request a color-mapped image from a PNG that is full-color or makes -+ * complex use of an alpha channel the transformation is extremely lossy and the -+ * result may look terrible. -+ * -+ * To write a PNG file using the simplified API: -+ * -+ * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. -+ * 2) Initialize the members of the structure that describe the image, setting -+ * the 'format' member to the format of the image samples. -+ * 3) Call the appropriate png_image_write... function with a pointer to the -+ * image and, if necessary, the color-map to write the PNG data. -+ * -+ * png_image is a structure that describes the in-memory format of an image -+ * when it is being read or defines the in-memory format of an image that you -+ * need to write: - */ -+#define PNG_IMAGE_VERSION 1 -+ -+typedef struct png_control *png_controlp; -+typedef struct -+{ -+ png_controlp opaque; /* Initialize to NULL, free with png_image_free */ -+ png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ -+ png_uint_32 width; /* Image width in pixels (columns) */ -+ png_uint_32 height; /* Image height in pixels (rows) */ -+ png_uint_32 format; /* Image format as defined below */ -+ png_uint_32 flags; /* A bit mask containing informational flags */ -+ png_uint_32 colormap_entries; -+ /* Number of entries in the color-map */ -+ -+ /* In the event of an error or warning the following field will be set to a -+ * non-zero value and the 'message' field will contain a '\0' terminated -+ * string with the libpng error or warning message. If both warnings and -+ * an error were encountered, only the error is recorded. If there -+ * are multiple warnings, only the first one is recorded. -+ * -+ * The upper 30 bits of this value are reserved, the low two bits contain -+ * a value as follows: -+ */ -+# define PNG_IMAGE_WARNING 1 -+# define PNG_IMAGE_ERROR 2 -+ /* -+ * The result is a two-bit code such that a value more than 1 indicates -+ * a failure in the API just called: -+ * -+ * 0 - no warning or error -+ * 1 - warning -+ * 2 - error -+ * 3 - error preceded by warning -+ */ -+# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) -+ -+ png_uint_32 warning_or_error; -+ -+ char message[64]; -+} png_image, *png_imagep; -+ -+/* The samples of the image have one to four channels whose components have -+ * original values in the range 0 to 1.0: -+ * -+ * 1: A single gray or luminance channel (G). -+ * 2: A gray/luminance channel and an alpha channel (GA). -+ * 3: Three red, green, blue color channels (RGB). -+ * 4: Three color channels and an alpha channel (RGBA). -+ * -+ * The components are encoded in one of two ways: -+ * -+ * a) As a small integer, value 0..255, contained in a single byte. For the -+ * alpha channel the original value is simply value/255. For the color or -+ * luminance channels the value is encoded according to the sRGB specification -+ * and matches the 8-bit format expected by typical display devices. -+ * -+ * The color/gray channels are not scaled (pre-multiplied) by the alpha -+ * channel and are suitable for passing to color management software. -+ * -+ * b) As a value in the range 0..65535, contained in a 2-byte integer. All -+ * channels can be converted to the original value by dividing by 65535; all -+ * channels are linear. Color channels use the RGB encoding (RGB end-points) of -+ * the sRGB specification. This encoding is identified by the -+ * PNG_FORMAT_FLAG_LINEAR flag below. -+ * -+ * When the simplified API needs to convert between sRGB and linear colorspaces, -+ * the actual sRGB transfer curve defined in the sRGB specification (see the -+ * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 -+ * approximation used elsewhere in libpng. -+ * -+ * When an alpha channel is present it is expected to denote pixel coverage -+ * of the color or luminance channels and is returned as an associated alpha -+ * channel: the color/gray channels are scaled (pre-multiplied) by the alpha -+ * value. -+ * -+ * The samples are either contained directly in the image data, between 1 and 8 -+ * bytes per pixel according to the encoding, or are held in a color-map indexed -+ * by bytes in the image data. In the case of a color-map the color-map entries -+ * are individual samples, encoded as above, and the image data has one byte per -+ * pixel to select the relevant sample from the color-map. -+ */ -+ -+/* PNG_FORMAT_* -+ * -+ * #defines to be used in png_image::format. Each #define identifies a -+ * particular layout of sample data and, if present, alpha values. There are -+ * separate defines for each of the two component encodings. -+ * -+ * A format is built up using single bit flag values. All combinations are -+ * valid. Formats can be built up from the flag values or you can use one of -+ * the predefined values below. When testing formats always use the FORMAT_FLAG -+ * macros to test for individual features - future versions of the library may -+ * add new flags. -+ * -+ * When reading or writing color-mapped images the format should be set to the -+ * format of the entries in the color-map then png_image_{read,write}_colormap -+ * called to read or write the color-map and set the format correctly for the -+ * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! -+ * -+ * NOTE: libpng can be built with particular features disabled, if you see -+ * compiler errors because the definition of one of the following flags has been -+ * compiled out it is because libpng does not have the required support. It is -+ * possible, however, for the libpng configuration to enable the format on just -+ * read or just write; in that case you may see an error at run time. You can -+ * guard against this by checking for the definition of the appropriate -+ * "_SUPPORTED" macro, one of: -+ * -+ * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED -+ */ -+#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ -+#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ -+#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ -+#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ -+ -+#ifdef PNG_FORMAT_BGR_SUPPORTED -+# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ -+#endif -+ -+#ifdef PNG_FORMAT_AFIRST_SUPPORTED -+# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ -+#endif -+ -+/* Commonly used formats have predefined macros. -+ * -+ * First the single byte (sRGB) formats: -+ */ -+#define PNG_FORMAT_GRAY 0 -+#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA -+#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) -+#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR -+#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) -+#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) -+#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) -+#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) -+#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) -+ -+/* Then the linear 2-byte formats. When naming these "Y" is used to -+ * indicate a luminance (gray) channel. -+ */ -+#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR -+#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) -+#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) -+#define PNG_FORMAT_LINEAR_RGB_ALPHA \ -+ (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) -+ -+/* With color-mapped formats the image data is one byte for each pixel, the byte -+ * is an index into the color-map which is formatted as above. To obtain a -+ * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP -+ * to one of the above definitions, or you can use one of the definitions below. -+ */ -+#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) -+#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) -+#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) -+#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) -+#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) -+#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) -+ -+/* PNG_IMAGE macros -+ * -+ * These are convenience macros to derive information from a png_image -+ * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the -+ * actual image sample values - either the entries in the color-map or the -+ * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values -+ * for the pixels and will always return 1 for color-mapped formats. The -+ * remaining macros return information about the rows in the image and the -+ * complete image. -+ * -+ * NOTE: All the macros that take a png_image::format parameter are compile time -+ * constants if the format parameter is, itself, a constant. Therefore these -+ * macros can be used in array declarations and case labels where required. -+ * Similarly the macros are also pre-processor constants (sizeof is not used) so -+ * they can be used in #if tests. -+ * -+ * First the information about the samples. -+ */ -+#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ -+ (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) -+ /* Return the total number of channels in a given format: 1..4 */ -+ -+#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ -+ ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) -+ /* Return the size in bytes of a single component of a pixel or color-map -+ * entry (as appropriate) in the image: 1 or 2. -+ */ -+ -+#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ -+ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) -+ /* This is the size of the sample data for one sample. If the image is -+ * color-mapped it is the size of one color-map entry (and image pixels are -+ * one byte in size), otherwise it is the size of one image pixel. -+ */ -+ -+#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ -+ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) -+ /* The maximum size of the color-map required by the format expressed in a -+ * count of components. This can be used to compile-time allocate a -+ * color-map: -+ * -+ * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; -+ * -+ * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; -+ * -+ * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the -+ * information from one of the png_image_begin_read_ APIs and dynamically -+ * allocate the required memory. -+ */ -+ -+/* Corresponding information about the pixels */ -+#define PNG_IMAGE_PIXEL_(test,fmt)\ -+ (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) -+ -+#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ -+ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) -+ /* The number of separate channels (components) in a pixel; 1 for a -+ * color-mapped image. -+ */ -+ -+#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ -+ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) -+ /* The size, in bytes, of each component in a pixel; 1 for a color-mapped -+ * image. -+ */ -+ -+#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) -+ /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ -+ -+/* Information about the whole row, or whole image */ -+#define PNG_IMAGE_ROW_STRIDE(image)\ -+ (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) -+ /* Return the total number of components in a single row of the image; this -+ * is the minimum 'row stride', the minimum count of components between each -+ * row. For a color-mapped image this is the minimum number of bytes in a -+ * row. -+ */ -+ -+#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ -+ (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) -+ /* Return the size, in bytes, of an image buffer given a png_image and a row -+ * stride - the number of components to leave space for in each row. -+ */ -+ -+#define PNG_IMAGE_SIZE(image)\ -+ PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) -+ /* Return the size, in bytes, of the image in memory given just a png_image; -+ * the row stride is the minimum stride required for the image. -+ */ -+ -+#define PNG_IMAGE_COLORMAP_SIZE(image)\ -+ (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) -+ /* Return the size, in bytes, of the color-map of this image. If the image -+ * format is not a color-map format this will return a size sufficient for -+ * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if -+ * you don't want to allocate a color-map in this case. -+ */ -+ -+/* PNG_IMAGE_FLAG_* -+ * -+ * Flags containing additional information about the image are held in the -+ * 'flags' field of png_image. -+ */ -+#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 -+ /* This indicates the the RGB values of the in-memory bitmap do not -+ * correspond to the red, green and blue end-points defined by sRGB. -+ */ -+ -+#define PNG_IMAGE_FLAG_FAST 0x02 -+ /* On write emphasise speed over compression; the resultant PNG file will be -+ * larger but will be produced significantly faster, particular for large -+ * images. Do not use this option for images which will be distributed, only -+ * used it when producing intermediate files that will be read back in -+ * repeatedly. For a typical 24-bit image the option will double the read -+ * speed at the cost of increasing the image size by 25%, however for many -+ * more compressible images the PNG file can be 10 times larger with only a -+ * slight speed gain. -+ */ -+ -+#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 -+ /* On read if the image is a 16-bit per component image and there is no gAMA -+ * or sRGB chunk assume that the components are sRGB encoded. Notice that -+ * images output by the simplified API always have gamma information; setting -+ * this flag only affects the interpretation of 16-bit images from an -+ * external source. It is recommended that the application expose this flag -+ * to the user; the user can normally easily recognize the difference between -+ * linear and sRGB encoding. This flag has no effect on write - the data -+ * passed to the write APIs must have the correct encoding (as defined -+ * above.) -+ * -+ * If the flag is not set (the default) input 16-bit per component data is -+ * assumed to be linear. -+ * -+ * NOTE: the flag can only be set after the png_image_begin_read_ call, -+ * because that call initializes the 'flags' field. -+ */ -+ -+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -+/* READ APIs -+ * --------- -+ * -+ * The png_image passed to the read APIs must have been initialized by setting -+ * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) -+ */ -+#ifdef PNG_STDIO_SUPPORTED -+PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, -+ const char *file_name)); -+ /* The named file is opened for read and the image header is filled in -+ * from the PNG header in the file. -+ */ -+ -+PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, -+ FILE* file)); -+ /* The PNG header is read from the stdio FILE object. */ -+#endif /* STDIO */ -+ -+PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, -+ png_const_voidp memory, png_size_t size)); -+ /* The PNG header is read from the given memory buffer. */ -+ -+PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, -+ png_const_colorp background, void *buffer, png_int_32 row_stride, -+ void *colormap)); -+ /* Finish reading the image into the supplied buffer and clean up the -+ * png_image structure. -+ * -+ * row_stride is the step, in byte or 2-byte units as appropriate, -+ * between adjacent rows. A positive stride indicates that the top-most row -+ * is first in the buffer - the normal top-down arrangement. A negative -+ * stride indicates that the bottom-most row is first in the buffer. -+ * -+ * background need only be supplied if an alpha channel must be removed from -+ * a png_byte format and the removal is to be done by compositing on a solid -+ * color; otherwise it may be NULL and any composition will be done directly -+ * onto the buffer. The value is an sRGB color to use for the background, -+ * for grayscale output the green channel is used. -+ * -+ * background must be supplied when an alpha channel must be removed from a -+ * single byte color-mapped output format, in other words if: -+ * -+ * 1) The original format from png_image_begin_read_from_* had -+ * PNG_FORMAT_FLAG_ALPHA set. -+ * 2) The format set by the application does not. -+ * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and -+ * PNG_FORMAT_FLAG_LINEAR *not* set. -+ * -+ * For linear output removing the alpha channel is always done by compositing -+ * on black and background is ignored. -+ * -+ * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must -+ * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. -+ * image->colormap_entries will be updated to the actual number of entries -+ * written to the colormap; this may be less than the original value. -+ */ -+ -+PNG_EXPORT(238, void, png_image_free, (png_imagep image)); -+ /* Free any data allocated by libpng in image->opaque, setting the pointer to -+ * NULL. May be called at any time after the structure is initialized. -+ */ -+#endif /* SIMPLIFIED_READ */ -+ -+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -+#ifdef PNG_STDIO_SUPPORTED -+/* WRITE APIS -+ * ---------- -+ * For write you must initialize a png_image structure to describe the image to -+ * be written. To do this use memset to set the whole structure to 0 then -+ * initialize fields describing your image. -+ * -+ * version: must be set to PNG_IMAGE_VERSION -+ * opaque: must be initialized to NULL -+ * width: image width in pixels -+ * height: image height in rows -+ * format: the format of the data (image and color-map) you wish to write -+ * flags: set to 0 unless one of the defined flags applies; set -+ * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB -+ * values do not correspond to the colors in sRGB. -+ * colormap_entries: set to the number of entries in the color-map (0 to 256) -+ */ -+PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, -+ const char *file, int convert_to_8bit, const void *buffer, -+ png_int_32 row_stride, const void *colormap)); -+ /* Write the image to the named file. */ -+ -+PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, -+ int convert_to_8_bit, const void *buffer, png_int_32 row_stride, -+ const void *colormap)); -+ /* Write the image to the given (FILE*). */ -+ -+/* With both write APIs if image is in one of the linear formats with 16-bit -+ * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG -+ * gamma encoded according to the sRGB specification, otherwise a 16-bit linear -+ * encoded PNG file is written. -+ * -+ * With color-mapped data formats the colormap parameter point to a color-map -+ * with at least image->colormap_entries encoded in the specified format. If -+ * the format is linear the written PNG color-map will be converted to sRGB -+ * regardless of the convert_to_8_bit flag. -+ * -+ * With all APIs row_stride is handled as in the read APIs - it is the spacing -+ * from one row to the next in component sized units (1 or 2 bytes) and if -+ * negative indicates a bottom-up row layout in the buffer. -+ * -+ * Note that the write API does not support interlacing or sub-8-bit pixels. -+ */ -+#endif /* STDIO */ -+#endif /* SIMPLIFIED_WRITE */ -+/******************************************************************************* -+ * END OF SIMPLIFIED API -+ ******************************************************************************/ -+#endif /* SIMPLIFIED_{READ|WRITE} */ -+ -+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -+PNG_EXPORT(242, void, png_set_check_for_invalid_index, -+ (png_structrp png_ptr, int allowed)); -+# ifdef PNG_GET_PALETTE_MAX_SUPPORTED -+PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, -+ png_const_infop info_ptr)); -+# endif -+#endif /* CHECK_FOR_INVALID_INDEX */ -+ -+/******************************************************************************* -+ * IMPLEMENTATION OPTIONS -+ ******************************************************************************* -+ * -+ * Support for arbitrary implementation-specific optimizations. The API allows -+ * particular options to be turned on or off. 'Option' is the number of the -+ * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given -+ * by the PNG_OPTION_ defines below. -+ * -+ * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, -+ * are detected at run time, however sometimes it may be impossible -+ * to do this in user mode, in which case it is necessary to discover -+ * the capabilities in an OS specific way. Such capabilities are -+ * listed here when libpng has support for them and must be turned -+ * ON by the application if present. -+ * -+ * SOFTWARE: sometimes software optimizations actually result in performance -+ * decrease on some architectures or systems, or with some sets of -+ * PNG images. 'Software' options allow such optimizations to be -+ * selected at run time. -+ */ -+#ifdef PNG_SET_OPTION_SUPPORTED -+#ifdef PNG_ARM_NEON_API_SUPPORTED -+# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ -+#endif -+#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ -+#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ -+#define PNG_OPTION_NEXT 6 /* Next option - numbers must be even */ -+ -+/* Return values: NOTE: there are four values and 'off' is *not* zero */ -+#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ -+#define PNG_OPTION_INVALID 1 /* Option number out of range */ -+#define PNG_OPTION_OFF 2 -+#define PNG_OPTION_ON 3 -+ -+PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, -+ int onoff)); -+#endif /* SET_OPTION */ -+ -+/******************************************************************************* -+ * END OF HARDWARE AND SOFTWARE OPTIONS -+ ******************************************************************************/ -+ -+/* Maintainer: Put new public prototypes here ^, in libpng.3, in project -+ * defs, and in scripts/symbols.def. -+ */ - - /* The last ordinal number (this is the *last* one already used; the next -- * one to use is one more than this.) Maintainer, remember to add an entry to -- * scripts/symbols.def as well. -+ * one to use is one more than this.) - */ - #ifdef PNG_EXPORT_LAST_ORDINAL -- PNG_EXPORT_LAST_ORDINAL(229); -+ PNG_EXPORT_LAST_ORDINAL(244); - #endif - - #ifdef __cplusplus ---- ./jdk/src/share/native/sun/awt/libpng/pngconf.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngconf.h Thu Feb 05 13:00:26 2015 +0100 -@@ -29,9 +29,9 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * libpng version 1.5.4 - July 7, 2011 -+ * libpng version 1.6.16,December 22, 2014 - * -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -50,37 +50,73 @@ - #ifndef PNGCONF_H - #define PNGCONF_H - --#ifndef PNG_BUILDING_SYMBOL_TABLE --/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C -- * definition file for machine specific limits, this may impact the -- * correctness of the definitons below (see uses of INT_MAX). -- */ --# ifndef PNG_NO_LIMITS_H --# include <limits.h> -+/* To do: Do all of this in scripts/pnglibconf.dfa */ -+#ifdef PNG_SAFE_LIMITS_SUPPORTED -+# ifdef PNG_USER_WIDTH_MAX -+# undef PNG_USER_WIDTH_MAX -+# define PNG_USER_WIDTH_MAX 1000000L - # endif -- --/* For the memory copy APIs (i.e. the standard definitions of these), -- * because this file defines png_memcpy and so on the base APIs must -- * be defined here. -- */ --# ifdef BSD --# include <strings.h> --# else --# include <string.h> -+# ifdef PNG_USER_HEIGHT_MAX -+# undef PNG_USER_HEIGHT_MAX -+# define PNG_USER_HEIGHT_MAX 1000000L - # endif -- --/* For png_FILE_p - this provides the standard definition of a -- * FILE -- */ --# ifdef PNG_STDIO_SUPPORTED --# include <stdio.h> -+# ifdef PNG_USER_CHUNK_MALLOC_MAX -+# undef PNG_USER_CHUNK_MALLOC_MAX -+# define PNG_USER_CHUNK_MALLOC_MAX 4000000L -+# endif -+# ifdef PNG_USER_CHUNK_CACHE_MAX -+# undef PNG_USER_CHUNK_CACHE_MAX -+# define PNG_USER_CHUNK_CACHE_MAX 128 - # endif - #endif - -+#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ -+ -+/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C -+ * compiler for correct compilation. The following header files are required by -+ * the standard. If your compiler doesn't provide these header files, or they -+ * do not match the standard, you will need to provide/improve them. -+ */ -+#include <limits.h> -+#include <stddef.h> -+ -+/* Library header files. These header files are all defined by ISOC90; libpng -+ * expects conformant implementations, however, an ISOC90 conformant system need -+ * not provide these header files if the functionality cannot be implemented. -+ * In this case it will be necessary to disable the relevant parts of libpng in -+ * the build of pnglibconf.h. -+ * -+ * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not -+ * include this unnecessary header file. -+ */ -+ -+#ifdef PNG_STDIO_SUPPORTED -+ /* Required for the definition of FILE: */ -+# include <stdio.h> -+#endif -+ -+#ifdef PNG_SETJMP_SUPPORTED -+ /* Required for the definition of jmp_buf and the declaration of longjmp: */ -+# include <setjmp.h> -+#endif -+ -+#ifdef PNG_CONVERT_tIME_SUPPORTED -+ /* Required for struct tm: */ -+# include <time.h> -+#endif -+ -+#endif /* PNG_BUILDING_SYMBOL_TABLE */ -+ -+/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using -+ * PNG_NO_CONST; this is no longer supported except for data declarations which -+ * apparently still cause problems in 2011 on some compilers. -+ */ -+#define PNG_CONST const /* backward compatibility only */ -+ - /* This controls optimization of the reading of 16 and 32 bit values - * from PNG files. It can be set on a per-app-file basis - it -- * just changes whether a macro is used to the function is called. -- * The library builder sets the default, if read functions are not -+ * just changes whether a macro is used when the function is called. -+ * The library builder sets the default; if read functions are not - * built into the library the macro implementation is forced on. - */ - #ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED -@@ -100,28 +136,13 @@ - * may be changed on a per-file basis when compiling against libpng. - */ - --/* The PNGARG macro protects us against machines that don't have function -- * prototypes (ie K&R style headers). If your compiler does not handle -- * function prototypes, define this macro and use the included ansi2knr. -- * I've always been able to use _NO_PROTO as the indicator, but you may -- * need to drag the empty declaration out in front of here, or change the -- * ifdef to suit your own needs. -+/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect -+ * against legacy (pre ISOC90) compilers that did not understand function -+ * prototypes. It is not required for modern C compilers. - */ - #ifndef PNGARG -- --# ifdef OF /* zlib prototype munger */ --# define PNGARG(arglist) OF(arglist) --# else -- --# ifdef _NO_PROTO --# define PNGARG(arglist) () --# else --# define PNGARG(arglist) arglist --# endif /* _NO_PROTO */ -- --# endif /* OF */ -- --#endif /* PNGARG */ -+# define PNGARG(arglist) arglist -+#endif - - /* Function calling conventions. - * ============================= -@@ -192,7 +213,9 @@ - * 'type', compiler specific. - * - * PNG_DLL_EXPORT Set to the magic to use during a libpng build to -- * make a symbol exported from the DLL. -+ * make a symbol exported from the DLL. Not used in the -+ * public header files; see pngpriv.h for how it is used -+ * in the libpng build. - * - * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come - * from a DLL - used to define PNG_IMPEXP when -@@ -203,18 +226,16 @@ - * ========================== - * This code is used at build time to find PNG_IMPEXP, the API settings - * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL -- * import processing is possible. On Windows/x86 systems it also sets -+ * import processing is possible. On Windows systems it also sets - * compiler-specific macros to the values required to change the calling - * conventions of the various functions. - */ --#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ -- defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\ -- ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\ -- defined(_M_X64) || defined(_M_IA64) ) -- /* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes -- * builds under Cygwin or MinGW. Also includes Watcom builds but these need -- * special treatment because they are not compatible with GCC or Visual C -- * because of different calling conventions. -+#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ -+ defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -+ /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or -+ * MinGW on any architecture currently supported by Windows. Also includes -+ * Watcom builds but these need special treatment because they are not -+ * compatible with GCC or Visual C because of different calling conventions. - */ - # if PNG_API_RULE == 2 - /* If this line results in an error, either because __watcall is not -@@ -225,9 +246,12 @@ - # define PNGCAPI __watcall - # endif - --# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) -+# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) - # define PNGCAPI __cdecl - # if PNG_API_RULE == 1 -+ /* If this line results in an error __stdcall is not understood and -+ * PNG_API_RULE should not have been set to '1'. -+ */ - # define PNGAPI __stdcall - # endif - # else -@@ -242,10 +266,11 @@ - # define PNGAPI _stdcall - # endif - # endif /* compiler/api */ -+ - /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ - - # if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) -- ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed -+# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" - # endif - - # if (defined(_MSC_VER) && _MSC_VER < 800) ||\ -@@ -265,7 +290,7 @@ - # endif - # endif /* compiler */ - --#else /* !Windows/x86 */ -+#else /* !Windows */ - # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) - # define PNGAPI _System - # else /* !Windows/x86 && !OS/2 */ -@@ -286,25 +311,14 @@ - # define PNGAPI PNGCAPI - #endif - --/* The default for PNG_IMPEXP depends on whether the library is -- * being built or used. -+/* PNG_IMPEXP may be set on the compilation system command line or (if not set) -+ * then in an internal header file when building the library, otherwise (when -+ * using the library) it is set here. - */ - #ifndef PNG_IMPEXP --# ifdef PNGLIB_BUILD -- /* Building the library */ --# if (defined(DLL_EXPORT)/*from libtool*/ ||\ -- defined(_WINDLL) || defined(_DLL) || defined(__DLL__) ||\ -- defined(_USRDLL) ||\ -- defined(PNG_BUILD_DLL)) && defined(PNG_DLL_EXPORT) -- /* Building a DLL. */ --# define PNG_IMPEXP PNG_DLL_EXPORT --# endif /* DLL */ --# else -- /* Using the library */ --# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) -- /* This forces use of a DLL, disallowing static linking */ --# define PNG_IMPEXP PNG_DLL_IMPORT --# endif -+# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) -+ /* This forces use of a DLL, disallowing static linking */ -+# define PNG_IMPEXP PNG_DLL_IMPORT - # endif - - # ifndef PNG_IMPEXP -@@ -370,26 +384,48 @@ - - #ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED - /* Support for compiler specific function attributes. These are used -- * so that where compiler support is available incorrect use of API -+ * so that where compiler support is available, incorrect use of API - * functions in png.h will generate compiler warnings. Added at libpng -- * version 1.2.41. -+ * version 1.2.41. Disabling these removes the warnings but may also produce -+ * less efficient code. - */ --# if defined(__GNUC__) -+# if defined(__clang__) && defined(__has_attribute) -+ /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ -+# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) -+# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -+# endif -+# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) -+# define PNG_NORETURN __attribute__((__noreturn__)) -+# endif -+# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) -+# define PNG_ALLOCATED __attribute__((__malloc__)) -+# endif -+# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) -+# define PNG_DEPRECATED __attribute__((__deprecated__)) -+# endif -+# if !defined(PNG_PRIVATE) -+# ifdef __has_extension -+# if __has_extension(attribute_unavailable_with_message) -+# define PNG_PRIVATE __attribute__((__unavailable__(\ -+ "This function is not exported by libpng."))) -+# endif -+# endif -+# endif -+# ifndef PNG_RESTRICT -+# define PNG_RESTRICT __restrict -+# endif -+ -+# elif defined(__GNUC__) - # ifndef PNG_USE_RESULT - # define PNG_USE_RESULT __attribute__((__warn_unused_result__)) - # endif - # ifndef PNG_NORETURN - # define PNG_NORETURN __attribute__((__noreturn__)) - # endif --# ifndef PNG_ALLOCATED --# define PNG_ALLOCATED __attribute__((__malloc__)) --# endif -- -- /* This specifically protects structure members that should only be -- * accessed from within the library, therefore should be empty during -- * a library build. -- */ --# ifndef PNGLIB_BUILD -+# if __GNUC__ >= 3 -+# ifndef PNG_ALLOCATED -+# define PNG_ALLOCATED __attribute__((__malloc__)) -+# endif - # ifndef PNG_DEPRECATED - # define PNG_DEPRECATED __attribute__((__deprecated__)) - # endif -@@ -402,10 +438,14 @@ - __attribute__((__deprecated__)) - # endif - # endif --# endif /* PNGLIB_BUILD */ --# endif /* __GNUC__ */ -+# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) -+# ifndef PNG_RESTRICT -+# define PNG_RESTRICT __restrict -+# endif -+# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ -+# endif /* __GNUC__ >= 3 */ - --# if defined(_MSC_VER) && (_MSC_VER >= 1300) -+# elif defined(_MSC_VER) && (_MSC_VER >= 1300) - # ifndef PNG_USE_RESULT - # define PNG_USE_RESULT /* not supported */ - # endif -@@ -417,20 +457,23 @@ - # define PNG_ALLOCATED __declspec(restrict) - # endif - # endif -+# ifndef PNG_DEPRECATED -+# define PNG_DEPRECATED __declspec(deprecated) -+# endif -+# ifndef PNG_PRIVATE -+# define PNG_PRIVATE __declspec(deprecated) -+# endif -+# ifndef PNG_RESTRICT -+# if (_MSC_VER >= 1400) -+# define PNG_RESTRICT __restrict -+# endif -+# endif - -- /* This specifically protects structure members that should only be -- * accessed from within the library, therefore should be empty during -- * a library build. -- */ --# ifndef PNGLIB_BUILD --# ifndef PNG_DEPRECATED --# define PNG_DEPRECATED __declspec(deprecated) --# endif --# ifndef PNG_PRIVATE --# define PNG_PRIVATE __declspec(deprecated) --# endif --# endif /* PNGLIB_BUILD */ --# endif /* _MSC_VER */ -+# elif defined(__WATCOMC__) -+# ifndef PNG_RESTRICT -+# define PNG_RESTRICT __restrict -+# endif -+# endif - #endif /* PNG_PEDANTIC_WARNINGS */ - - #ifndef PNG_DEPRECATED -@@ -448,10 +491,14 @@ - #ifndef PNG_PRIVATE - # define PNG_PRIVATE /* This is a private libpng function */ - #endif -+#ifndef PNG_RESTRICT -+# define PNG_RESTRICT /* The C99 "restrict" feature */ -+#endif -+ - #ifndef PNG_FP_EXPORT /* A floating point API. */ - # ifdef PNG_FLOATING_POINT_SUPPORTED - # define PNG_FP_EXPORT(ordinal, type, name, args)\ -- PNG_EXPORT(ordinal, type, name, args) -+ PNG_EXPORT(ordinal, type, name, args); - # else /* No floating point APIs */ - # define PNG_FP_EXPORT(ordinal, type, name, args) - # endif -@@ -459,189 +506,167 @@ - #ifndef PNG_FIXED_EXPORT /* A fixed point API. */ - # ifdef PNG_FIXED_POINT_SUPPORTED - # define PNG_FIXED_EXPORT(ordinal, type, name, args)\ -- PNG_EXPORT(ordinal, type, name, args) -+ PNG_EXPORT(ordinal, type, name, args); - # else /* No fixed point APIs */ - # define PNG_FIXED_EXPORT(ordinal, type, name, args) - # endif - #endif - --/* The following uses const char * instead of char * for error -- * and warning message functions, so some compilers won't complain. -- * If you do not want to use const, define PNG_NO_CONST here. -+#ifndef PNG_BUILDING_SYMBOL_TABLE -+/* Some typedefs to get us started. These should be safe on most of the common -+ * platforms. - * -- * This should not change how the APIs are called, so it can be done -- * on a per-file basis in the application. -+ * png_uint_32 and png_int_32 may, currently, be larger than required to hold a -+ * 32-bit value however this is not normally advisable. -+ * -+ * png_uint_16 and png_int_16 should always be two bytes in size - this is -+ * verified at library build time. -+ * -+ * png_byte must always be one byte in size. -+ * -+ * The checks below use constants from limits.h, as defined by the ISOC90 -+ * standard. - */ --#ifndef PNG_CONST --# ifndef PNG_NO_CONST --# define PNG_CONST const --# else --# define PNG_CONST -+#if CHAR_BIT == 8 && UCHAR_MAX == 255 -+ typedef unsigned char png_byte; -+#else -+# error "libpng requires 8 bit bytes" -+#endif -+ -+#if INT_MIN == -32768 && INT_MAX == 32767 -+ typedef int png_int_16; -+#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 -+ typedef short png_int_16; -+#else -+# error "libpng requires a signed 16 bit type" -+#endif -+ -+#if UINT_MAX == 65535 -+ typedef unsigned int png_uint_16; -+#elif USHRT_MAX == 65535 -+ typedef unsigned short png_uint_16; -+#else -+# error "libpng requires an unsigned 16 bit type" -+#endif -+ -+#if INT_MIN < -2147483646 && INT_MAX > 2147483646 -+ typedef int png_int_32; -+#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 -+ typedef long int png_int_32; -+#else -+# error "libpng requires a signed 32 bit (or more) type" -+#endif -+ -+#if UINT_MAX > 4294967294 -+ typedef unsigned int png_uint_32; -+#elif ULONG_MAX > 4294967294 -+ typedef unsigned long int png_uint_32; -+#else -+# error "libpng requires an unsigned 32 bit (or more) type" -+#endif -+ -+/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, -+ * requires an ISOC90 compiler and relies on consistent behavior of sizeof. -+ */ -+typedef size_t png_size_t; -+typedef ptrdiff_t png_ptrdiff_t; -+ -+/* libpng needs to know the maximum value of 'size_t' and this controls the -+ * definition of png_alloc_size_t, below. This maximum value of size_t limits -+ * but does not control the maximum allocations the library makes - there is -+ * direct application control of this through png_set_user_limits(). -+ */ -+#ifndef PNG_SMALL_SIZE_T -+ /* Compiler specific tests for systems where size_t is known to be less than -+ * 32 bits (some of these systems may no longer work because of the lack of -+ * 'far' support; see above.) -+ */ -+# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ -+ (defined(_MSC_VER) && defined(MAXSEG_64K)) -+# define PNG_SMALL_SIZE_T - # endif - #endif - --/* Some typedefs to get us started. These should be safe on most of the -- * common platforms. The typedefs should be at least as large as the -- * numbers suggest (a png_uint_32 must be at least 32 bits long), but they -- * don't have to be exactly that size. Some compilers dislike passing -- * unsigned shorts as function parameters, so you may be better off using -- * unsigned int for png_uint_16. -+/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no -+ * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to -+ * png_alloc_size_t are not necessary; in fact, it is recommended not to use -+ * them at all so that the compiler can complain when something turns out to be -+ * problematic. -+ * -+ * Casts in the other direction (from png_alloc_size_t to png_size_t or -+ * png_uint_32) should be explicitly applied; however, we do not expect to -+ * encounter practical situations that require such conversions. -+ * -+ * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than -+ * 4294967295 - i.e. less than the maximum value of png_uint_32. -+ */ -+#ifdef PNG_SMALL_SIZE_T -+ typedef png_uint_32 png_alloc_size_t; -+#else -+ typedef png_size_t png_alloc_size_t; -+#endif -+ -+/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler -+ * implementations of Intel CPU specific support of user-mode segmented address -+ * spaces, where 16-bit pointers address more than 65536 bytes of memory using -+ * separate 'segment' registers. The implementation requires two different -+ * types of pointer (only one of which includes the segment value.) -+ * -+ * If required this support is available in version 1.2 of libpng and may be -+ * available in versions through 1.5, although the correctness of the code has -+ * not been verified recently. - */ - --#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL) --typedef unsigned int png_uint_32; --typedef int png_int_32; --#else --typedef unsigned long png_uint_32; --typedef long png_int_32; --#endif --typedef unsigned short png_uint_16; --typedef short png_int_16; --typedef unsigned char png_byte; -- --#ifdef PNG_NO_SIZE_T --typedef unsigned int png_size_t; --#else --typedef size_t png_size_t; --#endif --#define png_sizeof(x) (sizeof (x)) -- --/* The following is needed for medium model support. It cannot be in the -- * pngpriv.h header. Needs modification for other compilers besides -- * MSC. Model independent support declares all arrays and pointers to be -- * large using the far keyword. The zlib version used must also support -- * model independent data. As of version zlib 1.0.4, the necessary changes -- * have been made in zlib. The USE_FAR_KEYWORD define triggers other -- * changes that are needed. (Tim Wegner) -- */ -- --/* Separate compiler dependencies (problem here is that zlib.h always -- * defines FAR. (SJT) -- */ --#ifdef __BORLANDC__ --# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) --# define LDATA 1 --# else --# define LDATA 0 --# endif -- /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ --# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) --# define PNG_MAX_MALLOC_64K /* only used in build */ --# if (LDATA != 1) --# ifndef FAR --# define FAR __far --# endif --# define USE_FAR_KEYWORD --# endif /* LDATA != 1 */ -- /* Possibly useful for moving data out of default segment. -- * Uncomment it if you want. Could also define FARDATA as -- * const if your compiler supports it. (SJT) --# define FARDATA FAR -- */ --# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ --#endif /* __BORLANDC__ */ -- -- --/* Suggest testing for specific compiler first before testing for -- * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, -- * making reliance oncertain keywords suspect. (SJT) -- */ -- --/* MSC Medium model */ --#ifdef FAR --# ifdef M_I86MM --# define USE_FAR_KEYWORD --# define FARDATA FAR --# include <dos.h> --# endif --#endif -- --/* SJT: default case */ --#ifndef FAR --# define FAR --#endif -- --/* At this point FAR is always defined */ --#ifndef FARDATA --# define FARDATA --#endif -- --/* Typedef for floating-point numbers that are converted -- * to fixed-point with a multiple of 100,000, e.g., gamma -+/* Typedef for floating-point numbers that are converted to fixed-point with a -+ * multiple of 100,000, e.g., gamma - */ - typedef png_int_32 png_fixed_point; - - /* Add typedefs for pointers */ --typedef void FAR * png_voidp; --typedef PNG_CONST void FAR * png_const_voidp; --typedef png_byte FAR * png_bytep; --typedef PNG_CONST png_byte FAR * png_const_bytep; --typedef png_uint_32 FAR * png_uint_32p; --typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p; --typedef png_int_32 FAR * png_int_32p; --typedef PNG_CONST png_int_32 FAR * png_const_int_32p; --typedef png_uint_16 FAR * png_uint_16p; --typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p; --typedef png_int_16 FAR * png_int_16p; --typedef PNG_CONST png_int_16 FAR * png_const_int_16p; --typedef char FAR * png_charp; --typedef PNG_CONST char FAR * png_const_charp; --typedef png_fixed_point FAR * png_fixed_point_p; --typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p; --typedef png_size_t FAR * png_size_tp; --typedef PNG_CONST png_size_t FAR * png_const_size_tp; -+typedef void * png_voidp; -+typedef const void * png_const_voidp; -+typedef png_byte * png_bytep; -+typedef const png_byte * png_const_bytep; -+typedef png_uint_32 * png_uint_32p; -+typedef const png_uint_32 * png_const_uint_32p; -+typedef png_int_32 * png_int_32p; -+typedef const png_int_32 * png_const_int_32p; -+typedef png_uint_16 * png_uint_16p; -+typedef const png_uint_16 * png_const_uint_16p; -+typedef png_int_16 * png_int_16p; -+typedef const png_int_16 * png_const_int_16p; -+typedef char * png_charp; -+typedef const char * png_const_charp; -+typedef png_fixed_point * png_fixed_point_p; -+typedef const png_fixed_point * png_const_fixed_point_p; -+typedef png_size_t * png_size_tp; -+typedef const png_size_t * png_const_size_tp; - - #ifdef PNG_STDIO_SUPPORTED - typedef FILE * png_FILE_p; - #endif - - #ifdef PNG_FLOATING_POINT_SUPPORTED --typedef double FAR * png_doublep; --typedef PNG_CONST double FAR * png_const_doublep; -+typedef double * png_doublep; -+typedef const double * png_const_doublep; - #endif - - /* Pointers to pointers; i.e. arrays */ --typedef png_byte FAR * FAR * png_bytepp; --typedef png_uint_32 FAR * FAR * png_uint_32pp; --typedef png_int_32 FAR * FAR * png_int_32pp; --typedef png_uint_16 FAR * FAR * png_uint_16pp; --typedef png_int_16 FAR * FAR * png_int_16pp; --typedef PNG_CONST char FAR * FAR * png_const_charpp; --typedef char FAR * FAR * png_charpp; --typedef png_fixed_point FAR * FAR * png_fixed_point_pp; -+typedef png_byte * * png_bytepp; -+typedef png_uint_32 * * png_uint_32pp; -+typedef png_int_32 * * png_int_32pp; -+typedef png_uint_16 * * png_uint_16pp; -+typedef png_int_16 * * png_int_16pp; -+typedef const char * * png_const_charpp; -+typedef char * * png_charpp; -+typedef png_fixed_point * * png_fixed_point_pp; - #ifdef PNG_FLOATING_POINT_SUPPORTED --typedef double FAR * FAR * png_doublepp; -+typedef double * * png_doublepp; - #endif - - /* Pointers to pointers to pointers; i.e., pointer to array */ --typedef char FAR * FAR * FAR * png_charppp; -+typedef char * * * png_charppp; - --/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, -- * and no smaller than png_uint_32. Casts from png_size_t or png_uint_32 -- * to png_alloc_size_t are not necessary; in fact, it is recommended -- * not to use them at all so that the compiler can complain when something -- * turns out to be problematic. -- * Casts in the other direction (from png_alloc_size_t to png_size_t or -- * png_uint_32) should be explicitly applied; however, we do not expect -- * to encounter practical situations that require such conversions. -- */ --#if defined(__TURBOC__) && !defined(__FLAT__) -- typedef unsigned long png_alloc_size_t; --#else --# if defined(_MSC_VER) && defined(MAXSEG_64K) -- typedef unsigned long png_alloc_size_t; --# else -- /* This is an attempt to detect an old Windows system where (int) is -- * actually 16 bits, in that case png_malloc must have an argument with a -- * bigger size to accommodate the requirements of the library. -- */ --# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \ -- (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL) -- typedef DWORD png_alloc_size_t; --# else -- typedef png_size_t png_alloc_size_t; --# endif --# endif --#endif -+#endif /* PNG_BUILDING_SYMBOL_TABLE */ - - #endif /* PNGCONF_H */ ---- ./jdk/src/share/native/sun/awt/libpng/pngdebug.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngdebug.h Thu Feb 05 13:00:26 2015 +0100 -@@ -29,11 +29,11 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -- * Last changed in libpng 1.5.0 [January 6, 2011] -+ * Last changed in libpng 1.6.8 [December 19, 2013] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer -@@ -53,7 +53,7 @@ - * (actually ((void)0)). - * - * level: level of detail of message, starting at 0. A level 'n' -- * message is preceded by 'n' tab characters (not implemented -+ * message is preceded by 'n' 3-space indentations (not implemented - * on Microsoft compilers unless PNG_DEBUG_FILE is also - * defined, to allow debug DLL compilation with no standard IO). - * message: a printf(3) style text string. A trailing '\n' is added -@@ -105,32 +105,29 @@ - # endif /* PNG_DEBUG_FILE */ - - # if (PNG_DEBUG > 1) --/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on -- * non-ISO compilers -- */ - # ifdef __STDC__ - # ifndef png_debug - # define png_debug(l,m) \ - do { \ - int num_tabs=l; \ -- fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ -- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ -+ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ -+ (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \ - } while (0) - # endif - # ifndef png_debug1 - # define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ -- fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ -- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ -+ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ -+ (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \ - } while (0) - # endif - # ifndef png_debug2 - # define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ -- fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ -- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ -+ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ -+ (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\ - } while (0) - # endif - # else /* __STDC __ */ ---- ./jdk/src/share/native/sun/awt/libpng/pngerror.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngerror.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -48,14 +48,14 @@ - - #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - --static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr, -+static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr, - png_const_charp error_message)),PNG_NORETURN); - - #ifdef PNG_WARNINGS_SUPPORTED - static void /* PRIVATE */ --png_default_warning PNGARG((png_structp png_ptr, -+png_default_warning PNGARG((png_const_structrp png_ptr, - png_const_charp warning_message)); --#endif /* PNG_WARNINGS_SUPPORTED */ -+#endif /* WARNINGS */ - - /* This function is called whenever there is a fatal error. This function - * should not be changed. If there is a need to handle errors differently, -@@ -64,14 +64,15 @@ - */ - #ifdef PNG_ERROR_TEXT_SUPPORTED - PNG_FUNCTION(void,PNGAPI --png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN) -+png_error,(png_const_structrp png_ptr, png_const_charp error_message), -+ PNG_NORETURN) - { - #ifdef PNG_ERROR_NUMBERS_SUPPORTED - char msg[16]; - if (png_ptr != NULL) - { -- if (png_ptr->flags& -- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) -+ if ((png_ptr->flags & -+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0 - { - if (*error_message == PNG_LITERAL_SHARP) - { -@@ -81,7 +82,7 @@ - if (error_message[offset] == ' ') - break; - -- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) -+ if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - int i; - for (i = 0; i < offset - 1; i++) -@@ -96,7 +97,7 @@ - - else - { -- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) -+ if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - msg[0] = '0'; - msg[1] = '\0'; -@@ -107,7 +108,8 @@ - } - #endif - if (png_ptr != NULL && png_ptr->error_fn != NULL) -- (*(png_ptr->error_fn))(png_ptr, error_message); -+ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), -+ error_message); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ -@@ -115,7 +117,7 @@ - } - #else - PNG_FUNCTION(void,PNGAPI --png_err,(png_structp png_ptr),PNG_NORETURN) -+png_err,(png_const_structrp png_ptr),PNG_NORETURN) - { - /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed - * erroneously as '\0', instead of the empty string "". This was -@@ -123,13 +125,13 @@ - * will crash in this case. - */ - if (png_ptr != NULL && png_ptr->error_fn != NULL) -- (*(png_ptr->error_fn))(png_ptr, ""); -+ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ""); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, ""); - } --#endif /* PNG_ERROR_TEXT_SUPPORTED */ -+#endif /* ERROR_TEXT */ - - /* Utility to safely appends strings to a buffer. This never errors out so - * error checking is not required in the caller. -@@ -178,7 +180,7 @@ - case PNG_NUMBER_FORMAT_fixed: - /* Needs five digits (the fraction) */ - mincount = 5; -- if (output || number % 10 != 0) -+ if (output != 0 || number % 10 != 0) - { - *--end = digits[number % 10]; - output = 1; -@@ -189,7 +191,7 @@ - case PNG_NUMBER_FORMAT_02u: - /* Expects at least 2 digits. */ - mincount = 2; -- /* fall through */ -+ /* FALL THROUGH */ - - case PNG_NUMBER_FORMAT_u: - *--end = digits[number % 10]; -@@ -199,7 +201,7 @@ - case PNG_NUMBER_FORMAT_02x: - /* This format expects at least two digits */ - mincount = 2; -- /* fall through */ -+ /* FALL THROUGH */ - - case PNG_NUMBER_FORMAT_x: - *--end = digits[number & 0xf]; -@@ -215,13 +217,13 @@ - ++count; - - /* Float a fixed number here: */ -- if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start) -+ if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start)) - { - /* End of the fraction, but maybe nothing was output? In that case - * drop the decimal point. If the number is a true zero handle that - * here. - */ -- if (output) -+ if (output != 0) - *--end = '.'; - else if (number == 0) /* and !output */ - *--end = '0'; -@@ -239,14 +241,14 @@ - * png_set_error_fn() to replace the warning function at run-time. - */ - void PNGAPI --png_warning(png_structp png_ptr, png_const_charp warning_message) -+png_warning(png_const_structrp png_ptr, png_const_charp warning_message) - { - int offset = 0; - if (png_ptr != NULL) - { - #ifdef PNG_ERROR_NUMBERS_SUPPORTED -- if (png_ptr->flags& -- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) -+ if ((png_ptr->flags & -+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) - #endif - { - if (*warning_message == PNG_LITERAL_SHARP) -@@ -258,7 +260,8 @@ - } - } - if (png_ptr != NULL && png_ptr->warning_fn != NULL) -- (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); -+ (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), -+ warning_message + offset); - else - png_default_warning(png_ptr, warning_message + offset); - } -@@ -306,38 +309,43 @@ - } - - void --png_formatted_warning(png_structp png_ptr, png_warning_parameters p, -+png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, - png_const_charp message) - { -- /* The internal buffer is just 128 bytes - enough for all our messages, -- * overflow doesn't happen because this code checks! -+ /* The internal buffer is just 192 bytes - enough for all our messages, -+ * overflow doesn't happen because this code checks! If someone figures -+ * out how to send us a message longer than 192 bytes, all that will -+ * happen is that the message will be truncated appropriately. - */ -- size_t i; -- char msg[128]; -+ size_t i = 0; /* Index in the msg[] buffer: */ -+ char msg[192]; - -- for (i=0; i<(sizeof msg)-1 && *message != '\0'; ++i) -+ /* Each iteration through the following loop writes at most one character -+ * to msg[i++] then returns here to validate that there is still space for -+ * the trailing '\0'. It may (in the case of a parameter) read more than -+ * one character from message[]; it must check for '\0' and continue to the -+ * test if it finds the end of string. -+ */ -+ while (i<(sizeof msg)-1 && *message != '\0') - { -- if (*message == '@') -+ /* '@' at end of string is now just printed (previously it was skipped); -+ * it is an error in the calling code to terminate the string with @. -+ */ -+ if (p != NULL && *message == '@' && message[1] != '\0') - { -- int parameter = -1; -- switch (*++message) -- { -- case '1': -- parameter = 0; -- break; -+ int parameter_char = *++message; /* Consume the '@' */ -+ static const char valid_parameters[] = "123456789"; -+ int parameter = 0; - -- case '2': -- parameter = 1; -- break; -+ /* Search for the parameter digit, the index in the string is the -+ * parameter to use. -+ */ -+ while (valid_parameters[parameter] != parameter_char && -+ valid_parameters[parameter] != '\0') -+ ++parameter; - -- case '\0': -- continue; /* To break out of the for loop above. */ -- -- default: -- break; -- } -- -- if (parameter >= 0 && parameter < PNG_WARNING_PARAMETER_COUNT) -+ /* If the parameter digit is out of range it will just get printed. */ -+ if (parameter < PNG_WARNING_PARAMETER_COUNT) - { - /* Append this parameter */ - png_const_charp parm = p[parameter]; -@@ -347,47 +355,101 @@ - * that parm[] has been initialized, so there is no guarantee of a - * trailing '\0': - */ -- for (; i<(sizeof msg)-1 && parm != '\0' && parm < pend; ++i) -- msg[i] = *parm++; -+ while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) -+ msg[i++] = *parm++; - -+ /* Consume the parameter digit too: */ - ++message; - continue; - } - - /* else not a parameter and there is a character after the @ sign; just -- * copy that. -+ * copy that. This is known not to be '\0' because of the test above. - */ - } - - /* At this point *message can't be '\0', even in the bad parameter case - * above where there is a lone '@' at the end of the message string. - */ -- msg[i] = *message++; -+ msg[i++] = *message++; - } - - /* i is always less than (sizeof msg), so: */ - msg[i] = '\0'; - -- /* And this is the formatted message: */ -+ /* And this is the formatted message. It may be larger than -+ * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these -+ * are not (currently) formatted. -+ */ - png_warning(png_ptr, msg); - } --#endif /* PNG_WARNINGS_SUPPORTED */ -+#endif /* WARNINGS */ - - #ifdef PNG_BENIGN_ERRORS_SUPPORTED - void PNGAPI --png_benign_error(png_structp png_ptr, png_const_charp error_message) -+png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) - { -- if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) -+ if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) -+ { -+# ifdef PNG_READ_SUPPORTED -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && -+ png_ptr->chunk_name != 0) -+ png_chunk_warning(png_ptr, error_message); -+ else -+# endif -+ png_warning(png_ptr, error_message); -+ } -+ -+ else -+ { -+# ifdef PNG_READ_SUPPORTED -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && -+ png_ptr->chunk_name != 0) -+ png_chunk_error(png_ptr, error_message); -+ else -+# endif -+ png_error(png_ptr, error_message); -+ } -+ -+# ifndef PNG_ERROR_TEXT_SUPPORTED -+ PNG_UNUSED(error_message) -+# endif -+} -+ -+void /* PRIVATE */ -+png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) -+{ -+ if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); -+ -+# ifndef PNG_ERROR_TEXT_SUPPORTED -+ PNG_UNUSED(error_message) -+# endif - } --#endif - -+void /* PRIVATE */ -+png_app_error(png_const_structrp png_ptr, png_const_charp error_message) -+{ -+ if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) -+ png_warning(png_ptr, error_message); -+ else -+ png_error(png_ptr, error_message); -+ -+# ifndef PNG_ERROR_TEXT_SUPPORTED -+ PNG_UNUSED(error_message) -+# endif -+} -+#endif /* BENIGN_ERRORS */ -+ -+#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */ -+#if defined(PNG_WARNINGS_SUPPORTED) || \ -+ (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)) - /* These utilities are used internally to build an error message that relates - * to the current chunk. The chunk name comes from png_ptr->chunk_name, -- * this is used to prefix the message. The message is limited in length -- * to 63 bytes, the name characters are output as hex digits wrapped in [] -+ * which is used to prefix the message. The message is limited in length -+ * to 63 bytes. The name characters are output as hex digits wrapped in [] - * if the character is invalid. - */ - #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -@@ -396,18 +458,19 @@ - 'A', 'B', 'C', 'D', 'E', 'F' - }; - --#define PNG_MAX_ERROR_TEXT 64 --#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) - static void /* PRIVATE */ --png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp -+png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp - error_message) - { -- int iout = 0, iin = 0; -+ png_uint_32 chunk_name = png_ptr->chunk_name; -+ int iout = 0, ishift = 24; - -- while (iin < 4) -+ while (ishift >= 0) - { -- int c = png_ptr->chunk_name[iin++]; -- if (isnonalpha(c)) -+ int c = (int)(chunk_name >> ishift) & 0xff; -+ -+ ishift -= 8; -+ if (isnonalpha(c) != 0) - { - buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; - buffer[iout++] = png_digit[(c & 0xf0) >> 4]; -@@ -417,7 +480,7 @@ - - else - { -- buffer[iout++] = (png_byte)c; -+ buffer[iout++] = (char)c; - } - } - -@@ -426,10 +489,11 @@ - - else - { -+ int iin = 0; -+ - buffer[iout++] = ':'; - buffer[iout++] = ' '; - -- iin = 0; - while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') - buffer[iout++] = error_message[iin++]; - -@@ -437,11 +501,11 @@ - buffer[iout] = '\0'; - } - } --#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */ -+#endif /* WARNINGS || ERROR_TEXT */ - - #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) - PNG_FUNCTION(void,PNGAPI --png_chunk_error,(png_structp png_ptr, png_const_charp error_message), -+png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) - { - char msg[18+PNG_MAX_ERROR_TEXT]; -@@ -454,11 +518,11 @@ - png_error(png_ptr, msg); - } - } --#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */ -+#endif /* READ && ERROR_TEXT */ - - #ifdef PNG_WARNINGS_SUPPORTED - void PNGAPI --png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) -+png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message) - { - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL) -@@ -470,38 +534,83 @@ - png_warning(png_ptr, msg); - } - } --#endif /* PNG_WARNINGS_SUPPORTED */ -+#endif /* WARNINGS */ - - #ifdef PNG_READ_SUPPORTED - #ifdef PNG_BENIGN_ERRORS_SUPPORTED - void PNGAPI --png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) -+png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp -+ error_message) - { -- if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) -+ if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) - png_chunk_warning(png_ptr, error_message); - - else - png_chunk_error(png_ptr, error_message); -+ -+# ifndef PNG_ERROR_TEXT_SUPPORTED -+ PNG_UNUSED(error_message) -+# endif - } - #endif --#endif /* PNG_READ_SUPPORTED */ -+#endif /* READ */ -+ -+void /* PRIVATE */ -+png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error) -+{ -+# ifndef PNG_WARNINGS_SUPPORTED -+ PNG_UNUSED(message) -+# endif -+ -+ /* This is always supported, but for just read or just write it -+ * unconditionally does the right thing. -+ */ -+# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -+# endif -+ -+# ifdef PNG_READ_SUPPORTED -+ { -+ if (error < PNG_CHUNK_ERROR) -+ png_chunk_warning(png_ptr, message); -+ -+ else -+ png_chunk_benign_error(png_ptr, message); -+ } -+# endif -+ -+# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) -+ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) -+# endif -+ -+# ifdef PNG_WRITE_SUPPORTED -+ { -+ if (error < PNG_CHUNK_WRITE_ERROR) -+ png_app_warning(png_ptr, message); -+ -+ else -+ png_app_error(png_ptr, message); -+ } -+# endif -+} - - #ifdef PNG_ERROR_TEXT_SUPPORTED - #ifdef PNG_FLOATING_POINT_SUPPORTED - PNG_FUNCTION(void, --png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN) -+png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) - { - # define fixed_message "fixed point overflow in " - # define fixed_message_ln ((sizeof fixed_message)-1) - int iin; - char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; -- png_memcpy(msg, fixed_message, fixed_message_ln); -+ memcpy(msg, fixed_message, fixed_message_ln); - iin = 0; -- if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) -- { -- msg[fixed_message_ln + iin] = name[iin]; -- ++iin; -- } -+ if (name != NULL) -+ while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) -+ { -+ msg[fixed_message_ln + iin] = name[iin]; -+ ++iin; -+ } - msg[fixed_message_ln + iin] = 0; - png_error(png_ptr, msg); - } -@@ -513,14 +622,111 @@ - * otherwise it is necessary for png_default_error to be overridden. - */ - jmp_buf* PNGAPI --png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, -+png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, - size_t jmp_buf_size) - { -- if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf)) -+ /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value -+ * and it must not change after that. Libpng doesn't care how big the -+ * buffer is, just that it doesn't change. -+ * -+ * If the buffer size is no *larger* than the size of jmp_buf when libpng is -+ * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0 -+ * semantics that this call will not fail. If the size is larger, however, -+ * the buffer is allocated and this may fail, causing the function to return -+ * NULL. -+ */ -+ if (png_ptr == NULL) - return NULL; - -+ if (png_ptr->jmp_buf_ptr == NULL) -+ { -+ png_ptr->jmp_buf_size = 0; /* not allocated */ -+ -+ if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local)) -+ png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; -+ -+ else -+ { -+ png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, -+ png_malloc_warn(png_ptr, jmp_buf_size)); -+ -+ if (png_ptr->jmp_buf_ptr == NULL) -+ return NULL; /* new NULL return on OOM */ -+ -+ png_ptr->jmp_buf_size = jmp_buf_size; -+ } -+ } -+ -+ else /* Already allocated: check the size */ -+ { -+ size_t size = png_ptr->jmp_buf_size; -+ -+ if (size == 0) -+ { -+ size = (sizeof png_ptr->jmp_buf_local); -+ if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local) -+ { -+ /* This is an internal error in libpng: somehow we have been left -+ * with a stack allocated jmp_buf when the application regained -+ * control. It's always possible to fix this up, but for the moment -+ * this is a png_error because that makes it easy to detect. -+ */ -+ png_error(png_ptr, "Libpng jmp_buf still allocated"); -+ /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */ -+ } -+ } -+ -+ if (size != jmp_buf_size) -+ { -+ png_warning(png_ptr, "Application jmp_buf size changed"); -+ return NULL; /* caller will probably crash: no choice here */ -+ } -+ } -+ -+ /* Finally fill in the function, now we have a satisfactory buffer. It is -+ * valid to change the function on every call. -+ */ - png_ptr->longjmp_fn = longjmp_fn; -- return &png_ptr->longjmp_buffer; -+ return png_ptr->jmp_buf_ptr; -+} -+ -+void /* PRIVATE */ -+png_free_jmpbuf(png_structrp png_ptr) -+{ -+ if (png_ptr != NULL) -+ { -+ jmp_buf *jb = png_ptr->jmp_buf_ptr; -+ -+ /* A size of 0 is used to indicate a local, stack, allocation of the -+ * pointer; used here and in png.c -+ */ -+ if (jb != NULL && png_ptr->jmp_buf_size > 0) -+ { -+ -+ /* This stuff is so that a failure to free the error control structure -+ * does not leave libpng in a state with no valid error handling: the -+ * free always succeeds, if there is an error it gets ignored. -+ */ -+ if (jb != &png_ptr->jmp_buf_local) -+ { -+ /* Make an internal, libpng, jmp_buf to return here */ -+ jmp_buf free_jmp_buf; -+ -+ if (!setjmp(free_jmp_buf)) -+ { -+ png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */ -+ png_ptr->jmp_buf_size = 0; /* stack allocation */ -+ png_ptr->longjmp_fn = longjmp; -+ png_free(png_ptr, jb); /* Return to setjmp on error */ -+ } -+ } -+ } -+ -+ /* *Always* cancel everything out: */ -+ png_ptr->jmp_buf_size = 0; -+ png_ptr->jmp_buf_ptr = NULL; -+ png_ptr->longjmp_fn = 0; -+ } - } - #endif - -@@ -530,7 +736,7 @@ - * error function pointer in png_set_error_fn(). - */ - static PNG_FUNCTION(void /* PRIVATE */, --png_default_error,(png_structp png_ptr, png_const_charp error_message), -+png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) - { - #ifdef PNG_CONSOLE_IO_SUPPORTED -@@ -577,24 +783,23 @@ - } - - PNG_FUNCTION(void,PNGAPI --png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN) -+png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN) - { - #ifdef PNG_SETJMP_SUPPORTED -- if (png_ptr && png_ptr->longjmp_fn) -- { --# ifdef USE_FAR_KEYWORD -- { -- jmp_buf tmp_jmpbuf; -- png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); -- png_ptr->longjmp_fn(tmp_jmpbuf, val); -- } -+ if (png_ptr != NULL && png_ptr->longjmp_fn != NULL && -+ png_ptr->jmp_buf_ptr != NULL) -+ png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(val) -+#endif - --# else -- png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val); --# endif -- } --#endif -- /* Here if not setjmp support or if png_ptr is null. */ -+ /* If control reaches this point, png_longjmp() must not return. The only -+ * choice is to terminate the whole process (or maybe the thread); to do -+ * this the ANSI-C abort() function is used unless a different method is -+ * implemented by overriding the default configuration setting for -+ * PNG_ABORT(). -+ */ - PNG_ABORT(); - } - -@@ -605,7 +810,7 @@ - * not used, but it is passed in case it may be useful. - */ - static void /* PRIVATE */ --png_default_warning(png_structp png_ptr, png_const_charp warning_message) -+png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) - { - #ifdef PNG_CONSOLE_IO_SUPPORTED - # ifdef PNG_ERROR_NUMBERS_SUPPORTED -@@ -647,15 +852,15 @@ - #endif - PNG_UNUSED(png_ptr) /* Make compiler happy */ - } --#endif /* PNG_WARNINGS_SUPPORTED */ -+#endif /* WARNINGS */ - - /* This function is called when the application wants to use another method - * of handling errors and warnings. Note that the error function MUST NOT - * return to the calling routine or serious problems will occur. The return -- * method used in the default routine calls longjmp(png_ptr->longjmp_buffer, 1) -+ * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1) - */ - void PNGAPI --png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, -+png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warning_fn) - { - if (png_ptr == NULL) -@@ -676,7 +881,7 @@ - * pointer before png_write_destroy and png_read_destroy are called. - */ - png_voidp PNGAPI --png_get_error_ptr(png_const_structp png_ptr) -+png_get_error_ptr(png_const_structrp png_ptr) - { - if (png_ptr == NULL) - return NULL; -@@ -687,7 +892,7 @@ - - #ifdef PNG_ERROR_NUMBERS_SUPPORTED - void PNGAPI --png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) -+png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) - { - if (png_ptr != NULL) - { -@@ -697,4 +902,90 @@ - } - } - #endif --#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ -+ -+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ -+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -+ /* Currently the above both depend on SETJMP_SUPPORTED, however it would be -+ * possible to implement without setjmp support just so long as there is some -+ * way to handle the error return here: -+ */ -+PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI -+png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), -+ PNG_NORETURN) -+{ -+ const png_const_structrp png_ptr = png_nonconst_ptr; -+ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); -+ -+ /* An error is always logged here, overwriting anything (typically a warning) -+ * that is already there: -+ */ -+ if (image != NULL) -+ { -+ png_safecat(image->message, (sizeof image->message), 0, error_message); -+ image->warning_or_error |= PNG_IMAGE_ERROR; -+ -+ /* Retrieve the jmp_buf from within the png_control, making this work for -+ * C++ compilation too is pretty tricky: C++ wants a pointer to the first -+ * element of a jmp_buf, but C doesn't tell us the type of that. -+ */ -+ if (image->opaque != NULL && image->opaque->error_buf != NULL) -+ longjmp(png_control_jmp_buf(image->opaque), 1); -+ -+ /* Missing longjmp buffer, the following is to help debugging: */ -+ { -+ size_t pos = png_safecat(image->message, (sizeof image->message), 0, -+ "bad longjmp: "); -+ png_safecat(image->message, (sizeof image->message), pos, -+ error_message); -+ } -+ } -+ -+ /* Here on an internal programming error. */ -+ abort(); -+} -+ -+#ifdef PNG_WARNINGS_SUPPORTED -+void /* PRIVATE */ PNGCBAPI -+png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) -+{ -+ const png_const_structrp png_ptr = png_nonconst_ptr; -+ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); -+ -+ /* A warning is only logged if there is no prior warning or error. */ -+ if (image->warning_or_error == 0) -+ { -+ png_safecat(image->message, (sizeof image->message), 0, warning_message); -+ image->warning_or_error |= PNG_IMAGE_WARNING; -+ } -+} -+#endif -+ -+int /* PRIVATE */ -+png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) -+{ -+ volatile png_imagep image = image_in; -+ volatile int result; -+ volatile png_voidp saved_error_buf; -+ jmp_buf safe_jmpbuf; -+ -+ /* Safely execute function(arg) with png_error returning to this function. */ -+ saved_error_buf = image->opaque->error_buf; -+ result = setjmp(safe_jmpbuf) == 0; -+ -+ if (result != 0) -+ { -+ -+ image->opaque->error_buf = safe_jmpbuf; -+ result = function(arg); -+ } -+ -+ image->opaque->error_buf = saved_error_buf; -+ -+ /* And do the cleanup prior to any failure return. */ -+ if (result == 0) -+ png_image_free(image); -+ -+ return result; -+} -+#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ -+#endif /* READ || WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pngget.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngget.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.1 [February 3, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -45,7 +45,7 @@ - #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - - png_uint_32 PNGAPI --png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 flag) - { - if (png_ptr != NULL && info_ptr != NULL) -@@ -55,7 +55,7 @@ - } - - png_size_t PNGAPI --png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->rowbytes); -@@ -65,7 +65,7 @@ - - #ifdef PNG_INFO_IMAGE_SUPPORTED - png_bytepp PNGAPI --png_get_rows(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->row_pointers); -@@ -77,7 +77,7 @@ - #ifdef PNG_EASY_ACCESS_SUPPORTED - /* Easy access to info, added in libpng-0.99 */ - png_uint_32 PNGAPI --png_get_image_width(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->width; -@@ -86,7 +86,7 @@ - } - - png_uint_32 PNGAPI --png_get_image_height(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->height; -@@ -95,7 +95,7 @@ - } - - png_byte PNGAPI --png_get_bit_depth(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->bit_depth; -@@ -104,7 +104,7 @@ - } - - png_byte PNGAPI --png_get_color_type(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->color_type; -@@ -113,7 +113,7 @@ - } - - png_byte PNGAPI --png_get_filter_type(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->filter_type; -@@ -122,7 +122,7 @@ - } - - png_byte PNGAPI --png_get_interlace_type(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->interlace_type; -@@ -131,7 +131,7 @@ - } - - png_byte PNGAPI --png_get_compression_type(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->compression_type; -@@ -140,10 +140,12 @@ - } - - png_uint_32 PNGAPI --png_get_x_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp -+ info_ptr) - { - #ifdef PNG_pHYs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_x_pixels_per_meter"); -@@ -151,16 +153,21 @@ - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->x_pixels_per_unit); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return (0); - } - - png_uint_32 PNGAPI --png_get_y_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp -+ info_ptr) - { - #ifdef PNG_pHYs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_y_pixels_per_meter"); -@@ -168,16 +175,20 @@ - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->y_pixels_per_unit); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return (0); - } - - png_uint_32 PNGAPI --png_get_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - #ifdef PNG_pHYs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - -@@ -185,6 +196,9 @@ - info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return (info_ptr->x_pixels_per_unit); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return (0); -@@ -192,10 +206,12 @@ - - #ifdef PNG_FLOATING_POINT_SUPPORTED - float PNGAPI --png_get_pixel_aspect_ratio(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp -+ info_ptr) - { - #ifdef PNG_READ_pHYs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - -@@ -203,6 +219,9 @@ - return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return ((float)0.0); -@@ -211,14 +230,15 @@ - - #ifdef PNG_FIXED_POINT_SUPPORTED - png_fixed_point PNGAPI --png_get_pixel_aspect_ratio_fixed(png_const_structp png_ptr, -- png_const_infop info_ptr) -+png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, -+ png_const_inforp info_ptr) - { - #ifdef PNG_READ_pHYs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) -- && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 -- && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX -- && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_pHYs) != 0 && -+ info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && -+ info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX && -+ info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) - { - png_fixed_point res; - -@@ -228,9 +248,12 @@ - * range of 0..2^31-1; otherwise the cast might overflow. - */ - if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, -- (png_int_32)info_ptr->x_pixels_per_unit)) -+ (png_int_32)info_ptr->x_pixels_per_unit) != 0) - return res; - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return 0; -@@ -238,64 +261,80 @@ - #endif - - png_int_32 PNGAPI --png_get_x_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - #ifdef PNG_oFFs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->x_offset); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return (0); - } - - png_int_32 PNGAPI --png_get_y_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - #ifdef PNG_oFFs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->y_offset); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return (0); - } - - png_int_32 PNGAPI --png_get_x_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - #ifdef PNG_oFFs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->x_offset); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return (0); - } - - png_int_32 PNGAPI --png_get_y_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - #ifdef PNG_oFFs_SUPPORTED -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->y_offset); - } -+#else -+ PNG_UNUSED(png_ptr) -+ PNG_UNUSED(info_ptr) - #endif - - return (0); -@@ -326,7 +365,7 @@ - */ - png_fixed_point result; - if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, -- 5000)) -+ 5000) != 0) - return result; - - /* Overflow. */ -@@ -335,26 +374,26 @@ - } - - png_uint_32 PNGAPI --png_get_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); - } - - png_uint_32 PNGAPI --png_get_x_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); - } - - png_uint_32 PNGAPI --png_get_y_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); - } - - #ifdef PNG_FIXED_POINT_SUPPORTED - static png_fixed_point --png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns) -+png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) - { - /* Convert from metres * 1,000,000 to inches * 100,000, meters to - * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. -@@ -365,8 +404,8 @@ - } - - png_fixed_point PNGAPI --png_get_x_offset_inches_fixed(png_structp png_ptr, -- png_const_infop info_ptr) -+png_get_x_offset_inches_fixed(png_const_structrp png_ptr, -+ png_const_inforp info_ptr) - { - return png_fixed_inches_from_microns(png_ptr, - png_get_x_offset_microns(png_ptr, info_ptr)); -@@ -375,8 +414,8 @@ - - #ifdef PNG_FIXED_POINT_SUPPORTED - png_fixed_point PNGAPI --png_get_y_offset_inches_fixed(png_structp png_ptr, -- png_const_infop info_ptr) -+png_get_y_offset_inches_fixed(png_const_structrp png_ptr, -+ png_const_inforp info_ptr) - { - return png_fixed_inches_from_microns(png_ptr, - png_get_y_offset_microns(png_ptr, info_ptr)); -@@ -385,7 +424,7 @@ - - #ifdef PNG_FLOATING_POINT_SUPPORTED - float PNGAPI --png_get_x_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - /* To avoid the overflow do the conversion directly in floating - * point. -@@ -396,7 +435,7 @@ - - #ifdef PNG_FLOATING_POINT_SUPPORTED - float PNGAPI --png_get_y_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - /* To avoid the overflow do the conversion directly in floating - * point. -@@ -407,12 +446,13 @@ - - #ifdef PNG_pHYs_SUPPORTED - png_uint_32 PNGAPI --png_get_pHYs_dpi(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) - { - png_uint_32 retval = 0; - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "pHYs"); - -@@ -443,15 +483,16 @@ - - return (retval); - } --#endif /* PNG_pHYs_SUPPORTED */ --#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ -+#endif /* pHYs */ -+#endif /* INCH_CONVERSIONS */ - - /* png_get_channels really belongs in here, too, but it's been around longer */ - --#endif /* PNG_EASY_ACCESS_SUPPORTED */ -+#endif /* EASY_ACCESS */ -+ - - png_byte PNGAPI --png_get_channels(png_const_structp png_ptr, png_const_infop info_ptr) -+png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->channels); -@@ -459,22 +500,25 @@ - return (0); - } - -+#ifdef PNG_READ_SUPPORTED - png_const_bytep PNGAPI --png_get_signature(png_const_structp png_ptr, png_infop info_ptr) -+png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->signature); - - return (NULL); - } -+#endif - - #ifdef PNG_bKGD_SUPPORTED - png_uint_32 PNGAPI --png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr, -+png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_16p *background) - { -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) -- && background != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_bKGD) != 0 && -+ background != NULL) - { - png_debug1(1, "in %s retrieval function", "bKGD"); - -@@ -487,32 +531,95 @@ - #endif - - #ifdef PNG_cHRM_SUPPORTED -+/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the -+ * same time to correct the rgb grayscale coefficient defaults obtained from the -+ * cHRM chunk in 1.5.4 -+ */ - # ifdef PNG_FLOATING_POINT_SUPPORTED - png_uint_32 PNGAPI --png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *white_x, double *white_y, double *red_x, double *red_y, - double *green_x, double *green_y, double *blue_x, double *blue_y) - { -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) -+ /* Quiet API change: this code used to only return the end points if a cHRM -+ * chunk was present, but the end points can also come from iCCP or sRGB -+ * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and -+ * the png_set_ APIs merely check that set end points are mutually -+ * consistent. -+ */ -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (white_x != NULL) -- *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X"); -+ *white_x = png_float(png_ptr, -+ info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); - if (white_y != NULL) -- *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y"); -+ *white_y = png_float(png_ptr, -+ info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); - if (red_x != NULL) -- *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X"); -+ *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, -+ "cHRM red X"); - if (red_y != NULL) -- *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y"); -+ *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, -+ "cHRM red Y"); - if (green_x != NULL) -- *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X"); -+ *green_x = png_float(png_ptr, -+ info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); - if (green_y != NULL) -- *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y"); -+ *green_y = png_float(png_ptr, -+ info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); - if (blue_x != NULL) -- *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X"); -+ *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, -+ "cHRM blue X"); - if (blue_y != NULL) -- *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y"); -+ *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, -+ "cHRM blue Y"); -+ return (PNG_INFO_cHRM); -+ } -+ -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, -+ double *red_X, double *red_Y, double *red_Z, double *green_X, -+ double *green_Y, double *green_Z, double *blue_X, double *blue_Y, -+ double *blue_Z) -+{ -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) -+ { -+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); -+ -+ if (red_X != NULL) -+ *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, -+ "cHRM red X"); -+ if (red_Y != NULL) -+ *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, -+ "cHRM red Y"); -+ if (red_Z != NULL) -+ *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, -+ "cHRM red Z"); -+ if (green_X != NULL) -+ *green_X = png_float(png_ptr, -+ info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); -+ if (green_Y != NULL) -+ *green_Y = png_float(png_ptr, -+ info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); -+ if (green_Z != NULL) -+ *green_Z = png_float(png_ptr, -+ info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); -+ if (blue_X != NULL) -+ *blue_X = png_float(png_ptr, -+ info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); -+ if (blue_Y != NULL) -+ *blue_Y = png_float(png_ptr, -+ info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); -+ if (blue_Z != NULL) -+ *blue_Z = png_float(png_ptr, -+ info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); - return (PNG_INFO_cHRM); - } - -@@ -522,31 +629,69 @@ - - # ifdef PNG_FIXED_POINT_SUPPORTED - png_uint_32 PNGAPI --png_get_cHRM_fixed(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, -+ png_fixed_point *int_red_X, png_fixed_point *int_red_Y, -+ png_fixed_point *int_red_Z, png_fixed_point *int_green_X, -+ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, -+ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, -+ png_fixed_point *int_blue_Z) -+{ -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) -+ { -+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); -+ -+ if (int_red_X != NULL) -+ *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; -+ if (int_red_Y != NULL) -+ *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; -+ if (int_red_Z != NULL) -+ *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; -+ if (int_green_X != NULL) -+ *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; -+ if (int_green_Y != NULL) -+ *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; -+ if (int_green_Z != NULL) -+ *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; -+ if (int_blue_X != NULL) -+ *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; -+ if (int_blue_Y != NULL) -+ *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; -+ if (int_blue_Z != NULL) -+ *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; -+ return (PNG_INFO_cHRM); -+ } -+ -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, - png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, - png_fixed_point *blue_x, png_fixed_point *blue_y) - { - png_debug1(1, "in %s retrieval function", "cHRM"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - if (white_x != NULL) -- *white_x = info_ptr->x_white; -+ *white_x = info_ptr->colorspace.end_points_xy.whitex; - if (white_y != NULL) -- *white_y = info_ptr->y_white; -+ *white_y = info_ptr->colorspace.end_points_xy.whitey; - if (red_x != NULL) -- *red_x = info_ptr->x_red; -+ *red_x = info_ptr->colorspace.end_points_xy.redx; - if (red_y != NULL) -- *red_y = info_ptr->y_red; -+ *red_y = info_ptr->colorspace.end_points_xy.redy; - if (green_x != NULL) -- *green_x = info_ptr->x_green; -+ *green_x = info_ptr->colorspace.end_points_xy.greenx; - if (green_y != NULL) -- *green_y = info_ptr->y_green; -+ *green_y = info_ptr->colorspace.end_points_xy.greeny; - if (blue_x != NULL) -- *blue_x = info_ptr->x_blue; -+ *blue_x = info_ptr->colorspace.end_points_xy.bluex; - if (blue_y != NULL) -- *blue_y = info_ptr->y_blue; -+ *blue_y = info_ptr->colorspace.end_points_xy.bluey; - return (PNG_INFO_cHRM); - } - -@@ -556,49 +701,57 @@ - #endif - - #ifdef PNG_gAMA_SUPPORTED --png_uint_32 PNGFAPI --png_get_gAMA_fixed(png_const_structp png_ptr, png_const_infop info_ptr, -+# ifdef PNG_FIXED_POINT_SUPPORTED -+png_uint_32 PNGAPI -+png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *file_gamma) - { - png_debug1(1, "in %s retrieval function", "gAMA"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) -- && file_gamma != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && -+ file_gamma != NULL) - { -- *file_gamma = info_ptr->gamma; -+ *file_gamma = info_ptr->colorspace.gamma; - return (PNG_INFO_gAMA); - } - - return (0); - } -+# endif -+ - # ifdef PNG_FLOATING_POINT_SUPPORTED - png_uint_32 PNGAPI --png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *file_gamma) - { -- png_fixed_point igamma; -- png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma); -+ png_debug1(1, "in %s retrieval function", "gAMA(float)"); - -- if (ok) -- *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA"); -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && -+ file_gamma != NULL) -+ { -+ *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, -+ "png_get_gAMA"); -+ return (PNG_INFO_gAMA); -+ } - -- return ok; -+ return (0); - } -- - # endif - #endif - - #ifdef PNG_sRGB_SUPPORTED - png_uint_32 PNGAPI --png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *file_srgb_intent) - { - png_debug1(1, "in %s retrieval function", "sRGB"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) -- && file_srgb_intent != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) - { -- *file_srgb_intent = (int)info_ptr->srgb_intent; -+ *file_srgb_intent = info_ptr->colorspace.rendering_intent; - return (PNG_INFO_sRGB); - } - -@@ -608,22 +761,24 @@ - - #ifdef PNG_iCCP_SUPPORTED - png_uint_32 PNGAPI --png_get_iCCP(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen) - { - png_debug1(1, "in %s retrieval function", "iCCP"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) -- && name != NULL && profile != NULL && proflen != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_iCCP) != 0 && -+ name != NULL && compression_type != NULL && profile != NULL && -+ proflen != NULL) - { - *name = info_ptr->iccp_name; - *profile = info_ptr->iccp_profile; -- /* Compression_type is a dummy so the API won't have to change -- * if we introduce multiple compression types later. -+ *proflen = png_get_uint_32(info_ptr->iccp_profile); -+ /* This is somewhat irrelevant since the profile data returned has -+ * actually been uncompressed. - */ -- *proflen = (int)info_ptr->iccp_proflen; -- *compression_type = (int)info_ptr->iccp_compression; -+ *compression_type = PNG_COMPRESSION_TYPE_BASE; - return (PNG_INFO_iCCP); - } - -@@ -632,14 +787,14 @@ - #endif - - #ifdef PNG_sPLT_SUPPORTED --png_uint_32 PNGAPI --png_get_sPLT(png_const_structp png_ptr, png_const_infop info_ptr, -+int PNGAPI -+png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, - png_sPLT_tpp spalettes) - { - if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) - { - *spalettes = info_ptr->splt_palettes; -- return ((png_uint_32)info_ptr->splt_palettes_num); -+ return info_ptr->splt_palettes_num; - } - - return (0); -@@ -648,13 +803,13 @@ - - #ifdef PNG_hIST_SUPPORTED - png_uint_32 PNGAPI --png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_16p *hist) - { - png_debug1(1, "in %s retrieval function", "hIST"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) -- && hist != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) - { - *hist = info_ptr->hist; - return (PNG_INFO_hIST); -@@ -665,11 +820,10 @@ - #endif - - png_uint_32 PNGAPI --png_get_IHDR(png_structp png_ptr, png_infop info_ptr, -+png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *width, png_uint_32 *height, int *bit_depth, - int *color_type, int *interlace_type, int *compression_type, - int *filter_type) -- - { - png_debug1(1, "in %s retrieval function", "IHDR"); - -@@ -696,7 +850,7 @@ - * application has ignored our advice not to mess with the members - * of info_ptr directly. - */ -- png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, -+ png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); - -@@ -705,13 +859,14 @@ - - #ifdef PNG_oFFs_SUPPORTED - png_uint_32 PNGAPI --png_get_oFFs(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) - { - png_debug1(1, "in %s retrieval function", "oFFs"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) -- && offset_x != NULL && offset_y != NULL && unit_type != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_oFFs) != 0 && -+ offset_x != NULL && offset_y != NULL && unit_type != NULL) - { - *offset_x = info_ptr->x_offset; - *offset_y = info_ptr->y_offset; -@@ -725,14 +880,15 @@ - - #ifdef PNG_pCAL_SUPPORTED - png_uint_32 PNGAPI --png_get_pCAL(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, - png_charp *units, png_charpp *params) - { - png_debug1(1, "in %s retrieval function", "pCAL"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) -- && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_pCAL) != 0 && -+ purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && - nparams != NULL && units != NULL && params != NULL) - { - *purpose = info_ptr->pcal_purpose; -@@ -751,16 +907,20 @@ - - #ifdef PNG_sCAL_SUPPORTED - # ifdef PNG_FIXED_POINT_SUPPORTED --# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED -+# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ -+ defined(PNG_FLOATING_POINT_SUPPORTED) - png_uint_32 PNGAPI --png_get_sCAL_fixed(png_structp png_ptr, png_const_infop info_ptr, -+png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_fixed_point *width, png_fixed_point *height) - { - if (png_ptr != NULL && info_ptr != NULL && -- (info_ptr->valid & PNG_INFO_sCAL)) -+ (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; -- /*TODO: make this work without FP support */ -+ /*TODO: make this work without FP support; the API is currently eliminated -+ * if neither floating point APIs nor internal floating point arithmetic -+ * are enabled. -+ */ - *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); - *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), - "sCAL height"); -@@ -773,11 +933,11 @@ - # endif /* FIXED_POINT */ - # ifdef PNG_FLOATING_POINT_SUPPORTED - png_uint_32 PNGAPI --png_get_sCAL(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, double *width, double *height) - { - if (png_ptr != NULL && info_ptr != NULL && -- (info_ptr->valid & PNG_INFO_sCAL)) -+ (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = atof(info_ptr->scal_s_width); -@@ -789,11 +949,11 @@ - } - # endif /* FLOATING POINT */ - png_uint_32 PNGAPI --png_get_sCAL_s(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_charpp width, png_charpp height) - { - if (png_ptr != NULL && info_ptr != NULL && -- (info_ptr->valid & PNG_INFO_sCAL)) -+ (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = info_ptr->scal_s_width; -@@ -807,7 +967,7 @@ - - #ifdef PNG_pHYs_SUPPORTED - png_uint_32 PNGAPI --png_get_pHYs(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) - { - png_uint_32 retval = 0; -@@ -815,7 +975,7 @@ - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (png_ptr != NULL && info_ptr != NULL && -- (info_ptr->valid & PNG_INFO_pHYs)) -+ (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (res_x != NULL) - { -@@ -841,13 +1001,13 @@ - #endif /* pHYs */ - - png_uint_32 PNGAPI --png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, - png_colorp *palette, int *num_palette) - { - png_debug1(1, "in %s retrieval function", "PLTE"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) -- && palette != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL) - { - *palette = info_ptr->palette; - *num_palette = info_ptr->num_palette; -@@ -860,13 +1020,13 @@ - - #ifdef PNG_sBIT_SUPPORTED - png_uint_32 PNGAPI --png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr, -+png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_8p *sig_bit) - { - png_debug1(1, "in %s retrieval function", "sBIT"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) -- && sig_bit != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) - { - *sig_bit = &(info_ptr->sig_bit); - return (PNG_INFO_sBIT); -@@ -877,15 +1037,14 @@ - #endif - - #ifdef PNG_TEXT_SUPPORTED --png_uint_32 PNGAPI --png_get_text(png_const_structp png_ptr, png_const_infop info_ptr, -+int PNGAPI -+png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, - png_textp *text_ptr, int *num_text) - { - if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) - { -- png_debug1(1, "in %s retrieval function", -- (png_ptr->chunk_name[0] == '\0' ? "text" : -- (png_const_charp)png_ptr->chunk_name)); -+ png_debug1(1, "in 0x%lx retrieval function", -+ (unsigned long)png_ptr->chunk_name); - - if (text_ptr != NULL) - *text_ptr = info_ptr->text; -@@ -893,7 +1052,7 @@ - if (num_text != NULL) - *num_text = info_ptr->num_text; - -- return ((png_uint_32)info_ptr->num_text); -+ return info_ptr->num_text; - } - - if (num_text != NULL) -@@ -905,12 +1064,13 @@ - - #ifdef PNG_tIME_SUPPORTED - png_uint_32 PNGAPI --png_get_tIME(png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time) -+png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, -+ png_timep *mod_time) - { - png_debug1(1, "in %s retrieval function", "tIME"); - -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) -- && mod_time != NULL) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) - { - *mod_time = &(info_ptr->mod_time); - return (PNG_INFO_tIME); -@@ -922,11 +1082,12 @@ - - #ifdef PNG_tRNS_SUPPORTED - png_uint_32 PNGAPI --png_get_tRNS(png_const_structp png_ptr, png_infop info_ptr, -+png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) - { - png_uint_32 retval = 0; -- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - png_debug1(1, "in %s retrieval function", "tRNS"); - -@@ -965,9 +1126,9 @@ - } - #endif - --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - int PNGAPI --png_get_unknown_chunks(png_const_structp png_ptr, png_const_infop info_ptr, -+png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, - png_unknown_chunkpp unknowns) - { - if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) -@@ -982,7 +1143,7 @@ - - #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - png_byte PNGAPI --png_get_rgb_to_gray_status (png_const_structp png_ptr) -+png_get_rgb_to_gray_status (png_const_structrp png_ptr) - { - return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); - } -@@ -990,71 +1151,91 @@ - - #ifdef PNG_USER_CHUNKS_SUPPORTED - png_voidp PNGAPI --png_get_user_chunk_ptr(png_const_structp png_ptr) -+png_get_user_chunk_ptr(png_const_structrp png_ptr) - { - return (png_ptr ? png_ptr->user_chunk_ptr : NULL); - } - #endif - - png_size_t PNGAPI --png_get_compression_buffer_size(png_const_structp png_ptr) -+png_get_compression_buffer_size(png_const_structrp png_ptr) - { -- return (png_ptr ? png_ptr->zbuf_size : 0L); -+ if (png_ptr == NULL) -+ return 0; -+ -+# ifdef PNG_WRITE_SUPPORTED -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -+# endif -+ { -+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+ return png_ptr->IDAT_read_size; -+# else -+ return PNG_IDAT_READ_SIZE; -+# endif -+ } -+ -+# ifdef PNG_WRITE_SUPPORTED -+ else -+ return png_ptr->zbuffer_size; -+# endif - } - -- - #ifdef PNG_SET_USER_LIMITS_SUPPORTED - /* These functions were added to libpng 1.2.6 and were enabled - * by default in libpng-1.4.0 */ - png_uint_32 PNGAPI --png_get_user_width_max (png_const_structp png_ptr) -+png_get_user_width_max (png_const_structrp png_ptr) - { - return (png_ptr ? png_ptr->user_width_max : 0); - } - - png_uint_32 PNGAPI --png_get_user_height_max (png_const_structp png_ptr) -+png_get_user_height_max (png_const_structrp png_ptr) - { - return (png_ptr ? png_ptr->user_height_max : 0); - } - - /* This function was added to libpng 1.4.0 */ - png_uint_32 PNGAPI --png_get_chunk_cache_max (png_const_structp png_ptr) -+png_get_chunk_cache_max (png_const_structrp png_ptr) - { - return (png_ptr ? png_ptr->user_chunk_cache_max : 0); - } - - /* This function was added to libpng 1.4.1 */ - png_alloc_size_t PNGAPI --png_get_chunk_malloc_max (png_const_structp png_ptr) -+png_get_chunk_malloc_max (png_const_structrp png_ptr) - { - return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); - } --#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ -+#endif /* SET_USER_LIMITS */ - - /* These functions were added to libpng 1.4.0 */ - #ifdef PNG_IO_STATE_SUPPORTED - png_uint_32 PNGAPI --png_get_io_state (png_structp png_ptr) -+png_get_io_state (png_const_structrp png_ptr) - { - return png_ptr->io_state; - } - - png_uint_32 PNGAPI --png_get_io_chunk_type (png_const_structp png_ptr) --{ -- return ((png_ptr->chunk_name[0] << 24) + -- (png_ptr->chunk_name[1] << 16) + -- (png_ptr->chunk_name[2] << 8) + -- (png_ptr->chunk_name[3])); --} -- --png_const_bytep PNGAPI --png_get_io_chunk_name (png_structp png_ptr) -+png_get_io_chunk_type (png_const_structrp png_ptr) - { - return png_ptr->chunk_name; - } --#endif /* ?PNG_IO_STATE_SUPPORTED */ -+#endif /* IO_STATE */ - --#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ -+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -+# ifdef PNG_GET_PALETTE_MAX_SUPPORTED -+int PNGAPI -+png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) -+{ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return png_ptr->num_palette_max; -+ -+ return (-1); -+} -+# endif -+#endif -+ -+#endif /* READ || WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pnginfo.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pnginfo.h Thu Feb 05 13:00:26 2015 +0100 -@@ -29,11 +29,11 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -- * Last changed in libpng 1.5.0 [January 6, 2011] -+ * Last changed in libpng 1.6.1 [March 28, 2013] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer -@@ -83,7 +83,7 @@ - - struct png_info_def - { -- /* the following are necessary for every PNG file */ -+ /* The following are necessary for every PNG file */ - png_uint_32 width; /* width of image in pixels (from IHDR) */ - png_uint_32 height; /* height of image in pixels (from IHDR) */ - png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ -@@ -98,11 +98,17 @@ - png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ - png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - -- /* The following is informational only on read, and not used on writes. */ -+ /* The following are set by png_set_IHDR, called from the application on -+ * write, but the are never actually used by the write code. -+ */ - png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte spare_byte; /* to align the data, and for future use */ -+ -+#ifdef PNG_READ_SUPPORTED -+ /* This is never set during write */ - png_byte signature[8]; /* magic bytes read by libpng from start of file */ -+#endif - - /* The rest of the data is optional. If you are reading, check the - * valid field to see if the information in these are valid. If you -@@ -110,18 +116,25 @@ - * and initialize the appropriate fields below. - */ - --#if defined(PNG_gAMA_SUPPORTED) -- /* The gAMA chunk describes the gamma characteristics of the system -- * on which the image was created, normally in the range [1.0, 2.5]. -- * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. -+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) -+ /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are -+ * defined. When COLORSPACE is switched on all the colorspace-defining -+ * chunks should be enabled, when GAMMA is switched on all the gamma-defining -+ * chunks should be enabled. If this is not done it becomes possible to read -+ * inconsistent PNG files and assign a probably incorrect interpretation to -+ * the information. (In other words, by carefully choosing which chunks to -+ * recognize the system configuration can select an interpretation for PNG -+ * files containing ambiguous data and this will result in inconsistent -+ * behavior between different libpng builds!) - */ -- png_fixed_point gamma; -+ png_colorspace colorspace; - #endif - --#ifdef PNG_sRGB_SUPPORTED -- /* GR-P, 0.96a */ -- /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ -- png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ -+#ifdef PNG_iCCP_SUPPORTED -+ /* iCCP chunk data. */ -+ png_charp iccp_name; /* profile name */ -+ png_bytep iccp_profile; /* International Color Consortium profile data */ -+ png_uint_32 iccp_proflen; /* ICC profile data length */ - #endif - - #ifdef PNG_TEXT_SUPPORTED -@@ -136,7 +149,7 @@ - int num_text; /* number of comments read or comments to write */ - int max_text; /* current size of text array */ - png_textp text; /* array of comments read or comments to write */ --#endif /* PNG_TEXT_SUPPORTED */ -+#endif /* TEXT */ - - #ifdef PNG_tIME_SUPPORTED - /* The tIME chunk holds the last time the displayed image data was -@@ -211,23 +224,6 @@ - png_uint_16p hist; - #endif - --#ifdef PNG_cHRM_SUPPORTED -- /* The cHRM chunk describes the CIE color characteristics of the monitor -- * on which the PNG was created. This data allows the viewer to do gamut -- * mapping of the input image to ensure that the viewer sees the same -- * colors in the image as the creator. Values are in the range -- * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. -- */ -- png_fixed_point x_white; -- png_fixed_point y_white; -- png_fixed_point x_red; -- png_fixed_point y_red; -- png_fixed_point x_green; -- png_fixed_point y_green; -- png_fixed_point x_blue; -- png_fixed_point y_blue; --#endif -- - #ifdef PNG_pCAL_SUPPORTED - /* The pCAL chunk describes a transformation between the stored pixel - * values and original physical data values used to create the image. -@@ -252,25 +248,20 @@ - /* New members added in libpng-1.0.6 */ - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - --#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ -- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - /* Storage for unknown chunks that the library doesn't recognize. */ - png_unknown_chunkp unknown_chunks; -- int unknown_chunks_num; --#endif - --#ifdef PNG_iCCP_SUPPORTED -- /* iCCP chunk data. */ -- png_charp iccp_name; /* profile name */ -- png_bytep iccp_profile; /* International Color Consortium profile data */ -- png_uint_32 iccp_proflen; /* ICC profile data length */ -- png_byte iccp_compression; /* Always zero */ -+ /* The type of this field is limited by the type of -+ * png_struct::user_chunk_cache_max, else overflow can occur. -+ */ -+ int unknown_chunks_num; - #endif - - #ifdef PNG_sPLT_SUPPORTED - /* Data on sPLT chunks (there may be more than one). */ - png_sPLT_tp splt_palettes; -- png_uint_32 splt_palettes_num; -+ int splt_palettes_num; /* Match type returned by png_get API */ - #endif - - #ifdef PNG_sCAL_SUPPORTED ---- ./jdk/src/share/native/sun/awt/libpng/pnglibconf.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pnglibconf.h Thu Feb 05 13:00:26 2015 +0100 -@@ -34,69 +34,47 @@ - * file and, per its terms, should not be removed: - */ - --/* libpng version 1.5.4 - last changed on June 22, 2011 */ -+/* libpng version 1.6.16,December 22, 2014 */ - --/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */ -+/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ - - /* This code is released under the libpng license. */ - /* For conditions of distribution and use, see the disclaimer */ - /* and license in png.h */ - - /* pnglibconf.h */ -+/* Machine generated file: DO NOT EDIT */ - /* Derived from: scripts/pnglibconf.dfa */ --/* If you edit this file by hand you must obey the rules expressed in */ --/* pnglibconf.dfa with respect to the dependencies between the following */ --/* symbols. It is much better to generate a new file using */ --/* scripts/libpngconf.mak */ -- - #ifndef PNGLCONF_H - #define PNGLCONF_H --/* settings */ --#define PNG_API_RULE 0 --#define PNG_CALLOC_SUPPORTED --#define PNG_COST_SHIFT 3 --#define PNG_DEFAULT_READ_MACROS 1 --#define PNG_GAMMA_THRESHOLD_FIXED 5000 --#define PNG_MAX_GAMMA_8 11 --#define PNG_QUANTIZE_BLUE_BITS 5 --#define PNG_QUANTIZE_GREEN_BITS 5 --#define PNG_QUANTIZE_RED_BITS 5 --#define PNG_sCAL_PRECISION 5 --#define PNG_USER_CHUNK_CACHE_MAX 0 --#define PNG_USER_CHUNK_MALLOC_MAX 0 --#define PNG_USER_HEIGHT_MAX 1000000L --#define PNG_USER_WIDTH_MAX 1000000L --#define PNG_WEIGHT_SHIFT 8 --#define PNG_ZBUF_SIZE 8192 --/* end of settings */ - /* options */ - #define PNG_16BIT_SUPPORTED --#define PNG_ALIGN_MEMORY_SUPPORTED -+#define PNG_ALIGNED_MEMORY_SUPPORTED -+/*#undef PNG_ARM_NEON_API_SUPPORTED*/ -+/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ - #define PNG_BENIGN_ERRORS_SUPPORTED --#define PNG_bKGD_SUPPORTED -+#define PNG_BENIGN_READ_ERRORS_SUPPORTED -+/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ - #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED --#define PNG_CHECK_cHRM_SUPPORTED --#define PNG_cHRM_SUPPORTED -+#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -+#define PNG_COLORSPACE_SUPPORTED - #define PNG_CONSOLE_IO_SUPPORTED --#define PNG_CONVERT_tIME_SUPPORTED -+/*#undef PNG_CONVERT_tIME_SUPPORTED*/ - #define PNG_EASY_ACCESS_SUPPORTED - /*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ - #define PNG_ERROR_TEXT_SUPPORTED - #define PNG_FIXED_POINT_SUPPORTED - #define PNG_FLOATING_ARITHMETIC_SUPPORTED - #define PNG_FLOATING_POINT_SUPPORTED --#define PNG_gAMA_SUPPORTED -+#define PNG_FORMAT_AFIRST_SUPPORTED -+#define PNG_FORMAT_BGR_SUPPORTED -+#define PNG_GAMMA_SUPPORTED -+#define PNG_GET_PALETTE_MAX_SUPPORTED - #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED --#define PNG_hIST_SUPPORTED --#define PNG_iCCP_SUPPORTED - #define PNG_INCH_CONVERSIONS_SUPPORTED - #define PNG_INFO_IMAGE_SUPPORTED - #define PNG_IO_STATE_SUPPORTED --#define PNG_iTXt_SUPPORTED - #define PNG_MNG_FEATURES_SUPPORTED --#define PNG_oFFs_SUPPORTED --#define PNG_pCAL_SUPPORTED --#define PNG_pHYs_SUPPORTED - #define PNG_POINTER_INDEXING_SUPPORTED - #define PNG_PROGRESSIVE_READ_SUPPORTED - #define PNG_READ_16BIT_SUPPORTED -@@ -104,67 +82,73 @@ - #define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED - #define PNG_READ_BACKGROUND_SUPPORTED - #define PNG_READ_BGR_SUPPORTED --#define PNG_READ_bKGD_SUPPORTED --#define PNG_READ_cHRM_SUPPORTED -+#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - #define PNG_READ_COMPOSITE_NODIV_SUPPORTED - #define PNG_READ_COMPRESSED_TEXT_SUPPORTED - #define PNG_READ_EXPAND_16_SUPPORTED - #define PNG_READ_EXPAND_SUPPORTED - #define PNG_READ_FILLER_SUPPORTED --#define PNG_READ_gAMA_SUPPORTED - #define PNG_READ_GAMMA_SUPPORTED -+#define PNG_READ_GET_PALETTE_MAX_SUPPORTED - #define PNG_READ_GRAY_TO_RGB_SUPPORTED --#define PNG_READ_hIST_SUPPORTED --#define PNG_READ_iCCP_SUPPORTED - #define PNG_READ_INTERLACING_SUPPORTED - #define PNG_READ_INT_FUNCTIONS_SUPPORTED - #define PNG_READ_INVERT_ALPHA_SUPPORTED - #define PNG_READ_INVERT_SUPPORTED --#define PNG_READ_iTXt_SUPPORTED --#define PNG_READ_oFFs_SUPPORTED - #define PNG_READ_OPT_PLTE_SUPPORTED -+#define PNG_READ_PACKSWAP_SUPPORTED - #define PNG_READ_PACK_SUPPORTED --#define PNG_READ_PACKSWAP_SUPPORTED --#define PNG_READ_pCAL_SUPPORTED --#define PNG_READ_pHYs_SUPPORTED - #define PNG_READ_QUANTIZE_SUPPORTED - #define PNG_READ_RGB_TO_GRAY_SUPPORTED --#define PNG_READ_sBIT_SUPPORTED - #define PNG_READ_SCALE_16_TO_8_SUPPORTED --#define PNG_READ_sCAL_SUPPORTED - #define PNG_READ_SHIFT_SUPPORTED --#define PNG_READ_sPLT_SUPPORTED --#define PNG_READ_sRGB_SUPPORTED - #define PNG_READ_STRIP_16_TO_8_SUPPORTED - #define PNG_READ_STRIP_ALPHA_SUPPORTED - #define PNG_READ_SUPPORTED - #define PNG_READ_SWAP_ALPHA_SUPPORTED - #define PNG_READ_SWAP_SUPPORTED --#define PNG_READ_tEXt_SUPPORTED - #define PNG_READ_TEXT_SUPPORTED --#define PNG_READ_tIME_SUPPORTED - #define PNG_READ_TRANSFORMS_SUPPORTED --#define PNG_READ_tRNS_SUPPORTED - #define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_READ_USER_CHUNKS_SUPPORTED - #define PNG_READ_USER_TRANSFORM_SUPPORTED -+#define PNG_READ_bKGD_SUPPORTED -+#define PNG_READ_cHRM_SUPPORTED -+#define PNG_READ_gAMA_SUPPORTED -+#define PNG_READ_hIST_SUPPORTED -+#define PNG_READ_iCCP_SUPPORTED -+#define PNG_READ_iTXt_SUPPORTED -+#define PNG_READ_oFFs_SUPPORTED -+#define PNG_READ_pCAL_SUPPORTED -+#define PNG_READ_pHYs_SUPPORTED -+#define PNG_READ_sBIT_SUPPORTED -+#define PNG_READ_sCAL_SUPPORTED -+#define PNG_READ_sPLT_SUPPORTED -+#define PNG_READ_sRGB_SUPPORTED -+#define PNG_READ_tEXt_SUPPORTED -+#define PNG_READ_tIME_SUPPORTED -+#define PNG_READ_tRNS_SUPPORTED - #define PNG_READ_zTXt_SUPPORTED --#define PNG_SAVE_INT_32_SUPPORTED --#define PNG_sBIT_SUPPORTED --#define PNG_sCAL_SUPPORTED -+/*#undef PNG_SAFE_LIMITS_SUPPORTED*/ -+/*#undef PNG_SAVE_INT_32_SUPPORTED*/ -+#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_SEQUENTIAL_READ_SUPPORTED -+#define PNG_SETJMP_SUPPORTED - #define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED - #define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED --#define PNG_SETJMP_SUPPORTED -+#define PNG_SET_OPTION_SUPPORTED -+#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_SET_USER_LIMITS_SUPPORTED --#define PNG_sPLT_SUPPORTED --#define PNG_sRGB_SUPPORTED -+#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED -+#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED -+#define PNG_SIMPLIFIED_READ_SUPPORTED -+/*#undef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED*/ -+/*#undef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED*/ -+/*#undef PNG_SIMPLIFIED_WRITE_SUPPORTED*/ - #define PNG_STDIO_SUPPORTED --#define PNG_tEXt_SUPPORTED -+#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_TEXT_SUPPORTED - #define PNG_TIME_RFC1123_SUPPORTED --#define PNG_tIME_SUPPORTED --#define PNG_tRNS_SUPPORTED - #define PNG_UNKNOWN_CHUNKS_SUPPORTED - #define PNG_USER_CHUNKS_SUPPORTED - #define PNG_USER_LIMITS_SUPPORTED -@@ -172,6 +156,91 @@ - #define PNG_USER_TRANSFORM_INFO_SUPPORTED - #define PNG_USER_TRANSFORM_PTR_SUPPORTED - #define PNG_WARNINGS_SUPPORTED -+/*#undef PNG_WRITE_16BIT_SUPPORTED*/ -+/*#undef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED*/ -+/*#undef PNG_WRITE_BGR_SUPPORTED*/ -+/*#undef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED*/ -+/*#undef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED*/ -+/*#undef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED*/ -+/*#undef PNG_WRITE_FILLER_SUPPORTED*/ -+/*#undef PNG_WRITE_FILTER_SUPPORTED*/ -+/*#undef PNG_WRITE_FLUSH_SUPPORTED*/ -+/*#undef PNG_WRITE_GET_PALETTE_MAX_SUPPORTED*/ -+/*#undef PNG_WRITE_INTERLACING_SUPPORTED*/ -+/*#undef PNG_WRITE_INT_FUNCTIONS_SUPPORTED*/ -+/*#undef PNG_WRITE_INVERT_ALPHA_SUPPORTED*/ -+/*#undef PNG_WRITE_INVERT_SUPPORTED*/ -+/*#undef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED*/ -+/*#undef PNG_WRITE_PACKSWAP_SUPPORTED*/ -+/*#undef PNG_WRITE_PACK_SUPPORTED*/ -+/*#undef PNG_WRITE_SHIFT_SUPPORTED*/ -+/*#undef PNG_WRITE_SUPPORTED*/ -+/*#undef PNG_WRITE_SWAP_ALPHA_SUPPORTED*/ -+/*#undef PNG_WRITE_SWAP_SUPPORTED*/ -+/*#undef PNG_WRITE_TEXT_SUPPORTED*/ -+/*#undef PNG_WRITE_TRANSFORMS_SUPPORTED*/ -+/*#undef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED*/ -+/*#undef PNG_WRITE_USER_TRANSFORM_SUPPORTED*/ -+/*#undef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED*/ -+/*#undef PNG_WRITE_bKGD_SUPPORTED*/ -+/*#undef PNG_WRITE_cHRM_SUPPORTED*/ -+/*#undef PNG_WRITE_gAMA_SUPPORTED*/ -+/*#undef PNG_WRITE_hIST_SUPPORTED*/ -+/*#undef PNG_WRITE_iCCP_SUPPORTED*/ -+/*#undef PNG_WRITE_iTXt_SUPPORTED*/ -+/*#undef PNG_WRITE_oFFs_SUPPORTED*/ -+/*#undef PNG_WRITE_pCAL_SUPPORTED*/ -+/*#undef PNG_WRITE_pHYs_SUPPORTED*/ -+/*#undef PNG_WRITE_sBIT_SUPPORTED*/ -+/*#undef PNG_WRITE_sCAL_SUPPORTED*/ -+/*#undef PNG_WRITE_sPLT_SUPPORTED*/ -+/*#undef PNG_WRITE_sRGB_SUPPORTED*/ -+/*#undef PNG_WRITE_tEXt_SUPPORTED*/ -+/*#undef PNG_WRITE_tIME_SUPPORTED*/ -+/*#undef PNG_WRITE_tRNS_SUPPORTED*/ -+/*#undef PNG_WRITE_zTXt_SUPPORTED*/ -+#define PNG_bKGD_SUPPORTED -+#define PNG_cHRM_SUPPORTED -+#define PNG_gAMA_SUPPORTED -+#define PNG_hIST_SUPPORTED -+#define PNG_iCCP_SUPPORTED -+#define PNG_iTXt_SUPPORTED -+#define PNG_oFFs_SUPPORTED -+#define PNG_pCAL_SUPPORTED -+#define PNG_pHYs_SUPPORTED -+#define PNG_sBIT_SUPPORTED -+#define PNG_sCAL_SUPPORTED -+#define PNG_sPLT_SUPPORTED -+#define PNG_sRGB_SUPPORTED -+#define PNG_tEXt_SUPPORTED -+#define PNG_tIME_SUPPORTED -+#define PNG_tRNS_SUPPORTED - #define PNG_zTXt_SUPPORTED - /* end of options */ -+/* settings */ -+#define PNG_API_RULE 0 -+#define PNG_COST_SHIFT 3 -+#define PNG_DEFAULT_READ_MACROS 1 -+#define PNG_GAMMA_THRESHOLD_FIXED 5000 -+#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE -+#define PNG_INFLATE_BUF_SIZE 1024 -+#define PNG_MAX_GAMMA_8 11 -+#define PNG_QUANTIZE_BLUE_BITS 5 -+#define PNG_QUANTIZE_GREEN_BITS 5 -+#define PNG_QUANTIZE_RED_BITS 5 -+#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) -+#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 -+#define PNG_USER_CHUNK_CACHE_MAX 0 -+#define PNG_USER_CHUNK_MALLOC_MAX 0 -+#define PNG_USER_HEIGHT_MAX 1000000 -+#define PNG_USER_WIDTH_MAX 1000000 -+#define PNG_WEIGHT_SHIFT 8 -+#define PNG_ZBUF_SIZE 8192 -+#define PNG_ZLIB_VERNUM 0 -+#define PNG_Z_DEFAULT_COMPRESSION (-1) -+#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 -+#define PNG_Z_DEFAULT_STRATEGY 1 -+#define PNG_sCAL_PRECISION 5 -+#define PNG_sRGB_PROFILE_CHECKS 2 -+/* end of settings */ - #endif /* PNGLCONF_H */ ---- ./jdk/src/share/native/sun/awt/libpng/pngmem.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngmem.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -48,457 +48,23 @@ - #include "pngpriv.h" - - #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -+/* Free a png_struct */ -+void /* PRIVATE */ -+png_destroy_png_struct(png_structrp png_ptr) -+{ -+ if (png_ptr != NULL) -+ { -+ /* png_free might call png_error and may certainly call -+ * png_get_mem_ptr, so fake a temporary png_struct to support this. -+ */ -+ png_struct dummy_struct = *png_ptr; -+ memset(png_ptr, 0, (sizeof *png_ptr)); -+ png_free(&dummy_struct, png_ptr); - --/* Borland DOS special memory handler */ --#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) --/* If you change this, be sure to change the one in png.h also */ -- --/* Allocate memory for a png_struct. The malloc and memset can be replaced -- by a single call to calloc() if this is thought to improve performance. */ --PNG_FUNCTION(png_voidp /* PRIVATE */, --png_create_struct,(int type),PNG_ALLOCATED) --{ --# ifdef PNG_USER_MEM_SUPPORTED -- return (png_create_struct_2(type, NULL, NULL)); --} -- --/* Alternate version of png_create_struct, for use with user-defined malloc. */ --PNG_FUNCTION(png_voidp /* PRIVATE */, --png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), -- PNG_ALLOCATED) --{ --# endif /* PNG_USER_MEM_SUPPORTED */ -- png_size_t size; -- png_voidp struct_ptr; -- -- if (type == PNG_STRUCT_INFO) -- size = png_sizeof(png_info); -- -- else if (type == PNG_STRUCT_PNG) -- size = png_sizeof(png_struct); -- -- else -- return (png_get_copyright(NULL)); -- --# ifdef PNG_USER_MEM_SUPPORTED -- if (malloc_fn != NULL) -- { -- png_struct dummy_struct; -- png_structp png_ptr = &dummy_struct; -- png_ptr->mem_ptr=mem_ptr; -- struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); -- } -- -- else --# endif /* PNG_USER_MEM_SUPPORTED */ -- struct_ptr = (png_voidp)farmalloc(size); -- if (struct_ptr != NULL) -- png_memset(struct_ptr, 0, size); -- -- return (struct_ptr); --} -- --/* Free memory allocated by a png_create_struct() call */ --void /* PRIVATE */ --png_destroy_struct(png_voidp struct_ptr) --{ --# ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2(struct_ptr, NULL, NULL); --} -- --/* Free memory allocated by a png_create_struct() call */ --void /* PRIVATE */ --png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, -- png_voidp mem_ptr) --{ --# endif -- if (struct_ptr != NULL) -- { --# ifdef PNG_USER_MEM_SUPPORTED -- if (free_fn != NULL) -- { -- png_struct dummy_struct; -- png_structp png_ptr = &dummy_struct; -- png_ptr->mem_ptr=mem_ptr; -- (*(free_fn))(png_ptr, struct_ptr); -- return; -- } -- --# endif /* PNG_USER_MEM_SUPPORTED */ -- farfree (struct_ptr); -- } --} -- --/* Allocate memory. For reasonable files, size should never exceed -- * 64K. However, zlib may allocate more then 64K if you don't tell -- * it not to. See zconf.h and png.h for more information. zlib does -- * need to allocate exactly 64K, so whatever you call here must -- * have the ability to do that. -- * -- * Borland seems to have a problem in DOS mode for exactly 64K. -- * It gives you a segment with an offset of 8 (perhaps to store its -- * memory stuff). zlib doesn't like this at all, so we have to -- * detect and deal with it. This code should not be needed in -- * Windows or OS/2 modes, and only in 16 bit mode. This code has -- * been updated by Alexander Lehmann for version 0.89 to waste less -- * memory. -- * -- * Note that we can't use png_size_t for the "size" declaration, -- * since on some systems a png_size_t is a 16-bit quantity, and as a -- * result, we would be truncating potentially larger memory requests -- * (which should cause a fatal error) and introducing major problems. -- */ --PNG_FUNCTION(png_voidp,PNGAPI --png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) --{ -- png_voidp ret; -- -- ret = (png_malloc(png_ptr, size)); -- -- if (ret != NULL) -- png_memset(ret,0,(png_size_t)size); -- -- return (ret); --} -- --PNG_FUNCTION(png_voidp,PNGAPI --png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) --{ -- png_voidp ret; -- -- if (png_ptr == NULL || size == 0) -- return (NULL); -- --# ifdef PNG_USER_MEM_SUPPORTED -- if (png_ptr->malloc_fn != NULL) -- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); -- -- else -- ret = (png_malloc_default(png_ptr, size)); -- -- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Out of memory"); -- -- return (ret); --} -- --PNG_FUNCTION(png_voidp,PNGAPI --png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) --{ -- png_voidp ret; --# endif /* PNG_USER_MEM_SUPPORTED */ -- -- if (png_ptr == NULL || size == 0) -- return (NULL); -- --# ifdef PNG_MAX_MALLOC_64K -- if (size > (png_uint_32)65536L) -- { -- png_warning(png_ptr, "Cannot Allocate > 64K"); -- ret = NULL; -- } -- -- else --# endif -- -- if (size != (size_t)size) -- ret = NULL; -- -- else if (size == (png_uint_32)65536L) -- { -- if (png_ptr->offset_table == NULL) -- { -- /* Try to see if we need to do any of this fancy stuff */ -- ret = farmalloc(size); -- if (ret == NULL || ((png_size_t)ret & 0xffff)) -- { -- int num_blocks; -- png_uint_32 total_size; -- png_bytep table; -- int i, mem_level, window_bits; -- png_byte huge * hptr; -- int window_bits -- -- if (ret != NULL) -- { -- farfree(ret); -- ret = NULL; -- } -- -- window_bits = -- png_ptr->zlib_window_bits >= png_ptr->zlib_text_window_bits ? -- png_ptr->zlib_window_bits : png_ptr->zlib_text_window_bits; -- -- if (window_bits > 14) -- num_blocks = (int)(1 << (window_bits - 14)); -- -- else -- num_blocks = 1; -- -- mem_level = -- png_ptr->zlib_mem_level >= png_ptr->zlib_text_mem_level ? -- png_ptr->zlib_mem_level : png_ptr->zlib_text_mem_level; -- -- if (mem_level >= 7) -- num_blocks += (int)(1 << (mem_level - 7)); -- -- else -- num_blocks++; -- -- total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; -- -- table = farmalloc(total_size); -- -- if (table == NULL) -- { --# ifndef PNG_USER_MEM_SUPPORTED -- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */ -- -- else -- png_warning(png_ptr, "Out Of Memory"); --# endif -- return (NULL); -- } -- -- if ((png_size_t)table & 0xfff0) -- { --# ifndef PNG_USER_MEM_SUPPORTED -- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, -- "Farmalloc didn't return normalized pointer"); -- -- else -- png_warning(png_ptr, -- "Farmalloc didn't return normalized pointer"); --# endif -- return (NULL); -- } -- -- png_ptr->offset_table = table; -- png_ptr->offset_table_ptr = farmalloc(num_blocks * -- png_sizeof(png_bytep)); -- -- if (png_ptr->offset_table_ptr == NULL) -- { --# ifndef PNG_USER_MEM_SUPPORTED -- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */ -- -- else -- png_warning(png_ptr, "Out Of memory"); --# endif -- return (NULL); -- } -- -- hptr = (png_byte huge *)table; -- if ((png_size_t)hptr & 0xf) -- { -- hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); -- hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ -- } -- -- for (i = 0; i < num_blocks; i++) -- { -- png_ptr->offset_table_ptr[i] = (png_bytep)hptr; -- hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ -- } -- -- png_ptr->offset_table_number = num_blocks; -- png_ptr->offset_table_count = 0; -- png_ptr->offset_table_count_free = 0; -- } -- } -- -- if (png_ptr->offset_table_count >= png_ptr->offset_table_number) -- { --# ifndef PNG_USER_MEM_SUPPORTED -- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Out of Memory"); /* Note "O" and "M" */ -- -- else -- png_warning(png_ptr, "Out of Memory"); --# endif -- return (NULL); -- } -- -- ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; -- } -- -- else -- ret = farmalloc(size); -- --# ifndef PNG_USER_MEM_SUPPORTED -- if (ret == NULL) -- { -- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */ -- -- else -- png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */ -- } --# endif -- -- return (ret); --} -- --/* Free a pointer allocated by png_malloc(). In the default -- * configuration, png_ptr is not used, but is passed in case it -- * is needed. If ptr is NULL, return without taking any action. -- */ --void PNGAPI --png_free(png_structp png_ptr, png_voidp ptr) --{ -- if (png_ptr == NULL || ptr == NULL) -- return; -- --# ifdef PNG_USER_MEM_SUPPORTED -- if (png_ptr->free_fn != NULL) -- { -- (*(png_ptr->free_fn))(png_ptr, ptr); -- return; -- } -- -- else -- png_free_default(png_ptr, ptr); --} -- --void PNGAPI --png_free_default(png_structp png_ptr, png_voidp ptr) --{ --# endif /* PNG_USER_MEM_SUPPORTED */ -- -- if (png_ptr == NULL || ptr == NULL) -- return; -- -- if (png_ptr->offset_table != NULL) -- { -- int i; -- -- for (i = 0; i < png_ptr->offset_table_count; i++) -- { -- if (ptr == png_ptr->offset_table_ptr[i]) -- { -- ptr = NULL; -- png_ptr->offset_table_count_free++; -- break; -- } -- } -- if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) -- { -- farfree(png_ptr->offset_table); -- farfree(png_ptr->offset_table_ptr); -- png_ptr->offset_table = NULL; -- png_ptr->offset_table_ptr = NULL; -- } -- } -- -- if (ptr != NULL) -- farfree(ptr); --} -- --#else /* Not the Borland DOS special memory handler */ -- --/* Allocate memory for a png_struct or a png_info. The malloc and -- memset can be replaced by a single call to calloc() if this is thought -- to improve performance noticably. */ --PNG_FUNCTION(png_voidp /* PRIVATE */, --png_create_struct,(int type),PNG_ALLOCATED) --{ --# ifdef PNG_USER_MEM_SUPPORTED -- return (png_create_struct_2(type, NULL, NULL)); --} -- --/* Allocate memory for a png_struct or a png_info. The malloc and -- memset can be replaced by a single call to calloc() if this is thought -- to improve performance noticably. */ --PNG_FUNCTION(png_voidp /* PRIVATE */, --png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), -- PNG_ALLOCATED) --{ --# endif /* PNG_USER_MEM_SUPPORTED */ -- png_size_t size; -- png_voidp struct_ptr; -- -- if (type == PNG_STRUCT_INFO) -- size = png_sizeof(png_info); -- -- else if (type == PNG_STRUCT_PNG) -- size = png_sizeof(png_struct); -- -- else -- return (NULL); -- --# ifdef PNG_USER_MEM_SUPPORTED -- if (malloc_fn != NULL) -- { -- png_struct dummy_struct; -- png_structp png_ptr = &dummy_struct; -- png_ptr->mem_ptr=mem_ptr; -- struct_ptr = (*(malloc_fn))(png_ptr, size); -- -- if (struct_ptr != NULL) -- png_memset(struct_ptr, 0, size); -- -- return (struct_ptr); -- } --# endif /* PNG_USER_MEM_SUPPORTED */ -- --# if defined(__TURBOC__) && !defined(__FLAT__) -- struct_ptr = (png_voidp)farmalloc(size); --# else --# if defined(_MSC_VER) && defined(MAXSEG_64K) -- struct_ptr = (png_voidp)halloc(size, 1); --# else -- struct_ptr = (png_voidp)malloc(size); --# endif --# endif -- -- if (struct_ptr != NULL) -- png_memset(struct_ptr, 0, size); -- -- return (struct_ptr); --} -- -- --/* Free memory allocated by a png_create_struct() call */ --void /* PRIVATE */ --png_destroy_struct(png_voidp struct_ptr) --{ --# ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2(struct_ptr, NULL, NULL); --} -- --/* Free memory allocated by a png_create_struct() call */ --void /* PRIVATE */ --png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, -- png_voidp mem_ptr) --{ --# endif /* PNG_USER_MEM_SUPPORTED */ -- if (struct_ptr != NULL) -- { --# ifdef PNG_USER_MEM_SUPPORTED -- if (free_fn != NULL) -- { -- png_struct dummy_struct; -- png_structp png_ptr = &dummy_struct; -- png_ptr->mem_ptr=mem_ptr; -- (*(free_fn))(png_ptr, struct_ptr); -- return; -- } --# endif /* PNG_USER_MEM_SUPPORTED */ --# if defined(__TURBOC__) && !defined(__FLAT__) -- farfree(struct_ptr); -- --# else --# if defined(_MSC_VER) && defined(MAXSEG_64K) -- hfree(struct_ptr); -- --# else -- free(struct_ptr); -- --# endif --# endif -+# ifdef PNG_SETJMP_SUPPORTED -+ /* We may have a jmp_buf left to deallocate. */ -+ png_free_jmpbuf(&dummy_struct); -+# endif - } - } - -@@ -508,167 +74,215 @@ - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - */ -- - PNG_FUNCTION(png_voidp,PNGAPI --png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -+png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) - { - png_voidp ret; - -- ret = (png_malloc(png_ptr, size)); -+ ret = png_malloc(png_ptr, size); - - if (ret != NULL) -- png_memset(ret,0,(png_size_t)size); -+ memset(ret, 0, size); - -- return (ret); -+ return ret; - } - -+/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of -+ * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. -+ * Checking and error handling must happen outside this routine; it returns NULL -+ * if the allocation cannot be done (for any reason.) -+ */ -+PNG_FUNCTION(png_voidp /* PRIVATE */, -+png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), -+ PNG_ALLOCATED) -+{ -+ /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS -+ * allocators have also been removed in 1.6.0, so any 16-bit system now has -+ * to implement a user memory handler. This checks to be sure it isn't -+ * called with big numbers. -+ */ -+#ifndef PNG_USER_MEM_SUPPORTED -+ PNG_UNUSED(png_ptr) -+#endif -+ -+ if (size > 0 && size <= PNG_SIZE_MAX -+# ifdef PNG_MAX_MALLOC_64K -+ && size <= 65536U -+# endif -+ ) -+ { -+#ifdef PNG_USER_MEM_SUPPORTED -+ if (png_ptr != NULL && png_ptr->malloc_fn != NULL) -+ return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); -+ -+ else -+#endif -+ return malloc((size_t)size); /* checked for truncation above */ -+ } -+ -+ else -+ return NULL; -+} -+ -+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ -+ defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -+/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 -+ * that arises because of the checks in png_realloc_array that are repeated in -+ * png_malloc_array. -+ */ -+static png_voidp -+png_malloc_array_checked(png_const_structrp png_ptr, int nelements, -+ size_t element_size) -+{ -+ png_alloc_size_t req = nelements; /* known to be > 0 */ -+ -+ if (req <= PNG_SIZE_MAX/element_size) -+ return png_malloc_base(png_ptr, req * element_size); -+ -+ /* The failure case when the request is too large */ -+ return NULL; -+} -+ -+PNG_FUNCTION(png_voidp /* PRIVATE */, -+png_malloc_array,(png_const_structrp png_ptr, int nelements, -+ size_t element_size),PNG_ALLOCATED) -+{ -+ if (nelements <= 0 || element_size == 0) -+ png_error(png_ptr, "internal error: array alloc"); -+ -+ return png_malloc_array_checked(png_ptr, nelements, element_size); -+} -+ -+PNG_FUNCTION(png_voidp /* PRIVATE */, -+png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, -+ int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) -+{ -+ /* These are internal errors: */ -+ if (add_elements <= 0 || element_size == 0 || old_elements < 0 || -+ (old_array == NULL && old_elements > 0)) -+ png_error(png_ptr, "internal error: array realloc"); -+ -+ /* Check for overflow on the elements count (so the caller does not have to -+ * check.) -+ */ -+ if (add_elements <= INT_MAX - old_elements) -+ { -+ png_voidp new_array = png_malloc_array_checked(png_ptr, -+ old_elements+add_elements, element_size); -+ -+ if (new_array != NULL) -+ { -+ /* Because png_malloc_array worked the size calculations below cannot -+ * overflow. -+ */ -+ if (old_elements > 0) -+ memcpy(new_array, old_array, element_size*(unsigned)old_elements); -+ -+ memset((char*)new_array + element_size*(unsigned)old_elements, 0, -+ element_size*(unsigned)add_elements); -+ -+ return new_array; -+ } -+ } -+ -+ return NULL; /* error */ -+} -+#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ -+ -+/* Various functions that have different error handling are derived from this. -+ * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate -+ * function png_malloc_default is also provided. -+ */ - PNG_FUNCTION(png_voidp,PNGAPI --png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -+png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) - { - png_voidp ret; - --# ifdef PNG_USER_MEM_SUPPORTED -- if (png_ptr == NULL || size == 0) -- return (NULL); -+ if (png_ptr == NULL) -+ return NULL; - -- if (png_ptr->malloc_fn != NULL) -- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); -+ ret = png_malloc_base(png_ptr, size); - -- else -- ret = (png_malloc_default(png_ptr, size)); -+ if (ret == NULL) -+ png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */ - -- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Out of Memory"); -- -- return (ret); -+ return ret; - } - -+#ifdef PNG_USER_MEM_SUPPORTED - PNG_FUNCTION(png_voidp,PNGAPI --png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -+png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), -+ PNG_ALLOCATED PNG_DEPRECATED) - { - png_voidp ret; --# endif /* PNG_USER_MEM_SUPPORTED */ - -- if (png_ptr == NULL || size == 0) -- return (NULL); -+ if (png_ptr == NULL) -+ return NULL; - --# ifdef PNG_MAX_MALLOC_64K -- if (size > (png_uint_32)65536L) -+ /* Passing 'NULL' here bypasses the application provided memory handler. */ -+ ret = png_malloc_base(NULL/*use malloc*/, size); -+ -+ if (ret == NULL) -+ png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */ -+ -+ return ret; -+} -+#endif /* USER_MEM */ -+ -+/* This function was added at libpng version 1.2.3. The png_malloc_warn() -+ * function will issue a png_warning and return NULL instead of issuing a -+ * png_error, if it fails to allocate the requested memory. -+ */ -+PNG_FUNCTION(png_voidp,PNGAPI -+png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), -+ PNG_ALLOCATED) -+{ -+ if (png_ptr != NULL) - { --# ifndef PNG_USER_MEM_SUPPORTED -- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Cannot Allocate > 64K"); -+ png_voidp ret = png_malloc_base(png_ptr, size); - -- else --# endif -- return NULL; -+ if (ret != NULL) -+ return ret; -+ -+ png_warning(png_ptr, "Out of memory"); - } --# endif - -- /* Check for overflow */ --# if defined(__TURBOC__) && !defined(__FLAT__) -- -- if (size != (unsigned long)size) -- ret = NULL; -- -- else -- ret = farmalloc(size); -- --# else --# if defined(_MSC_VER) && defined(MAXSEG_64K) -- if (size != (unsigned long)size) -- ret = NULL; -- -- else -- ret = halloc(size, 1); -- --# else -- if (size != (size_t)size) -- ret = NULL; -- -- else -- ret = malloc((size_t)size); --# endif --# endif -- --# ifndef PNG_USER_MEM_SUPPORTED -- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) -- png_error(png_ptr, "Out of Memory"); --# endif -- -- return (ret); -+ return NULL; - } - - /* Free a pointer allocated by png_malloc(). If ptr is NULL, return - * without taking any action. - */ - void PNGAPI --png_free(png_structp png_ptr, png_voidp ptr) -+png_free(png_const_structrp png_ptr, png_voidp ptr) - { - if (png_ptr == NULL || ptr == NULL) - return; - --# ifdef PNG_USER_MEM_SUPPORTED -+#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr->free_fn != NULL) -- { -- (*(png_ptr->free_fn))(png_ptr, ptr); -- return; -- } -+ png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); - - else - png_free_default(png_ptr, ptr); - } - --void PNGAPI --png_free_default(png_structp png_ptr, png_voidp ptr) -+PNG_FUNCTION(void,PNGAPI -+png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED) - { - if (png_ptr == NULL || ptr == NULL) - return; -+#endif /* USER_MEM */ - --# endif /* PNG_USER_MEM_SUPPORTED */ -- --# if defined(__TURBOC__) && !defined(__FLAT__) -- farfree(ptr); -- --# else --# if defined(_MSC_VER) && defined(MAXSEG_64K) -- hfree(ptr); -- --# else - free(ptr); -- --# endif --# endif - } --#endif /* Not Borland DOS special memory handler */ -- --/* This function was added at libpng version 1.2.3. The png_malloc_warn() -- * function will set up png_malloc() to issue a png_warning and return NULL -- * instead of issuing a png_error, if it fails to allocate the requested -- * memory. -- */ --PNG_FUNCTION(png_voidp,PNGAPI --png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) --{ -- png_voidp ptr; -- png_uint_32 save_flags; -- if (png_ptr == NULL) -- return (NULL); -- -- save_flags = png_ptr->flags; -- png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; -- ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); -- png_ptr->flags=save_flags; -- return(ptr); --} -- - - #ifdef PNG_USER_MEM_SUPPORTED - /* This function is called when the application wants to use another method - * of allocating and freeing memory. - */ - void PNGAPI --png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr -+png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr - malloc_fn, png_free_ptr free_fn) - { - if (png_ptr != NULL) -@@ -684,12 +298,12 @@ - * pointer before png_write_destroy and png_read_destroy are called. - */ - png_voidp PNGAPI --png_get_mem_ptr(png_const_structp png_ptr) -+png_get_mem_ptr(png_const_structrp png_ptr) - { - if (png_ptr == NULL) -- return (NULL); -+ return NULL; - -- return ((png_voidp)png_ptr->mem_ptr); -+ return png_ptr->mem_ptr; - } --#endif /* PNG_USER_MEM_SUPPORTED */ --#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ -+#endif /* USER_MEM */ -+#endif /* READ || WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pngpread.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngpread.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.2 [March 31, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -54,8 +54,15 @@ - #define PNG_READ_iTXt_MODE 7 - #define PNG_ERROR_MODE 8 - -+#define PNG_PUSH_SAVE_BUFFER_IF_FULL \ -+if (png_ptr->push_length + 4 > png_ptr->buffer_size) \ -+ { png_push_save_buffer(png_ptr); return; } -+#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ -+if (png_ptr->buffer_size < N) \ -+ { png_push_save_buffer(png_ptr); return; } -+ - void PNGAPI --png_process_data(png_structp png_ptr, png_infop info_ptr, -+png_process_data(png_structrp png_ptr, png_inforp info_ptr, - png_bytep buffer, png_size_t buffer_size) - { - if (png_ptr == NULL || info_ptr == NULL) -@@ -70,14 +77,14 @@ - } - - png_size_t PNGAPI --png_process_data_pause(png_structp png_ptr, int save) -+png_process_data_pause(png_structrp png_ptr, int save) - { - if (png_ptr != NULL) - { -- /* It's easiest for the caller if we do the save, then the caller doesn't -+ /* It's easiest for the caller if we do the save; then the caller doesn't - * have to supply the same data again: - */ -- if (save) -+ if (save != 0) - png_push_save_buffer(png_ptr); - else - { -@@ -97,7 +104,7 @@ - } - - png_uint_32 PNGAPI --png_process_data_skip(png_structp png_ptr) -+png_process_data_skip(png_structrp png_ptr) - { - png_uint_32 remaining = 0; - -@@ -131,7 +138,7 @@ - * doing before we ran out of data... - */ - void /* PRIVATE */ --png_process_some_data(png_structp png_ptr, png_infop info_ptr) -+png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) - { - if (png_ptr == NULL) - return; -@@ -156,30 +163,6 @@ - break; - } - --#ifdef PNG_READ_tEXt_SUPPORTED -- case PNG_READ_tEXt_MODE: -- { -- png_push_read_tEXt(png_ptr, info_ptr); -- break; -- } -- --#endif --#ifdef PNG_READ_zTXt_SUPPORTED -- case PNG_READ_zTXt_MODE: -- { -- png_push_read_zTXt(png_ptr, info_ptr); -- break; -- } -- --#endif --#ifdef PNG_READ_iTXt_SUPPORTED -- case PNG_READ_iTXt_MODE: -- { -- png_push_read_iTXt(png_ptr, info_ptr); -- break; -- } -- --#endif - case PNG_SKIP_MODE: - { - png_push_crc_finish(png_ptr); -@@ -201,9 +184,9 @@ - * routine. - */ - void /* PRIVATE */ --png_push_read_sig(png_structp png_ptr, png_infop info_ptr) -+png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) - { -- png_size_t num_checked = png_ptr->sig_bytes, -+ png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ - num_to_check = 8 - num_checked; - - if (png_ptr->buffer_size < num_to_check) -@@ -234,114 +217,75 @@ - } - - void /* PRIVATE */ --png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) -+png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) - { -- PNG_IHDR; -- PNG_IDAT; -- PNG_IEND; -- PNG_PLTE; --#ifdef PNG_READ_bKGD_SUPPORTED -- PNG_bKGD; --#endif --#ifdef PNG_READ_cHRM_SUPPORTED -- PNG_cHRM; --#endif --#ifdef PNG_READ_gAMA_SUPPORTED -- PNG_gAMA; --#endif --#ifdef PNG_READ_hIST_SUPPORTED -- PNG_hIST; --#endif --#ifdef PNG_READ_iCCP_SUPPORTED -- PNG_iCCP; --#endif --#ifdef PNG_READ_iTXt_SUPPORTED -- PNG_iTXt; --#endif --#ifdef PNG_READ_oFFs_SUPPORTED -- PNG_oFFs; --#endif --#ifdef PNG_READ_pCAL_SUPPORTED -- PNG_pCAL; --#endif --#ifdef PNG_READ_pHYs_SUPPORTED -- PNG_pHYs; --#endif --#ifdef PNG_READ_sBIT_SUPPORTED -- PNG_sBIT; --#endif --#ifdef PNG_READ_sCAL_SUPPORTED -- PNG_sCAL; --#endif --#ifdef PNG_READ_sRGB_SUPPORTED -- PNG_sRGB; --#endif --#ifdef PNG_READ_sPLT_SUPPORTED -- PNG_sPLT; --#endif --#ifdef PNG_READ_tEXt_SUPPORTED -- PNG_tEXt; --#endif --#ifdef PNG_READ_tIME_SUPPORTED -- PNG_tIME; --#endif --#ifdef PNG_READ_tRNS_SUPPORTED -- PNG_tRNS; --#endif --#ifdef PNG_READ_zTXt_SUPPORTED -- PNG_zTXt; -+ png_uint_32 chunk_name; -+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+ int keep; /* unknown handling method */ - #endif - -- /* First we make sure we have enough data for the 4 byte chunk name -- * and the 4 byte chunk length before proceeding with decoding the -+ /* First we make sure we have enough data for the 4-byte chunk name -+ * and the 4-byte chunk length before proceeding with decoding the - * chunk data. To fully decode each of these chunks, we also make -- * sure we have enough data in the buffer for the 4 byte CRC at the -+ * sure we have enough data in the buffer for the 4-byte CRC at the - * end of every chunk (except IDAT, which is handled separately). - */ -- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) -+ if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) - { - png_byte chunk_length[4]; -+ png_byte chunk_tag[4]; - -- if (png_ptr->buffer_size < 8) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); -- png_crc_read(png_ptr, png_ptr->chunk_name, 4); -+ png_crc_read(png_ptr, chunk_tag, 4); -+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - } - -- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -- if (png_ptr->mode & PNG_AFTER_IDAT) -+ chunk_name = png_ptr->chunk_name; -+ -+ if (chunk_name == png_IDAT) -+ { -+ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - -- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) -+ /* If we reach an IDAT chunk, this means we have read all of the -+ * header chunks, and we can start reading the image (or if this -+ * is called after the image has been read - we have an error). -+ */ -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_error(png_ptr, "Missing IHDR before IDAT"); -+ -+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -+ (png_ptr->mode & PNG_HAVE_PLTE) == 0) -+ png_error(png_ptr, "Missing PLTE before IDAT"); -+ -+ png_ptr->mode |= PNG_HAVE_IDAT; -+ png_ptr->process_mode = PNG_READ_IDAT_MODE; -+ -+ if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) -+ if (png_ptr->push_length == 0) -+ return; -+ -+ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) -+ png_benign_error(png_ptr, "Too many IDATs found"); -+ } -+ -+ if (chunk_name == png_IHDR) - { - if (png_ptr->push_length != 13) - png_error(png_ptr, "Invalid IHDR length"); - -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); - } - -- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) -+ else if (chunk_name == png_IEND) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); - - png_ptr->process_mode = PNG_READ_DONE_MODE; -@@ -349,70 +293,25 @@ - } - - #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) -+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -+ PNG_PUSH_SAVE_BUFFER_IF_FULL -+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); - -- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -- png_ptr->mode |= PNG_HAVE_IDAT; -+ if (chunk_name == png_PLTE) -+ png_ptr->mode |= PNG_HAVE_PLTE; -+ } -+#endif - -- png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); -- -- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) -- png_ptr->mode |= PNG_HAVE_PLTE; -- -- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -- { -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before IDAT"); -- -- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -- !(png_ptr->mode & PNG_HAVE_PLTE)) -- png_error(png_ptr, "Missing PLTE before IDAT"); -- } -- } -- --#endif -- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) -+ else if (chunk_name == png_PLTE) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); - } - -- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+ else if (chunk_name == png_IDAT) - { -- /* If we reach an IDAT chunk, this means we have read all of the -- * header chunks, and we can start reading the image (or if this -- * is called after the image has been read - we have an error). -- */ -- -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before IDAT"); -- -- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -- !(png_ptr->mode & PNG_HAVE_PLTE)) -- png_error(png_ptr, "Missing PLTE before IDAT"); -- -- if (png_ptr->mode & PNG_HAVE_IDAT) -- { -- if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) -- if (png_ptr->push_length == 0) -- return; -- -- if (png_ptr->mode & PNG_AFTER_IDAT) -- png_benign_error(png_ptr, "Too many IDATs found"); -- } -- - png_ptr->idat_size = png_ptr->push_length; -- png_ptr->mode |= PNG_HAVE_IDAT; - png_ptr->process_mode = PNG_READ_IDAT_MODE; - png_push_have_info(png_ptr, info_ptr); - png_ptr->zstream.avail_out = -@@ -423,250 +322,162 @@ - } - - #ifdef PNG_READ_gAMA_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) -+ else if (png_ptr->chunk_name == png_gAMA) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_sBIT_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) -+ else if (png_ptr->chunk_name == png_sBIT) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_cHRM_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) -+ else if (png_ptr->chunk_name == png_cHRM) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_sRGB_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) -+ else if (chunk_name == png_sRGB) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_iCCP_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) -+ else if (png_ptr->chunk_name == png_iCCP) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_sPLT_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) -+ else if (chunk_name == png_sPLT) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_tRNS_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) -+ else if (chunk_name == png_tRNS) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_bKGD_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) -+ else if (chunk_name == png_bKGD) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_hIST_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) -+ else if (chunk_name == png_hIST) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_pHYs_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) -+ else if (chunk_name == png_pHYs) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_oFFs_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) -+ else if (chunk_name == png_oFFs) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); - } - #endif - - #ifdef PNG_READ_pCAL_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) -+ else if (chunk_name == png_pCAL) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_sCAL_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) -+ else if (chunk_name == png_sCAL) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_tIME_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) -+ else if (chunk_name == png_tIME) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_tEXt_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) -+ else if (chunk_name == png_tEXt) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -- png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); -+ PNG_PUSH_SAVE_BUFFER_IF_FULL -+ png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_zTXt_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) -+ else if (chunk_name == png_zTXt) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -- png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); -+ PNG_PUSH_SAVE_BUFFER_IF_FULL -+ png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); - } - - #endif - #ifdef PNG_READ_iTXt_SUPPORTED -- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) -+ else if (chunk_name == png_iTXt) - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -+ PNG_PUSH_SAVE_BUFFER_IF_FULL -+ png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); -+ } -+#endif - -- png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); -- } -- --#endif - else - { -- if (png_ptr->push_length + 4 > png_ptr->buffer_size) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); -+ PNG_PUSH_SAVE_BUFFER_IF_FULL -+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, -+ PNG_HANDLE_CHUNK_AS_DEFAULT); - } - - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - } - - void /* PRIVATE */ --png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) -+png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip) - { - png_ptr->process_mode = PNG_SKIP_MODE; - png_ptr->skip_length = skip; - } - - void /* PRIVATE */ --png_push_crc_finish(png_structp png_ptr) -+png_push_crc_finish(png_structrp png_ptr) - { -- if (png_ptr->skip_length && png_ptr->save_buffer_size) -+ if (png_ptr->skip_length != 0 && png_ptr->save_buffer_size != 0) - { - png_size_t save_size = png_ptr->save_buffer_size; - png_uint_32 skip_length = png_ptr->skip_length; -@@ -690,7 +501,7 @@ - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } -- if (png_ptr->skip_length && png_ptr->current_buffer_size) -+ if (png_ptr->skip_length != 0 && png_ptr->current_buffer_size != 0) - { - png_size_t save_size = png_ptr->current_buffer_size; - png_uint_32 skip_length = png_ptr->skip_length; -@@ -711,14 +522,9 @@ - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } -- if (!png_ptr->skip_length) -+ if (png_ptr->skip_length == 0) - { -- if (png_ptr->buffer_size < 4) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_LT(4) - png_crc_finish(png_ptr, 0); - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } -@@ -733,7 +539,7 @@ - return; - - ptr = buffer; -- if (png_ptr->save_buffer_size) -+ if (png_ptr->save_buffer_size != 0) - { - png_size_t save_size; - -@@ -743,14 +549,14 @@ - else - save_size = png_ptr->save_buffer_size; - -- png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); -+ memcpy(ptr, png_ptr->save_buffer_ptr, save_size); - length -= save_size; - ptr += save_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } -- if (length && png_ptr->current_buffer_size) -+ if (length != 0 && png_ptr->current_buffer_size != 0) - { - png_size_t save_size; - -@@ -760,7 +566,7 @@ - else - save_size = png_ptr->current_buffer_size; - -- png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); -+ memcpy(ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; -@@ -768,9 +574,9 @@ - } - - void /* PRIVATE */ --png_push_save_buffer(png_structp png_ptr) -+png_push_save_buffer(png_structrp png_ptr) - { -- if (png_ptr->save_buffer_size) -+ if (png_ptr->save_buffer_size != 0) - { - if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) - { -@@ -806,16 +612,18 @@ - if (png_ptr->save_buffer == NULL) - { - png_free(png_ptr, old_buffer); -+ old_buffer = NULL; - png_error(png_ptr, "Insufficient memory for save_buffer"); - } - -- png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); -+ memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); - png_free(png_ptr, old_buffer); -+ old_buffer = NULL; - png_ptr->save_buffer_max = new_max; - } - if (png_ptr->current_buffer_size) - { -- png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, -+ memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, - png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); - png_ptr->save_buffer_size += png_ptr->current_buffer_size; - png_ptr->current_buffer_size = 0; -@@ -825,7 +633,7 @@ - } - - void /* PRIVATE */ --png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, -+png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, - png_size_t buffer_length) - { - png_ptr->current_buffer = buffer; -@@ -835,30 +643,27 @@ - } - - void /* PRIVATE */ --png_push_read_IDAT(png_structp png_ptr) -+png_push_read_IDAT(png_structrp png_ptr) - { -- PNG_IDAT; -- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) -+ if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) - { - png_byte chunk_length[4]; -+ png_byte chunk_tag[4]; - -- if (png_ptr->buffer_size < 8) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ /* TODO: this code can be commoned up with the same code in push_read */ -+ PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); -- png_crc_read(png_ptr, png_ptr->chunk_name, 4); -+ png_crc_read(png_ptr, chunk_tag, 4); -+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - -- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+ if (png_ptr->chunk_name != png_IDAT) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - -- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) -+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - png_error(png_ptr, "Not enough compressed data"); - - return; -@@ -866,7 +671,8 @@ - - png_ptr->idat_size = png_ptr->push_length; - } -- if (png_ptr->idat_size && png_ptr->save_buffer_size) -+ -+ if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) - { - png_size_t save_size = png_ptr->save_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; -@@ -893,7 +699,7 @@ - png_ptr->save_buffer_ptr += save_size; - } - -- if (png_ptr->idat_size && png_ptr->current_buffer_size) -+ if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) - { - png_size_t save_size = png_ptr->current_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; -@@ -918,22 +724,18 @@ - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } -- if (!png_ptr->idat_size) -+ if (png_ptr->idat_size == 0) - { -- if (png_ptr->buffer_size < 4) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -+ PNG_PUSH_SAVE_BUFFER_IF_LT(4) - png_crc_finish(png_ptr, 0); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - png_ptr->mode |= PNG_AFTER_IDAT; -+ png_ptr->zowner = 0; - } - } - - void /* PRIVATE */ --png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, -+png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, - png_size_t buffer_length) - { - /* The caller checks for a non-zero buffer length. */ -@@ -945,13 +747,14 @@ - * handle the uncompressed results. - */ - png_ptr->zstream.next_in = buffer; -+ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ - png_ptr->zstream.avail_in = (uInt)buffer_length; - - /* Keep going until the decompressed data is all processed - * or the stream marked as finished. - */ - while (png_ptr->zstream.avail_in > 0 && -- !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) -+ !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) - { - int ret; - -@@ -962,9 +765,9 @@ - */ - if (!(png_ptr->zstream.avail_out > 0)) - { -- png_ptr->zstream.avail_out = -- (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, -- png_ptr->iwidth) + 1; -+ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ -+ png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, -+ png_ptr->iwidth) + 1); - - png_ptr->zstream.next_out = png_ptr->row_buf; - } -@@ -982,7 +785,8 @@ - if (ret != Z_OK && ret != Z_STREAM_END) - { - /* Terminate the decompression. */ -- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; -+ png_ptr->zowner = 0; - - /* This may be a truncated stream (missing or - * damaged end code). Treat that as a warning. -@@ -1010,7 +814,8 @@ - { - /* Extra data. */ - png_warning(png_ptr, "Extra compressed data in IDAT"); -- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; -+ png_ptr->zowner = 0; - - /* Do no more processing; skip the unprocessed - * input check below. -@@ -1025,7 +830,7 @@ - - /* And check for the end of the stream. */ - if (ret == Z_STREAM_END) -- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - } - - /* All the data should have been processed, if anything -@@ -1037,41 +842,62 @@ - } - - void /* PRIVATE */ --png_push_process_row(png_structp png_ptr) -+png_push_process_row(png_structrp png_ptr) - { -- png_ptr->row_info.color_type = png_ptr->color_type; -- png_ptr->row_info.width = png_ptr->iwidth; -- png_ptr->row_info.channels = png_ptr->channels; -- png_ptr->row_info.bit_depth = png_ptr->bit_depth; -- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; -+ /* 1.5.6: row_info moved out of png_struct to a local here. */ -+ png_row_info row_info; - -- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, -- png_ptr->row_info.width); -+ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ -+ row_info.color_type = png_ptr->color_type; -+ row_info.bit_depth = png_ptr->bit_depth; -+ row_info.channels = png_ptr->channels; -+ row_info.pixel_depth = png_ptr->pixel_depth; -+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - -- png_read_filter_row(png_ptr, &(png_ptr->row_info), -- png_ptr->row_buf + 1, png_ptr->prev_row + 1, -- (int)(png_ptr->row_buf[0])); -+ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) -+ { -+ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) -+ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, -+ png_ptr->prev_row + 1, png_ptr->row_buf[0]); -+ else -+ png_error(png_ptr, "bad adaptive filter value"); -+ } - -- png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); -+ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before -+ * 1.5.6, while the buffer really is this big in current versions of libpng -+ * it may not be in the future, so this was changed just to copy the -+ * interlaced row count: -+ */ -+ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - - #ifdef PNG_READ_TRANSFORMS_SUPPORTED -- if (png_ptr->transformations) -- png_do_read_transformations(png_ptr); -+ if (png_ptr->transformations != 0) -+ png_do_read_transformations(png_ptr, &row_info); - #endif - -+ /* The transformed pixel depth should match the depth now in row_info. */ -+ if (png_ptr->transformed_pixel_depth == 0) -+ { -+ png_ptr->transformed_pixel_depth = row_info.pixel_depth; -+ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) -+ png_error(png_ptr, "progressive row overflow"); -+ } -+ -+ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) -+ png_error(png_ptr, "internal progressive row size calculation error"); -+ -+ - #ifdef PNG_READ_INTERLACING_SUPPORTED -- /* Blow up interlaced rows to full size */ -- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) -+ /* Expand interlaced rows to full size */ -+ if (png_ptr->interlaced != 0 && -+ (png_ptr->transformations & PNG_INTERLACE) != 0) - { - if (png_ptr->pass < 6) --/* old interface (pre-1.0.9): -- png_do_read_interlace(&(png_ptr->row_info), -- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); -- */ -- png_do_read_interlace(png_ptr); -+ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, -+ png_ptr->transformations); - -- switch (png_ptr->pass) -- { -+ switch (png_ptr->pass) -+ { - case 0: - { - int i; -@@ -1238,7 +1064,6 @@ - } - } - else --#endif - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); -@@ -1246,36 +1071,36 @@ - } - - void /* PRIVATE */ --png_read_push_finish_row(png_structp png_ptr) -+png_read_push_finish_row(png_structrp png_ptr) - { - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ -- PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; -+ static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ -- PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ -- PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; -+ static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ -- PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; -+ static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; - - /* Height of interlace block. This is not currently used - if you need - * it, uncomment it here and in png.h -- PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; - */ -+#endif - - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - --#ifdef PNG_READ_INTERLACING_SUPPORTED -- if (png_ptr->interlaced) -+ if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; -- png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); -+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { -@@ -1296,7 +1121,7 @@ - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - -- if (png_ptr->transformations & PNG_INTERLACE) -+ if ((png_ptr->transformations & PNG_INTERLACE) != 0) - break; - - png_ptr->num_rows = (png_ptr->height + -@@ -1306,538 +1131,24 @@ - - } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); - } --#endif /* PNG_READ_INTERLACING_SUPPORTED */ --} -- --#ifdef PNG_READ_tEXt_SUPPORTED --void /* PRIVATE */ --png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 -- length) --{ -- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) -- { -- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ -- png_error(png_ptr, "Out of place tEXt"); -- /* NOT REACHED */ -- } -- --#ifdef PNG_MAX_MALLOC_64K -- png_ptr->skip_length = 0; /* This may not be necessary */ -- -- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ -- { -- png_warning(png_ptr, "tEXt chunk too large to fit in memory"); -- png_ptr->skip_length = length - (png_uint_32)65535L; -- length = (png_uint_32)65535L; -- } --#endif -- -- png_ptr->current_text = (png_charp)png_malloc(png_ptr, -- (png_size_t)(length + 1)); -- png_ptr->current_text[length] = '\0'; -- png_ptr->current_text_ptr = png_ptr->current_text; -- png_ptr->current_text_size = (png_size_t)length; -- png_ptr->current_text_left = (png_size_t)length; -- png_ptr->process_mode = PNG_READ_tEXt_MODE; - } - - void /* PRIVATE */ --png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) --{ -- if (png_ptr->buffer_size && png_ptr->current_text_left) -- { -- png_size_t text_size; -- -- if (png_ptr->buffer_size < png_ptr->current_text_left) -- text_size = png_ptr->buffer_size; -- -- else -- text_size = png_ptr->current_text_left; -- -- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); -- png_ptr->current_text_left -= text_size; -- png_ptr->current_text_ptr += text_size; -- } -- if (!(png_ptr->current_text_left)) -- { -- png_textp text_ptr; -- png_charp text; -- png_charp key; -- int ret; -- -- if (png_ptr->buffer_size < 4) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -- png_push_crc_finish(png_ptr); -- --#ifdef PNG_MAX_MALLOC_64K -- if (png_ptr->skip_length) -- return; --#endif -- -- key = png_ptr->current_text; -- -- for (text = key; *text; text++) -- /* Empty loop */ ; -- -- if (text < key + png_ptr->current_text_size) -- text++; -- -- text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text)); -- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; -- text_ptr->key = key; -- text_ptr->itxt_length = 0; -- text_ptr->lang = NULL; -- text_ptr->lang_key = NULL; -- text_ptr->text = text; -- -- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); -- -- png_free(png_ptr, key); -- png_free(png_ptr, text_ptr); -- png_ptr->current_text = NULL; -- -- if (ret) -- png_warning(png_ptr, "Insufficient memory to store text chunk"); -- } --} --#endif -- --#ifdef PNG_READ_zTXt_SUPPORTED --void /* PRIVATE */ --png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 -- length) --{ -- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) -- { -- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ -- png_error(png_ptr, "Out of place zTXt"); -- /* NOT REACHED */ -- } -- --#ifdef PNG_MAX_MALLOC_64K -- /* We can't handle zTXt chunks > 64K, since we don't have enough space -- * to be able to store the uncompressed data. Actually, the threshold -- * is probably around 32K, but it isn't as definite as 64K is. -- */ -- if (length > (png_uint_32)65535L) -- { -- png_warning(png_ptr, "zTXt chunk too large to fit in memory"); -- png_push_crc_skip(png_ptr, length); -- return; -- } --#endif -- -- png_ptr->current_text = (png_charp)png_malloc(png_ptr, -- (png_size_t)(length + 1)); -- png_ptr->current_text[length] = '\0'; -- png_ptr->current_text_ptr = png_ptr->current_text; -- png_ptr->current_text_size = (png_size_t)length; -- png_ptr->current_text_left = (png_size_t)length; -- png_ptr->process_mode = PNG_READ_zTXt_MODE; --} -- --void /* PRIVATE */ --png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) --{ -- if (png_ptr->buffer_size && png_ptr->current_text_left) -- { -- png_size_t text_size; -- -- if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) -- text_size = png_ptr->buffer_size; -- -- else -- text_size = png_ptr->current_text_left; -- -- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); -- png_ptr->current_text_left -= text_size; -- png_ptr->current_text_ptr += text_size; -- } -- if (!(png_ptr->current_text_left)) -- { -- png_textp text_ptr; -- png_charp text; -- png_charp key; -- int ret; -- png_size_t text_size, key_size; -- -- if (png_ptr->buffer_size < 4) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -- png_push_crc_finish(png_ptr); -- -- key = png_ptr->current_text; -- -- for (text = key; *text; text++) -- /* Empty loop */ ; -- -- /* zTXt can't have zero text */ -- if (text >= key + png_ptr->current_text_size) -- { -- png_ptr->current_text = NULL; -- png_free(png_ptr, key); -- return; -- } -- -- text++; -- -- if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ -- { -- png_ptr->current_text = NULL; -- png_free(png_ptr, key); -- return; -- } -- -- text++; -- -- png_ptr->zstream.next_in = (png_bytep)text; -- png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - -- (text - key)); -- png_ptr->zstream.next_out = png_ptr->zbuf; -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -- -- key_size = text - key; -- text_size = 0; -- text = NULL; -- ret = Z_STREAM_END; -- -- while (png_ptr->zstream.avail_in) -- { -- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); -- if (ret != Z_OK && ret != Z_STREAM_END) -- { -- inflateReset(&png_ptr->zstream); -- png_ptr->zstream.avail_in = 0; -- png_ptr->current_text = NULL; -- png_free(png_ptr, key); -- png_free(png_ptr, text); -- return; -- } -- -- if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) -- { -- if (text == NULL) -- { -- text = (png_charp)png_malloc(png_ptr, -- (png_ptr->zbuf_size -- - png_ptr->zstream.avail_out + key_size + 1)); -- -- png_memcpy(text + key_size, png_ptr->zbuf, -- png_ptr->zbuf_size - png_ptr->zstream.avail_out); -- -- png_memcpy(text, key, key_size); -- -- text_size = key_size + png_ptr->zbuf_size - -- png_ptr->zstream.avail_out; -- -- *(text + text_size) = '\0'; -- } -- -- else -- { -- png_charp tmp; -- -- tmp = text; -- text = (png_charp)png_malloc(png_ptr, text_size + -- (png_ptr->zbuf_size -- - png_ptr->zstream.avail_out + 1)); -- -- png_memcpy(text, tmp, text_size); -- png_free(png_ptr, tmp); -- -- png_memcpy(text + text_size, png_ptr->zbuf, -- png_ptr->zbuf_size - png_ptr->zstream.avail_out); -- -- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; -- *(text + text_size) = '\0'; -- } -- -- if (ret != Z_STREAM_END) -- { -- png_ptr->zstream.next_out = png_ptr->zbuf; -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -- } -- } -- else -- { -- break; -- } -- -- if (ret == Z_STREAM_END) -- break; -- } -- -- inflateReset(&png_ptr->zstream); -- png_ptr->zstream.avail_in = 0; -- -- if (ret != Z_STREAM_END) -- { -- png_ptr->current_text = NULL; -- png_free(png_ptr, key); -- png_free(png_ptr, text); -- return; -- } -- -- png_ptr->current_text = NULL; -- png_free(png_ptr, key); -- key = text; -- text += key_size; -- -- text_ptr = (png_textp)png_malloc(png_ptr, -- png_sizeof(png_text)); -- text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; -- text_ptr->key = key; -- text_ptr->itxt_length = 0; -- text_ptr->lang = NULL; -- text_ptr->lang_key = NULL; -- text_ptr->text = text; -- -- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); -- -- png_free(png_ptr, key); -- png_free(png_ptr, text_ptr); -- -- if (ret) -- png_warning(png_ptr, "Insufficient memory to store text chunk"); -- } --} --#endif -- --#ifdef PNG_READ_iTXt_SUPPORTED --void /* PRIVATE */ --png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 -- length) --{ -- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) -- { -- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ -- png_error(png_ptr, "Out of place iTXt"); -- /* NOT REACHED */ -- } -- --#ifdef PNG_MAX_MALLOC_64K -- png_ptr->skip_length = 0; /* This may not be necessary */ -- -- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ -- { -- png_warning(png_ptr, "iTXt chunk too large to fit in memory"); -- png_ptr->skip_length = length - (png_uint_32)65535L; -- length = (png_uint_32)65535L; -- } --#endif -- -- png_ptr->current_text = (png_charp)png_malloc(png_ptr, -- (png_size_t)(length + 1)); -- png_ptr->current_text[length] = '\0'; -- png_ptr->current_text_ptr = png_ptr->current_text; -- png_ptr->current_text_size = (png_size_t)length; -- png_ptr->current_text_left = (png_size_t)length; -- png_ptr->process_mode = PNG_READ_iTXt_MODE; --} -- --void /* PRIVATE */ --png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) --{ -- -- if (png_ptr->buffer_size && png_ptr->current_text_left) -- { -- png_size_t text_size; -- -- if (png_ptr->buffer_size < png_ptr->current_text_left) -- text_size = png_ptr->buffer_size; -- -- else -- text_size = png_ptr->current_text_left; -- -- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); -- png_ptr->current_text_left -= text_size; -- png_ptr->current_text_ptr += text_size; -- } -- -- if (!(png_ptr->current_text_left)) -- { -- png_textp text_ptr; -- png_charp key; -- int comp_flag; -- png_charp lang; -- png_charp lang_key; -- png_charp text; -- int ret; -- -- if (png_ptr->buffer_size < 4) -- { -- png_push_save_buffer(png_ptr); -- return; -- } -- -- png_push_crc_finish(png_ptr); -- --#ifdef PNG_MAX_MALLOC_64K -- if (png_ptr->skip_length) -- return; --#endif -- -- key = png_ptr->current_text; -- -- for (lang = key; *lang; lang++) -- /* Empty loop */ ; -- -- if (lang < key + png_ptr->current_text_size - 3) -- lang++; -- -- comp_flag = *lang++; -- lang++; /* Skip comp_type, always zero */ -- -- for (lang_key = lang; *lang_key; lang_key++) -- /* Empty loop */ ; -- -- lang_key++; /* Skip NUL separator */ -- -- text=lang_key; -- -- if (lang_key < key + png_ptr->current_text_size - 1) -- { -- for (; *text; text++) -- /* Empty loop */ ; -- } -- -- if (text < key + png_ptr->current_text_size) -- text++; -- -- text_ptr = (png_textp)png_malloc(png_ptr, -- png_sizeof(png_text)); -- -- text_ptr->compression = comp_flag + 2; -- text_ptr->key = key; -- text_ptr->lang = lang; -- text_ptr->lang_key = lang_key; -- text_ptr->text = text; -- text_ptr->text_length = 0; -- text_ptr->itxt_length = png_strlen(text); -- -- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); -- -- png_ptr->current_text = NULL; -- -- png_free(png_ptr, text_ptr); -- if (ret) -- png_warning(png_ptr, "Insufficient memory to store iTXt chunk"); -- } --} --#endif -- --/* This function is called when we haven't found a handler for this -- * chunk. If there isn't a problem with the chunk itself (ie a bad chunk -- * name or a critical chunk), the chunk is (currently) silently ignored. -- */ --void /* PRIVATE */ --png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 -- length) --{ -- png_uint_32 skip = 0; -- -- if (!(png_ptr->chunk_name[0] & 0x20)) -- { --#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != -- PNG_HANDLE_CHUNK_ALWAYS --#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -- && png_ptr->read_user_chunk_fn == NULL --#endif -- ) --#endif -- png_chunk_error(png_ptr, "unknown critical chunk"); -- -- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ -- } -- --#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -- if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) -- { --#ifdef PNG_MAX_MALLOC_64K -- if (length > (png_uint_32)65535L) -- { -- png_warning(png_ptr, "unknown chunk too large to fit in memory"); -- skip = length - (png_uint_32)65535L; -- length = (png_uint_32)65535L; -- } --#endif -- png_memcpy((png_charp)png_ptr->unknown_chunk.name, -- (png_charp)png_ptr->chunk_name, -- png_sizeof(png_ptr->unknown_chunk.name)); -- png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] -- = '\0'; -- -- png_ptr->unknown_chunk.size = (png_size_t)length; -- -- if (length == 0) -- png_ptr->unknown_chunk.data = NULL; -- -- else -- { -- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, -- (png_size_t)length); -- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); -- } -- --#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -- if (png_ptr->read_user_chunk_fn != NULL) -- { -- /* Callback to user unknown chunk handler */ -- int ret; -- ret = (*(png_ptr->read_user_chunk_fn)) -- (png_ptr, &png_ptr->unknown_chunk); -- -- if (ret < 0) -- png_chunk_error(png_ptr, "error in user chunk"); -- -- if (ret == 0) -- { -- if (!(png_ptr->chunk_name[0] & 0x20)) -- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != -- PNG_HANDLE_CHUNK_ALWAYS) -- png_chunk_error(png_ptr, "unknown critical chunk"); -- png_set_unknown_chunks(png_ptr, info_ptr, -- &png_ptr->unknown_chunk, 1); -- } -- } -- -- else --#endif -- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); -- png_free(png_ptr, png_ptr->unknown_chunk.data); -- png_ptr->unknown_chunk.data = NULL; -- } -- -- else --#endif -- skip=length; -- png_push_crc_skip(png_ptr, skip); --} -- --void /* PRIVATE */ --png_push_have_info(png_structp png_ptr, png_infop info_ptr) -+png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) - { - if (png_ptr->info_fn != NULL) - (*(png_ptr->info_fn))(png_ptr, info_ptr); - } - - void /* PRIVATE */ --png_push_have_end(png_structp png_ptr, png_infop info_ptr) -+png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) - { - if (png_ptr->end_fn != NULL) - (*(png_ptr->end_fn))(png_ptr, info_ptr); - } - - void /* PRIVATE */ --png_push_have_row(png_structp png_ptr, png_bytep row) -+png_push_have_row(png_structrp png_ptr, png_bytep row) - { - if (png_ptr->row_fn != NULL) - (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, -@@ -1845,21 +1156,22 @@ - } - - void PNGAPI --png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, -+png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, - png_const_bytep new_row) - { -- PNG_CONST int FARDATA png_pass_dsp_mask[7] = -- {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; -- - if (png_ptr == NULL) - return; - -- if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ -- png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); -+ /* new_row is a flag here - if it is NULL then the app callback was called -+ * from an empty row (see the calls to png_struct::row_fn below), otherwise -+ * it must be png_ptr->row_buf+1 -+ */ -+ if (new_row != NULL) -+ png_combine_row(png_ptr, old_row, 1/*blocky display*/); - } - - void PNGAPI --png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, -+png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn) - { -@@ -1874,11 +1186,11 @@ - } - - png_voidp PNGAPI --png_get_progressive_ptr(png_const_structp png_ptr) -+png_get_progressive_ptr(png_const_structrp png_ptr) - { - if (png_ptr == NULL) - return (NULL); - - return png_ptr->io_ptr; - } --#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -+#endif /* PROGRESSIVE_READ */ ---- ./jdk/src/share/native/sun/awt/libpng/pngpriv.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngpriv.h Thu Feb 05 13:00:26 2015 +0100 -@@ -30,11 +30,11 @@ - * file and, per its terms, should not be removed: - * - * For conditions of distribution and use, see copyright notice in png.h -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -+ * Last changed in libpng 1.6.10 [March 6, 1014]] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer -@@ -42,7 +42,7 @@ - */ - - /* The symbols declared in this file (including the functions declared -- * as PNG_EXTERN) are PRIVATE. They are not part of the libpng public -+ * as extern) are PRIVATE. They are not part of the libpng public - * interface, and are not recommended for use by regular applications. - * Some of them may become public in the future; others may stay private, - * change in an incompatible way, or even disappear. -@@ -67,12 +67,44 @@ - */ - #define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ - --/* This is required for the definition of abort(), used as a last ditch -- * error handler when all else fails. -+#ifndef PNG_VERSION_INFO_ONLY -+/* Standard library headers not required by png.h: */ -+# include <stdlib.h> -+# include <string.h> -+#endif -+ -+#define PNGLIB_BUILD /*libpng is being built, not used*/ -+ -+/* If HAVE_CONFIG_H is defined during the build then the build system must -+ * provide an appropriate "config.h" file on the include path. The header file -+ * must provide definitions as required below (search for "HAVE_CONFIG_H"); -+ * see configure.ac for more details of the requirements. The macro -+ * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on -+ * 'configure'; define this macro to prevent the configure build including the -+ * configure generated config.h. Libpng is expected to compile without *any* -+ * special build system support on a reasonably ANSI-C compliant system. - */ --#include <stdlib.h> -+#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) -+# include <config.h> - --#define PNGLIB_BUILD -+ /* Pick up the definition of 'restrict' from config.h if it was read: */ -+# define PNG_RESTRICT restrict -+#endif -+ -+/* To support symbol prefixing it is necessary to know *before* including png.h -+ * whether the fixed point (and maybe other) APIs are exported, because if they -+ * are not internal definitions may be required. This is handled below just -+ * before png.h is included, but load the configuration now if it is available. -+ */ -+#ifndef PNGLCONF_H -+# include "pnglibconf.h" -+#endif -+ -+/* Local renames may change non-exported API functions from png.h */ -+#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) -+# include "pngprefix.h" -+#endif -+ - #ifdef PNG_USER_CONFIG - # include "pngusr.h" - /* These should have been defined in pngusr.h */ -@@ -83,25 +115,253 @@ - # define PNG_USER_DLLFNAME_POSTFIX "Cb" - # endif - #endif -+ -+/* Compile time options. -+ * ===================== -+ * In a multi-arch build the compiler may compile the code several times for the -+ * same object module, producing different binaries for different architectures. -+ * When this happens configure-time setting of the target host options cannot be -+ * done and this interferes with the handling of the ARM NEON optimizations, and -+ * possibly other similar optimizations. Put additional tests here; in general -+ * this is needed when the same option can be changed at both compile time and -+ * run time depending on the target OS (i.e. iOS vs Android.) -+ * -+ * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because -+ * this is not possible with certain compilers (Oracle SUN OS CC), as a result -+ * it is necessary to ensure that all extern functions that *might* be used -+ * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__ -+ * below is one example of this behavior because it is controlled by the -+ * presence or not of -mfpu=neon on the GCC command line, it is possible to do -+ * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely -+ * do this. -+ */ -+#ifndef PNG_ARM_NEON_OPT -+ /* ARM NEON optimizations are being controlled by the compiler settings, -+ * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon -+ * with GCC) then the compiler will define __ARM_NEON__ and we can rely -+ * unconditionally on NEON instructions not crashing, otherwise we must -+ * disable use of NEON instructions. -+ * -+ * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they -+ * can only be turned on automatically if that is supported too. If -+ * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail -+ * to compile with an appropriate #error if ALIGNED_MEMORY has been turned -+ * off. -+ * -+ * Note that gcc-4.9 defines __ARM_NEON instead of __ARM_NEON__, so we -+ * check both variants. -+ */ -+# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \ -+ defined(PNG_ALIGNED_MEMORY_SUPPORTED) -+# define PNG_ARM_NEON_OPT 2 -+# else -+# define PNG_ARM_NEON_OPT 0 -+# endif -+#endif -+ -+#if PNG_ARM_NEON_OPT > 0 -+ /* NEON optimizations are to be at least considered by libpng, so enable the -+ * callbacks to do this. -+ */ -+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon -+ -+ /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used -+ * if possible - if __ARM_NEON__ is set and the compiler version is not known -+ * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can -+ * be: -+ * -+ * 1 The intrinsics code (the default with __ARM_NEON__) -+ * 2 The hand coded assembler (the default without __ARM_NEON__) -+ * -+ * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however -+ * this is *NOT* supported and may cease to work even after a minor revision -+ * to libpng. It *is* valid to do this for testing purposes, e.g. speed -+ * testing or a new compiler, but the results should be communicated to the -+ * libpng implementation list for incorporation in the next minor release. -+ */ -+# ifndef PNG_ARM_NEON_IMPLEMENTATION -+# if defined(__ARM_NEON__) || defined(__ARM_NEON) -+# if defined(__clang__) -+ /* At present it is unknown by the libpng developers which versions -+ * of clang support the intrinsics, however some or perhaps all -+ * versions do not work with the assembler so this may be -+ * irrelevant, so just use the default (do nothing here.) -+ */ -+# elif defined(__GNUC__) -+ /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to -+ * work, so if this *is* GCC, or G++, look for a version >4.5 -+ */ -+# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6) -+# define PNG_ARM_NEON_IMPLEMENTATION 2 -+# endif /* no GNUC support */ -+# endif /* __GNUC__ */ -+# else /* !defined __ARM_NEON__ */ -+ /* The 'intrinsics' code simply won't compile without this -mfpu=neon: -+ */ -+# define PNG_ARM_NEON_IMPLEMENTATION 2 -+# endif /* __ARM_NEON__ */ -+# endif /* !PNG_ARM_NEON_IMPLEMENTATION */ -+ -+# ifndef PNG_ARM_NEON_IMPLEMENTATION -+ /* Use the intrinsics code by default. */ -+# define PNG_ARM_NEON_IMPLEMENTATION 1 -+# endif -+#endif /* PNG_ARM_NEON_OPT > 0 */ -+ -+/* Is this a build of a DLL where compilation of the object modules requires -+ * different preprocessor settings to those required for a simple library? If -+ * so PNG_BUILD_DLL must be set. -+ * -+ * If libpng is used inside a DLL but that DLL does not export the libpng APIs -+ * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a -+ * static library of libpng then link the DLL against that. -+ */ -+#ifndef PNG_BUILD_DLL -+# ifdef DLL_EXPORT -+ /* This is set by libtool when files are compiled for a DLL; libtool -+ * always compiles twice, even on systems where it isn't necessary. Set -+ * PNG_BUILD_DLL in case it is necessary: -+ */ -+# define PNG_BUILD_DLL -+# else -+# ifdef _WINDLL -+ /* This is set by the Microsoft Visual Studio IDE in projects that -+ * build a DLL. It can't easily be removed from those projects (it -+ * isn't visible in the Visual Studio UI) so it is a fairly reliable -+ * indication that PNG_IMPEXP needs to be set to the DLL export -+ * attributes. -+ */ -+# define PNG_BUILD_DLL -+# else -+# ifdef __DLL__ -+ /* This is set by the Borland C system when compiling for a DLL -+ * (as above.) -+ */ -+# define PNG_BUILD_DLL -+# else -+ /* Add additional compiler cases here. */ -+# endif -+# endif -+# endif -+#endif /* Setting PNG_BUILD_DLL if required */ -+ -+/* See pngconf.h for more details: the builder of the library may set this on -+ * the command line to the right thing for the specific compilation system or it -+ * may be automagically set above (at present we know of no system where it does -+ * need to be set on the command line.) -+ * -+ * PNG_IMPEXP must be set here when building the library to prevent pngconf.h -+ * setting it to the "import" setting for a DLL build. -+ */ -+#ifndef PNG_IMPEXP -+# ifdef PNG_BUILD_DLL -+# define PNG_IMPEXP PNG_DLL_EXPORT -+# else -+ /* Not building a DLL, or the DLL doesn't require specific export -+ * definitions. -+ */ -+# define PNG_IMPEXP -+# endif -+#endif -+ -+/* No warnings for private or deprecated functions in the build: */ -+#ifndef PNG_DEPRECATED -+# define PNG_DEPRECATED -+#endif -+#ifndef PNG_PRIVATE -+# define PNG_PRIVATE -+#endif -+ -+/* Symbol preprocessing support. -+ * -+ * To enable listing global, but internal, symbols the following macros should -+ * always be used to declare an extern data or function object in this file. -+ */ -+#ifndef PNG_INTERNAL_DATA -+# define PNG_INTERNAL_DATA(type, name, array) extern type name array -+#endif -+ -+#ifndef PNG_INTERNAL_FUNCTION -+# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ -+ extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) -+#endif -+ -+#ifndef PNG_INTERNAL_CALLBACK -+# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ -+ extern PNG_FUNCTION(type, (PNGCBAPI name), args, PNG_EMPTY attributes) -+#endif -+ -+/* If floating or fixed point APIs are disabled they may still be compiled -+ * internally. To handle this make sure they are declared as the appropriate -+ * internal extern function (otherwise the symbol prefixing stuff won't work and -+ * the functions will be used without definitions.) -+ * -+ * NOTE: although all the API functions are declared here they are not all -+ * actually built! Because the declarations are still made it is necessary to -+ * fake out types that they depend on. -+ */ -+#ifndef PNG_FP_EXPORT -+# ifndef PNG_FLOATING_POINT_SUPPORTED -+# define PNG_FP_EXPORT(ordinal, type, name, args)\ -+ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -+# ifndef PNG_VERSION_INFO_ONLY -+ typedef struct png_incomplete png_double; -+ typedef png_double* png_doublep; -+ typedef const png_double* png_const_doublep; -+ typedef png_double** png_doublepp; -+# endif -+# endif -+#endif -+#ifndef PNG_FIXED_EXPORT -+# ifndef PNG_FIXED_POINT_SUPPORTED -+# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ -+ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -+# endif -+#endif -+ - #include "png.h" --#include "pnginfo.h" --#include "pngstruct.h" - --/* This is used for 16 bit gamma tables - only the top level pointers are const, -- * this could be changed: -+/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ -+#ifndef PNG_DLL_EXPORT -+# define PNG_DLL_EXPORT -+#endif -+ -+/* SECURITY and SAFETY: -+ * -+ * By default libpng is built without any internal limits on image size, -+ * individual heap (png_malloc) allocations or the total amount of memory used. -+ * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used -+ * (unless individually overridden). These limits are believed to be fairly -+ * safe, but builders of secure systems should verify the values against the -+ * real system capabilities. - */ --typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp; -- --/* Added at libpng-1.2.9 */ --/* Moved to pngpriv.h at libpng-1.5.0 */ -- --/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" -- * script. We may need it here to get the correct configuration on things -- * like limits. -- */ --#ifdef PNG_CONFIGURE_LIBPNG --# ifdef HAVE_CONFIG_H --# include "config.h" -+#ifdef PNG_SAFE_LIMITS_SUPPORTED -+ /* 'safe' limits */ -+# ifndef PNG_USER_WIDTH_MAX -+# define PNG_USER_WIDTH_MAX 1000000 -+# endif -+# ifndef PNG_USER_HEIGHT_MAX -+# define PNG_USER_HEIGHT_MAX 1000000 -+# endif -+# ifndef PNG_USER_CHUNK_CACHE_MAX -+# define PNG_USER_CHUNK_CACHE_MAX 128 -+# endif -+# ifndef PNG_USER_CHUNK_MALLOC_MAX -+# define PNG_USER_CHUNK_MALLOC_MAX 8000000 -+# endif -+#else -+ /* values for no limits */ -+# ifndef PNG_USER_WIDTH_MAX -+# define PNG_USER_WIDTH_MAX 0x7fffffff -+# endif -+# ifndef PNG_USER_HEIGHT_MAX -+# define PNG_USER_HEIGHT_MAX 0x7fffffff -+# endif -+# ifndef PNG_USER_CHUNK_CACHE_MAX -+# define PNG_USER_CHUNK_CACHE_MAX 0 -+# endif -+# ifndef PNG_USER_CHUNK_MALLOC_MAX -+# define PNG_USER_CHUNK_MALLOC_MAX 0 - # endif - #endif - -@@ -143,13 +403,6 @@ - # define PNG_ZBUF_SIZE 65536L - #endif - --/* PNG_STATIC is used to mark internal file scope functions if they need to be -- * accessed for implementation tests (see the code in tests/?*). -- */ --#ifndef PNG_STATIC --# define PNG_STATIC static --#endif -- - /* If warnings or errors are turned off the code is disabled or redirected here. - * From 1.5.4 functions have been added to allow very limited formatting of - * error and warning messages - this code will also be disabled here. -@@ -157,8 +410,6 @@ - #ifdef PNG_WARNINGS_SUPPORTED - # define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; - #else --# define png_warning(s1,s2) ((void)(s1)) --# define png_chunk_warning(s1,s2) ((void)(s1)) - # define png_warning_parameter(p,number,string) ((void)0) - # define png_warning_parameter_unsigned(p,number,format,value) ((void)0) - # define png_warning_parameter_signed(p,number,format,value) ((void)0) -@@ -166,21 +417,27 @@ - # define PNG_WARNING_PARAMETERS(p) - #endif - #ifndef PNG_ERROR_TEXT_SUPPORTED --# define png_error(s1,s2) png_err(s1) --# define png_chunk_error(s1,s2) png_err(s1) - # define png_fixed_error(s1,s2) png_err(s1) - #endif - --#ifndef PNG_EXTERN --/* The functions exported by PNG_EXTERN are internal functions, which -- * aren't usually used outside the library (as far as I know), so it is -- * debatable if they should be exported at all. In the future, when it -- * is possible to have run-time registry of chunk-handling functions, -- * some of these might be made available again. --# define PNG_EXTERN extern -+/* C allows up-casts from (void*) to any pointer and (const void*) to any -+ * pointer to a const object. C++ regards this as a type error and requires an -+ * explicit, static, cast and provides the static_cast<> rune to ensure that -+ * const is not cast away. - */ --# define PNG_EXTERN --#endif -+#ifdef __cplusplus -+# define png_voidcast(type, value) static_cast<type>(value) -+# define png_constcast(type, value) const_cast<type>(value) -+# define png_aligncast(type, value) \ -+ static_cast<type>(static_cast<void*>(value)) -+# define png_aligncastconst(type, value) \ -+ static_cast<type>(static_cast<const void*>(value)) -+#else -+# define png_voidcast(type, value) (value) -+# define png_constcast(type, value) ((type)(value)) -+# define png_aligncast(type, value) ((void*)(value)) -+# define png_aligncastconst(type, value) ((const void*)(value)) -+#endif /* __cplusplus */ - - /* Some fixed point APIs are still required even if not exported because - * they get used by the corresponding floating point APIs. This magic -@@ -192,6 +449,7 @@ - # define PNGFAPI /* PRIVATE */ - #endif - -+#ifndef PNG_VERSION_INFO_ONLY - /* Other defines specific to compilers can go here. Try to keep - * them inside an appropriate ifdef/endif pair for portability. - */ -@@ -236,6 +494,7 @@ - defined(_WIN32) || defined(__WIN32__) - # include <windows.h> /* defines _WINDOWS_ macro */ - #endif -+#endif /* PNG_VERSION_INFO_ONLY */ - - /* Moved here around 1.5.0beta36 from pngconf.h */ - /* Users may want to use these so they are not private. Any library -@@ -251,33 +510,51 @@ - # endif - #endif - --#ifdef USE_FAR_KEYWORD --/* Use this to make far-to-near assignments */ --# define CHECK 1 --# define NOCHECK 0 --# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) --# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) --# define png_strlen _fstrlen --# define png_memcmp _fmemcmp /* SJT: added */ --# define png_memcpy _fmemcpy --# define png_memset _fmemset -+/* These macros may need to be architecture dependent. */ -+#define PNG_ALIGN_NONE 0 /* do not use data alignment */ -+#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ -+#ifdef offsetof -+# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ - #else --# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ --# define CVT_PTR(ptr) (ptr) --# define CVT_PTR_NOCHECK(ptr) (ptr) --# define png_strlen lstrlenA --# define png_memcmp memcmp --# define png_memcpy CopyMemory --# define png_memset memset -+# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ -+#endif -+#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ -+ -+#ifndef PNG_ALIGN_TYPE -+ /* Default to using aligned access optimizations and requiring alignment to a -+ * multiple of the data type size. Override in a compiler specific fashion -+ * if necessary by inserting tests here: -+ */ -+# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE -+#endif -+ -+#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE -+ /* This is used because in some compiler implementations non-aligned -+ * structure members are supported, so the offsetof approach below fails. -+ * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access -+ * is good for performance. Do not do this unless you have tested the result -+ * and understand it. -+ */ -+# define png_alignof(type) (sizeof (type)) -+#else -+# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET -+# define png_alignof(type) offsetof(struct{char c; type t;}, t) - # else --# define CVT_PTR(ptr) (ptr) --# define CVT_PTR_NOCHECK(ptr) (ptr) --# define png_strlen strlen --# define png_memcmp memcmp /* SJT: added */ --# define png_memcpy memcpy --# define png_memset memset -+# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS -+# define png_alignof(type) (1) -+# endif -+ /* Else leave png_alignof undefined to prevent use thereof */ - # endif - #endif -+ -+/* This implicitly assumes alignment is always to a power of 2. */ -+#ifdef png_alignof -+# define png_isaligned(ptr, type)\ -+ ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) -+#else -+# define png_isaligned(ptr, type) 0 -+#endif -+ - /* End of memory model/platform independent support */ - /* End of 1.5.0beta36 move from pngconf.h */ - -@@ -295,15 +572,17 @@ - #define PNG_HAVE_IDAT 0x04 - /* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */ - #define PNG_HAVE_IEND 0x10 --#define PNG_HAVE_gAMA 0x20 --#define PNG_HAVE_cHRM 0x40 --#define PNG_HAVE_sRGB 0x80 -+ /* 0x20 (unused) */ -+ /* 0x40 (unused) */ -+ /* 0x80 (unused) */ - #define PNG_HAVE_CHUNK_HEADER 0x100 - #define PNG_WROTE_tIME 0x200 - #define PNG_WROTE_INFO_BEFORE_PLTE 0x400 - #define PNG_BACKGROUND_IS_GRAY 0x800 - #define PNG_HAVE_PNG_SIGNATURE 0x1000 - #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ -+ /* 0x4000 (unused) */ -+#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */ - - /* Flags for the transformations the PNG library does on the image data */ - #define PNG_BGR 0x0001 -@@ -321,24 +600,23 @@ - #define PNG_EXPAND 0x1000 - #define PNG_GAMMA 0x2000 - #define PNG_GRAY_TO_RGB 0x4000 --#define PNG_FILLER 0x8000L --#define PNG_PACKSWAP 0x10000L --#define PNG_SWAP_ALPHA 0x20000L --#define PNG_STRIP_ALPHA 0x40000L --#define PNG_INVERT_ALPHA 0x80000L --#define PNG_USER_TRANSFORM 0x100000L --#define PNG_RGB_TO_GRAY_ERR 0x200000L --#define PNG_RGB_TO_GRAY_WARN 0x400000L --#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ --#define PNG_ENCODE_ALPHA 0x800000L /* Added to libpng-1.5.4 */ --#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ --#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ --#define PNG_SCALE_16_TO_8 0x4000000L /* Added to libpng-1.5.4 */ -- /* 0x8000000L unused */ -- /* 0x10000000L unused */ -- /* 0x20000000L unused */ -- /* 0x40000000L unused */ -- -+#define PNG_FILLER 0x8000 -+#define PNG_PACKSWAP 0x10000 -+#define PNG_SWAP_ALPHA 0x20000 -+#define PNG_STRIP_ALPHA 0x40000 -+#define PNG_INVERT_ALPHA 0x80000 -+#define PNG_USER_TRANSFORM 0x100000 -+#define PNG_RGB_TO_GRAY_ERR 0x200000 -+#define PNG_RGB_TO_GRAY_WARN 0x400000 -+#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */ -+#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */ -+#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */ -+#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */ -+#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */ -+ /* 0x8000000 unused */ -+ /* 0x10000000 unused */ -+ /* 0x20000000 unused */ -+ /* 0x40000000 unused */ - /* Flags for png_create_struct */ - #define PNG_STRUCT_PNG 0x0001 - #define PNG_STRUCT_INFO 0x0002 -@@ -349,36 +627,36 @@ - - /* Flags for the png_ptr->flags rather than declaring a byte for each one */ - #define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 --#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 --#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 --#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 --#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 --#define PNG_FLAG_ZLIB_FINISHED 0x0020 -+#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */ -+ /* 0x0004 unused */ -+#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */ -+ /* 0x0010 unused */ -+ /* 0x0020 unused */ - #define PNG_FLAG_ROW_INIT 0x0040 - #define PNG_FLAG_FILLER_AFTER 0x0080 - #define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 - #define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 - #define PNG_FLAG_CRC_CRITICAL_USE 0x0400 - #define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 --#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ --#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ --#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ --#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L --#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L --#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L --#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L --#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L --#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L -- /* 0x200000L unused */ -- /* 0x400000L unused */ --#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000L /* Added to libpng-1.4.0 */ --#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000L /* 5 lines added */ --#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000L /* to libpng-1.5.4 */ --#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000L --#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000L --#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000L -- /* 0x20000000L unused */ -- /* 0x40000000L unused */ -+#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ -+#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ -+#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ -+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 */ -+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 */ -+#define PNG_FLAG_LIBRARY_MISMATCH 0x20000 -+#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000 -+#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 -+#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */ -+#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */ -+#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */ -+ /* 0x800000 unused */ -+ /* 0x1000000 unused */ -+ /* 0x2000000 unused */ -+ /* 0x4000000 unused */ -+ /* 0x8000000 unused */ -+ /* 0x10000000 unused */ -+ /* 0x20000000 unused */ -+ /* 0x40000000 unused */ - - #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ - PNG_FLAG_CRC_ANCILLARY_NOWARN) -@@ -389,24 +667,23 @@ - #define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ - PNG_FLAG_CRC_CRITICAL_MASK) - --/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib -- * can handle at once. This type need be no larger than 16 bits (so maximum of -- * 65535), this define allows us to discover how big it is, but limited by the -- * maximuum for png_size_t. The value can be overriden in a library build -- * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably -- * lower value (e.g. 255 works). A lower value may help memory usage (slightly) -- * and may even improve performance on some systems (and degrade it on others.) -- */ --#ifndef ZLIB_IO_MAX --# define ZLIB_IO_MAX ((uInt)-1) --#endif -- - /* Save typing and make code easier to understand */ - - #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ - abs((int)((c1).green) - (int)((c2).green)) + \ - abs((int)((c1).blue) - (int)((c2).blue))) - -+/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255 -+ * by dividing by 257 *with rounding*. This macro is exact for the given range. -+ * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the -+ * macro were established by experiment (modifying the added value). The macro -+ * has a second variant that takes a value already scaled by 255 and divides by -+ * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it -+ * only gives off-by-one errors and only for 0.5% (1 in 200) of the values. -+ */ -+#define PNG_DIV65535(v24) (((v24) + 32895) >> 16) -+#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255) -+ - /* Added to libpng-1.2.6 JB */ - #define PNG_ROWBYTES(pixel_bits, width) \ - ((pixel_bits) >= 8 ? \ -@@ -454,151 +731,314 @@ - #ifdef PNG_FIXED_POINT_MACRO_SUPPORTED - #define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ - ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) --#else --PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, -- png_const_charp text)); - #endif -+/* else the corresponding function is defined below, inside the scope of the -+ * cplusplus test. -+ */ - #endif - --/* Constant strings for known chunk types. If you need to add a chunk, -- * define the name here, and add an invocation of the macro wherever it's -- * needed. -+/* Constants for known chunk types. If you need to add a chunk, define the name -+ * here. For historical reasons these constants have the form png_<name>; i.e. -+ * the prefix is lower case. Please use decimal values as the parameters to -+ * match the ISO PNG specification and to avoid relying on the C locale -+ * interpretation of character values. -+ * -+ * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values -+ * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string -+ * to be generated if required. -+ * -+ * PNG_32b correctly produces a value shifted by up to 24 bits, even on -+ * architectures where (int) is only 16 bits. - */ --#define PNG_IHDR PNG_CONST png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} --#define PNG_IDAT PNG_CONST png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} --#define PNG_IEND PNG_CONST png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} --#define PNG_PLTE PNG_CONST png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} --#define PNG_bKGD PNG_CONST png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} --#define PNG_cHRM PNG_CONST png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} --#define PNG_gAMA PNG_CONST png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} --#define PNG_hIST PNG_CONST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} --#define PNG_iCCP PNG_CONST png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} --#define PNG_iTXt PNG_CONST png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} --#define PNG_oFFs PNG_CONST png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} --#define PNG_pCAL PNG_CONST png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} --#define PNG_sCAL PNG_CONST png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} --#define PNG_pHYs PNG_CONST png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} --#define PNG_sBIT PNG_CONST png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} --#define PNG_sPLT PNG_CONST png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} --#define PNG_sRGB PNG_CONST png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} --#define PNG_sTER PNG_CONST png_byte png_sTER[5] = {115, 84, 69, 82, '\0'} --#define PNG_tEXt PNG_CONST png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} --#define PNG_tIME PNG_CONST png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} --#define PNG_tRNS PNG_CONST png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} --#define PNG_zTXt PNG_CONST png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} -+#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) -+#define PNG_U32(b1,b2,b3,b4) \ -+ (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) -+ -+/* Constants for known chunk types. -+ * -+ * MAINTAINERS: If you need to add a chunk, define the name here. -+ * For historical reasons these constants have the form png_<name>; i.e. -+ * the prefix is lower case. Please use decimal values as the parameters to -+ * match the ISO PNG specification and to avoid relying on the C locale -+ * interpretation of character values. Please keep the list sorted. -+ * -+ * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk -+ * type. In fact the specification does not express chunk types this way, -+ * however using a 32-bit value means that the chunk type can be read from the -+ * stream using exactly the same code as used for a 32-bit unsigned value and -+ * can be examined far more efficiently (using one arithmetic compare). -+ * -+ * Prior to 1.5.6 the chunk type constants were expressed as C strings. The -+ * libpng API still uses strings for 'unknown' chunks and a macro, -+ * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice -+ * that for portable code numeric values must still be used; the string "IHDR" -+ * is not portable and neither is PNG_U32('I', 'H', 'D', 'R'). -+ * -+ * In 1.7.0 the definitions will be made public in png.h to avoid having to -+ * duplicate the same definitions in application code. -+ */ -+#define png_IDAT PNG_U32( 73, 68, 65, 84) -+#define png_IEND PNG_U32( 73, 69, 78, 68) -+#define png_IHDR PNG_U32( 73, 72, 68, 82) -+#define png_PLTE PNG_U32( 80, 76, 84, 69) -+#define png_bKGD PNG_U32( 98, 75, 71, 68) -+#define png_cHRM PNG_U32( 99, 72, 82, 77) -+#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ -+#define png_gAMA PNG_U32(103, 65, 77, 65) -+#define png_gIFg PNG_U32(103, 73, 70, 103) -+#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ -+#define png_gIFx PNG_U32(103, 73, 70, 120) -+#define png_hIST PNG_U32(104, 73, 83, 84) -+#define png_iCCP PNG_U32(105, 67, 67, 80) -+#define png_iTXt PNG_U32(105, 84, 88, 116) -+#define png_oFFs PNG_U32(111, 70, 70, 115) -+#define png_pCAL PNG_U32(112, 67, 65, 76) -+#define png_pHYs PNG_U32(112, 72, 89, 115) -+#define png_sBIT PNG_U32(115, 66, 73, 84) -+#define png_sCAL PNG_U32(115, 67, 65, 76) -+#define png_sPLT PNG_U32(115, 80, 76, 84) -+#define png_sRGB PNG_U32(115, 82, 71, 66) -+#define png_sTER PNG_U32(115, 84, 69, 82) -+#define png_tEXt PNG_U32(116, 69, 88, 116) -+#define png_tIME PNG_U32(116, 73, 77, 69) -+#define png_tRNS PNG_U32(116, 82, 78, 83) -+#define png_zTXt PNG_U32(122, 84, 88, 116) -+ -+/* The following will work on (signed char*) strings, whereas the get_uint_32 -+ * macro will fail on top-bit-set values because of the sign extension. -+ */ -+#define PNG_CHUNK_FROM_STRING(s)\ -+ PNG_U32(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3]) -+ -+/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is -+ * signed and the argument is a (char[]) This macro will fail miserably on -+ * systems where (char) is more than 8 bits. -+ */ -+#define PNG_STRING_FROM_CHUNK(s,c)\ -+ (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\ -+ ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c))) -+ -+/* Do the same but terminate with a null character. */ -+#define PNG_CSTRING_FROM_CHUNK(s,c)\ -+ (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) -+ -+/* Test on flag values as defined in the spec (section 5.4): */ -+#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29)) -+#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c)) -+#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) -+#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) -+#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) - - /* Gamma values (new at libpng-1.5.4): */ - #define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ - #define PNG_GAMMA_MAC_INVERSE 65909 - #define PNG_GAMMA_sRGB_INVERSE 45455 - -+/* Almost everything below is C specific; the #defines above can be used in -+ * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. -+ */ -+#ifndef PNG_VERSION_INFO_ONLY -+ -+#include "pngstruct.h" -+#include "pnginfo.h" -+ -+/* Validate the include paths - the include path used to generate pnglibconf.h -+ * must match that used in the build, or we must be using pnglibconf.h.prebuilt: -+ */ -+#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM -+# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \ -+ "-I (include path) error: see the notes in pngpriv.h" -+ /* This means that when pnglibconf.h was built the copy of zlib.h that it -+ * used is not the same as the one being used here. Because the build of -+ * libpng makes decisions to use inflateInit2 and inflateReset2 based on the -+ * zlib version number and because this affects handling of certain broken -+ * PNG files the -I directives must match. -+ * -+ * The most likely explanation is that you passed a -I in CFLAGS. This will -+ * not work; all the preprocessor directories and in particular all the -I -+ * directives must be in CPPFLAGS. -+ */ -+#endif -+ -+/* This is used for 16 bit gamma tables -- only the top level pointers are -+ * const; this could be changed: -+ */ -+typedef const png_uint_16p * png_const_uint_16pp; -+ -+/* Added to libpng-1.5.7: sRGB conversion tables */ -+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ -+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]); -+ /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value, -+ * 0..65535. This table gives the closest 16-bit answers (no errors). -+ */ -+#endif -+ -+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]); -+PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]); -+ -+#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\ -+ ((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)) -+ /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB -+ * encoded value with maximum error 0.646365. Note that the input is not a -+ * 16-bit value; it has been multiplied by 255! */ -+#endif /* SIMPLIFIED_READ/WRITE */ -+ - - /* Inhibit C++ name-mangling for libpng functions but not for system calls. */ - #ifdef __cplusplus - extern "C" { - #endif /* __cplusplus */ - --/* These functions are used internally in the code. They generally -- * shouldn't be used unless you are writing code to add or replace some -- * functionality in libpng. More information about most functions can -- * be found in the files where the functions are located. -+/* Internal functions; these are not exported from a DLL however because they -+ * are used within several of the C source files they have to be C extern. -+ * -+ * All of these functions must be declared with PNG_INTERNAL_FUNCTION. - */ - -+/* Zlib support */ -+#define PNG_UNEXPECTED_ZLIB_RETURN (-7) -+PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret), -+ PNG_EMPTY); -+ /* Used by the zlib handling functions to ensure that z_stream::msg is always -+ * set before they return. -+ */ -+ -+#ifdef PNG_WRITE_SUPPORTED -+PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr, -+ png_compression_bufferp *list),PNG_EMPTY); -+ /* Free the buffer list used by the compressed write code. */ -+#endif -+ -+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ -+ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ -+ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ -+ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ -+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ -+ (defined(PNG_sCAL_SUPPORTED) && \ -+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) -+PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr, -+ double fp, png_const_charp text),PNG_EMPTY); -+#endif -+ - /* Check the user version string for compatibility, returns false if the version - * numbers aren't compatible. - */ --PNG_EXTERN int png_user_version_check(png_structp png_ptr, -- png_const_charp user_png_ver); -+PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr, -+ png_const_charp user_png_ver),PNG_EMPTY); - --/* Allocate memory for an internal libpng struct */ --PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct,PNGARG((int type)), -+/* Internal base allocator - no messages, NULL on failure to allocate. This -+ * does, however, call the application provided allocator and that could call -+ * png_error (although that would be a bug in the application implementation.) -+ */ -+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr, -+ png_alloc_size_t size),PNG_ALLOCATED); -+ -+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ -+ defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -+/* Internal array allocator, outputs no error or warning messages on failure, -+ * just returns NULL. -+ */ -+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr, -+ int nelements, size_t element_size),PNG_ALLOCATED); -+ -+/* The same but an existing array is extended by add_elements. This function -+ * also memsets the new elements to 0 and copies the old elements. The old -+ * array is not freed or altered. -+ */ -+PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr, -+ png_const_voidp array, int old_elements, int add_elements, -+ size_t element_size),PNG_ALLOCATED); -+#endif /* text, sPLT or unknown chunks */ -+ -+/* Magic to create a struct when there is no struct to call the user supplied -+ * memory allocators. Because error handling has not been set up the memory -+ * handlers can't safely call png_error, but this is an obscure and undocumented -+ * restriction so libpng has to assume that the 'free' handler, at least, might -+ * call png_error. -+ */ -+PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct, -+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, -+ png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, -+ png_free_ptr free_fn),PNG_ALLOCATED); -+ -+/* Free memory from internal libpng struct */ -+PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr), -+ PNG_EMPTY); -+ -+/* Free an allocated jmp_buf (always succeeds) */ -+PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY); -+ -+/* Function to allocate memory for zlib. PNGAPI is disallowed. */ -+PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size), - PNG_ALLOCATED); - --/* Free memory from internal libpng struct */ --PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); -- --PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct_2, -- PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)), -- PNG_ALLOCATED); --PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, -- png_free_ptr free_fn, png_voidp mem_ptr)); -- --/* Free any memory that info_ptr points to and reset struct. */ --PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, -- png_infop info_ptr)); -- --/* Function to allocate memory for zlib. PNGAPI is disallowed. */ --PNG_EXTERN PNG_FUNCTION(voidpf,png_zalloc,PNGARG((voidpf png_ptr, uInt items, -- uInt size)),PNG_ALLOCATED); -- - /* Function to free memory for zlib. PNGAPI is disallowed. */ --PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); -+PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); - - /* Next four functions are used internally as callbacks. PNGCBAPI is required - * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to - * PNGCBAPI at 1.5.0 - */ - --PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr, -- png_bytep data, png_size_t length)); -+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, -+ png_bytep data, png_size_t length),PNG_EMPTY); - - #ifdef PNG_PROGRESSIVE_READ_SUPPORTED --PNG_EXTERN void PNGCBAPI png_push_fill_buffer PNGARG((png_structp png_ptr, -- png_bytep buffer, png_size_t length)); -+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, -+ png_bytep buffer, png_size_t length),PNG_EMPTY); - #endif - --PNG_EXTERN void PNGCBAPI png_default_write_data PNGARG((png_structp png_ptr, -- png_bytep data, png_size_t length)); -+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, -+ png_bytep data, png_size_t length),PNG_EMPTY); - - #ifdef PNG_WRITE_FLUSH_SUPPORTED - # ifdef PNG_STDIO_SUPPORTED --PNG_EXTERN void PNGCBAPI png_default_flush PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr), -+ PNG_EMPTY); - # endif - #endif - - /* Reset the CRC variable */ --PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY); - - /* Write the "data" buffer to whatever output you are using */ --PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, -- png_const_bytep data, png_size_t length)); -+PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, -+ png_const_bytep data, png_size_t length),PNG_EMPTY); - - /* Read and check the PNG file signature */ --PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); - - /* Read the chunk header (length + type name) */ --PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr), -+ PNG_EMPTY); - - /* Read data from whatever input you are using into the "data" buffer */ --PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, -- png_size_t length)); -+PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data, -+ png_size_t length),PNG_EMPTY); - - /* Read bytes into buf, and update png_ptr->crc */ --PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, -- png_size_t length)); -- --/* Decompress data in a chunk that uses compression */ --#if defined(PNG_READ_COMPRESSED_TEXT_SUPPORTED) --PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, -- int comp_type, png_size_t chunklength, png_size_t prefix_length, -- png_size_t *data_length)); --#endif -+PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, -+ png_uint_32 length),PNG_EMPTY); - - /* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ --PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); -+PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr, -+ png_uint_32 skip),PNG_EMPTY); - - /* Read the CRC from the file and compare it to the libpng calculated CRC */ --PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY); - - /* Calculate the CRC over a section of data. Note that we are only - * passing a maximum of 64K on systems that have this as a memory limit, - * since this is the maximum buffer size we can specify. - */ --PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, -- png_const_bytep ptr, png_size_t length)); -+PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, -+ png_const_bytep ptr, png_size_t length),PNG_EMPTY); - - #ifdef PNG_WRITE_FLUSH_SUPPORTED --PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY); - #endif - - /* Write various chunks */ -@@ -606,317 +1046,256 @@ - /* Write the IHDR chunk, and update the png_struct with the necessary - * information. - */ --PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, -- png_uint_32 height, -- int bit_depth, int color_type, int compression_method, int filter_method, -- int interlace_method)); -+PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr, -+ png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, -+ int compression_method, int filter_method, int interlace_method),PNG_EMPTY); - --PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, -- png_const_colorp palette, png_uint_32 num_pal)); -+PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr, -+ png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY); - --PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, -- png_size_t length)); -+PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr, -+ png_const_bytep row_data, png_alloc_size_t row_data_length, int flush), -+ PNG_EMPTY); - --PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY); - - #ifdef PNG_WRITE_gAMA_SUPPORTED --# ifdef PNG_FLOATING_POINT_SUPPORTED --PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); --# endif --# ifdef PNG_FIXED_POINT_SUPPORTED --PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, -- png_fixed_point file_gamma)); --# endif -+PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr, -+ png_fixed_point file_gamma),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_sBIT_SUPPORTED --PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, -- png_const_color_8p sbit, int color_type)); -+PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr, -+ png_const_color_8p sbit, int color_type),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_cHRM_SUPPORTED --# ifdef PNG_FLOATING_POINT_SUPPORTED --PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, -- double white_x, double white_y, -- double red_x, double red_y, double green_x, double green_y, -- double blue_x, double blue_y)); --# endif --PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, -- png_fixed_point int_white_x, png_fixed_point int_white_y, -- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point -- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, -- png_fixed_point int_blue_y)); -+PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, -+ const png_xy *xy), PNG_EMPTY); -+ /* The xy value must have been previously validated */ - #endif - - #ifdef PNG_WRITE_sRGB_SUPPORTED --PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, -- int intent)); -+PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr, -+ int intent),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_iCCP_SUPPORTED --PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, -- png_const_charp name, int compression_type, -- png_const_charp profile, int proflen)); -- /* Note to maintainer: profile should be png_bytep */ -+PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, -+ png_const_charp name, png_const_bytep profile), PNG_EMPTY); -+ /* The profile must have been previously validated for correctness, the -+ * length comes from the first four bytes. Only the base, deflate, -+ * compression is supported. -+ */ - #endif - - #ifdef PNG_WRITE_sPLT_SUPPORTED --PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, -- png_const_sPLT_tp palette)); -+PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr, -+ png_const_sPLT_tp palette),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_tRNS_SUPPORTED --PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, -+PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr, - png_const_bytep trans, png_const_color_16p values, int number, -- int color_type)); -+ int color_type),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_bKGD_SUPPORTED --PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, -- png_const_color_16p values, int color_type)); -+PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr, -+ png_const_color_16p values, int color_type),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_hIST_SUPPORTED --PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, -- png_const_uint_16p hist, int num_hist)); -+PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr, -+ png_const_uint_16p hist, int num_hist),PNG_EMPTY); - #endif - - /* Chunks that have keywords */ --#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ -- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) --PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, -- png_const_charp key, png_charpp new_key)); --#endif -- - #ifdef PNG_WRITE_tEXt_SUPPORTED --PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key, -- png_const_charp text, png_size_t text_len)); -+PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, -+ png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_zTXt_SUPPORTED --PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_const_charp key, -- png_const_charp text, png_size_t text_len, int compression)); -+PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp -+ key, png_const_charp text, int compression),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_iTXt_SUPPORTED --PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, -+PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr, - int compression, png_const_charp key, png_const_charp lang, -- png_const_charp lang_key, png_const_charp text)); -+ png_const_charp lang_key, png_const_charp text),PNG_EMPTY); - #endif - - #ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ --PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, -- png_infop info_ptr, png_const_textp text_ptr, int num_text)); -+PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_oFFs_SUPPORTED --PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, -- png_int_32 x_offset, png_int_32 y_offset, int unit_type)); -+PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr, -+ png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_pCAL_SUPPORTED --PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, -- png_int_32 X0, png_int_32 X1, int type, int nparams, -- png_const_charp units, png_charpp params)); -+PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr, -+ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, -+ png_const_charp units, png_charpp params),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_pHYs_SUPPORTED --PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, -+PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr, - png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, -- int unit_type)); -+ int unit_type),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_tIME_SUPPORTED --PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, -- png_const_timep mod_time)); -+PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr, -+ png_const_timep mod_time),PNG_EMPTY); - #endif - - #ifdef PNG_WRITE_sCAL_SUPPORTED --PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, -- int unit, png_const_charp width, png_const_charp height)); -+PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr, -+ int unit, png_const_charp width, png_const_charp height),PNG_EMPTY); - #endif - - /* Called when finished processing a row of data */ --PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr), -+ PNG_EMPTY); - - /* Internal use only. Called before first row of data */ --PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr), -+ PNG_EMPTY); - --/* Combine a row of data, dealing with alpha, etc. if requested */ --PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, -- int mask)); -+/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an -+ * array of png_ptr->width pixels. If the image is not interlaced or this -+ * is the final pass this just does a memcpy, otherwise the "display" flag -+ * is used to determine whether to copy pixels that are not in the current pass. -+ * -+ * Because 'png_do_read_interlace' (below) replicates pixels this allows this -+ * function to achieve the documented 'blocky' appearance during interlaced read -+ * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' -+ * are not changed if they are not in the current pass, when display is 0. -+ * -+ * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. -+ * -+ * The API always reads from the png_struct row buffer and always assumes that -+ * it is full width (png_do_read_interlace has already been called.) -+ * -+ * This function is only ever used to write to row buffers provided by the -+ * caller of the relevant libpng API and the row must have already been -+ * transformed by the read transformations. -+ * -+ * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed -+ * bitmasks for use within the code, otherwise runtime generated masks are used. -+ * The default is compile time masks. -+ */ -+#ifndef PNG_USE_COMPILE_TIME_MASKS -+# define PNG_USE_COMPILE_TIME_MASKS 1 -+#endif -+PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr, -+ png_bytep row, int display),PNG_EMPTY); - - #ifdef PNG_READ_INTERLACING_SUPPORTED --/* Expand an interlaced row */ --/* OLD pre-1.0.9 interface: --PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, -- png_bytep row, int pass, png_uint_32 transformations)); -+/* Expand an interlaced row: the 'row_info' describes the pass data that has -+ * been read in and must correspond to the pixels in 'row', the pixels are -+ * expanded (moved apart) in 'row' to match the final layout, when doing this -+ * the pixels are *replicated* to the intervening space. This is essential for -+ * the correct operation of png_combine_row, above. - */ --PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info, -+ png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY); - #endif - - /* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ - - #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Grab pixels out of a row for an interlaced pass */ --PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, -- png_bytep row, int pass)); -+PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info, -+ png_bytep row, int pass),PNG_EMPTY); - #endif - --/* Unfilter a row */ --PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, -- png_row_infop row_info, png_bytep row, png_const_bytep prev_row, -- int filter)); -+/* Unfilter a row: check the filter value before calling this, there is no point -+ * calling it for PNG_FILTER_VALUE_NONE. -+ */ -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop -+ row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY); -+ -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info, -+ png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop -+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop -+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop -+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop -+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop -+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop -+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); - - /* Choose the best filter to use and filter the row data */ --PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, -- png_row_infop row_info)); -+PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, -+ png_row_infop row_info),PNG_EMPTY); - --/* Finish a row while reading, dealing with interlacing passes, etc. */ --PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); -+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr, -+ png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY); -+ /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer -+ * is NULL the function checks, instead, for the end of the stream. In this -+ * case a benign error will be issued if the stream end is not found or if -+ * extra data has to be consumed. -+ */ -+PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr), -+ PNG_EMPTY); -+ /* This cleans up when the IDAT LZ stream does not end when the last image -+ * byte is read; there is still some pending input. -+ */ -+ -+PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr), -+ PNG_EMPTY); -+ /* Finish a row while reading, dealing with interlacing passes, etc. */ -+#endif /* SEQUENTIAL_READ */ - - /* Initialize the row buffers, etc. */ --PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); - - #ifdef PNG_READ_TRANSFORMS_SUPPORTED - /* Optional call to update the users info structure */ --PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, -- png_infop info_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); - #endif - --/* These are the functions that do the transformations */ --#ifdef PNG_READ_FILLER_SUPPORTED --PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, -- png_bytep row, png_uint_32 filler, png_uint_32 flags)); --#endif -- --#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED --PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED --PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED --PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED --PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- -+/* Shared transform functions, defined in pngtran.c */ - #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) --PNG_EXTERN void png_do_strip_channel PNGARG((png_row_infop row_info, -- png_bytep row, int at_start)); -+PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info, -+ png_bytep row, int at_start),PNG_EMPTY); - #endif - - #ifdef PNG_16BIT_SUPPORTED - #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) --PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, -- png_bytep row)); -+PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info, -+ png_bytep row),PNG_EMPTY); - #endif - #endif - - #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) --PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED --PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, -- png_row_infop row_info, png_bytep row)); --#endif -- --#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED --PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_READ_PACK_SUPPORTED --PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_READ_SHIFT_SUPPORTED --PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, -- png_bytep row, png_const_color_8p sig_bits)); -+PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info, -+ png_bytep row),PNG_EMPTY); - #endif - - #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) --PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED --PNG_EXTERN void png_do_scale_16_to_8 PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED --PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_READ_QUANTIZE_SUPPORTED --PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info, -- png_bytep row, png_const_bytep palette_lookup, -- png_const_bytep quantize_lookup)); -- --# ifdef PNG_CORRECT_PALETTE_SUPPORTED --PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, -- png_colorp palette, int num_palette)); --# endif -+PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info, -+ png_bytep row),PNG_EMPTY); - #endif - - #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) --PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, -- png_bytep row)); --#endif -- --#ifdef PNG_WRITE_PACK_SUPPORTED --PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, -- png_bytep row, png_uint_32 bit_depth)); --#endif -- --#ifdef PNG_WRITE_SHIFT_SUPPORTED --PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, -- png_bytep row, png_const_color_8p bit_depth)); --#endif -- --#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ -- defined(PNG_READ_ALPHA_MODE_SUPPORTED) --PNG_EXTERN void png_do_compose PNGARG((png_row_infop row_info, -- png_bytep row, png_structp png_ptr)); --#endif -- --#ifdef PNG_READ_GAMMA_SUPPORTED --PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, -- png_bytep row, png_structp png_ptr)); --#endif -- --#ifdef PNG_READ_ALPHA_MODE_SUPPORTED --PNG_EXTERN void png_do_encode_alpha PNGARG((png_row_infop row_info, -- png_bytep row, png_structp png_ptr)); --#endif -- --#ifdef PNG_READ_EXPAND_SUPPORTED --PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, -- png_bytep row, png_const_colorp palette, png_const_bytep trans, -- int num_trans)); --PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, -- png_bytep row, png_const_color_16p trans_color)); --#endif -- --#ifdef PNG_READ_EXPAND_16_SUPPORTED --PNG_EXTERN void png_do_expand_16 PNGARG((png_row_infop row_info, -- png_bytep row)); -+PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info, -+ png_bytep row),PNG_EMPTY); - #endif - - /* The following decodes the appropriate chunks, and does error correction, -@@ -924,208 +1303,283 @@ - */ - - /* Decode the IHDR chunk */ --PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); --PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); --PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - - #ifdef PNG_READ_bKGD_SUPPORTED --PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_cHRM_SUPPORTED --PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_gAMA_SUPPORTED --PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_hIST_SUPPORTED --PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_iCCP_SUPPORTED --PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); --#endif /* PNG_READ_iCCP_SUPPORTED */ -+PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+#endif /* READ_iCCP */ - - #ifdef PNG_READ_iTXt_SUPPORTED --PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_oFFs_SUPPORTED --PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_pCAL_SUPPORTED --PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_pHYs_SUPPORTED --PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_sBIT_SUPPORTED --PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_sCAL_SUPPORTED --PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_sPLT_SUPPORTED --PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); --#endif /* PNG_READ_sPLT_SUPPORTED */ -+PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+#endif /* READ_sPLT */ - - #ifdef PNG_READ_sRGB_SUPPORTED --PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_tEXt_SUPPORTED --PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_tIME_SUPPORTED --PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_tRNS_SUPPORTED --PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - - #ifdef PNG_READ_zTXt_SUPPORTED --PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, -- png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - #endif - --PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, -- png_infop info_ptr, png_uint_32 length)); -+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr, -+ png_uint_32 chunk_name),PNG_EMPTY); - --PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, -- png_const_bytep chunk_name)); -+PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); -+ /* This is the function that gets called for unknown chunks. The 'keep' -+ * argument is either non-zero for a known chunk that has been set to be -+ * handled as unknown or zero for an unknown chunk. By default the function -+ * just skips the chunk or errors out if it is critical. -+ */ -+ -+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ -+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -+PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling, -+ (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY); -+ /* Exactly as the API png_handle_as_unknown() except that the argument is a -+ * 32-bit chunk name, not a string. -+ */ -+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ - - /* Handle the transformations for reading and writing */ - #ifdef PNG_READ_TRANSFORMS_SUPPORTED --PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr, -+ png_row_infop row_info),PNG_EMPTY); - #endif - #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED --PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr, -+ png_row_infop row_info),PNG_EMPTY); - #endif - - #ifdef PNG_READ_TRANSFORMS_SUPPORTED --PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr), -+ PNG_EMPTY); - #endif - - #ifdef PNG_PROGRESSIVE_READ_SUPPORTED --PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, -- png_infop info_ptr)); --PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, -- png_infop info_ptr)); --PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); --PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, -- png_uint_32 length)); --PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); --PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); --PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, -- png_bytep buffer, png_size_t buffer_length)); --PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); --PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, -- png_bytep buffer, png_size_t buffer_length)); --PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); --PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, -- png_infop info_ptr, png_uint_32 length)); --PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, -- png_infop info_ptr)); --PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, -- png_infop info_ptr)); --PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); --PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, -- png_infop info_ptr)); --PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, -- png_infop info_ptr)); --PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_crc_skip,(png_structrp png_ptr, -+ png_uint_32 length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_crc_finish,(png_structrp png_ptr), -+ PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr), -+ PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, -+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, -+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), -+ PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr, -+ png_bytep row),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr), -+ PNG_EMPTY); - # ifdef PNG_READ_tEXt_SUPPORTED --PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, -- png_infop info_ptr, png_uint_32 length)); --PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, -- png_infop info_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); - # endif - # ifdef PNG_READ_zTXt_SUPPORTED --PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, -- png_infop info_ptr, png_uint_32 length)); --PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, -- png_infop info_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); - # endif - # ifdef PNG_READ_iTXt_SUPPORTED --PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, -- png_infop info_ptr, png_uint_32 length)); --PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, -- png_infop info_ptr)); -+PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr, -+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr, -+ png_inforp info_ptr),PNG_EMPTY); - # endif - --#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -+#endif /* PROGRESSIVE_READ */ - --#ifdef PNG_MNG_FEATURES_SUPPORTED --PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, -- png_bytep row)); --PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, -- png_bytep row)); -+/* Added at libpng version 1.6.0 */ -+#ifdef PNG_GAMMA_SUPPORTED -+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY); -+ /* Set the colorspace gamma with a value provided by the application or by -+ * the gAMA chunk on read. The value will override anything set by an ICC -+ * profile. -+ */ -+ -+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, -+ png_inforp info_ptr), PNG_EMPTY); -+ /* Synchronize the info 'valid' flags with the colorspace */ -+ -+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, -+ png_inforp info_ptr), PNG_EMPTY); -+ /* Copy the png_struct colorspace to the info_struct and call the above to -+ * synchronize the flags. Checks for NULL info_ptr and does nothing. -+ */ - #endif - - /* Added at libpng version 1.4.0 */ --#ifdef PNG_CHECK_cHRM_SUPPORTED --PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, -- png_fixed_point int_white_x, png_fixed_point int_white_y, -- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point -- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, -- png_fixed_point int_blue_y)); -+#ifdef PNG_COLORSPACE_SUPPORTED -+/* These internal functions are for maintaining the colorspace structure within -+ * a png_info or png_struct (or, indeed, both). -+ */ -+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities, -+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy, -+ int preferred), PNG_EMPTY); -+ -+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints, -+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ, -+ int preferred), PNG_EMPTY); -+ -+#ifdef PNG_sRGB_SUPPORTED -+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, int intent), PNG_EMPTY); -+ /* This does set the colorspace gAMA and cHRM values too, but doesn't set the -+ * flags to write them, if it returns false there was a problem and an error -+ * message has already been output (but the colorspace may still need to be -+ * synced to record the invalid flag). -+ */ -+#endif /* sRGB */ -+ -+#ifdef PNG_iCCP_SUPPORTED -+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_const_charp name, -+ png_uint_32 profile_length, png_const_bytep profile, int color_type), -+ PNG_EMPTY); -+ /* The 'name' is used for information only */ -+ -+/* Routines for checking parts of an ICC profile. */ -+PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_const_charp name, -+ png_uint_32 profile_length), PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_const_charp name, -+ png_uint_32 profile_length, -+ png_const_bytep profile /* first 132 bytes only */, int color_type), -+ PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr, -+ png_colorspacerp colorspace, png_const_charp name, -+ png_uint_32 profile_length, -+ png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY); -+#ifdef PNG_sRGB_SUPPORTED -+PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,( -+ png_const_structrp png_ptr, png_colorspacerp colorspace, -+ png_const_bytep profile, uLong adler), PNG_EMPTY); -+ /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may -+ * be zero to indicate that it is not available. It is used, if provided, -+ * as a fast check on the profile when checking to see if it is sRGB. -+ */ -+#endif -+#endif /* iCCP */ -+ -+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients, -+ (png_structrp png_ptr), PNG_EMPTY); -+ /* Set the rgb_to_gray coefficients from the colorspace Y values */ -+#endif /* READ_RGB_TO_GRAY */ -+#endif /* COLORSPACE */ -+ -+/* Added at libpng version 1.4.0 */ -+PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr, -+ png_uint_32 width, png_uint_32 height, int bit_depth, -+ int color_type, int interlace_type, int compression_type, -+ int filter_type),PNG_EMPTY); -+ -+/* Added at libpng version 1.5.10 */ -+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ -+ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) -+PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes, -+ (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); - #endif - --#ifdef PNG_CHECK_cHRM_SUPPORTED --/* Added at libpng version 1.2.34 and 1.4.0 */ --/* Currently only used by png_check_cHRM_fixed */ --PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, -- unsigned long *hi_product, unsigned long *lo_product)); --#endif -- --/* Added at libpng version 1.4.0 */ --PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, -- png_uint_32 width, png_uint_32 height, int bit_depth, -- int color_type, int interlace_type, int compression_type, -- int filter_type)); -- --/* Free all memory used by the read (old method - NOT DLL EXPORTED) */ --PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, -- png_infop info_ptr, png_infop end_info_ptr)); -- --/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ --PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr)); -- --#ifdef USE_FAR_KEYWORD /* memory model conversion function */ --PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr, -- int check)); --#endif /* USE_FAR_KEYWORD */ -- - #if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) --PNG_EXTERN PNG_FUNCTION(void, png_fixed_error, (png_structp png_ptr, -+PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr, - png_const_charp name),PNG_NORETURN); - #endif - -@@ -1133,8 +1587,8 @@ - * the end. Always leaves the buffer nul terminated. Never errors out (and - * there is no error code.) - */ --PNG_EXTERN size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos, -- png_const_charp string); -+PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize, -+ size_t pos, png_const_charp string),PNG_EMPTY); - - /* Various internal functions to handle formatted warning messages, currently - * only implemented for warnings. -@@ -1145,8 +1599,8 @@ - * Returns the pointer to the start of the formatted string. This utility only - * does unsigned values. - */ --PNG_EXTERN png_charp png_format_number(png_const_charp start, png_charp end, -- int format, png_alloc_size_t number); -+PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start, -+ png_charp end, int format, png_alloc_size_t number),PNG_EMPTY); - - /* Convenience macro that takes an array: */ - #define PNG_FORMAT_NUMBER(buffer,format,number) \ -@@ -1170,7 +1624,7 @@ - #ifdef PNG_WARNINGS_SUPPORTED - /* New defines and members adding in libpng-1.5.4 */ - # define PNG_WARNING_PARAMETER_SIZE 32 --# define PNG_WARNING_PARAMETER_COUNT 8 -+# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */ - - /* An l-value of this type has to be passed to the APIs below to cache the - * values of the parameters to a formatted warning message. -@@ -1178,48 +1632,97 @@ - typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ - PNG_WARNING_PARAMETER_SIZE]; - --PNG_EXTERN void png_warning_parameter(png_warning_parameters p, int number, -- png_const_charp string); -- /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, -- * including the trailing '\0'. -- */ --PNG_EXTERN void png_warning_parameter_unsigned(png_warning_parameters p, -- int number, int format, png_alloc_size_t value); -- /* Use png_alloc_size_t because it is an unsigned type as big as any we -- * need to output. Use the following for a signed value. -- */ --PNG_EXTERN void png_warning_parameter_signed(png_warning_parameters p, -- int number, int format, png_int_32 value); -+PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p, -+ int number, png_const_charp string),PNG_EMPTY); -+ /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, -+ * including the trailing '\0'. -+ */ -+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned, -+ (png_warning_parameters p, int number, int format, png_alloc_size_t value), -+ PNG_EMPTY); -+ /* Use png_alloc_size_t because it is an unsigned type as big as any we -+ * need to output. Use the following for a signed value. -+ */ -+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed, -+ (png_warning_parameters p, int number, int format, png_int_32 value), -+ PNG_EMPTY); - --PNG_EXTERN void png_formatted_warning(png_structp png_ptr, -- png_warning_parameters p, png_const_charp message); -- /* 'message' follows the X/Open approach of using @1, @2 to insert -- * parameters previously supplied using the above functions. Errors in -- * specifying the parameters will simple result in garbage substitutions. -- */ -+PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr, -+ png_warning_parameters p, png_const_charp message),PNG_EMPTY); -+ /* 'message' follows the X/Open approach of using @1, @2 to insert -+ * parameters previously supplied using the above functions. Errors in -+ * specifying the parameters will simply result in garbage substitutions. -+ */ - #endif - -+#ifdef PNG_BENIGN_ERRORS_SUPPORTED -+/* Application errors (new in 1.6); use these functions (declared below) for -+ * errors in the parameters or order of API function calls on read. The -+ * 'warning' should be used for an error that can be handled completely; the -+ * 'error' for one which can be handled safely but which may lose application -+ * information or settings. -+ * -+ * By default these both result in a png_error call prior to release, while in a -+ * released version the 'warning' is just a warning. However if the application -+ * explicitly disables benign errors (explicitly permitting the code to lose -+ * information) they both turn into warnings. -+ * -+ * If benign errors aren't supported they end up as the corresponding base call -+ * (png_warning or png_error.) -+ */ -+PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr, -+ png_const_charp message),PNG_EMPTY); -+ /* The application provided invalid parameters to an API function or called -+ * an API function at the wrong time, libpng can completely recover. -+ */ -+ -+PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr, -+ png_const_charp message),PNG_EMPTY); -+ /* As above but libpng will ignore the call, or attempt some other partial -+ * recovery from the error. -+ */ -+#else -+# define png_app_warning(pp,s) png_warning(pp,s) -+# define png_app_error(pp,s) png_error(pp,s) -+#endif -+ -+PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr, -+ png_const_charp message, int error),PNG_EMPTY); -+ /* Report a recoverable issue in chunk data. On read this is used to report -+ * a problem found while reading a particular chunk and the -+ * png_chunk_benign_error or png_chunk_warning function is used as -+ * appropriate. On write this is used to report an error that comes from -+ * data set via an application call to a png_set_ API and png_app_error or -+ * png_app_warning is used as appropriate. -+ * -+ * The 'error' parameter must have one of the following values: -+ */ -+#define PNG_CHUNK_WARNING 0 /* never an error */ -+#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */ -+#define PNG_CHUNK_ERROR 2 /* always an error */ -+ - /* ASCII to FP interfaces, currently only implemented if sCAL - * support is required. - */ --#if defined(PNG_READ_sCAL_SUPPORTED) -+#if defined(PNG_sCAL_SUPPORTED) - /* MAX_DIGITS is actually the maximum number of characters in an sCAL - * width or height, derived from the precision (number of significant -- * digits - a build time settable option) and assumpitions about the -+ * digits - a build time settable option) and assumptions about the - * maximum ridiculous exponent. - */ - #define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) - - #ifdef PNG_FLOATING_POINT_SUPPORTED --PNG_EXTERN void png_ascii_from_fp PNGARG((png_structp png_ptr, png_charp ascii, -- png_size_t size, double fp, unsigned int precision)); -+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, -+ png_charp ascii, png_size_t size, double fp, unsigned int precision), -+ PNG_EMPTY); - #endif /* FLOATING_POINT */ - - #ifdef PNG_FIXED_POINT_SUPPORTED --PNG_EXTERN void png_ascii_from_fixed PNGARG((png_structp png_ptr, -- png_charp ascii, png_size_t size, png_fixed_point fp)); -+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, -+ png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY); - #endif /* FIXED_POINT */ --#endif /* READ_sCAL */ -+#endif /* sCAL */ - - #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) - /* An internal API to validate the format of a floating point number. -@@ -1243,7 +1746,7 @@ - * NOTE: The dangling E problem. - * There is a PNG valid floating point number in the following: - * -- * PNG floating point numb1.ers are not greedy. -+ * PNG floating point numbers are not greedy. - * - * Working this out requires *TWO* character lookahead (because of the - * sign), the parser does not do this - it will fail at the 'r' - this -@@ -1294,14 +1797,14 @@ - #define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) - #define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) - --/* The actual parser. This can be called repeatedly, it updates -+/* The actual parser. This can be called repeatedly. It updates - * the index into the string and the state variable (which must -- * be initialzed to 0). It returns a result code, as above. There -+ * be initialized to 0). It returns a result code, as above. There - * is no point calling the parser any more if it fails to advance to - * the end of the string - it is stuck on an invalid character (or - * terminated by '\0'). - * -- * Note that the pointer will consume an E or even an E+ then leave -+ * Note that the pointer will consume an E or even an E+ and then leave - * a 'maybe' state even though a preceding integer.fraction is valid. - * The PNG_FP_WAS_VALID flag indicates that a preceding substring was - * a valid number. It's possible to recover from this by calling -@@ -1309,8 +1812,8 @@ - * that omits the last character (i.e. set the size to the index of - * the problem character.) This has not been tested within libpng. - */ --PNG_EXTERN int png_check_fp_number PNGARG((png_const_charp string, -- png_size_t size, int *statep, png_size_tp whereami)); -+PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, -+ png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); - - /* This is the same but it checks a complete string and returns true - * only if it just contains a floating point number. As of 1.5.4 this -@@ -1318,11 +1821,11 @@ - * it was valid (otherwise it returns 0.) This can be used for testing - * for negative or zero values using the sticky flag. - */ --PNG_EXTERN int png_check_fp_string PNGARG((png_const_charp string, -- png_size_t size)); -+PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, -+ png_size_t size),PNG_EMPTY); - #endif /* pCAL || sCAL */ - --#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ -+#if defined(PNG_GAMMA_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) - /* Added at libpng version 1.5.0 */ - /* This is a utility to provide a*times/div (rounded) and indicate -@@ -1330,29 +1833,37 @@ - * for overflow, true (1) if no overflow, in which case *res - * holds the result. - */ --PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a, -- png_int_32 multiplied_by, png_int_32 divided_by)); -+PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a, -+ png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY); - #endif - - #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) - /* Same deal, but issue a warning on overflow and return 0. */ --PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr, -- png_fixed_point a, png_int_32 multiplied_by, png_int_32 divided_by)); -+PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn, -+ (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by, -+ png_int_32 divided_by),PNG_EMPTY); - #endif - --#ifdef PNG_READ_GAMMA_SUPPORTED -+#ifdef PNG_GAMMA_SUPPORTED - /* Calculate a reciprocal - used for gamma values. This returns -- * 0 if the argument is 0 in order to maintain an undefined value, -+ * 0 if the argument is 0 in order to maintain an undefined value; - * there are no warnings. - */ --PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a)); -+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a), -+ PNG_EMPTY); - -+#ifdef PNG_READ_GAMMA_SUPPORTED - /* The same but gives a reciprocal of the product of two fixed point - * values. Accuracy is suitable for gamma calculations but this is -- * not exact - use png_muldiv for that. -+ * not exact - use png_muldiv for that. Only required at present on read. - */ --PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a, -- png_fixed_point b)); -+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a, -+ png_fixed_point b),PNG_EMPTY); -+#endif -+ -+/* Return true if the gamma value is significantly different from 1.0 */ -+PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value), -+ PNG_EMPTY); - #endif - - #ifdef PNG_READ_GAMMA_SUPPORTED -@@ -1363,19 +1874,93 @@ - * While the input is an 'unsigned' value it must actually be the - * correct bit value - 0..255 or 0..65535 as required. - */ --PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr, -- unsigned int value, png_fixed_point gamma_value)); --PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma_value)); --PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value, -- png_fixed_point gamma_value)); --PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, -- png_fixed_point gamma_value)); --PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, -- int bit_depth)); -+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr, -+ unsigned int value, png_fixed_point gamma_value),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value, -+ png_fixed_point gamma_value),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value, -+ png_fixed_point gamma_value),PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr), -+ PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr, -+ int bit_depth),PNG_EMPTY); - #endif - --/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ -+/* SIMPLIFIED READ/WRITE SUPPORT */ -+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ -+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -+/* The internal structure that png_image::opaque points to. */ -+typedef struct png_control -+{ -+ png_structp png_ptr; -+ png_infop info_ptr; -+ png_voidp error_buf; /* Always a jmp_buf at present. */ - -+ png_const_bytep memory; /* Memory buffer. */ -+ png_size_t size; /* Size of the memory buffer. */ -+ -+ unsigned int for_write :1; /* Otherwise it is a read structure */ -+ unsigned int owned_file :1; /* We own the file in io_ptr */ -+} png_control; -+ -+/* Return the pointer to the jmp_buf from a png_control: necessary because C -+ * does not reveal the type of the elements of jmp_buf. -+ */ -+#ifdef __cplusplus -+# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0]) -+#else -+# define png_control_jmp_buf(pc) ((pc)->error_buf) -+#endif -+ -+/* Utility to safely execute a piece of libpng code catching and logging any -+ * errors that might occur. Returns true on success, false on failure (either -+ * of the function or as a result of a png_error.) -+ */ -+PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr, -+ png_const_charp error_message),PNG_NORETURN); -+ -+#ifdef PNG_WARNINGS_SUPPORTED -+PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr, -+ png_const_charp warning_message),PNG_EMPTY); -+#else -+# define png_safe_warning 0/*dummy argument*/ -+#endif -+ -+PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image, -+ int (*function)(png_voidp), png_voidp arg),PNG_EMPTY); -+ -+/* Utility to log an error; this also cleans up the png_image; the function -+ * always returns 0 (false). -+ */ -+PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image, -+ png_const_charp error_message),PNG_EMPTY); -+ -+#ifndef PNG_SIMPLIFIED_READ_SUPPORTED -+/* png_image_free is used by the write code but not exported */ -+PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY); -+#endif /* !SIMPLIFIED_READ */ -+ -+#endif /* SIMPLIFIED READ/WRITE */ -+ -+/* These are initialization functions for hardware specific PNG filter -+ * optimizations; list these here then select the appropriate one at compile -+ * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined -+ * the generic code is used. -+ */ -+#ifdef PNG_FILTER_OPTIMIZATIONS -+PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr, -+ unsigned int bpp), PNG_EMPTY); -+ /* Just declare the optimization that will be used */ -+#else -+ /* List *all* the possible optimizations here - this branch is required if -+ * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in -+ * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. -+ */ -+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, -+ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -+#endif -+ -+/* Maintainer: Put new private prototypes here ^ */ - - #include "pngdebug.h" - -@@ -1383,4 +1968,5 @@ - } - #endif - -+#endif /* PNG_VERSION_INFO_ONLY */ - #endif /* PNGPRIV_H */ ---- ./jdk/src/share/native/sun/awt/libpng/pngread.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngread.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -43,6 +43,9 @@ - */ - - #include "pngpriv.h" -+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -+# include <errno.h> -+#endif - - #ifdef PNG_READ_SUPPORTED - -@@ -51,10 +54,12 @@ - png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) - { -- --#ifdef PNG_USER_MEM_SUPPORTED -- return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, -- warn_fn, NULL, NULL, NULL)); -+#ifndef PNG_USER_MEM_SUPPORTED -+ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, -+ error_fn, warn_fn, NULL, NULL, NULL); -+#else -+ return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, -+ warn_fn, NULL, NULL, NULL); - } - - /* Alternate create PNG structure for reading, and allocate any memory -@@ -65,134 +70,40 @@ - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) - { --#endif /* PNG_USER_MEM_SUPPORTED */ -- --#ifdef PNG_SETJMP_SUPPORTED -- volatile --#endif -- png_structp png_ptr; -- volatile int png_cleanup_needed = 0; -- --#ifdef PNG_SETJMP_SUPPORTED --#ifdef USE_FAR_KEYWORD -- jmp_buf tmp_jmpbuf; --#endif --#endif -- -- png_debug(1, "in png_create_read_struct"); -- --#ifdef PNG_USER_MEM_SUPPORTED -- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, -- malloc_fn, mem_ptr); --#else -- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); --#endif -- if (png_ptr == NULL) -- return (NULL); -- -- /* Added at libpng-1.2.6 */ --#ifdef PNG_USER_LIMITS_SUPPORTED -- png_ptr->user_width_max = PNG_USER_WIDTH_MAX; -- png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; -- --# ifdef PNG_USER_CHUNK_CACHE_MAX -- /* Added at libpng-1.2.43 and 1.4.0 */ -- png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; --# endif -- --# ifdef PNG_SET_USER_CHUNK_MALLOC_MAX -- /* Added at libpng-1.2.43 and 1.4.1 */ -- png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; --# endif --#endif -- --#ifdef PNG_SETJMP_SUPPORTED --/* Applications that neglect to set up their own setjmp() and then -- encounter a png_error() will longjmp here. Since the jmpbuf is -- then meaningless we abort instead of returning. */ --#ifdef USE_FAR_KEYWORD -- if (setjmp(tmp_jmpbuf)) --#else -- if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ --#endif -- PNG_ABORT(); --#ifdef USE_FAR_KEYWORD -- png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); --#endif --#endif /* PNG_SETJMP_SUPPORTED */ -- --#ifdef PNG_USER_MEM_SUPPORTED -- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); --#endif -- -- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); -- -- /* Call the general version checker (shared with read and write code): */ -- if (!png_user_version_check(png_ptr, user_png_ver)) -- png_cleanup_needed = 1; -- -- if (!png_cleanup_needed) -+ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, -+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -+#endif /* USER_MEM */ -+ -+ if (png_ptr != NULL) - { -- /* Initialize zbuf - compression buffer */ -- png_ptr->zbuf_size = PNG_ZBUF_SIZE; -- png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); -- -- if (png_ptr->zbuf == NULL) -- png_cleanup_needed = 1; -+ png_ptr->mode = PNG_IS_READ_STRUCT; -+ -+ /* Added in libpng-1.6.0; this can be used to detect a read structure if -+ * required (it will be zero in a write structure.) -+ */ -+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+ png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; -+# endif -+ -+# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED -+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; -+ -+ /* In stable builds only warn if an application error can be completely -+ * handled. -+ */ -+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC -+ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; -+# endif -+# endif -+ -+ /* TODO: delay this, it can be done in png_init_io (if the app doesn't -+ * do it itself) avoiding setting the default function if it is not -+ * required. -+ */ -+ png_set_read_fn(png_ptr, NULL, NULL); - } - -- png_ptr->zstream.zalloc = png_zalloc; -- png_ptr->zstream.zfree = png_zfree; -- png_ptr->zstream.opaque = (voidpf)png_ptr; -- -- if (!png_cleanup_needed) -- { -- switch (inflateInit(&png_ptr->zstream)) -- { -- case Z_OK: -- break; /* Do nothing */ -- -- case Z_MEM_ERROR: -- png_warning(png_ptr, "zlib memory error"); -- png_cleanup_needed = 1; -- break; -- -- case Z_STREAM_ERROR: -- png_warning(png_ptr, "zlib stream error"); -- png_cleanup_needed = 1; -- break; -- -- case Z_VERSION_ERROR: -- png_warning(png_ptr, "zlib version error"); -- png_cleanup_needed = 1; -- break; -- -- default: png_warning(png_ptr, "Unknown zlib error"); -- png_cleanup_needed = 1; -- } -- } -- -- if (png_cleanup_needed) -- { -- /* Clean up PNG structure and deallocate any memory. */ -- png_free(png_ptr, png_ptr->zbuf); -- png_ptr->zbuf = NULL; --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)png_ptr, -- (png_free_ptr)free_fn, (png_voidp)mem_ptr); --#else -- png_destroy_struct((png_voidp)png_ptr); --#endif -- return (NULL); -- } -- -- png_ptr->zstream.next_out = png_ptr->zbuf; -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -- -- png_set_read_fn(png_ptr, NULL, NULL); -- -- -- return (png_ptr); -+ return png_ptr; - } - - -@@ -206,8 +117,12 @@ - * read if it is determined that this isn't a valid PNG file. - */ - void PNGAPI --png_read_info(png_structp png_ptr, png_infop info_ptr) -+png_read_info(png_structrp png_ptr, png_inforp info_ptr) - { -+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+ int keep; -+#endif -+ - png_debug(1, "in png_read_info"); - - if (png_ptr == NULL || info_ptr == NULL) -@@ -218,231 +133,179 @@ - - for (;;) - { -- PNG_IHDR; -- PNG_IDAT; -- PNG_IEND; -- PNG_PLTE; --#ifdef PNG_READ_bKGD_SUPPORTED -- PNG_bKGD; --#endif --#ifdef PNG_READ_cHRM_SUPPORTED -- PNG_cHRM; --#endif --#ifdef PNG_READ_gAMA_SUPPORTED -- PNG_gAMA; --#endif --#ifdef PNG_READ_hIST_SUPPORTED -- PNG_hIST; --#endif --#ifdef PNG_READ_iCCP_SUPPORTED -- PNG_iCCP; --#endif --#ifdef PNG_READ_iTXt_SUPPORTED -- PNG_iTXt; --#endif --#ifdef PNG_READ_oFFs_SUPPORTED -- PNG_oFFs; --#endif --#ifdef PNG_READ_pCAL_SUPPORTED -- PNG_pCAL; --#endif --#ifdef PNG_READ_pHYs_SUPPORTED -- PNG_pHYs; --#endif --#ifdef PNG_READ_sBIT_SUPPORTED -- PNG_sBIT; --#endif --#ifdef PNG_READ_sCAL_SUPPORTED -- PNG_sCAL; --#endif --#ifdef PNG_READ_sPLT_SUPPORTED -- PNG_sPLT; --#endif --#ifdef PNG_READ_sRGB_SUPPORTED -- PNG_sRGB; --#endif --#ifdef PNG_READ_tEXt_SUPPORTED -- PNG_tEXt; --#endif --#ifdef PNG_READ_tIME_SUPPORTED -- PNG_tIME; --#endif --#ifdef PNG_READ_tRNS_SUPPORTED -- PNG_tRNS; --#endif --#ifdef PNG_READ_zTXt_SUPPORTED -- PNG_zTXt; --#endif - png_uint_32 length = png_read_chunk_header(png_ptr); -- PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; -+ png_uint_32 chunk_name = png_ptr->chunk_name; -+ -+ /* IDAT logic needs to happen here to simplify getting the two flags -+ * right. -+ */ -+ if (chunk_name == png_IDAT) -+ { -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "Missing IHDR before IDAT"); -+ -+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -+ (png_ptr->mode & PNG_HAVE_PLTE) == 0) -+ png_chunk_error(png_ptr, "Missing PLTE before IDAT"); -+ -+ else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) -+ png_chunk_benign_error(png_ptr, "Too many IDATs found"); -+ -+ png_ptr->mode |= PNG_HAVE_IDAT; -+ } -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) -+ png_ptr->mode |= PNG_AFTER_IDAT; - - /* This should be a binary subdivision search or a hash for - * matching the chunk name rather than a linear search. - */ -- if (!png_memcmp(chunk_name, png_IDAT, 4)) -- if (png_ptr->mode & PNG_AFTER_IDAT) -- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; -- -- if (!png_memcmp(chunk_name, png_IHDR, 4)) -+ if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - -- else if (!png_memcmp(chunk_name, png_IEND, 4)) -+ else if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); - - #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- else if (png_handle_as_unknown(png_ptr, chunk_name)) -+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { -- if (!png_memcmp(chunk_name, png_IDAT, 4)) -- png_ptr->mode |= PNG_HAVE_IDAT; -- -- png_handle_unknown(png_ptr, info_ptr, length); -- -- if (!png_memcmp(chunk_name, png_PLTE, 4)) -+ png_handle_unknown(png_ptr, info_ptr, length, keep); -+ -+ if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - -- else if (!png_memcmp(chunk_name, png_IDAT, 4)) -+ else if (chunk_name == png_IDAT) - { -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before IDAT"); -- -- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -- !(png_ptr->mode & PNG_HAVE_PLTE)) -- png_error(png_ptr, "Missing PLTE before IDAT"); -- -+ png_ptr->idat_size = 0; /* It has been consumed */ - break; - } - } - #endif -- else if (!png_memcmp(chunk_name, png_PLTE, 4)) -+ else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - -- else if (!png_memcmp(chunk_name, png_IDAT, 4)) -+ else if (chunk_name == png_IDAT) - { -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before IDAT"); -- -- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -- !(png_ptr->mode & PNG_HAVE_PLTE)) -- png_error(png_ptr, "Missing PLTE before IDAT"); -- - png_ptr->idat_size = length; -- png_ptr->mode |= PNG_HAVE_IDAT; - break; - } - - #ifdef PNG_READ_bKGD_SUPPORTED -- else if (!png_memcmp(chunk_name, png_bKGD, 4)) -+ else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_cHRM_SUPPORTED -- else if (!png_memcmp(chunk_name, png_cHRM, 4)) -+ else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_gAMA_SUPPORTED -- else if (!png_memcmp(chunk_name, png_gAMA, 4)) -+ else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_hIST_SUPPORTED -- else if (!png_memcmp(chunk_name, png_hIST, 4)) -+ else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_oFFs_SUPPORTED -- else if (!png_memcmp(chunk_name, png_oFFs, 4)) -+ else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_pCAL_SUPPORTED -- else if (!png_memcmp(chunk_name, png_pCAL, 4)) -+ else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sCAL_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sCAL, 4)) -+ else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_pHYs_SUPPORTED -- else if (!png_memcmp(chunk_name, png_pHYs, 4)) -+ else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sBIT_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sBIT, 4)) -+ else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sRGB_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sRGB, 4)) -+ else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_iCCP_SUPPORTED -- else if (!png_memcmp(chunk_name, png_iCCP, 4)) -+ else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sPLT_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sPLT, 4)) -+ else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_tEXt_SUPPORTED -- else if (!png_memcmp(chunk_name, png_tEXt, 4)) -+ else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_tIME_SUPPORTED -- else if (!png_memcmp(chunk_name, png_tIME, 4)) -+ else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_tRNS_SUPPORTED -- else if (!png_memcmp(chunk_name, png_tRNS, 4)) -+ else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_zTXt_SUPPORTED -- else if (!png_memcmp(chunk_name, png_zTXt, 4)) -+ else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_iTXt_SUPPORTED -- else if (!png_memcmp(chunk_name, png_iTXt, 4)) -+ else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); - #endif - - else -- png_handle_unknown(png_ptr, info_ptr, length); -+ png_handle_unknown(png_ptr, info_ptr, length, -+ PNG_HANDLE_CHUNK_AS_DEFAULT); - } - } --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -+#endif /* SEQUENTIAL_READ */ - - /* Optional call to update the users info_ptr structure */ - void PNGAPI --png_read_update_info(png_structp png_ptr, png_infop info_ptr) -+png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) - { - png_debug(1, "in png_read_update_info"); - -- if (png_ptr == NULL) -- return; -- -- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) -- png_read_start_row(png_ptr); -- -- else -- png_warning(png_ptr, -- "Ignoring extra png_read_update_info() call;" -- " row buffer not reallocated"); -- --#ifdef PNG_READ_TRANSFORMS_SUPPORTED -- png_read_transform_info(png_ptr, info_ptr); --#else -- PNG_UNUSED(info_ptr) --#endif -+ if (png_ptr != NULL) -+ { -+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) -+ { -+ png_read_start_row(png_ptr); -+ -+# ifdef PNG_READ_TRANSFORMS_SUPPORTED -+ png_read_transform_info(png_ptr, info_ptr); -+# else -+ PNG_UNUSED(info_ptr) -+# endif -+ } -+ -+ /* New in 1.6.0 this avoids the bug of doing the initializations twice */ -+ else -+ png_app_error(png_ptr, -+ "png_read_update_info/png_start_read_image: duplicate call"); -+ } - } - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED -@@ -452,86 +315,166 @@ - * If the user doesn't call this, we will do it ourselves. - */ - void PNGAPI --png_start_read_image(png_structp png_ptr) -+png_start_read_image(png_structrp png_ptr) - { - png_debug(1, "in png_start_read_image"); - -+ if (png_ptr != NULL) -+ { -+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) -+ png_read_start_row(png_ptr); -+ -+ /* New in 1.6.0 this avoids the bug of doing the initializations twice */ -+ else -+ png_app_error(png_ptr, -+ "png_start_read_image/png_read_update_info: duplicate call"); -+ } -+} -+#endif /* SEQUENTIAL_READ */ -+ -+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+#ifdef PNG_MNG_FEATURES_SUPPORTED -+/* Undoes intrapixel differencing, -+ * NOTE: this is apparently only supported in the 'sequential' reader. -+ */ -+static void -+png_do_read_intrapixel(png_row_infop row_info, png_bytep row) -+{ -+ png_debug(1, "in png_do_read_intrapixel"); -+ -+ if ( -+ (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) -+ { -+ int bytes_per_pixel; -+ png_uint_32 row_width = row_info->width; -+ -+ if (row_info->bit_depth == 8) -+ { -+ png_bytep rp; -+ png_uint_32 i; -+ -+ if (row_info->color_type == PNG_COLOR_TYPE_RGB) -+ bytes_per_pixel = 3; -+ -+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -+ bytes_per_pixel = 4; -+ -+ else -+ return; -+ -+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -+ { -+ *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); -+ *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); -+ } -+ } -+ else if (row_info->bit_depth == 16) -+ { -+ png_bytep rp; -+ png_uint_32 i; -+ -+ if (row_info->color_type == PNG_COLOR_TYPE_RGB) -+ bytes_per_pixel = 6; -+ -+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -+ bytes_per_pixel = 8; -+ -+ else -+ return; -+ -+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -+ { -+ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); -+ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); -+ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); -+ png_uint_32 red = (s0 + s1 + 65536) & 0xffff; -+ png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; -+ *(rp ) = (png_byte)((red >> 8) & 0xff); -+ *(rp + 1) = (png_byte)(red & 0xff); -+ *(rp + 4) = (png_byte)((blue >> 8) & 0xff); -+ *(rp + 5) = (png_byte)(blue & 0xff); -+ } -+ } -+ } -+} -+#endif /* MNG_FEATURES */ -+ -+void PNGAPI -+png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) -+{ -+ png_row_info row_info; -+ - if (png_ptr == NULL) - return; - -- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) -- png_read_start_row(png_ptr); -- else -- png_warning(png_ptr, -- "Ignoring extra png_start_read_image() call;" -- " row buffer not reallocated"); --} --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -- --#ifdef PNG_SEQUENTIAL_READ_SUPPORTED --void PNGAPI --png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) --{ -- PNG_IDAT; --#ifdef PNG_READ_INTERLACING_SUPPORTED -- PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, -- 0xff}; -- PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; --#endif -- int ret; -- -- if (png_ptr == NULL) -- return; -- - png_debug2(1, "in png_read_row (row %lu, pass %d)", - (unsigned long)png_ptr->row_number, png_ptr->pass); - -- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) -+ /* png_read_start_row sets the information (in particular iwidth) for this -+ * interlace pass. -+ */ -+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - png_read_start_row(png_ptr); - -+ /* 1.5.6: row_info moved out of png_struct to a local here. */ -+ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ -+ row_info.color_type = png_ptr->color_type; -+ row_info.bit_depth = png_ptr->bit_depth; -+ row_info.channels = png_ptr->channels; -+ row_info.pixel_depth = png_ptr->pixel_depth; -+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); -+ -+#ifdef PNG_WARNINGS_SUPPORTED - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Check for transforms that have been set but were defined out */ - #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) -- if (png_ptr->transformations & PNG_INVERT_MONO) -+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); - #endif - - #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) -- if (png_ptr->transformations & PNG_FILLER) -+ if ((png_ptr->transformations & PNG_FILLER) != 0) - png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); - #endif - - #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - !defined(PNG_READ_PACKSWAP_SUPPORTED) -- if (png_ptr->transformations & PNG_PACKSWAP) -+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); - #endif - - #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) -- if (png_ptr->transformations & PNG_PACK) -+ if ((png_ptr->transformations & PNG_PACK) != 0) - png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); - #endif - - #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) -- if (png_ptr->transformations & PNG_SHIFT) -+ if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); - #endif - - #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) -- if (png_ptr->transformations & PNG_BGR) -+ if ((png_ptr->transformations & PNG_BGR) != 0) - png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); - #endif - - #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) -- if (png_ptr->transformations & PNG_SWAP_BYTES) -+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); - #endif - } -+#endif /* WARNINGS */ - - #ifdef PNG_READ_INTERLACING_SUPPORTED -- /* If interlaced and we do not need a new row, combine row and return */ -- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) -+ /* If interlaced and we do not need a new row, combine row and return. -+ * Notice that the pixels we have from previous rows have been transformed -+ * already; we can only combine like with like (transformed or -+ * untransformed) and, because of the libpng API for interlaced images, this -+ * means we must transform before de-interlacing. -+ */ -+ if (png_ptr->interlaced != 0 && -+ (png_ptr->transformations & PNG_INTERLACE) != 0) - { - switch (png_ptr->pass) - { -@@ -539,8 +482,7 @@ - if (png_ptr->row_number & 0x07) - { - if (dsp_row != NULL) -- png_combine_row(png_ptr, dsp_row, -- png_pass_dsp_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, dsp_row, 1/*display*/); - png_read_finish_row(png_ptr); - return; - } -@@ -550,8 +492,7 @@ - if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) - { - if (dsp_row != NULL) -- png_combine_row(png_ptr, dsp_row, -- png_pass_dsp_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; -@@ -562,8 +503,7 @@ - if ((png_ptr->row_number & 0x07) != 4) - { - if (dsp_row != NULL && (png_ptr->row_number & 4)) -- png_combine_row(png_ptr, dsp_row, -- png_pass_dsp_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; -@@ -574,8 +514,7 @@ - if ((png_ptr->row_number & 3) || png_ptr->width < 3) - { - if (dsp_row != NULL) -- png_combine_row(png_ptr, dsp_row, -- png_pass_dsp_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; -@@ -586,19 +525,18 @@ - if ((png_ptr->row_number & 3) != 2) - { - if (dsp_row != NULL && (png_ptr->row_number & 2)) -- png_combine_row(png_ptr, dsp_row, -- png_pass_dsp_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; -+ - case 5: - if ((png_ptr->row_number & 1) || png_ptr->width < 2) - { - if (dsp_row != NULL) -- png_combine_row(png_ptr, dsp_row, -- png_pass_dsp_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; -@@ -607,7 +545,7 @@ - - default: - case 6: -- if (!(png_ptr->row_number & 1)) -+ if ((png_ptr->row_number & 1) == 0) - { - png_read_finish_row(png_ptr); - return; -@@ -617,117 +555,85 @@ - } - #endif - -- if (!(png_ptr->mode & PNG_HAVE_IDAT)) -+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_error(png_ptr, "Invalid attempt to read row data"); - -- png_ptr->zstream.next_out = png_ptr->row_buf; -- png_ptr->zstream.avail_out = -- (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, -- png_ptr->iwidth) + 1); -- -- do -+ /* Fill the row with IDAT data: */ -+ png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); -+ -+ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) - { -- if (!(png_ptr->zstream.avail_in)) -- { -- while (!png_ptr->idat_size) -- { -- png_crc_finish(png_ptr, 0); -- -- png_ptr->idat_size = png_read_chunk_header(png_ptr); -- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -- png_error(png_ptr, "Not enough image data"); -- } -- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; -- png_ptr->zstream.next_in = png_ptr->zbuf; -- if (png_ptr->zbuf_size > png_ptr->idat_size) -- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; -- png_crc_read(png_ptr, png_ptr->zbuf, -- (png_size_t)png_ptr->zstream.avail_in); -- png_ptr->idat_size -= png_ptr->zstream.avail_in; -- } -- -- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); -- -- if (ret == Z_STREAM_END) -- { -- if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || -- png_ptr->idat_size) -- png_benign_error(png_ptr, "Extra compressed data"); -- png_ptr->mode |= PNG_AFTER_IDAT; -- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -- break; -- } -- -- if (ret != Z_OK) -- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : -- "Decompression error"); -- -- } while (png_ptr->zstream.avail_out); -- -- png_ptr->row_info.color_type = png_ptr->color_type; -- png_ptr->row_info.width = png_ptr->iwidth; -- png_ptr->row_info.channels = png_ptr->channels; -- png_ptr->row_info.bit_depth = png_ptr->bit_depth; -- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; -- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, -- png_ptr->row_info.width); -- -- if (png_ptr->row_buf[0]) -- png_read_filter_row(png_ptr, &(png_ptr->row_info), -- png_ptr->row_buf + 1, png_ptr->prev_row + 1, -- (int)(png_ptr->row_buf[0])); -- -- png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); -+ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) -+ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, -+ png_ptr->prev_row + 1, png_ptr->row_buf[0]); -+ else -+ png_error(png_ptr, "bad adaptive filter value"); -+ } -+ -+ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before -+ * 1.5.6, while the buffer really is this big in current versions of libpng -+ * it may not be in the future, so this was changed just to copy the -+ * interlaced count: -+ */ -+ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - - #ifdef PNG_MNG_FEATURES_SUPPORTED -- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && -+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ -- png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); -+ png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); - } - #endif - -- - #ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations) -- png_do_read_transformations(png_ptr); -+ png_do_read_transformations(png_ptr, &row_info); - #endif - -+ /* The transformed pixel depth should match the depth now in row_info. */ -+ if (png_ptr->transformed_pixel_depth == 0) -+ { -+ png_ptr->transformed_pixel_depth = row_info.pixel_depth; -+ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) -+ png_error(png_ptr, "sequential row overflow"); -+ } -+ -+ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) -+ png_error(png_ptr, "internal sequential row size calculation error"); -+ - #ifdef PNG_READ_INTERLACING_SUPPORTED -- /* Blow up interlaced rows to full size */ -- if (png_ptr->interlaced && -- (png_ptr->transformations & PNG_INTERLACE)) -+ /* Expand interlaced rows to full size */ -+ if (png_ptr->interlaced != 0 && -+ (png_ptr->transformations & PNG_INTERLACE) != 0) - { - if (png_ptr->pass < 6) -- /* Old interface (pre-1.0.9): -- * png_do_read_interlace(&(png_ptr->row_info), -- * png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); -- */ -- png_do_read_interlace(png_ptr); -+ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, -+ png_ptr->transformations); - - if (dsp_row != NULL) -- png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, dsp_row, 1/*display*/); - - if (row != NULL) -- png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]); -+ png_combine_row(png_ptr, row, 0/*row*/); - } - - else - #endif - { - if (row != NULL) -- png_combine_row(png_ptr, row, 0xff); -+ png_combine_row(png_ptr, row, -1/*ignored*/); - - if (dsp_row != NULL) -- png_combine_row(png_ptr, dsp_row, 0xff); -+ png_combine_row(png_ptr, dsp_row, -1/*ignored*/); - } - png_read_finish_row(png_ptr); - - if (png_ptr->read_row_fn != NULL) - (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); -+ - } --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -+#endif /* SEQUENTIAL_READ */ - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read one or more rows of image data. If the image is interlaced, -@@ -755,7 +661,7 @@ - */ - - void PNGAPI --png_read_rows(png_structp png_ptr, png_bytepp row, -+png_read_rows(png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows) - { - png_uint_32 i; -@@ -794,7 +700,7 @@ - dp++; - } - } --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -+#endif /* SEQUENTIAL_READ */ - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read the entire image. If the image has an alpha channel or a tRNS -@@ -810,7 +716,7 @@ - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ - void PNGAPI --png_read_image(png_structp png_ptr, png_bytepp image) -+png_read_image(png_structrp png_ptr, png_bytepp image) - { - png_uint_32 i, image_height; - int pass, j; -@@ -822,7 +728,7 @@ - return; - - #ifdef PNG_READ_INTERLACING_SUPPORTED -- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) -+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - { - pass = png_set_interlace_handling(png_ptr); - /* And make sure transforms are initialized. */ -@@ -830,7 +736,8 @@ - } - else - { -- if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) -+ if (png_ptr->interlaced != 0 && -+ (png_ptr->transformations & PNG_INTERLACE) == 0) - { - /* Caller called png_start_read_image or png_read_update_info without - * first turning on the PNG_INTERLACE transform. We can fix this here, -@@ -867,7 +774,7 @@ - } - } - } --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -+#endif /* SEQUENTIAL_READ */ - - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - /* Read the end of the PNG file. Will not read past the end of the -@@ -875,416 +782,261 @@ - * or time information at the end of the file, if info is not NULL. - */ - void PNGAPI --png_read_end(png_structp png_ptr, png_infop info_ptr) -+png_read_end(png_structrp png_ptr, png_inforp info_ptr) - { -+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+ int keep; -+#endif -+ - png_debug(1, "in png_read_end"); - - if (png_ptr == NULL) - return; - -- png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ -+ /* If png_read_end is called in the middle of reading the rows there may -+ * still be pending IDAT data and an owned zstream. Deal with this here. -+ */ -+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+ if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) -+#endif -+ png_read_finish_IDAT(png_ptr); -+ -+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED -+ /* Report invalid palette index; added at libng-1.5.10 */ -+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -+ png_ptr->num_palette_max > png_ptr->num_palette) -+ png_benign_error(png_ptr, "Read palette index exceeding num_palette"); -+#endif - - do - { -- PNG_IHDR; -- PNG_IDAT; -- PNG_IEND; -- PNG_PLTE; --#ifdef PNG_READ_bKGD_SUPPORTED -- PNG_bKGD; --#endif --#ifdef PNG_READ_cHRM_SUPPORTED -- PNG_cHRM; --#endif --#ifdef PNG_READ_gAMA_SUPPORTED -- PNG_gAMA; --#endif --#ifdef PNG_READ_hIST_SUPPORTED -- PNG_hIST; --#endif --#ifdef PNG_READ_iCCP_SUPPORTED -- PNG_iCCP; --#endif --#ifdef PNG_READ_iTXt_SUPPORTED -- PNG_iTXt; --#endif --#ifdef PNG_READ_oFFs_SUPPORTED -- PNG_oFFs; --#endif --#ifdef PNG_READ_pCAL_SUPPORTED -- PNG_pCAL; --#endif --#ifdef PNG_READ_pHYs_SUPPORTED -- PNG_pHYs; --#endif --#ifdef PNG_READ_sBIT_SUPPORTED -- PNG_sBIT; --#endif --#ifdef PNG_READ_sCAL_SUPPORTED -- PNG_sCAL; --#endif --#ifdef PNG_READ_sPLT_SUPPORTED -- PNG_sPLT; --#endif --#ifdef PNG_READ_sRGB_SUPPORTED -- PNG_sRGB; --#endif --#ifdef PNG_READ_tEXt_SUPPORTED -- PNG_tEXt; --#endif --#ifdef PNG_READ_tIME_SUPPORTED -- PNG_tIME; --#endif --#ifdef PNG_READ_tRNS_SUPPORTED -- PNG_tRNS; --#endif --#ifdef PNG_READ_zTXt_SUPPORTED -- PNG_zTXt; --#endif - png_uint_32 length = png_read_chunk_header(png_ptr); -- PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; -- -- if (!png_memcmp(chunk_name, png_IHDR, 4)) -+ png_uint_32 chunk_name = png_ptr->chunk_name; -+ -+ if (chunk_name == png_IEND) -+ png_handle_IEND(png_ptr, info_ptr, length); -+ -+ else if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - -- else if (!png_memcmp(chunk_name, png_IEND, 4)) -- png_handle_IEND(png_ptr, info_ptr, length); -+ else if (info_ptr == NULL) -+ png_crc_finish(png_ptr, length); - - #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- else if (png_handle_as_unknown(png_ptr, chunk_name)) -+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { -- if (!png_memcmp(chunk_name, png_IDAT, 4)) -+ if (chunk_name == png_IDAT) - { -- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) -+ if ((length > 0) || -+ (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "Too many IDATs found"); - } -- png_handle_unknown(png_ptr, info_ptr, length); -- if (!png_memcmp(chunk_name, png_PLTE, 4)) -+ png_handle_unknown(png_ptr, info_ptr, length, keep); -+ if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - } - #endif - -- else if (!png_memcmp(chunk_name, png_IDAT, 4)) -+ else if (chunk_name == png_IDAT) - { - /* Zero length IDATs are legal after the last IDAT has been - * read, but not after other chunks have been read. - */ -- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) -+ if ((length > 0) || -+ (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "Too many IDATs found"); - - png_crc_finish(png_ptr, length); - } -- else if (!png_memcmp(chunk_name, png_PLTE, 4)) -+ else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - - #ifdef PNG_READ_bKGD_SUPPORTED -- else if (!png_memcmp(chunk_name, png_bKGD, 4)) -+ else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_cHRM_SUPPORTED -- else if (!png_memcmp(chunk_name, png_cHRM, 4)) -+ else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_gAMA_SUPPORTED -- else if (!png_memcmp(chunk_name, png_gAMA, 4)) -+ else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_hIST_SUPPORTED -- else if (!png_memcmp(chunk_name, png_hIST, 4)) -+ else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_oFFs_SUPPORTED -- else if (!png_memcmp(chunk_name, png_oFFs, 4)) -+ else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_pCAL_SUPPORTED -- else if (!png_memcmp(chunk_name, png_pCAL, 4)) -+ else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sCAL_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sCAL, 4)) -+ else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_pHYs_SUPPORTED -- else if (!png_memcmp(chunk_name, png_pHYs, 4)) -+ else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sBIT_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sBIT, 4)) -+ else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sRGB_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sRGB, 4)) -+ else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_iCCP_SUPPORTED -- else if (!png_memcmp(chunk_name, png_iCCP, 4)) -+ else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_sPLT_SUPPORTED -- else if (!png_memcmp(chunk_name, png_sPLT, 4)) -+ else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_tEXt_SUPPORTED -- else if (!png_memcmp(chunk_name, png_tEXt, 4)) -+ else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_tIME_SUPPORTED -- else if (!png_memcmp(chunk_name, png_tIME, 4)) -+ else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_tRNS_SUPPORTED -- else if (!png_memcmp(chunk_name, png_tRNS, 4)) -+ else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_zTXt_SUPPORTED -- else if (!png_memcmp(chunk_name, png_zTXt, 4)) -+ else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); - #endif - - #ifdef PNG_READ_iTXt_SUPPORTED -- else if (!png_memcmp(chunk_name, png_iTXt, 4)) -+ else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); - #endif - - else -- png_handle_unknown(png_ptr, info_ptr, length); -- } while (!(png_ptr->mode & PNG_HAVE_IEND)); -+ png_handle_unknown(png_ptr, info_ptr, length, -+ PNG_HANDLE_CHUNK_AS_DEFAULT); -+ } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); - } --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -+#endif /* SEQUENTIAL_READ */ -+ -+/* Free all memory used in the read struct */ -+static void -+png_read_destroy(png_structrp png_ptr) -+{ -+ png_debug(1, "in png_read_destroy"); -+ -+#ifdef PNG_READ_GAMMA_SUPPORTED -+ png_destroy_gamma_table(png_ptr); -+#endif -+ -+ png_free(png_ptr, png_ptr->big_row_buf); -+ png_ptr->big_row_buf = NULL; -+ png_free(png_ptr, png_ptr->big_prev_row); -+ png_ptr->big_prev_row = NULL; -+ png_free(png_ptr, png_ptr->read_buffer); -+ png_ptr->read_buffer = NULL; -+ -+#ifdef PNG_READ_QUANTIZE_SUPPORTED -+ png_free(png_ptr, png_ptr->palette_lookup); -+ png_ptr->palette_lookup = NULL; -+ png_free(png_ptr, png_ptr->quantize_index); -+ png_ptr->quantize_index = NULL; -+#endif -+ -+ if ((png_ptr->free_me & PNG_FREE_PLTE) != 0) -+ { -+ png_zfree(png_ptr, png_ptr->palette); -+ png_ptr->palette = NULL; -+ } -+ png_ptr->free_me &= ~PNG_FREE_PLTE; -+ -+#if defined(PNG_tRNS_SUPPORTED) || \ -+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -+ if ((png_ptr->free_me & PNG_FREE_TRNS) != 0) -+ { -+ png_free(png_ptr, png_ptr->trans_alpha); -+ png_ptr->trans_alpha = NULL; -+ } -+ png_ptr->free_me &= ~PNG_FREE_TRNS; -+#endif -+ -+ inflateEnd(&png_ptr->zstream); -+ -+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -+ png_free(png_ptr, png_ptr->save_buffer); -+ png_ptr->save_buffer = NULL; -+#endif -+ -+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \ -+ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) -+ png_free(png_ptr, png_ptr->unknown_chunk.data); -+ png_ptr->unknown_chunk.data = NULL; -+#endif -+ -+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+ png_free(png_ptr, png_ptr->chunk_list); -+ png_ptr->chunk_list = NULL; -+#endif -+ -+ /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error -+ * callbacks are still set at this point. They are required to complete the -+ * destruction of the png_struct itself. -+ */ -+} - - /* Free all memory used by the read */ - void PNGAPI - png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, - png_infopp end_info_ptr_ptr) - { -- png_structp png_ptr = NULL; -- png_infop info_ptr = NULL, end_info_ptr = NULL; --#ifdef PNG_USER_MEM_SUPPORTED -- png_free_ptr free_fn = NULL; -- png_voidp mem_ptr = NULL; --#endif -+ png_structrp png_ptr = NULL; - - png_debug(1, "in png_destroy_read_struct"); - - if (png_ptr_ptr != NULL) - png_ptr = *png_ptr_ptr; -+ - if (png_ptr == NULL) - return; - --#ifdef PNG_USER_MEM_SUPPORTED -- free_fn = png_ptr->free_fn; -- mem_ptr = png_ptr->mem_ptr; --#endif -- -- if (info_ptr_ptr != NULL) -- info_ptr = *info_ptr_ptr; -- -- if (end_info_ptr_ptr != NULL) -- end_info_ptr = *end_info_ptr_ptr; -- -- png_read_destroy(png_ptr, info_ptr, end_info_ptr); -- -- if (info_ptr != NULL) -- { --#ifdef PNG_TEXT_SUPPORTED -- png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); --#endif -- --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, -- (png_voidp)mem_ptr); --#else -- png_destroy_struct((png_voidp)info_ptr); --#endif -- *info_ptr_ptr = NULL; -- } -- -- if (end_info_ptr != NULL) -- { --#ifdef PNG_READ_TEXT_SUPPORTED -- png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); --#endif --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, -- (png_voidp)mem_ptr); --#else -- png_destroy_struct((png_voidp)end_info_ptr); --#endif -- *end_info_ptr_ptr = NULL; -- } -- -- if (png_ptr != NULL) -- { --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, -- (png_voidp)mem_ptr); --#else -- png_destroy_struct((png_voidp)png_ptr); --#endif -- *png_ptr_ptr = NULL; -- } -+ /* libpng 1.6.0: use the API to destroy info structs to ensure consistent -+ * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. -+ * The extra was, apparently, unnecessary yet this hides memory leak bugs. -+ */ -+ png_destroy_info_struct(png_ptr, end_info_ptr_ptr); -+ png_destroy_info_struct(png_ptr, info_ptr_ptr); -+ -+ *png_ptr_ptr = NULL; -+ png_read_destroy(png_ptr); -+ png_destroy_png_struct(png_ptr); - } - --/* Free all memory used by the read (old method) */ --void /* PRIVATE */ --png_read_destroy(png_structp png_ptr, png_infop info_ptr, -- png_infop end_info_ptr) --{ --#ifdef PNG_SETJMP_SUPPORTED -- jmp_buf tmp_jmp; --#endif -- png_error_ptr error_fn; --#ifdef PNG_WARNINGS_SUPPORTED -- png_error_ptr warning_fn; --#endif -- png_voidp error_ptr; --#ifdef PNG_USER_MEM_SUPPORTED -- png_free_ptr free_fn; --#endif -- -- png_debug(1, "in png_read_destroy"); -- -- if (info_ptr != NULL) -- png_info_destroy(png_ptr, info_ptr); -- -- if (end_info_ptr != NULL) -- png_info_destroy(png_ptr, end_info_ptr); -- -- png_free(png_ptr, png_ptr->zbuf); -- png_free(png_ptr, png_ptr->big_row_buf); -- png_free(png_ptr, png_ptr->prev_row); -- png_free(png_ptr, png_ptr->chunkdata); -- --#ifdef PNG_READ_QUANTIZE_SUPPORTED -- png_free(png_ptr, png_ptr->palette_lookup); -- png_free(png_ptr, png_ptr->quantize_index); --#endif -- --#ifdef PNG_READ_GAMMA_SUPPORTED -- png_free(png_ptr, png_ptr->gamma_table); --#endif -- --#ifdef PNG_READ_BACKGROUND_SUPPORTED -- png_free(png_ptr, png_ptr->gamma_from_1); -- png_free(png_ptr, png_ptr->gamma_to_1); --#endif -- -- if (png_ptr->free_me & PNG_FREE_PLTE) -- png_zfree(png_ptr, png_ptr->palette); -- png_ptr->free_me &= ~PNG_FREE_PLTE; -- --#if defined(PNG_tRNS_SUPPORTED) || \ -- defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -- if (png_ptr->free_me & PNG_FREE_TRNS) -- png_free(png_ptr, png_ptr->trans_alpha); -- png_ptr->free_me &= ~PNG_FREE_TRNS; --#endif -- --#ifdef PNG_READ_hIST_SUPPORTED -- if (png_ptr->free_me & PNG_FREE_HIST) -- png_free(png_ptr, png_ptr->hist); -- png_ptr->free_me &= ~PNG_FREE_HIST; --#endif -- --#ifdef PNG_READ_GAMMA_SUPPORTED -- if (png_ptr->gamma_16_table != NULL) -- { -- int i; -- int istop = (1 << (8 - png_ptr->gamma_shift)); -- for (i = 0; i < istop; i++) -- { -- png_free(png_ptr, png_ptr->gamma_16_table[i]); -- } -- png_free(png_ptr, png_ptr->gamma_16_table); -- } -- --#ifdef PNG_READ_BACKGROUND_SUPPORTED -- if (png_ptr->gamma_16_from_1 != NULL) -- { -- int i; -- int istop = (1 << (8 - png_ptr->gamma_shift)); -- for (i = 0; i < istop; i++) -- { -- png_free(png_ptr, png_ptr->gamma_16_from_1[i]); -- } -- png_free(png_ptr, png_ptr->gamma_16_from_1); -- } -- if (png_ptr->gamma_16_to_1 != NULL) -- { -- int i; -- int istop = (1 << (8 - png_ptr->gamma_shift)); -- for (i = 0; i < istop; i++) -- { -- png_free(png_ptr, png_ptr->gamma_16_to_1[i]); -- } -- png_free(png_ptr, png_ptr->gamma_16_to_1); -- } --#endif --#endif -- -- inflateEnd(&png_ptr->zstream); -- --#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -- png_free(png_ptr, png_ptr->save_buffer); --#endif -- --#ifdef PNG_PROGRESSIVE_READ_SUPPORTED --#ifdef PNG_TEXT_SUPPORTED -- png_free(png_ptr, png_ptr->current_text); --#endif /* PNG_TEXT_SUPPORTED */ --#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -- -- /* Save the important info out of the png_struct, in case it is -- * being used again. -- */ --#ifdef PNG_SETJMP_SUPPORTED -- png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); --#endif -- -- error_fn = png_ptr->error_fn; --#ifdef PNG_WARNINGS_SUPPORTED -- warning_fn = png_ptr->warning_fn; --#endif -- error_ptr = png_ptr->error_ptr; --#ifdef PNG_USER_MEM_SUPPORTED -- free_fn = png_ptr->free_fn; --#endif -- -- png_memset(png_ptr, 0, png_sizeof(png_struct)); -- -- png_ptr->error_fn = error_fn; --#ifdef PNG_WARNINGS_SUPPORTED -- png_ptr->warning_fn = warning_fn; --#endif -- png_ptr->error_ptr = error_ptr; --#ifdef PNG_USER_MEM_SUPPORTED -- png_ptr->free_fn = free_fn; --#endif -- --#ifdef PNG_SETJMP_SUPPORTED -- png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); --#endif -- --} -- - void PNGAPI --png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) -+png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) - { - if (png_ptr == NULL) - return; -@@ -1296,12 +1048,10 @@ - #ifdef PNG_SEQUENTIAL_READ_SUPPORTED - #ifdef PNG_INFO_IMAGE_SUPPORTED - void PNGAPI --png_read_png(png_structp png_ptr, png_infop info_ptr, -+png_read_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, - voidp params) - { -- int row; -- - if (png_ptr == NULL || info_ptr == NULL) - return; - -@@ -1309,130 +1059,153 @@ - * PNG file before the first IDAT (image data chunk). - */ - png_read_info(png_ptr, info_ptr); -- if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) -+ if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep))) - png_error(png_ptr, "Image is too high to process with png_read_png()"); - - /* -------------- image transformations start here ------------------- */ -- --#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -+ /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM -+ * is not implemented. This will only happen in de-configured (non-default) -+ * libpng builds. The results can be unexpected - png_read_png may return -+ * short or mal-formed rows because the transform is skipped. -+ */ -+ - /* Tell libpng to strip 16-bit/color files down to 8 bits per color. - */ -- if (transforms & PNG_TRANSFORM_SCALE_16) -- { -+ if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) - /* Added at libpng-1.5.4. "strip_16" produces the same result that it - * did in earlier versions, while "scale_16" is now more accurate. - */ -+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_set_scale_16(png_ptr); -- } -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); - #endif - --#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* If both SCALE and STRIP are required pngrtran will effectively cancel the - * latter by doing SCALE first. This is ok and allows apps not to check for - * which is supported to get the right answer. - */ -- if (transforms & PNG_TRANSFORM_STRIP_16) -+ if ((transforms & PNG_TRANSFORM_STRIP_16) != 0) -+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - png_set_strip_16(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); - #endif - --#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - /* Strip alpha bytes from the input data without combining with - * the background (not recommended). - */ -- if (transforms & PNG_TRANSFORM_STRIP_ALPHA) -+ if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0) -+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - png_set_strip_alpha(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); - #endif - --#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) - /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single - * byte into separate bytes (useful for paletted and grayscale images). - */ -- if (transforms & PNG_TRANSFORM_PACKING) -+ if ((transforms & PNG_TRANSFORM_PACKING) != 0) -+#ifdef PNG_READ_PACK_SUPPORTED - png_set_packing(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); - #endif - --#ifdef PNG_READ_PACKSWAP_SUPPORTED - /* Change the order of packed pixels to least significant bit first - * (not useful if you are using png_set_packing). - */ -- if (transforms & PNG_TRANSFORM_PACKSWAP) -+ if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -+#ifdef PNG_READ_PACKSWAP_SUPPORTED - png_set_packswap(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); - #endif - --#ifdef PNG_READ_EXPAND_SUPPORTED - /* Expand paletted colors into true RGB triplets - * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel - * Expand paletted or RGB images with transparency to full alpha - * channels so the data will be available as RGBA quartets. - */ -- if (transforms & PNG_TRANSFORM_EXPAND) -- if ((png_ptr->bit_depth < 8) || -- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || -- (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) -- png_set_expand(png_ptr); -+ if ((transforms & PNG_TRANSFORM_EXPAND) != 0) -+#ifdef PNG_READ_EXPAND_SUPPORTED -+ png_set_expand(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); - #endif - - /* We don't handle background color or gamma transformation or quantizing. - */ - --#ifdef PNG_READ_INVERT_SUPPORTED - /* Invert monochrome files to have 0 as white and 1 as black - */ -- if (transforms & PNG_TRANSFORM_INVERT_MONO) -+ if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) -+#ifdef PNG_READ_INVERT_SUPPORTED - png_set_invert_mono(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); - #endif - --#ifdef PNG_READ_SHIFT_SUPPORTED - /* If you want to shift the pixel values from the range [0,255] or - * [0,65535] to the original [0,7] or [0,31], or whatever range the - * colors were originally in: - */ -- if ((transforms & PNG_TRANSFORM_SHIFT) -- && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) -- { -- png_color_8p sig_bit; -- -- png_get_sBIT(png_ptr, info_ptr, &sig_bit); -- png_set_shift(png_ptr, sig_bit); -- } -+ if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -+#ifdef PNG_READ_SHIFT_SUPPORTED -+ if ((info_ptr->valid & PNG_INFO_sBIT) != 0) -+ png_set_shift(png_ptr, &info_ptr->sig_bit); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); - #endif - -+ /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ -+ if ((transforms & PNG_TRANSFORM_BGR) != 0) - #ifdef PNG_READ_BGR_SUPPORTED -- /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ -- if (transforms & PNG_TRANSFORM_BGR) - png_set_bgr(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); - #endif - -+ /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ -+ if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) - #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -- /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ -- if (transforms & PNG_TRANSFORM_SWAP_ALPHA) - png_set_swap_alpha(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); - #endif - -+ /* Swap bytes of 16-bit files to least significant byte first */ -+ if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) - #ifdef PNG_READ_SWAP_SUPPORTED -- /* Swap bytes of 16-bit files to least significant byte first */ -- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) - png_set_swap(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); - #endif - - /* Added at libpng-1.2.41 */ -+ /* Invert the alpha channel from opacity to transparency */ -+ if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) - #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -- /* Invert the alpha channel from opacity to transparency */ -- if (transforms & PNG_TRANSFORM_INVERT_ALPHA) - png_set_invert_alpha(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); - #endif - - /* Added at libpng-1.2.41 */ -+ /* Expand grayscale image to RGB */ -+ if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0) - #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -- /* Expand grayscale image to RGB */ -- if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) - png_set_gray_to_rgb(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); - #endif - - /* Added at libpng-1.5.4 */ -+ if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0) - #ifdef PNG_READ_EXPAND_16_SUPPORTED -- if (transforms & PNG_TRANSFORM_EXPAND_16) - png_set_expand_16(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); - #endif - - /* We don't handle adding filler bytes */ -@@ -1455,16 +1228,17 @@ - { - png_uint_32 iptr; - -- info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, -- info_ptr->height * png_sizeof(png_bytep)); -+ info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr, -+ info_ptr->height * (sizeof (png_bytep)))); -+ - for (iptr=0; iptr<info_ptr->height; iptr++) - info_ptr->row_pointers[iptr] = NULL; - - info_ptr->free_me |= PNG_FREE_ROWS; - -- for (row = 0; row < (int)info_ptr->height; row++) -- info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, -- png_get_rowbytes(png_ptr, info_ptr)); -+ for (iptr = 0; iptr < info_ptr->height; iptr++) -+ info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, -+ png_malloc(png_ptr, info_ptr->rowbytes)); - } - - png_read_image(png_ptr, info_ptr->row_pointers); -@@ -1473,10 +1247,2903 @@ - /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end(png_ptr, info_ptr); - -- PNG_UNUSED(transforms) /* Quiet compiler warnings */ - PNG_UNUSED(params) -- - } --#endif /* PNG_INFO_IMAGE_SUPPORTED */ --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ --#endif /* PNG_READ_SUPPORTED */ -+#endif /* INFO_IMAGE */ -+#endif /* SEQUENTIAL_READ */ -+ -+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -+/* SIMPLIFIED READ -+ * -+ * This code currently relies on the sequential reader, though it could easily -+ * be made to work with the progressive one. -+ */ -+/* Arguments to png_image_finish_read: */ -+ -+/* Encoding of PNG data (used by the color-map code) */ -+# define P_NOTSET 0 /* File encoding not yet known */ -+# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ -+# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ -+# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ -+# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ -+ -+/* Color-map processing: after libpng has run on the PNG image further -+ * processing may be needed to convert the data to color-map indices. -+ */ -+#define PNG_CMAP_NONE 0 -+#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ -+#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ -+#define PNG_CMAP_RGB 3 /* Process RGB data */ -+#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ -+ -+/* The following document where the background is for each processing case. */ -+#define PNG_CMAP_NONE_BACKGROUND 256 -+#define PNG_CMAP_GA_BACKGROUND 231 -+#define PNG_CMAP_TRANS_BACKGROUND 254 -+#define PNG_CMAP_RGB_BACKGROUND 256 -+#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 -+ -+typedef struct -+{ -+ /* Arguments: */ -+ png_imagep image; -+ png_voidp buffer; -+ png_int_32 row_stride; -+ png_voidp colormap; -+ png_const_colorp background; -+ /* Local variables: */ -+ png_voidp local_row; -+ 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 */ -+ int colormap_processing; /* PNG_CMAP_ values above */ -+} png_image_read_control; -+ -+/* Do all the *safe* initialization - 'safe' means that png_error won't be -+ * called, so setting up the jmp_buf is not required. This means that anything -+ * called from here must *not* call png_malloc - it has to call png_malloc_warn -+ * instead so that control is returned safely back to this routine. -+ */ -+static int -+png_image_read_init(png_imagep image) -+{ -+ if (image->opaque == NULL) -+ { -+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, -+ png_safe_error, png_safe_warning); -+ -+ /* And set the rest of the structure to NULL to ensure that the various -+ * fields are consistent. -+ */ -+ memset(image, 0, (sizeof *image)); -+ image->version = PNG_IMAGE_VERSION; -+ -+ if (png_ptr != NULL) -+ { -+ png_infop info_ptr = png_create_info_struct(png_ptr); -+ -+ if (info_ptr != NULL) -+ { -+ png_controlp control = png_voidcast(png_controlp, -+ png_malloc_warn(png_ptr, (sizeof *control))); -+ -+ if (control != NULL) -+ { -+ memset(control, 0, (sizeof *control)); -+ -+ control->png_ptr = png_ptr; -+ control->info_ptr = info_ptr; -+ control->for_write = 0; -+ -+ image->opaque = control; -+ return 1; -+ } -+ -+ /* Error clean up */ -+ png_destroy_info_struct(png_ptr, &info_ptr); -+ } -+ -+ png_destroy_read_struct(&png_ptr, NULL, NULL); -+ } -+ -+ return png_image_error(image, "png_image_read: out of memory"); -+ } -+ -+ return png_image_error(image, "png_image_read: opaque pointer not NULL"); -+} -+ -+/* Utility to find the base format of a PNG file from a png_struct. */ -+static png_uint_32 -+png_image_format(png_structrp png_ptr) -+{ -+ png_uint_32 format = 0; -+ -+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) -+ format |= PNG_FORMAT_FLAG_COLOR; -+ -+ if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) -+ format |= PNG_FORMAT_FLAG_ALPHA; -+ -+ /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS -+ * sets the png_struct fields; that's all we are interested in here. The -+ * precise interaction with an app call to png_set_tRNS and PNG file reading -+ * is unclear. -+ */ -+ else if (png_ptr->num_trans > 0) -+ format |= PNG_FORMAT_FLAG_ALPHA; -+ -+ if (png_ptr->bit_depth == 16) -+ format |= PNG_FORMAT_FLAG_LINEAR; -+ -+ if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0) -+ format |= PNG_FORMAT_FLAG_COLORMAP; -+ -+ return format; -+} -+ -+/* Is the given gamma significantly different from sRGB? The test is the same -+ * one used in pngrtran.c when deciding whether to do gamma correction. The -+ * arithmetic optimizes the division by using the fact that the inverse of the -+ * file sRGB gamma is 2.2 -+ */ -+static int -+png_gamma_not_sRGB(png_fixed_point g) -+{ -+ if (g < PNG_FP_1) -+ { -+ /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ -+ if (g == 0) -+ return 0; -+ -+ return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); -+ } -+ -+ return 1; -+} -+ -+/* Do the main body of a 'png_image_begin_read' function; read the PNG file -+ * header and fill in all the information. This is executed in a safe context, -+ * unlike the init routine above. -+ */ -+static int -+png_image_read_header(png_voidp argument) -+{ -+ png_imagep image = png_voidcast(png_imagep, argument); -+ png_structrp png_ptr = image->opaque->png_ptr; -+ png_inforp info_ptr = image->opaque->info_ptr; -+ -+ png_set_benign_errors(png_ptr, 1/*warn*/); -+ png_read_info(png_ptr, info_ptr); -+ -+ /* Do this the fast way; just read directly out of png_struct. */ -+ image->width = png_ptr->width; -+ image->height = png_ptr->height; -+ -+ { -+ png_uint_32 format = png_image_format(png_ptr); -+ -+ image->format = format; -+ -+#ifdef PNG_COLORSPACE_SUPPORTED -+ /* Does the colorspace match sRGB? If there is no color endpoint -+ * (colorant) information assume yes, otherwise require the -+ * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the -+ * colorspace has been determined to be invalid ignore it. -+ */ -+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags -+ & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| -+ PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) -+ image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; -+#endif -+ } -+ -+ /* We need the maximum number of entries regardless of the format the -+ * application sets here. -+ */ -+ { -+ png_uint_32 cmap_entries; -+ -+ switch (png_ptr->color_type) -+ { -+ case PNG_COLOR_TYPE_GRAY: -+ cmap_entries = 1U << png_ptr->bit_depth; -+ break; -+ -+ case PNG_COLOR_TYPE_PALETTE: -+ cmap_entries = png_ptr->num_palette; -+ break; -+ -+ default: -+ cmap_entries = 256; -+ break; -+ } -+ -+ if (cmap_entries > 256) -+ cmap_entries = 256; -+ -+ image->colormap_entries = cmap_entries; -+ } -+ -+ return 1; -+} -+ -+#ifdef PNG_STDIO_SUPPORTED -+int PNGAPI -+png_image_begin_read_from_stdio(png_imagep image, FILE* file) -+{ -+ if (image != NULL && image->version == PNG_IMAGE_VERSION) -+ { -+ if (file != NULL) -+ { -+ if (png_image_read_init(image) != 0) -+ { -+ /* This is slightly evil, but png_init_io doesn't do anything other -+ * than this and we haven't changed the standard IO functions so -+ * this saves a 'safe' function. -+ */ -+ image->opaque->png_ptr->io_ptr = file; -+ return png_safe_execute(image, png_image_read_header, image); -+ } -+ } -+ -+ else -+ return png_image_error(image, -+ "png_image_begin_read_from_stdio: invalid argument"); -+ } -+ -+ else if (image != NULL) -+ return png_image_error(image, -+ "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); -+ -+ return 0; -+} -+ -+int PNGAPI -+png_image_begin_read_from_file(png_imagep image, const char *file_name) -+{ -+ if (image != NULL && image->version == PNG_IMAGE_VERSION) -+ { -+ if (file_name != NULL) -+ { -+ FILE *fp = fopen(file_name, "rb"); -+ -+ if (fp != NULL) -+ { -+ if (png_image_read_init(image) != 0) -+ { -+ image->opaque->png_ptr->io_ptr = fp; -+ image->opaque->owned_file = 1; -+ return png_safe_execute(image, png_image_read_header, image); -+ } -+ -+ /* Clean up: just the opened file. */ -+ (void)fclose(fp); -+ } -+ -+ else -+ return png_image_error(image, strerror(errno)); -+ } -+ -+ else -+ return png_image_error(image, -+ "png_image_begin_read_from_file: invalid argument"); -+ } -+ -+ else if (image != NULL) -+ return png_image_error(image, -+ "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); -+ -+ return 0; -+} -+#endif /* STDIO */ -+ -+static void PNGCBAPI -+png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) -+{ -+ if (png_ptr != NULL) -+ { -+ png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); -+ if (image != NULL) -+ { -+ png_controlp cp = image->opaque; -+ if (cp != NULL) -+ { -+ png_const_bytep memory = cp->memory; -+ png_size_t size = cp->size; -+ -+ if (memory != NULL && size >= need) -+ { -+ memcpy(out, memory, need); -+ cp->memory = memory + need; -+ cp->size = size - need; -+ return; -+ } -+ -+ png_error(png_ptr, "read beyond end of data"); -+ } -+ } -+ -+ png_error(png_ptr, "invalid memory read"); -+ } -+} -+ -+int PNGAPI png_image_begin_read_from_memory(png_imagep image, -+ png_const_voidp memory, png_size_t size) -+{ -+ if (image != NULL && image->version == PNG_IMAGE_VERSION) -+ { -+ if (memory != NULL && size > 0) -+ { -+ if (png_image_read_init(image) != 0) -+ { -+ /* Now set the IO functions to read from the memory buffer and -+ * store it into io_ptr. Again do this in-place to avoid calling a -+ * libpng function that requires error handling. -+ */ -+ image->opaque->memory = png_voidcast(png_const_bytep, memory); -+ image->opaque->size = size; -+ image->opaque->png_ptr->io_ptr = image; -+ image->opaque->png_ptr->read_data_fn = png_image_memory_read; -+ -+ return png_safe_execute(image, png_image_read_header, image); -+ } -+ } -+ -+ else -+ return png_image_error(image, -+ "png_image_begin_read_from_memory: invalid argument"); -+ } -+ -+ else if (image != NULL) -+ return png_image_error(image, -+ "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); -+ -+ return 0; -+} -+ -+/* Utility function to skip chunks that are not used by the simplified image -+ * read functions and an appropriate macro to call it. -+ */ -+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+static void -+png_image_skip_unused_chunks(png_structrp png_ptr) -+{ -+ /* Prepare the reader to ignore all recognized chunks whose data will not -+ * be used, i.e., all chunks recognized by libpng except for those -+ * involved in basic image reading: -+ * -+ * IHDR, PLTE, IDAT, IEND -+ * -+ * Or image data handling: -+ * -+ * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. -+ * -+ * This provides a small performance improvement and eliminates any -+ * potential vulnerability to security problems in the unused chunks. -+ * -+ * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored -+ * too. This allows the simplified API to be compiled without iCCP support, -+ * however if the support is there the chunk is still checked to detect -+ * errors (which are unfortunately quite common.) -+ */ -+ { -+ static PNG_CONST png_byte chunks_to_process[] = { -+ 98, 75, 71, 68, '\0', /* bKGD */ -+ 99, 72, 82, 77, '\0', /* cHRM */ -+ 103, 65, 77, 65, '\0', /* gAMA */ -+# ifdef PNG_READ_iCCP_SUPPORTED -+ 105, 67, 67, 80, '\0', /* iCCP */ -+# endif -+ 115, 66, 73, 84, '\0', /* sBIT */ -+ 115, 82, 71, 66, '\0', /* sRGB */ -+ }; -+ -+ /* Ignore unknown chunks and all other chunks except for the -+ * IHDR, PLTE, tRNS, IDAT, and IEND chunks. -+ */ -+ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, -+ NULL, -1); -+ -+ /* But do not ignore image data handling chunks */ -+ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, -+ chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); -+ } -+} -+ -+# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) -+#else -+# define PNG_SKIP_CHUNKS(p) ((void)0) -+#endif /* HANDLE_AS_UNKNOWN */ -+ -+/* The following macro gives the exact rounded answer for all values in the -+ * range 0..255 (it actually divides by 51.2, but the rounding still generates -+ * the correct numbers 0..5 -+ */ -+#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) -+ -+/* Utility functions to make particular color-maps */ -+static void -+set_file_encoding(png_image_read_control *display) -+{ -+ png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; -+ if (png_gamma_significant(g) != 0) -+ { -+ if (png_gamma_not_sRGB(g) != 0) -+ { -+ display->file_encoding = P_FILE; -+ display->gamma_to_linear = png_reciprocal(g); -+ } -+ -+ else -+ display->file_encoding = P_sRGB; -+ } -+ -+ else -+ display->file_encoding = P_LINEAR8; -+} -+ -+static unsigned int -+decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) -+{ -+ if (encoding == P_FILE) /* double check */ -+ encoding = display->file_encoding; -+ -+ if (encoding == P_NOTSET) /* must be the file encoding */ -+ { -+ set_file_encoding(display); -+ encoding = display->file_encoding; -+ } -+ -+ switch (encoding) -+ { -+ case P_FILE: -+ value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); -+ break; -+ -+ case P_sRGB: -+ value = png_sRGB_table[value]; -+ break; -+ -+ case P_LINEAR: -+ break; -+ -+ case P_LINEAR8: -+ value *= 257; -+ break; -+ -+ default: -+ png_error(display->image->opaque->png_ptr, -+ "unexpected encoding (internal error)"); -+ break; -+ } -+ -+ return value; -+} -+ -+static png_uint_32 -+png_colormap_compose(png_image_read_control *display, -+ png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, -+ png_uint_32 background, int encoding) -+{ -+ /* The file value is composed on the background, the background has the given -+ * encoding and so does the result, the file is encoded with P_FILE and the -+ * file and alpha are 8-bit values. The (output) encoding will always be -+ * P_LINEAR or P_sRGB. -+ */ -+ png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); -+ png_uint_32 b = decode_gamma(display, background, encoding); -+ -+ /* The alpha is always an 8-bit value (it comes from the palette), the value -+ * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. -+ */ -+ f = f * alpha + b * (255-alpha); -+ -+ if (encoding == P_LINEAR) -+ { -+ /* Scale to 65535; divide by 255, approximately (in fact this is extremely -+ * accurate, it divides by 255.00000005937181414556, with no overflow.) -+ */ -+ f *= 257; /* Now scaled by 65535 */ -+ f += f >> 16; -+ f = (f+32768) >> 16; -+ } -+ -+ else /* P_sRGB */ -+ f = PNG_sRGB_FROM_LINEAR(f); -+ -+ return f; -+} -+ -+/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must -+ * be 8-bit. -+ */ -+static void -+png_create_colormap_entry(png_image_read_control *display, -+ png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, -+ png_uint_32 alpha, int encoding) -+{ -+ png_imagep image = display->image; -+ const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? -+ P_LINEAR : P_sRGB; -+ const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && -+ (red != green || green != blue); -+ -+ if (ip > 255) -+ png_error(image->opaque->png_ptr, "color-map index out of range"); -+ -+ /* Update the cache with whether the file gamma is significantly different -+ * from sRGB. -+ */ -+ if (encoding == P_FILE) -+ { -+ 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. -+ */ -+ encoding = display->file_encoding; -+ } -+ -+ if (encoding == P_FILE) -+ { -+ png_fixed_point g = display->gamma_to_linear; -+ -+ red = png_gamma_16bit_correct(red*257, g); -+ green = png_gamma_16bit_correct(green*257, g); -+ blue = png_gamma_16bit_correct(blue*257, g); -+ -+ if (convert_to_Y != 0 || output_encoding == P_LINEAR) -+ { -+ alpha *= 257; -+ encoding = P_LINEAR; -+ } -+ -+ else -+ { -+ red = PNG_sRGB_FROM_LINEAR(red * 255); -+ green = PNG_sRGB_FROM_LINEAR(green * 255); -+ blue = PNG_sRGB_FROM_LINEAR(blue * 255); -+ encoding = P_sRGB; -+ } -+ } -+ -+ else if (encoding == P_LINEAR8) -+ { -+ /* This encoding occurs quite frequently in test cases because PngSuite -+ * includes a gAMA 1.0 chunk with most images. -+ */ -+ red *= 257; -+ green *= 257; -+ blue *= 257; -+ alpha *= 257; -+ encoding = P_LINEAR; -+ } -+ -+ else if (encoding == P_sRGB && -+ (convert_to_Y != 0 || output_encoding == P_LINEAR)) -+ { -+ /* The values are 8-bit sRGB values, but must be converted to 16-bit -+ * linear. -+ */ -+ red = png_sRGB_table[red]; -+ green = png_sRGB_table[green]; -+ blue = png_sRGB_table[blue]; -+ alpha *= 257; -+ encoding = P_LINEAR; -+ } -+ -+ /* This is set if the color isn't gray but the output is. */ -+ if (encoding == P_LINEAR) -+ { -+ if (convert_to_Y != 0) -+ { -+ /* NOTE: these values are copied from png_do_rgb_to_gray */ -+ png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + -+ (png_uint_32)2366 * blue; -+ -+ if (output_encoding == P_LINEAR) -+ y = (y + 16384) >> 15; -+ -+ else -+ { -+ /* y is scaled by 32768, we need it scaled by 255: */ -+ y = (y + 128) >> 8; -+ y *= 255; -+ y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); -+ encoding = P_sRGB; -+ } -+ -+ blue = red = green = y; -+ } -+ -+ else if (output_encoding == P_sRGB) -+ { -+ red = PNG_sRGB_FROM_LINEAR(red * 255); -+ green = PNG_sRGB_FROM_LINEAR(green * 255); -+ blue = PNG_sRGB_FROM_LINEAR(blue * 255); -+ alpha = PNG_DIV257(alpha); -+ encoding = P_sRGB; -+ } -+ } -+ -+ if (encoding != output_encoding) -+ png_error(image->opaque->png_ptr, "bad encoding (internal error)"); -+ -+ /* Store the value. */ -+ { -+# ifdef PNG_FORMAT_AFIRST_SUPPORTED -+ const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && -+ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; -+# else -+# define afirst 0 -+# endif -+# ifdef PNG_FORMAT_BGR_SUPPORTED -+ const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -+# else -+# define bgr 0 -+# endif -+ -+ if (output_encoding == P_LINEAR) -+ { -+ png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); -+ -+ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); -+ -+ /* The linear 16-bit values must be pre-multiplied by the alpha channel -+ * value, if less than 65535 (this is, effectively, composite on black -+ * if the alpha channel is removed.) -+ */ -+ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) -+ { -+ case 4: -+ entry[afirst ? 0 : 3] = (png_uint_16)alpha; -+ /* FALL THROUGH */ -+ -+ case 3: -+ if (alpha < 65535) -+ { -+ if (alpha > 0) -+ { -+ blue = (blue * alpha + 32767U)/65535U; -+ green = (green * alpha + 32767U)/65535U; -+ red = (red * alpha + 32767U)/65535U; -+ } -+ -+ else -+ red = green = blue = 0; -+ } -+ entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; -+ entry[afirst + 1] = (png_uint_16)green; -+ entry[afirst + bgr] = (png_uint_16)red; -+ break; -+ -+ case 2: -+ entry[1 ^ afirst] = (png_uint_16)alpha; -+ /* FALL THROUGH */ -+ -+ case 1: -+ if (alpha < 65535) -+ { -+ if (alpha > 0) -+ green = (green * alpha + 32767U)/65535U; -+ -+ else -+ green = 0; -+ } -+ entry[afirst] = (png_uint_16)green; -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ else /* output encoding is P_sRGB */ -+ { -+ png_bytep entry = png_voidcast(png_bytep, display->colormap); -+ -+ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); -+ -+ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) -+ { -+ case 4: -+ entry[afirst ? 0 : 3] = (png_byte)alpha; -+ case 3: -+ entry[afirst + (2 ^ bgr)] = (png_byte)blue; -+ entry[afirst + 1] = (png_byte)green; -+ entry[afirst + bgr] = (png_byte)red; -+ break; -+ -+ case 2: -+ entry[1 ^ afirst] = (png_byte)alpha; -+ case 1: -+ entry[afirst] = (png_byte)green; -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+# ifdef afirst -+# undef afirst -+# endif -+# ifdef bgr -+# undef bgr -+# endif -+ } -+} -+ -+static int -+make_gray_file_colormap(png_image_read_control *display) -+{ -+ unsigned int i; -+ -+ for (i=0; i<256; ++i) -+ png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); -+ -+ return i; -+} -+ -+static int -+make_gray_colormap(png_image_read_control *display) -+{ -+ unsigned int i; -+ -+ for (i=0; i<256; ++i) -+ png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); -+ -+ return i; -+} -+#define PNG_GRAY_COLORMAP_ENTRIES 256 -+ -+static int -+make_ga_colormap(png_image_read_control *display) -+{ -+ unsigned int i, a; -+ -+ /* Alpha is retained, the output will be a color-map with entries -+ * selected by six levels of alpha. One transparent entry, 6 gray -+ * levels for all the intermediate alpha values, leaving 230 entries -+ * for the opaque grays. The color-map entries are the six values -+ * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the -+ * relevant entry. -+ * -+ * if (alpha > 229) // opaque -+ * { -+ * // The 231 entries are selected to make the math below work: -+ * base = 0; -+ * entry = (231 * gray + 128) >> 8; -+ * } -+ * else if (alpha < 26) // transparent -+ * { -+ * base = 231; -+ * entry = 0; -+ * } -+ * else // partially opaque -+ * { -+ * base = 226 + 6 * PNG_DIV51(alpha); -+ * entry = PNG_DIV51(gray); -+ * } -+ */ -+ i = 0; -+ while (i < 231) -+ { -+ unsigned int gray = (i * 256 + 115) / 231; -+ png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); -+ } -+ -+ /* 255 is used here for the component values for consistency with the code -+ * that undoes premultiplication in pngwrite.c. -+ */ -+ png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); -+ -+ for (a=1; a<5; ++a) -+ { -+ unsigned int g; -+ -+ for (g=0; g<6; ++g) -+ png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, -+ P_sRGB); -+ } -+ -+ return i; -+} -+ -+#define PNG_GA_COLORMAP_ENTRIES 256 -+ -+static int -+make_rgb_colormap(png_image_read_control *display) -+{ -+ unsigned int i, r; -+ -+ /* Build a 6x6x6 opaque RGB cube */ -+ for (i=r=0; r<6; ++r) -+ { -+ unsigned int g; -+ -+ for (g=0; g<6; ++g) -+ { -+ unsigned int b; -+ -+ for (b=0; b<6; ++b) -+ png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, -+ P_sRGB); -+ } -+ } -+ -+ return i; -+} -+ -+#define PNG_RGB_COLORMAP_ENTRIES 216 -+ -+/* Return a palette index to the above palette given three 8-bit sRGB values. */ -+#define PNG_RGB_INDEX(r,g,b) \ -+ ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) -+ -+static int -+png_image_read_colormap(png_voidp argument) -+{ -+ png_image_read_control *display = -+ png_voidcast(png_image_read_control*, argument); -+ const png_imagep image = display->image; -+ -+ const png_structrp png_ptr = image->opaque->png_ptr; -+ const png_uint_32 output_format = image->format; -+ const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? -+ P_LINEAR : P_sRGB; -+ -+ unsigned int cmap_entries; -+ unsigned int output_processing; /* Output processing option */ -+ unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ -+ -+ /* Background information; the background color and the index of this color -+ * in the color-map if it exists (else 256). -+ */ -+ unsigned int background_index = 256; -+ png_uint_32 back_r, back_g, back_b; -+ -+ /* Flags to accumulate things that need to be done to the input. */ -+ int expand_tRNS = 0; -+ -+ /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is -+ * very difficult to do, the results look awful, and it is difficult to see -+ * what possible use it is because the application can't control the -+ * color-map. -+ */ -+ if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || -+ png_ptr->num_trans > 0) /* alpha in input */ && -+ ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) -+ { -+ if (output_encoding == P_LINEAR) /* compose on black */ -+ back_b = back_g = back_r = 0; -+ -+ else if (display->background == NULL /* no way to remove it */) -+ png_error(png_ptr, -+ "a background color must be supplied to remove alpha/transparency"); -+ -+ /* Get a copy of the background color (this avoids repeating the checks -+ * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the -+ * output format. -+ */ -+ else -+ { -+ back_g = display->background->green; -+ if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0) -+ { -+ back_r = display->background->red; -+ back_b = display->background->blue; -+ } -+ else -+ back_b = back_r = back_g; -+ } -+ } -+ -+ else if (output_encoding == P_LINEAR) -+ back_b = back_r = back_g = 65535; -+ -+ else -+ back_b = back_r = back_g = 255; -+ -+ /* Default the input file gamma if required - this is necessary because -+ * libpng assumes that if no gamma information is present the data is in the -+ * output format, but the simplified API deduces the gamma from the input -+ * format. -+ */ -+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) -+ { -+ /* Do this directly, not using the png_colorspace functions, to ensure -+ * that it happens even if the colorspace is invalid (though probably if -+ * it is the setting will be ignored) Note that the same thing can be -+ * achieved at the application interface with png_set_gAMA. -+ */ -+ if (png_ptr->bit_depth == 16 && -+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) -+ png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; -+ -+ else -+ png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; -+ -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; -+ } -+ -+ /* Decide what to do based on the PNG color type of the input data. The -+ * utility function png_create_colormap_entry deals with most aspects of the -+ * output transformations; this code works out how to produce bytes of -+ * color-map entries from the original format. -+ */ -+ switch (png_ptr->color_type) -+ { -+ case PNG_COLOR_TYPE_GRAY: -+ if (png_ptr->bit_depth <= 8) -+ { -+ /* There at most 256 colors in the output, regardless of -+ * transparency. -+ */ -+ unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; -+ -+ cmap_entries = 1U << png_ptr->bit_depth; -+ if (cmap_entries > image->colormap_entries) -+ png_error(png_ptr, "gray[8] color-map: too few entries"); -+ -+ step = 255 / (cmap_entries - 1); -+ output_processing = PNG_CMAP_NONE; -+ -+ /* If there is a tRNS chunk then this either selects a transparent -+ * value or, if the output has no alpha, the background color. -+ */ -+ if (png_ptr->num_trans > 0) -+ { -+ trans = png_ptr->trans_color.gray; -+ -+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) -+ back_alpha = output_encoding == P_LINEAR ? 65535 : 255; -+ } -+ -+ /* png_create_colormap_entry just takes an RGBA and writes the -+ * corresponding color-map entry using the format from 'image', -+ * including the required conversion to sRGB or linear as -+ * appropriate. The input values are always either sRGB (if the -+ * gamma correction flag is 0) or 0..255 scaled file encoded values -+ * (if the function must gamma correct them). -+ */ -+ for (i=val=0; i<cmap_entries; ++i, val += step) -+ { -+ /* 'i' is a file value. While this will result in duplicated -+ * entries for 8-bit non-sRGB encoded files it is necessary to -+ * have non-gamma corrected values to do tRNS handling. -+ */ -+ if (i != trans) -+ png_create_colormap_entry(display, i, val, val, val, 255, -+ P_FILE/*8-bit with file gamma*/); -+ -+ /* Else this entry is transparent. The colors don't matter if -+ * there is an alpha channel (back_alpha == 0), but it does no -+ * harm to pass them in; the values are not set above so this -+ * passes in white. -+ * -+ * NOTE: this preserves the full precision of the application -+ * supplied background color when it is used. -+ */ -+ else -+ png_create_colormap_entry(display, i, back_r, back_g, back_b, -+ back_alpha, output_encoding); -+ } -+ -+ /* We need libpng to preserve the original encoding. */ -+ data_encoding = P_FILE; -+ -+ /* The rows from libpng, while technically gray values, are now also -+ * color-map indices; however, they may need to be expanded to 1 -+ * byte per pixel. This is what png_set_packing does (i.e., it -+ * unpacks the bit values into bytes.) -+ */ -+ if (png_ptr->bit_depth < 8) -+ png_set_packing(png_ptr); -+ } -+ -+ else /* bit depth is 16 */ -+ { -+ /* The 16-bit input values can be converted directly to 8-bit gamma -+ * encoded values; however, if a tRNS chunk is present 257 color-map -+ * entries are required. This means that the extra entry requires -+ * special processing; add an alpha channel, sacrifice gray level -+ * 254 and convert transparent (alpha==0) entries to that. -+ * -+ * Use libpng to chop the data to 8 bits. Convert it to sRGB at the -+ * same time to minimize quality loss. If a tRNS chunk is present -+ * this means libpng must handle it too; otherwise it is impossible -+ * to do the exact match on the 16-bit value. -+ * -+ * If the output has no alpha channel *and* the background color is -+ * gray then it is possible to let libpng handle the substitution by -+ * ensuring that the corresponding gray level matches the background -+ * color exactly. -+ */ -+ data_encoding = P_sRGB; -+ -+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) -+ png_error(png_ptr, "gray[16] color-map: too few entries"); -+ -+ cmap_entries = make_gray_colormap(display); -+ -+ if (png_ptr->num_trans > 0) -+ { -+ unsigned int back_alpha; -+ -+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ back_alpha = 0; -+ -+ else -+ { -+ if (back_r == back_g && back_g == back_b) -+ { -+ /* Background is gray; no special processing will be -+ * required. -+ */ -+ png_color_16 c; -+ png_uint_32 gray = back_g; -+ -+ if (output_encoding == P_LINEAR) -+ { -+ gray = PNG_sRGB_FROM_LINEAR(gray * 255); -+ -+ /* And make sure the corresponding palette entry -+ * matches. -+ */ -+ png_create_colormap_entry(display, gray, back_g, back_g, -+ back_g, 65535, P_LINEAR); -+ } -+ -+ /* The background passed to libpng, however, must be the -+ * sRGB value. -+ */ -+ c.index = 0; /*unused*/ -+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray; -+ -+ /* NOTE: does this work without expanding tRNS to alpha? -+ * It should be the color->gray case below apparently -+ * doesn't. -+ */ -+ png_set_background_fixed(png_ptr, &c, -+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, -+ 0/*gamma: not used*/); -+ -+ output_processing = PNG_CMAP_NONE; -+ break; -+ } -+ -+ back_alpha = output_encoding == P_LINEAR ? 65535 : 255; -+ } -+ -+ /* output_processing means that the libpng-processed row will be -+ * 8-bit GA and it has to be processing to single byte color-map -+ * values. Entry 254 is replaced by either a completely -+ * transparent entry or by the background color at full -+ * precision (and the background color is not a simple gray -+ * level in this case.) -+ */ -+ expand_tRNS = 1; -+ output_processing = PNG_CMAP_TRANS; -+ background_index = 254; -+ -+ /* And set (overwrite) color-map entry 254 to the actual -+ * background color at full precision. -+ */ -+ png_create_colormap_entry(display, 254, back_r, back_g, back_b, -+ back_alpha, output_encoding); -+ } -+ -+ else -+ output_processing = PNG_CMAP_NONE; -+ } -+ break; -+ -+ case PNG_COLOR_TYPE_GRAY_ALPHA: -+ /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum -+ * of 65536 combinations. If, however, the alpha channel is to be -+ * removed there are only 256 possibilities if the background is gray. -+ * (Otherwise there is a subset of the 65536 possibilities defined by -+ * the triangle between black, white and the background color.) -+ * -+ * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to -+ * worry about tRNS matching - tRNS is ignored if there is an alpha -+ * channel. -+ */ -+ data_encoding = P_sRGB; -+ -+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) -+ png_error(png_ptr, "gray+alpha color-map: too few entries"); -+ -+ cmap_entries = make_ga_colormap(display); -+ -+ background_index = PNG_CMAP_GA_BACKGROUND; -+ output_processing = PNG_CMAP_GA; -+ } -+ -+ else /* alpha is removed */ -+ { -+ /* Alpha must be removed as the PNG data is processed when the -+ * background is a color because the G and A channels are -+ * independent and the vector addition (non-parallel vectors) is a -+ * 2-D problem. -+ * -+ * This can be reduced to the same algorithm as above by making a -+ * colormap containing gray levels (for the opaque grays), a -+ * background entry (for a transparent pixel) and a set of four six -+ * level color values, one set for each intermediate alpha value. -+ * See the comments in make_ga_colormap for how this works in the -+ * per-pixel processing. -+ * -+ * If the background is gray, however, we only need a 256 entry gray -+ * level color map. It is sufficient to make the entry generated -+ * for the background color be exactly the color specified. -+ */ -+ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || -+ (back_r == back_g && back_g == back_b)) -+ { -+ /* Background is gray; no special processing will be required. */ -+ png_color_16 c; -+ png_uint_32 gray = back_g; -+ -+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) -+ png_error(png_ptr, "gray-alpha color-map: too few entries"); -+ -+ cmap_entries = make_gray_colormap(display); -+ -+ if (output_encoding == P_LINEAR) -+ { -+ gray = PNG_sRGB_FROM_LINEAR(gray * 255); -+ -+ /* And make sure the corresponding palette entry matches. */ -+ png_create_colormap_entry(display, gray, back_g, back_g, -+ back_g, 65535, P_LINEAR); -+ } -+ -+ /* The background passed to libpng, however, must be the sRGB -+ * value. -+ */ -+ c.index = 0; /*unused*/ -+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray; -+ -+ png_set_background_fixed(png_ptr, &c, -+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, -+ 0/*gamma: not used*/); -+ -+ output_processing = PNG_CMAP_NONE; -+ } -+ -+ else -+ { -+ png_uint_32 i, a; -+ -+ /* This is the same as png_make_ga_colormap, above, except that -+ * the entries are all opaque. -+ */ -+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) -+ png_error(png_ptr, "ga-alpha color-map: too few entries"); -+ -+ i = 0; -+ while (i < 231) -+ { -+ png_uint_32 gray = (i * 256 + 115) / 231; -+ png_create_colormap_entry(display, i++, gray, gray, gray, -+ 255, P_sRGB); -+ } -+ -+ /* NOTE: this preserves the full precision of the application -+ * background color. -+ */ -+ background_index = i; -+ png_create_colormap_entry(display, i++, back_r, back_g, back_b, -+ output_encoding == P_LINEAR ? 65535U : 255U, output_encoding); -+ -+ /* For non-opaque input composite on the sRGB background - this -+ * requires inverting the encoding for each component. The input -+ * is still converted to the sRGB encoding because this is a -+ * reasonable approximate to the logarithmic curve of human -+ * visual sensitivity, at least over the narrow range which PNG -+ * represents. Consequently 'G' is always sRGB encoded, while -+ * 'A' is linear. We need the linear background colors. -+ */ -+ if (output_encoding == P_sRGB) /* else already linear */ -+ { -+ /* This may produce a value not exactly matching the -+ * background, but that's ok because these numbers are only -+ * used when alpha != 0 -+ */ -+ back_r = png_sRGB_table[back_r]; -+ back_g = png_sRGB_table[back_g]; -+ back_b = png_sRGB_table[back_b]; -+ } -+ -+ for (a=1; a<5; ++a) -+ { -+ unsigned int g; -+ -+ /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled -+ * by an 8-bit alpha value (0..255). -+ */ -+ png_uint_32 alpha = 51 * a; -+ png_uint_32 back_rx = (255-alpha) * back_r; -+ png_uint_32 back_gx = (255-alpha) * back_g; -+ png_uint_32 back_bx = (255-alpha) * back_b; -+ -+ for (g=0; g<6; ++g) -+ { -+ png_uint_32 gray = png_sRGB_table[g*51] * alpha; -+ -+ png_create_colormap_entry(display, i++, -+ PNG_sRGB_FROM_LINEAR(gray + back_rx), -+ PNG_sRGB_FROM_LINEAR(gray + back_gx), -+ PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); -+ } -+ } -+ -+ cmap_entries = i; -+ output_processing = PNG_CMAP_GA; -+ } -+ } -+ break; -+ -+ case PNG_COLOR_TYPE_RGB: -+ case PNG_COLOR_TYPE_RGB_ALPHA: -+ /* Exclude the case where the output is gray; we can always handle this -+ * with the cases above. -+ */ -+ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) -+ { -+ /* The color-map will be grayscale, so we may as well convert the -+ * input RGB values to a simple grayscale and use the grayscale -+ * code above. -+ * -+ * NOTE: calling this apparently damages the recognition of the -+ * transparent color in background color handling; call -+ * png_set_tRNS_to_alpha before png_set_background_fixed. -+ */ -+ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, -+ -1); -+ data_encoding = P_sRGB; -+ -+ /* The output will now be one or two 8-bit gray or gray+alpha -+ * channels. The more complex case arises when the input has alpha. -+ */ -+ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || -+ png_ptr->num_trans > 0) && -+ (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+ /* Both input and output have an alpha channel, so no background -+ * processing is required; just map the GA bytes to the right -+ * color-map entry. -+ */ -+ expand_tRNS = 1; -+ -+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) -+ png_error(png_ptr, "rgb[ga] color-map: too few entries"); -+ -+ cmap_entries = make_ga_colormap(display); -+ background_index = PNG_CMAP_GA_BACKGROUND; -+ output_processing = PNG_CMAP_GA; -+ } -+ -+ else -+ { -+ /* Either the input or the output has no alpha channel, so there -+ * will be no non-opaque pixels in the color-map; it will just be -+ * grayscale. -+ */ -+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) -+ png_error(png_ptr, "rgb[gray] color-map: too few entries"); -+ -+ /* Ideally this code would use libpng to do the gamma correction, -+ * but if an input alpha channel is to be removed we will hit the -+ * libpng bug in gamma+compose+rgb-to-gray (the double gamma -+ * correction bug). Fix this by dropping the gamma correction in -+ * this case and doing it in the palette; this will result in -+ * duplicate palette entries, but that's better than the -+ * alternative of double gamma correction. -+ */ -+ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || -+ png_ptr->num_trans > 0) && -+ png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) -+ { -+ cmap_entries = make_gray_file_colormap(display); -+ data_encoding = P_FILE; -+ } -+ -+ else -+ cmap_entries = make_gray_colormap(display); -+ -+ /* But if the input has alpha or transparency it must be removed -+ */ -+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || -+ png_ptr->num_trans > 0) -+ { -+ png_color_16 c; -+ png_uint_32 gray = back_g; -+ -+ /* We need to ensure that the application background exists in -+ * the colormap and that completely transparent pixels map to -+ * it. Achieve this simply by ensuring that the entry -+ * selected for the background really is the background color. -+ */ -+ if (data_encoding == P_FILE) /* from the fixup above */ -+ { -+ /* The app supplied a gray which is in output_encoding, we -+ * need to convert it to a value of the input (P_FILE) -+ * encoding then set this palette entry to the required -+ * output encoding. -+ */ -+ if (output_encoding == P_sRGB) -+ gray = png_sRGB_table[gray]; /* now P_LINEAR */ -+ -+ gray = PNG_DIV257(png_gamma_16bit_correct(gray, -+ png_ptr->colorspace.gamma)); /* now P_FILE */ -+ -+ /* And make sure the corresponding palette entry contains -+ * exactly the required sRGB value. -+ */ -+ png_create_colormap_entry(display, gray, back_g, back_g, -+ back_g, 0/*unused*/, output_encoding); -+ } -+ -+ else if (output_encoding == P_LINEAR) -+ { -+ gray = PNG_sRGB_FROM_LINEAR(gray * 255); -+ -+ /* And make sure the corresponding palette entry matches. -+ */ -+ png_create_colormap_entry(display, gray, back_g, back_g, -+ back_g, 0/*unused*/, P_LINEAR); -+ } -+ -+ /* The background passed to libpng, however, must be the -+ * output (normally sRGB) value. -+ */ -+ c.index = 0; /*unused*/ -+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray; -+ -+ /* NOTE: the following is apparently a bug in libpng. Without -+ * it the transparent color recognition in -+ * png_set_background_fixed seems to go wrong. -+ */ -+ expand_tRNS = 1; -+ png_set_background_fixed(png_ptr, &c, -+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, -+ 0/*gamma: not used*/); -+ } -+ -+ output_processing = PNG_CMAP_NONE; -+ } -+ } -+ -+ else /* output is color */ -+ { -+ /* We could use png_quantize here so long as there is no transparent -+ * color or alpha; png_quantize ignores alpha. Easier overall just -+ * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. -+ * Consequently we always want libpng to produce sRGB data. -+ */ -+ data_encoding = P_sRGB; -+ -+ /* Is there any transparency or alpha? */ -+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || -+ png_ptr->num_trans > 0) -+ { -+ /* Is there alpha in the output too? If so all four channels are -+ * processed into a special RGB cube with alpha support. -+ */ -+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+ png_uint_32 r; -+ -+ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) -+ png_error(png_ptr, "rgb+alpha color-map: too few entries"); -+ -+ cmap_entries = make_rgb_colormap(display); -+ -+ /* Add a transparent entry. */ -+ png_create_colormap_entry(display, cmap_entries, 255, 255, -+ 255, 0, P_sRGB); -+ -+ /* This is stored as the background index for the processing -+ * algorithm. -+ */ -+ background_index = cmap_entries++; -+ -+ /* Add 27 r,g,b entries each with alpha 0.5. */ -+ for (r=0; r<256; r = (r << 1) | 0x7f) -+ { -+ png_uint_32 g; -+ -+ for (g=0; g<256; g = (g << 1) | 0x7f) -+ { -+ png_uint_32 b; -+ -+ /* This generates components with the values 0, 127 and -+ * 255 -+ */ -+ for (b=0; b<256; b = (b << 1) | 0x7f) -+ png_create_colormap_entry(display, cmap_entries++, -+ r, g, b, 128, P_sRGB); -+ } -+ } -+ -+ expand_tRNS = 1; -+ output_processing = PNG_CMAP_RGB_ALPHA; -+ } -+ -+ else -+ { -+ /* Alpha/transparency must be removed. The background must -+ * exist in the color map (achieved by setting adding it after -+ * the 666 color-map). If the standard processing code will -+ * pick up this entry automatically that's all that is -+ * required; libpng can be called to do the background -+ * processing. -+ */ -+ unsigned int sample_size = -+ PNG_IMAGE_SAMPLE_SIZE(output_format); -+ png_uint_32 r, g, b; /* sRGB background */ -+ -+ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) -+ png_error(png_ptr, "rgb-alpha color-map: too few entries"); -+ -+ cmap_entries = make_rgb_colormap(display); -+ -+ png_create_colormap_entry(display, cmap_entries, back_r, -+ back_g, back_b, 0/*unused*/, output_encoding); -+ -+ if (output_encoding == P_LINEAR) -+ { -+ r = PNG_sRGB_FROM_LINEAR(back_r * 255); -+ g = PNG_sRGB_FROM_LINEAR(back_g * 255); -+ b = PNG_sRGB_FROM_LINEAR(back_b * 255); -+ } -+ -+ else -+ { -+ r = back_r; -+ g = back_g; -+ b = back_g; -+ } -+ -+ /* Compare the newly-created color-map entry with the one the -+ * PNG_CMAP_RGB algorithm will use. If the two entries don't -+ * match, add the new one and set this as the background -+ * index. -+ */ -+ if (memcmp((png_const_bytep)display->colormap + -+ sample_size * cmap_entries, -+ (png_const_bytep)display->colormap + -+ sample_size * PNG_RGB_INDEX(r,g,b), -+ sample_size) != 0) -+ { -+ /* The background color must be added. */ -+ background_index = cmap_entries++; -+ -+ /* Add 27 r,g,b entries each with created by composing with -+ * the background at alpha 0.5. -+ */ -+ for (r=0; r<256; r = (r << 1) | 0x7f) -+ { -+ for (g=0; g<256; g = (g << 1) | 0x7f) -+ { -+ /* This generates components with the values 0, 127 -+ * and 255 -+ */ -+ for (b=0; b<256; b = (b << 1) | 0x7f) -+ png_create_colormap_entry(display, cmap_entries++, -+ png_colormap_compose(display, r, P_sRGB, 128, -+ back_r, output_encoding), -+ png_colormap_compose(display, g, P_sRGB, 128, -+ back_g, output_encoding), -+ png_colormap_compose(display, b, P_sRGB, 128, -+ back_b, output_encoding), -+ 0/*unused*/, output_encoding); -+ } -+ } -+ -+ expand_tRNS = 1; -+ output_processing = PNG_CMAP_RGB_ALPHA; -+ } -+ -+ else /* background color is in the standard color-map */ -+ { -+ png_color_16 c; -+ -+ c.index = 0; /*unused*/ -+ c.red = (png_uint_16)back_r; -+ c.gray = c.green = (png_uint_16)back_g; -+ c.blue = (png_uint_16)back_b; -+ -+ png_set_background_fixed(png_ptr, &c, -+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, -+ 0/*gamma: not used*/); -+ -+ output_processing = PNG_CMAP_RGB; -+ } -+ } -+ } -+ -+ else /* no alpha or transparency in the input */ -+ { -+ /* Alpha in the output is irrelevant, simply map the opaque input -+ * pixels to the 6x6x6 color-map. -+ */ -+ if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) -+ png_error(png_ptr, "rgb color-map: too few entries"); -+ -+ cmap_entries = make_rgb_colormap(display); -+ output_processing = PNG_CMAP_RGB; -+ } -+ } -+ break; -+ -+ case PNG_COLOR_TYPE_PALETTE: -+ /* It's already got a color-map. It may be necessary to eliminate the -+ * tRNS entries though. -+ */ -+ { -+ unsigned int num_trans = png_ptr->num_trans; -+ png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; -+ png_const_colorp colormap = png_ptr->palette; -+ const int do_background = trans != NULL && -+ (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; -+ unsigned int i; -+ -+ /* Just in case: */ -+ if (trans == NULL) -+ num_trans = 0; -+ -+ output_processing = PNG_CMAP_NONE; -+ data_encoding = P_FILE; /* Don't change from color-map indices */ -+ cmap_entries = png_ptr->num_palette; -+ if (cmap_entries > 256) -+ cmap_entries = 256; -+ -+ if (cmap_entries > image->colormap_entries) -+ png_error(png_ptr, "palette color-map: too few entries"); -+ -+ for (i=0; i < cmap_entries; ++i) -+ { -+ if (do_background != 0 && i < num_trans && trans[i] < 255) -+ { -+ if (trans[i] == 0) -+ png_create_colormap_entry(display, i, back_r, back_g, -+ back_b, 0, output_encoding); -+ -+ else -+ { -+ /* Must compose the PNG file color in the color-map entry -+ * on the sRGB color in 'back'. -+ */ -+ png_create_colormap_entry(display, i, -+ png_colormap_compose(display, colormap[i].red, P_FILE, -+ trans[i], back_r, output_encoding), -+ png_colormap_compose(display, colormap[i].green, P_FILE, -+ trans[i], back_g, output_encoding), -+ png_colormap_compose(display, colormap[i].blue, P_FILE, -+ trans[i], back_b, output_encoding), -+ output_encoding == P_LINEAR ? trans[i] * 257U : -+ trans[i], -+ output_encoding); -+ } -+ } -+ -+ else -+ png_create_colormap_entry(display, i, colormap[i].red, -+ colormap[i].green, colormap[i].blue, -+ i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); -+ } -+ -+ /* The PNG data may have indices packed in fewer than 8 bits, it -+ * must be expanded if so. -+ */ -+ if (png_ptr->bit_depth < 8) -+ png_set_packing(png_ptr); -+ } -+ break; -+ -+ default: -+ png_error(png_ptr, "invalid PNG color type"); -+ /*NOT REACHED*/ -+ break; -+ } -+ -+ /* Now deal with the output processing */ -+ if (expand_tRNS != 0 && png_ptr->num_trans > 0 && -+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) -+ png_set_tRNS_to_alpha(png_ptr); -+ -+ switch (data_encoding) -+ { -+ default: -+ png_error(png_ptr, "bad data option (internal error)"); -+ break; -+ -+ case P_sRGB: -+ /* Change to 8-bit sRGB */ -+ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); -+ /* FALL THROUGH */ -+ -+ case P_FILE: -+ if (png_ptr->bit_depth > 8) -+ png_set_scale_16(png_ptr); -+ break; -+ } -+ -+ if (cmap_entries > 256 || cmap_entries > image->colormap_entries) -+ png_error(png_ptr, "color map overflow (BAD internal error)"); -+ -+ image->colormap_entries = cmap_entries; -+ -+ /* Double check using the recorded background index */ -+ switch (output_processing) -+ { -+ case PNG_CMAP_NONE: -+ if (background_index != PNG_CMAP_NONE_BACKGROUND) -+ goto bad_background; -+ break; -+ -+ case PNG_CMAP_GA: -+ if (background_index != PNG_CMAP_GA_BACKGROUND) -+ goto bad_background; -+ break; -+ -+ case PNG_CMAP_TRANS: -+ if (background_index >= cmap_entries || -+ background_index != PNG_CMAP_TRANS_BACKGROUND) -+ goto bad_background; -+ break; -+ -+ case PNG_CMAP_RGB: -+ if (background_index != PNG_CMAP_RGB_BACKGROUND) -+ goto bad_background; -+ break; -+ -+ case PNG_CMAP_RGB_ALPHA: -+ if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) -+ goto bad_background; -+ break; -+ -+ default: -+ png_error(png_ptr, "bad processing option (internal error)"); -+ -+ bad_background: -+ png_error(png_ptr, "bad background index (internal error)"); -+ } -+ -+ display->colormap_processing = output_processing; -+ -+ return 1/*ok*/; -+} -+ -+/* The final part of the color-map read called from png_image_finish_read. */ -+static int -+png_image_read_and_map(png_voidp argument) -+{ -+ png_image_read_control *display = png_voidcast(png_image_read_control*, -+ argument); -+ png_imagep image = display->image; -+ png_structrp png_ptr = image->opaque->png_ptr; -+ int passes; -+ -+ /* Called when the libpng data must be transformed into the color-mapped -+ * form. There is a local row buffer in display->local and this routine must -+ * do the interlace handling. -+ */ -+ switch (png_ptr->interlaced) -+ { -+ case PNG_INTERLACE_NONE: -+ passes = 1; -+ break; -+ -+ case PNG_INTERLACE_ADAM7: -+ passes = PNG_INTERLACE_ADAM7_PASSES; -+ break; -+ -+ default: -+ png_error(png_ptr, "unknown interlace type"); -+ } -+ -+ { -+ png_uint_32 height = image->height; -+ png_uint_32 width = image->width; -+ int proc = display->colormap_processing; -+ png_bytep first_row = png_voidcast(png_bytep, display->first_row); -+ ptrdiff_t step_row = display->row_bytes; -+ int pass; -+ -+ for (pass = 0; pass < passes; ++pass) -+ { -+ unsigned int startx, stepx, stepy; -+ png_uint_32 y; -+ -+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) -+ { -+ /* The row may be empty for a short image: */ -+ if (PNG_PASS_COLS(width, pass) == 0) -+ continue; -+ -+ startx = PNG_PASS_START_COL(pass); -+ stepx = PNG_PASS_COL_OFFSET(pass); -+ y = PNG_PASS_START_ROW(pass); -+ stepy = PNG_PASS_ROW_OFFSET(pass); -+ } -+ -+ else -+ { -+ y = 0; -+ startx = 0; -+ stepx = stepy = 1; -+ } -+ -+ for (; y<height; y += stepy) -+ { -+ png_bytep inrow = png_voidcast(png_bytep, display->local_row); -+ png_bytep outrow = first_row + y * step_row; -+ png_const_bytep end_row = outrow + width; -+ -+ /* Read read the libpng data into the temporary buffer. */ -+ png_read_row(png_ptr, inrow, NULL); -+ -+ /* Now process the row according to the processing option, note -+ * that the caller verifies that the format of the libpng output -+ * data is as required. -+ */ -+ outrow += startx; -+ switch (proc) -+ { -+ case PNG_CMAP_GA: -+ for (; outrow < end_row; outrow += stepx) -+ { -+ /* The data is always in the PNG order */ -+ unsigned int gray = *inrow++; -+ unsigned int alpha = *inrow++; -+ unsigned int entry; -+ -+ /* NOTE: this code is copied as a comment in -+ * make_ga_colormap above. Please update the -+ * comment if you change this code! -+ */ -+ if (alpha > 229) /* opaque */ -+ { -+ entry = (231 * gray + 128) >> 8; -+ } -+ else if (alpha < 26) /* transparent */ -+ { -+ entry = 231; -+ } -+ else /* partially opaque */ -+ { -+ entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); -+ } -+ -+ *outrow = (png_byte)entry; -+ } -+ break; -+ -+ case PNG_CMAP_TRANS: -+ for (; outrow < end_row; outrow += stepx) -+ { -+ png_byte gray = *inrow++; -+ png_byte alpha = *inrow++; -+ -+ if (alpha == 0) -+ *outrow = PNG_CMAP_TRANS_BACKGROUND; -+ -+ else if (gray != PNG_CMAP_TRANS_BACKGROUND) -+ *outrow = gray; -+ -+ else -+ *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); -+ } -+ break; -+ -+ case PNG_CMAP_RGB: -+ for (; outrow < end_row; outrow += stepx) -+ { -+ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); -+ inrow += 3; -+ } -+ break; -+ -+ case PNG_CMAP_RGB_ALPHA: -+ for (; outrow < end_row; outrow += stepx) -+ { -+ unsigned int alpha = inrow[3]; -+ -+ /* Because the alpha entries only hold alpha==0.5 values -+ * split the processing at alpha==0.25 (64) and 0.75 -+ * (196). -+ */ -+ -+ if (alpha >= 196) -+ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], -+ inrow[2]); -+ -+ else if (alpha < 64) -+ *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; -+ -+ else -+ { -+ /* Likewise there are three entries for each of r, g -+ * and b. We could select the entry by popcount on -+ * the top two bits on those architectures that -+ * support it, this is what the code below does, -+ * crudely. -+ */ -+ unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; -+ -+ /* Here are how the values map: -+ * -+ * 0x00 .. 0x3f -> 0 -+ * 0x40 .. 0xbf -> 1 -+ * 0xc0 .. 0xff -> 2 -+ * -+ * So, as above with the explicit alpha checks, the -+ * breakpoints are at 64 and 196. -+ */ -+ if (inrow[0] & 0x80) back_i += 9; /* red */ -+ if (inrow[0] & 0x40) back_i += 9; -+ if (inrow[0] & 0x80) back_i += 3; /* green */ -+ if (inrow[0] & 0x40) back_i += 3; -+ if (inrow[0] & 0x80) back_i += 1; /* blue */ -+ if (inrow[0] & 0x40) back_i += 1; -+ -+ *outrow = (png_byte)back_i; -+ } -+ -+ inrow += 4; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } -+ } -+ } -+ -+ return 1; -+} -+ -+static int -+png_image_read_colormapped(png_voidp argument) -+{ -+ png_image_read_control *display = png_voidcast(png_image_read_control*, -+ argument); -+ png_imagep image = display->image; -+ png_controlp control = image->opaque; -+ png_structrp png_ptr = control->png_ptr; -+ png_inforp info_ptr = control->info_ptr; -+ -+ int passes = 0; /* As a flag */ -+ -+ PNG_SKIP_CHUNKS(png_ptr); -+ -+ /* Update the 'info' structure and make sure the result is as required; first -+ * make sure to turn on the interlace handling if it will be required -+ * (because it can't be turned on *after* the call to png_read_update_info!) -+ */ -+ if (display->colormap_processing == PNG_CMAP_NONE) -+ passes = png_set_interlace_handling(png_ptr); -+ -+ png_read_update_info(png_ptr, info_ptr); -+ -+ /* The expected output can be deduced from the colormap_processing option. */ -+ switch (display->colormap_processing) -+ { -+ case PNG_CMAP_NONE: -+ /* Output must be one channel and one byte per pixel, the output -+ * encoding can be anything. -+ */ -+ if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || -+ info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && -+ info_ptr->bit_depth == 8) -+ break; -+ -+ goto bad_output; -+ -+ case PNG_CMAP_TRANS: -+ case PNG_CMAP_GA: -+ /* Output must be two channels and the 'G' one must be sRGB, the latter -+ * can be checked with an exact number because it should have been set -+ * to this number above! -+ */ -+ if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && -+ info_ptr->bit_depth == 8 && -+ png_ptr->screen_gamma == PNG_GAMMA_sRGB && -+ image->colormap_entries == 256) -+ break; -+ -+ goto bad_output; -+ -+ case PNG_CMAP_RGB: -+ /* Output must be 8-bit sRGB encoded RGB */ -+ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && -+ info_ptr->bit_depth == 8 && -+ png_ptr->screen_gamma == PNG_GAMMA_sRGB && -+ image->colormap_entries == 216) -+ break; -+ -+ goto bad_output; -+ -+ case PNG_CMAP_RGB_ALPHA: -+ /* Output must be 8-bit sRGB encoded RGBA */ -+ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && -+ info_ptr->bit_depth == 8 && -+ png_ptr->screen_gamma == PNG_GAMMA_sRGB && -+ image->colormap_entries == 244 /* 216 + 1 + 27 */) -+ break; -+ -+ /* goto bad_output; */ -+ /* FALL THROUGH */ -+ -+ default: -+ bad_output: -+ png_error(png_ptr, "bad color-map processing (internal error)"); -+ } -+ -+ /* Now read the rows. Do this here if it is possible to read directly into -+ * the output buffer, otherwise allocate a local row buffer of the maximum -+ * size libpng requires and call the relevant processing routine safely. -+ */ -+ { -+ png_voidp first_row = display->buffer; -+ ptrdiff_t row_bytes = display->row_stride; -+ -+ /* The following expression is designed to work correctly whether it gives -+ * a signed or an unsigned result. -+ */ -+ if (row_bytes < 0) -+ { -+ char *ptr = png_voidcast(char*, first_row); -+ ptr += (image->height-1) * (-row_bytes); -+ first_row = png_voidcast(png_voidp, ptr); -+ } -+ -+ display->first_row = first_row; -+ display->row_bytes = row_bytes; -+ } -+ -+ if (passes == 0) -+ { -+ int result; -+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); -+ -+ display->local_row = row; -+ result = png_safe_execute(image, png_image_read_and_map, display); -+ display->local_row = NULL; -+ png_free(png_ptr, row); -+ -+ return result; -+ } -+ -+ else -+ { -+ png_alloc_size_t row_bytes = display->row_bytes; -+ -+ while (--passes >= 0) -+ { -+ png_uint_32 y = image->height; -+ png_bytep row = png_voidcast(png_bytep, display->first_row); -+ -+ while (y-- > 0) -+ { -+ png_read_row(png_ptr, row, NULL); -+ row += row_bytes; -+ } -+ } -+ -+ return 1; -+ } -+} -+ -+/* Just the row reading part of png_image_read. */ -+static int -+png_image_read_composite(png_voidp argument) -+{ -+ png_image_read_control *display = png_voidcast(png_image_read_control*, -+ argument); -+ png_imagep image = display->image; -+ png_structrp png_ptr = image->opaque->png_ptr; -+ int passes; -+ -+ switch (png_ptr->interlaced) -+ { -+ case PNG_INTERLACE_NONE: -+ passes = 1; -+ break; -+ -+ case PNG_INTERLACE_ADAM7: -+ passes = PNG_INTERLACE_ADAM7_PASSES; -+ break; -+ -+ default: -+ png_error(png_ptr, "unknown interlace type"); -+ } -+ -+ { -+ png_uint_32 height = image->height; -+ png_uint_32 width = image->width; -+ ptrdiff_t step_row = display->row_bytes; -+ unsigned int channels = -+ (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; -+ int pass; -+ -+ for (pass = 0; pass < passes; ++pass) -+ { -+ unsigned int startx, stepx, stepy; -+ png_uint_32 y; -+ -+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) -+ { -+ /* The row may be empty for a short image: */ -+ if (PNG_PASS_COLS(width, pass) == 0) -+ continue; -+ -+ startx = PNG_PASS_START_COL(pass) * channels; -+ stepx = PNG_PASS_COL_OFFSET(pass) * channels; -+ y = PNG_PASS_START_ROW(pass); -+ stepy = PNG_PASS_ROW_OFFSET(pass); -+ } -+ -+ else -+ { -+ y = 0; -+ startx = 0; -+ stepx = channels; -+ stepy = 1; -+ } -+ -+ for (; y<height; y += stepy) -+ { -+ png_bytep inrow = png_voidcast(png_bytep, display->local_row); -+ png_bytep outrow; -+ png_const_bytep end_row; -+ -+ /* Read the row, which is packed: */ -+ png_read_row(png_ptr, inrow, NULL); -+ -+ outrow = png_voidcast(png_bytep, display->first_row); -+ outrow += y * step_row; -+ end_row = outrow + width * channels; -+ -+ /* Now do the composition on each pixel in this row. */ -+ outrow += startx; -+ for (; outrow < end_row; outrow += stepx) -+ { -+ png_byte alpha = inrow[channels]; -+ -+ if (alpha > 0) /* else no change to the output */ -+ { -+ unsigned int c; -+ -+ for (c=0; c<channels; ++c) -+ { -+ png_uint_32 component = inrow[c]; -+ -+ if (alpha < 255) /* else just use component */ -+ { -+ /* This is PNG_OPTIMIZED_ALPHA, the component value -+ * is a linear 8-bit value. Combine this with the -+ * current outrow[c] value which is sRGB encoded. -+ * Arithmetic here is 16-bits to preserve the output -+ * values correctly. -+ */ -+ component *= 257*255; /* =65535 */ -+ component += (255-alpha)*png_sRGB_table[outrow[c]]; -+ -+ /* So 'component' is scaled by 255*65535 and is -+ * therefore appropriate for the sRGB to linear -+ * conversion table. -+ */ -+ component = PNG_sRGB_FROM_LINEAR(component); -+ } -+ -+ outrow[c] = (png_byte)component; -+ } -+ } -+ -+ inrow += channels+1; /* components and alpha channel */ -+ } -+ } -+ } -+ } -+ -+ return 1; -+} -+ -+/* The do_local_background case; called when all the following transforms are to -+ * be done: -+ * -+ * PNG_RGB_TO_GRAY -+ * PNG_COMPOSITE -+ * PNG_GAMMA -+ * -+ * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and -+ * PNG_COMPOSITE code performs gamma correction, so we get double gamma -+ * correction. The fix-up is to prevent the PNG_COMPOSITE operation from -+ * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha -+ * row and handles the removal or pre-multiplication of the alpha channel. -+ */ -+static int -+png_image_read_background(png_voidp argument) -+{ -+ png_image_read_control *display = png_voidcast(png_image_read_control*, -+ argument); -+ png_imagep image = display->image; -+ png_structrp png_ptr = image->opaque->png_ptr; -+ png_inforp info_ptr = image->opaque->info_ptr; -+ png_uint_32 height = image->height; -+ png_uint_32 width = image->width; -+ int pass, passes; -+ -+ /* Double check the convoluted logic below. We expect to get here with -+ * libpng doing rgb to gray and gamma correction but background processing -+ * left to the png_image_read_background function. The rows libpng produce -+ * might be 8 or 16-bit but should always have two channels; gray plus alpha. -+ */ -+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) -+ png_error(png_ptr, "lost rgb to gray"); -+ -+ if ((png_ptr->transformations & PNG_COMPOSE) != 0) -+ png_error(png_ptr, "unexpected compose"); -+ -+ if (png_get_channels(png_ptr, info_ptr) != 2) -+ png_error(png_ptr, "lost/gained channels"); -+ -+ /* Expect the 8-bit case to always remove the alpha channel */ -+ if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && -+ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ png_error(png_ptr, "unexpected 8-bit transformation"); -+ -+ switch (png_ptr->interlaced) -+ { -+ case PNG_INTERLACE_NONE: -+ passes = 1; -+ break; -+ -+ case PNG_INTERLACE_ADAM7: -+ passes = PNG_INTERLACE_ADAM7_PASSES; -+ break; -+ -+ default: -+ png_error(png_ptr, "unknown interlace type"); -+ } -+ -+ /* Use direct access to info_ptr here because otherwise the simplified API -+ * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is -+ * checking the value after libpng expansions, not the original value in the -+ * PNG. -+ */ -+ switch (info_ptr->bit_depth) -+ { -+ default: -+ png_error(png_ptr, "unexpected bit depth"); -+ break; -+ -+ case 8: -+ /* 8-bit sRGB gray values with an alpha channel; the alpha channel is -+ * to be removed by composing on a background: either the row if -+ * display->background is NULL or display->background->green if not. -+ * Unlike the code above ALPHA_OPTIMIZED has *not* been done. -+ */ -+ { -+ png_bytep first_row = png_voidcast(png_bytep, display->first_row); -+ ptrdiff_t step_row = display->row_bytes; -+ -+ for (pass = 0; pass < passes; ++pass) -+ { -+ png_bytep row = png_voidcast(png_bytep, -+ display->first_row); -+ unsigned int startx, stepx, stepy; -+ png_uint_32 y; -+ -+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) -+ { -+ /* The row may be empty for a short image: */ -+ if (PNG_PASS_COLS(width, pass) == 0) -+ continue; -+ -+ startx = PNG_PASS_START_COL(pass); -+ stepx = PNG_PASS_COL_OFFSET(pass); -+ y = PNG_PASS_START_ROW(pass); -+ stepy = PNG_PASS_ROW_OFFSET(pass); -+ } -+ -+ else -+ { -+ y = 0; -+ startx = 0; -+ stepx = stepy = 1; -+ } -+ -+ if (display->background == NULL) -+ { -+ for (; y<height; y += stepy) -+ { -+ png_bytep inrow = png_voidcast(png_bytep, -+ display->local_row); -+ png_bytep outrow = first_row + y * step_row; -+ png_const_bytep end_row = outrow + width; -+ -+ /* Read the row, which is packed: */ -+ png_read_row(png_ptr, inrow, NULL); -+ -+ /* Now do the composition on each pixel in this row. */ -+ outrow += startx; -+ for (; outrow < end_row; outrow += stepx) -+ { -+ png_byte alpha = inrow[1]; -+ -+ if (alpha > 0) /* else no change to the output */ -+ { -+ png_uint_32 component = inrow[0]; -+ -+ if (alpha < 255) /* else just use component */ -+ { -+ /* Since PNG_OPTIMIZED_ALPHA was not set it is -+ * necessary to invert the sRGB transfer -+ * function and multiply the alpha out. -+ */ -+ component = png_sRGB_table[component] * alpha; -+ component += png_sRGB_table[outrow[0]] * -+ (255-alpha); -+ component = PNG_sRGB_FROM_LINEAR(component); -+ } -+ -+ outrow[0] = (png_byte)component; -+ } -+ -+ inrow += 2; /* gray and alpha channel */ -+ } -+ } -+ } -+ -+ else /* constant background value */ -+ { -+ png_byte background8 = display->background->green; -+ png_uint_16 background = png_sRGB_table[background8]; -+ -+ for (; y<height; y += stepy) -+ { -+ png_bytep inrow = png_voidcast(png_bytep, -+ display->local_row); -+ png_bytep outrow = first_row + y * step_row; -+ png_const_bytep end_row = outrow + width; -+ -+ /* Read the row, which is packed: */ -+ png_read_row(png_ptr, inrow, NULL); -+ -+ /* Now do the composition on each pixel in this row. */ -+ outrow += startx; -+ for (; outrow < end_row; outrow += stepx) -+ { -+ png_byte alpha = inrow[1]; -+ -+ if (alpha > 0) /* else use background */ -+ { -+ png_uint_32 component = inrow[0]; -+ -+ if (alpha < 255) /* else just use component */ -+ { -+ component = png_sRGB_table[component] * alpha; -+ component += background * (255-alpha); -+ component = PNG_sRGB_FROM_LINEAR(component); -+ } -+ -+ outrow[0] = (png_byte)component; -+ } -+ -+ else -+ outrow[0] = background8; -+ -+ inrow += 2; /* gray and alpha channel */ -+ } -+ -+ row += display->row_bytes; -+ } -+ } -+ } -+ } -+ break; -+ -+ case 16: -+ /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must -+ * still be done and, maybe, the alpha channel removed. This code also -+ * handles the alpha-first option. -+ */ -+ { -+ png_uint_16p first_row = png_voidcast(png_uint_16p, -+ display->first_row); -+ /* The division by two is safe because the caller passed in a -+ * stride which was multiplied by 2 (below) to get row_bytes. -+ */ -+ ptrdiff_t step_row = display->row_bytes / 2; -+ int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; -+ unsigned int outchannels = 1+preserve_alpha; -+ int swap_alpha = 0; -+ -+# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED -+ if (preserve_alpha != 0 && -+ (image->format & PNG_FORMAT_FLAG_AFIRST) != 0) -+ swap_alpha = 1; -+# endif -+ -+ for (pass = 0; pass < passes; ++pass) -+ { -+ unsigned int startx, stepx, stepy; -+ png_uint_32 y; -+ -+ /* The 'x' start and step are adjusted to output components here. -+ */ -+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) -+ { -+ /* The row may be empty for a short image: */ -+ if (PNG_PASS_COLS(width, pass) == 0) -+ continue; -+ -+ startx = PNG_PASS_START_COL(pass) * outchannels; -+ stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; -+ y = PNG_PASS_START_ROW(pass); -+ stepy = PNG_PASS_ROW_OFFSET(pass); -+ } -+ -+ else -+ { -+ y = 0; -+ startx = 0; -+ stepx = outchannels; -+ stepy = 1; -+ } -+ -+ for (; y<height; y += stepy) -+ { -+ png_const_uint_16p inrow; -+ png_uint_16p outrow = first_row + y*step_row; -+ png_uint_16p end_row = outrow + width * outchannels; -+ -+ /* Read the row, which is packed: */ -+ png_read_row(png_ptr, png_voidcast(png_bytep, -+ display->local_row), NULL); -+ inrow = png_voidcast(png_const_uint_16p, display->local_row); -+ -+ /* Now do the pre-multiplication on each pixel in this row. -+ */ -+ outrow += startx; -+ for (; outrow < end_row; outrow += stepx) -+ { -+ png_uint_32 component = inrow[0]; -+ png_uint_16 alpha = inrow[1]; -+ -+ if (alpha > 0) /* else 0 */ -+ { -+ if (alpha < 65535) /* else just use component */ -+ { -+ component *= alpha; -+ component += 32767; -+ component /= 65535; -+ } -+ } -+ -+ else -+ component = 0; -+ -+ outrow[swap_alpha] = (png_uint_16)component; -+ if (preserve_alpha != 0) -+ outrow[1 ^ swap_alpha] = alpha; -+ -+ inrow += 2; /* components and alpha channel */ -+ } -+ } -+ } -+ } -+ break; -+ } -+ -+ return 1; -+} -+ -+/* The guts of png_image_finish_read as a png_safe_execute callback. */ -+static int -+png_image_read_direct(png_voidp argument) -+{ -+ png_image_read_control *display = png_voidcast(png_image_read_control*, -+ argument); -+ png_imagep image = display->image; -+ png_structrp png_ptr = image->opaque->png_ptr; -+ png_inforp info_ptr = image->opaque->info_ptr; -+ -+ png_uint_32 format = image->format; -+ int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; -+ int do_local_compose = 0; -+ int do_local_background = 0; /* to avoid double gamma correction bug */ -+ int passes = 0; -+ -+ /* Add transforms to ensure the correct output format is produced then check -+ * that the required implementation support is there. Always expand; always -+ * need 8 bits minimum, no palette and expanded tRNS. -+ */ -+ png_set_expand(png_ptr); -+ -+ /* Now check the format to see if it was modified. */ -+ { -+ png_uint_32 base_format = png_image_format(png_ptr) & -+ ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; -+ png_uint_32 change = format ^ base_format; -+ png_fixed_point output_gamma; -+ int mode; /* alpha mode */ -+ -+ /* Do this first so that we have a record if rgb to gray is happening. */ -+ if ((change & PNG_FORMAT_FLAG_COLOR) != 0) -+ { -+ /* gray<->color transformation required. */ -+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0) -+ png_set_gray_to_rgb(png_ptr); -+ -+ else -+ { -+ /* libpng can't do both rgb to gray and -+ * background/pre-multiplication if there is also significant gamma -+ * correction, because both operations require linear colors and -+ * the code only supports one transform doing the gamma correction. -+ * Handle this by doing the pre-multiplication or background -+ * operation in this code, if necessary. -+ * -+ * TODO: fix this by rewriting pngrtran.c (!) -+ * -+ * For the moment (given that fixing this in pngrtran.c is an -+ * enormous change) 'do_local_background' is used to indicate that -+ * the problem exists. -+ */ -+ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ do_local_background = 1/*maybe*/; -+ -+ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -+ PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); -+ } -+ -+ change &= ~PNG_FORMAT_FLAG_COLOR; -+ } -+ -+ /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. -+ */ -+ { -+ png_fixed_point input_gamma_default; -+ -+ if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && -+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) -+ input_gamma_default = PNG_GAMMA_LINEAR; -+ else -+ input_gamma_default = PNG_DEFAULT_sRGB; -+ -+ /* Call png_set_alpha_mode to set the default for the input gamma; the -+ * output gamma is set by a second call below. -+ */ -+ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); -+ } -+ -+ if (linear != 0) -+ { -+ /* If there *is* an alpha channel in the input it must be multiplied -+ * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. -+ */ -+ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ mode = PNG_ALPHA_STANDARD; /* associated alpha */ -+ -+ else -+ mode = PNG_ALPHA_PNG; -+ -+ output_gamma = PNG_GAMMA_LINEAR; -+ } -+ -+ else -+ { -+ mode = PNG_ALPHA_PNG; -+ output_gamma = PNG_DEFAULT_sRGB; -+ } -+ -+ /* If 'do_local_background' is set check for the presence of gamma -+ * correction; this is part of the work-round for the libpng bug -+ * described above. -+ * -+ * TODO: fix libpng and remove this. -+ */ -+ if (do_local_background != 0) -+ { -+ png_fixed_point gtest; -+ -+ /* This is 'png_gamma_threshold' from pngrtran.c; the test used for -+ * gamma correction, the screen gamma hasn't been set on png_struct -+ * yet; it's set below. png_struct::gamma, however, is set to the -+ * final value. -+ */ -+ if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, -+ PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) -+ do_local_background = 0; -+ -+ else if (mode == PNG_ALPHA_STANDARD) -+ { -+ do_local_background = 2/*required*/; -+ mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ -+ } -+ -+ /* else leave as 1 for the checks below */ -+ } -+ -+ /* If the bit-depth changes then handle that here. */ -+ if ((change & PNG_FORMAT_FLAG_LINEAR) != 0) -+ { -+ if (linear != 0 /*16-bit output*/) -+ png_set_expand_16(png_ptr); -+ -+ else /* 8-bit output */ -+ png_set_scale_16(png_ptr); -+ -+ change &= ~PNG_FORMAT_FLAG_LINEAR; -+ } -+ -+ /* Now the background/alpha channel changes. */ -+ if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+ /* Removing an alpha channel requires composition for the 8-bit -+ * formats; for the 16-bit it is already done, above, by the -+ * pre-multiplication and the channel just needs to be stripped. -+ */ -+ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+ /* If RGB->gray is happening the alpha channel must be left and the -+ * operation completed locally. -+ * -+ * TODO: fix libpng and remove this. -+ */ -+ if (do_local_background != 0) -+ do_local_background = 2/*required*/; -+ -+ /* 16-bit output: just remove the channel */ -+ else if (linear != 0) /* compose on black (well, pre-multiply) */ -+ png_set_strip_alpha(png_ptr); -+ -+ /* 8-bit output: do an appropriate compose */ -+ else if (display->background != NULL) -+ { -+ png_color_16 c; -+ -+ c.index = 0; /*unused*/ -+ c.red = display->background->red; -+ c.green = display->background->green; -+ c.blue = display->background->blue; -+ c.gray = display->background->green; -+ -+ /* This is always an 8-bit sRGB value, using the 'green' channel -+ * for gray is much better than calculating the luminance here; -+ * we can get off-by-one errors in that calculation relative to -+ * the app expectations and that will show up in transparent -+ * pixels. -+ */ -+ png_set_background_fixed(png_ptr, &c, -+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, -+ 0/*gamma: not used*/); -+ } -+ -+ else /* compose on row: implemented below. */ -+ { -+ do_local_compose = 1; -+ /* This leaves the alpha channel in the output, so it has to be -+ * removed by the code below. Set the encoding to the 'OPTIMIZE' -+ * one so the code only has to hack on the pixels that require -+ * composition. -+ */ -+ mode = PNG_ALPHA_OPTIMIZED; -+ } -+ } -+ -+ else /* output needs an alpha channel */ -+ { -+ /* This is tricky because it happens before the swap operation has -+ * been accomplished; however, the swap does *not* swap the added -+ * alpha channel (weird API), so it must be added in the correct -+ * place. -+ */ -+ png_uint_32 filler; /* opaque filler */ -+ int where; -+ -+ if (linear != 0) -+ filler = 65535; -+ -+ else -+ filler = 255; -+ -+# ifdef PNG_FORMAT_AFIRST_SUPPORTED -+ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) -+ { -+ where = PNG_FILLER_BEFORE; -+ change &= ~PNG_FORMAT_FLAG_AFIRST; -+ } -+ -+ else -+# endif -+ where = PNG_FILLER_AFTER; -+ -+ png_set_add_alpha(png_ptr, filler, where); -+ } -+ -+ /* This stops the (irrelevant) call to swap_alpha below. */ -+ change &= ~PNG_FORMAT_FLAG_ALPHA; -+ } -+ -+ /* Now set the alpha mode correctly; this is always done, even if there is -+ * no alpha channel in either the input or the output because it correctly -+ * sets the output gamma. -+ */ -+ png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); -+ -+# ifdef PNG_FORMAT_BGR_SUPPORTED -+ if ((change & PNG_FORMAT_FLAG_BGR) != 0) -+ { -+ /* Check only the output format; PNG is never BGR; don't do this if -+ * the output is gray, but fix up the 'format' value in that case. -+ */ -+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0) -+ png_set_bgr(png_ptr); -+ -+ else -+ format &= ~PNG_FORMAT_FLAG_BGR; -+ -+ change &= ~PNG_FORMAT_FLAG_BGR; -+ } -+# endif -+ -+# ifdef PNG_FORMAT_AFIRST_SUPPORTED -+ if ((change & PNG_FORMAT_FLAG_AFIRST) != 0) -+ { -+ /* Only relevant if there is an alpha channel - it's particularly -+ * important to handle this correctly because do_local_compose may -+ * be set above and then libpng will keep the alpha channel for this -+ * code to remove. -+ */ -+ if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+ /* Disable this if doing a local background, -+ * TODO: remove this when local background is no longer required. -+ */ -+ if (do_local_background != 2) -+ png_set_swap_alpha(png_ptr); -+ } -+ -+ else -+ format &= ~PNG_FORMAT_FLAG_AFIRST; -+ -+ change &= ~PNG_FORMAT_FLAG_AFIRST; -+ } -+# endif -+ -+ /* If the *output* is 16-bit then we need to check for a byte-swap on this -+ * architecture. -+ */ -+ if (linear != 0) -+ { -+ PNG_CONST png_uint_16 le = 0x0001; -+ -+ if ((*(png_const_bytep) & le) != 0) -+ png_set_swap(png_ptr); -+ } -+ -+ /* If change is not now 0 some transformation is missing - error out. */ -+ if (change != 0) -+ png_error(png_ptr, "png_read_image: unsupported transformation"); -+ } -+ -+ PNG_SKIP_CHUNKS(png_ptr); -+ -+ /* Update the 'info' structure and make sure the result is as required; first -+ * make sure to turn on the interlace handling if it will be required -+ * (because it can't be turned on *after* the call to png_read_update_info!) -+ * -+ * TODO: remove the do_local_background fixup below. -+ */ -+ if (do_local_compose == 0 && do_local_background != 2) -+ passes = png_set_interlace_handling(png_ptr); -+ -+ png_read_update_info(png_ptr, info_ptr); -+ -+ { -+ png_uint_32 info_format = 0; -+ -+ if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) -+ info_format |= PNG_FORMAT_FLAG_COLOR; -+ -+ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) -+ { -+ /* do_local_compose removes this channel below. */ -+ if (do_local_compose == 0) -+ { -+ /* do_local_background does the same if required. */ -+ if (do_local_background != 2 || -+ (format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ info_format |= PNG_FORMAT_FLAG_ALPHA; -+ } -+ } -+ -+ else if (do_local_compose != 0) /* internal error */ -+ png_error(png_ptr, "png_image_read: alpha channel lost"); -+ -+ if (info_ptr->bit_depth == 16) -+ info_format |= PNG_FORMAT_FLAG_LINEAR; -+ -+# ifdef PNG_FORMAT_BGR_SUPPORTED -+ if ((png_ptr->transformations & PNG_BGR) != 0) -+ info_format |= PNG_FORMAT_FLAG_BGR; -+# endif -+ -+# ifdef PNG_FORMAT_AFIRST_SUPPORTED -+ if (do_local_background == 2) -+ { -+ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) -+ info_format |= PNG_FORMAT_FLAG_AFIRST; -+ } -+ -+ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || -+ ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && -+ (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) -+ { -+ if (do_local_background == 2) -+ png_error(png_ptr, "unexpected alpha swap transformation"); -+ -+ info_format |= PNG_FORMAT_FLAG_AFIRST; -+ } -+# endif -+ -+ /* This is actually an internal error. */ -+ if (info_format != format) -+ png_error(png_ptr, "png_read_image: invalid transformations"); -+ } -+ -+ /* Now read the rows. If do_local_compose is set then it is necessary to use -+ * a local row buffer. The output will be GA, RGBA or BGRA and must be -+ * converted to G, RGB or BGR as appropriate. The 'local_row' member of the -+ * display acts as a flag. -+ */ -+ { -+ png_voidp first_row = display->buffer; -+ ptrdiff_t row_bytes = display->row_stride; -+ -+ if (linear != 0) -+ row_bytes *= 2; -+ -+ /* The following expression is designed to work correctly whether it gives -+ * a signed or an unsigned result. -+ */ -+ if (row_bytes < 0) -+ { -+ char *ptr = png_voidcast(char*, first_row); -+ ptr += (image->height-1) * (-row_bytes); -+ first_row = png_voidcast(png_voidp, ptr); -+ } -+ -+ display->first_row = first_row; -+ display->row_bytes = row_bytes; -+ } -+ -+ if (do_local_compose != 0) -+ { -+ int result; -+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); -+ -+ display->local_row = row; -+ result = png_safe_execute(image, png_image_read_composite, display); -+ display->local_row = NULL; -+ png_free(png_ptr, row); -+ -+ return result; -+ } -+ -+ else if (do_local_background == 2) -+ { -+ int result; -+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); -+ -+ display->local_row = row; -+ result = png_safe_execute(image, png_image_read_background, display); -+ display->local_row = NULL; -+ png_free(png_ptr, row); -+ -+ return result; -+ } -+ -+ else -+ { -+ png_alloc_size_t row_bytes = display->row_bytes; -+ -+ while (--passes >= 0) -+ { -+ png_uint_32 y = image->height; -+ png_bytep row = png_voidcast(png_bytep, display->first_row); -+ -+ while (y-- > 0) -+ { -+ png_read_row(png_ptr, row, NULL); -+ row += row_bytes; -+ } -+ } -+ -+ return 1; -+ } -+} -+ -+int PNGAPI -+png_image_finish_read(png_imagep image, png_const_colorp background, -+ void *buffer, png_int_32 row_stride, void *colormap) -+{ -+ if (image != NULL && image->version == PNG_IMAGE_VERSION) -+ { -+ png_uint_32 check; -+ -+ if (row_stride == 0) -+ row_stride = PNG_IMAGE_ROW_STRIDE(*image); -+ -+ if (row_stride < 0) -+ check = -row_stride; -+ -+ else -+ check = row_stride; -+ -+ if (image->opaque != NULL && buffer != NULL && -+ check >= PNG_IMAGE_ROW_STRIDE(*image)) -+ { -+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || -+ (image->colormap_entries > 0 && colormap != NULL)) -+ { -+ int result; -+ png_image_read_control display; -+ -+ memset(&display, 0, (sizeof display)); -+ display.image = image; -+ display.buffer = buffer; -+ display.row_stride = row_stride; -+ display.colormap = colormap; -+ display.background = background; -+ display.local_row = NULL; -+ -+ /* Choose the correct 'end' routine; for the color-map case all the -+ * setup has already been done. -+ */ -+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) -+ result = -+ png_safe_execute(image, png_image_read_colormap, &display) && -+ png_safe_execute(image, png_image_read_colormapped, &display); -+ -+ else -+ result = -+ png_safe_execute(image, png_image_read_direct, &display); -+ -+ png_image_free(image); -+ return result; -+ } -+ -+ else -+ return png_image_error(image, -+ "png_image_finish_read[color-map]: no color-map"); -+ } -+ -+ else -+ return png_image_error(image, -+ "png_image_finish_read: invalid argument"); -+ } -+ -+ else if (image != NULL) -+ return png_image_error(image, -+ "png_image_finish_read: damaged PNG_IMAGE_VERSION"); -+ -+ return 0; -+} -+ -+#endif /* SIMPLIFIED_READ */ -+#endif /* READ */ ---- ./jdk/src/share/native/sun/awt/libpng/pngrio.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngrio.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.0 [January 6, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -57,7 +57,7 @@ - * to read more then 64K on a 16 bit machine. - */ - void /* PRIVATE */ --png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) -+png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length) - { - png_debug1(4, "reading %d bytes", (int)length); - -@@ -74,7 +74,6 @@ - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ --# ifndef USE_FAR_KEYWORD - void PNGCBAPI - png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) - { -@@ -86,68 +85,11 @@ - /* fread() returns 0 on error, so it is OK to store this in a png_size_t - * instead of an int, which is what fread() actually returns. - */ -- check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr); -+ check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Read Error"); - } --# else --/* This is the model-independent version. Since the standard I/O library -- can't handle far buffers in the medium and small models, we have to copy -- the data. --*/ -- --#define NEAR_BUF_SIZE 1024 --#define MIN(a,b) (a <= b ? a : b) -- --static void PNGCBAPI --png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) --{ -- png_size_t check; -- png_byte *n_data; -- png_FILE_p io_ptr; -- -- if (png_ptr == NULL) -- return; -- -- /* Check if data really is near. If so, use usual code. */ -- n_data = (png_byte *)CVT_PTR_NOCHECK(data); -- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); -- -- if ((png_bytep)n_data == data) -- { -- check = fread(n_data, 1, length, io_ptr); -- } -- -- else -- { -- png_byte buf[NEAR_BUF_SIZE]; -- png_size_t read, remaining, err; -- check = 0; -- remaining = length; -- -- do -- { -- read = MIN(NEAR_BUF_SIZE, remaining); -- err = fread(buf, 1, read, io_ptr); -- png_memcpy(data, buf, read); /* copy far buffer to near buffer */ -- -- if (err != read) -- break; -- -- else -- check += err; -- -- data += read; -- remaining -= read; -- } -- while (remaining != 0); -- } -- -- if ((png_uint_32)check != (png_uint_32)length) -- png_error(png_ptr, "read Error"); --} --# endif - #endif - - /* This function allows the application to supply a new input function -@@ -170,7 +112,7 @@ - * be used. - */ - void PNGAPI --png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, -+png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn) - { - if (png_ptr == NULL) -@@ -188,6 +130,7 @@ - png_ptr->read_data_fn = read_data_fn; - #endif - -+#ifdef PNG_WRITE_SUPPORTED - /* It is an error to write to a read device */ - if (png_ptr->write_data_fn != NULL) - { -@@ -196,9 +139,10 @@ - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } -+#endif - - #ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->output_flush_fn = NULL; - #endif - } --#endif /* PNG_READ_SUPPORTED */ -+#endif /* READ */ ---- ./jdk/src/share/native/sun/awt/libpng/pngrtran.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngrtran.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -50,7 +50,7 @@ - - /* Set the action on getting a CRC error for an ancillary or critical chunk. */ - void PNGAPI --png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) -+png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) - { - png_debug(1, "in png_set_crc_action"); - -@@ -116,16 +116,47 @@ - } - } - -+#ifdef PNG_READ_TRANSFORMS_SUPPORTED -+/* Is it OK to set a transformation now? Only if png_start_read_image or -+ * png_read_update_info have not been called. It is not necessary for the IHDR -+ * to have been read in all cases; the need_IHDR parameter allows for this -+ * check too. -+ */ -+static int -+png_rtran_ok(png_structrp png_ptr, int need_IHDR) -+{ -+ if (png_ptr != NULL) -+ { -+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) -+ png_app_error(png_ptr, -+ "invalid after png_start_read_image or png_read_update_info"); -+ -+ else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_app_error(png_ptr, "invalid before the PNG header has been read"); -+ -+ else -+ { -+ /* Turn on failure to initialize correctly for all transforms. */ -+ png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; -+ -+ return 1; /* Ok */ -+ } -+ } -+ -+ return 0; /* no png_error possible! */ -+} -+#endif -+ - #ifdef PNG_READ_BACKGROUND_SUPPORTED - /* Handle alpha and tRNS via a background color */ - void PNGFAPI --png_set_background_fixed(png_structp png_ptr, -+png_set_background_fixed(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma) - { - png_debug(1, "in png_set_background_fixed"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL) - return; - - if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) -@@ -138,11 +169,10 @@ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - -- png_memcpy(&(png_ptr->background), background_color, -- png_sizeof(png_color_16)); -+ png_ptr->background = *background_color; - png_ptr->background_gamma = background_gamma; - png_ptr->background_gamma_type = (png_byte)(background_gamma_code); -- if (need_expand) -+ if (need_expand != 0) - png_ptr->transformations |= PNG_BACKGROUND_EXPAND; - else - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; -@@ -150,7 +180,7 @@ - - # ifdef PNG_FLOATING_POINT_SUPPORTED - void PNGAPI --png_set_background(png_structp png_ptr, -+png_set_background(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma) - { -@@ -166,11 +196,11 @@ - */ - #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - void PNGAPI --png_set_scale_16(png_structp png_ptr) -+png_set_scale_16(png_structrp png_ptr) - { - png_debug(1, "in png_set_scale_16"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_SCALE_16_TO_8; -@@ -180,11 +210,11 @@ - #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* Chop 16-bit depth files to 8-bit depth */ - void PNGAPI --png_set_strip_16(png_structp png_ptr) -+png_set_strip_16(png_structrp png_ptr) - { - png_debug(1, "in png_set_strip_16"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_16_TO_8; -@@ -193,11 +223,11 @@ - - #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - void PNGAPI --png_set_strip_alpha(png_structp png_ptr) -+png_set_strip_alpha(png_structrp png_ptr) - { - png_debug(1, "in png_set_strip_alpha"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_STRIP_ALPHA; -@@ -206,7 +236,7 @@ - - #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) - static png_fixed_point --translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, -+translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, - int is_screen) - { - /* Check for flag values. The main reason for having the old Mac value as a -@@ -222,8 +252,10 @@ - */ - # ifdef PNG_READ_sRGB_SUPPORTED - png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; -+# else -+ PNG_UNUSED(png_ptr) - # endif -- if (is_screen) -+ if (is_screen != 0) - output_gamma = PNG_GAMMA_sRGB; - else - output_gamma = PNG_GAMMA_sRGB_INVERSE; -@@ -232,7 +264,7 @@ - else if (output_gamma == PNG_GAMMA_MAC_18 || - output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) - { -- if (is_screen) -+ if (is_screen != 0) - output_gamma = PNG_GAMMA_MAC_OLD; - else - output_gamma = PNG_GAMMA_MAC_INVERSE; -@@ -243,7 +275,7 @@ - - # ifdef PNG_FLOATING_POINT_SUPPORTED - static png_fixed_point --convert_gamma_value(png_structp png_ptr, double output_gamma) -+convert_gamma_value(png_structrp png_ptr, double output_gamma) - { - /* The following silently ignores cases where fixed point (times 100,000) - * gamma values are passed to the floating point API. This is safe and it -@@ -268,7 +300,7 @@ - - #ifdef PNG_READ_ALPHA_MODE_SUPPORTED - void PNGFAPI --png_set_alpha_mode_fixed(png_structp png_ptr, int mode, -+png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, - png_fixed_point output_gamma) - { - int compose = 0; -@@ -276,7 +308,7 @@ - - png_debug(1, "in png_set_alpha_mode"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); -@@ -348,8 +380,11 @@ - * the side effect that the gamma in a second call to png_set_alpha_mode will - * be ignored.) - */ -- if (png_ptr->gamma == 0) -- png_ptr->gamma = file_gamma; -+ if (png_ptr->colorspace.gamma == 0) -+ { -+ png_ptr->colorspace.gamma = file_gamma; -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; -+ } - - /* But always set the output gamma: */ - png_ptr->screen_gamma = output_gamma; -@@ -357,28 +392,25 @@ - /* Finally, if pre-multiplying, set the background fields to achieve the - * desired result. - */ -- if (compose) -+ if (compose != 0) - { - /* And obtain alpha pre-multiplication by composing on black: */ -- png_memset(&png_ptr->background, 0, sizeof png_ptr->background); -- png_ptr->background_gamma = png_ptr->gamma; /* just in case */ -+ memset(&png_ptr->background, 0, (sizeof png_ptr->background)); -+ png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; - -- if (png_ptr->transformations & PNG_COMPOSE) -+ if ((png_ptr->transformations & PNG_COMPOSE) != 0) - png_error(png_ptr, - "conflicting calls to set alpha mode and background"); - - png_ptr->transformations |= PNG_COMPOSE; - } -- -- /* New API, make sure apps call the correct initializers: */ -- png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; - } - - # ifdef PNG_FLOATING_POINT_SUPPORTED - void PNGAPI --png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) -+png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) - { - png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, - output_gamma)); -@@ -398,31 +430,31 @@ - - typedef struct png_dsort_struct - { -- struct png_dsort_struct FAR * next; -+ struct png_dsort_struct * next; - png_byte left; - png_byte right; - } png_dsort; --typedef png_dsort FAR * png_dsortp; --typedef png_dsort FAR * FAR * png_dsortpp; -+typedef png_dsort * png_dsortp; -+typedef png_dsort * * png_dsortpp; - - void PNGAPI --png_set_quantize(png_structp png_ptr, png_colorp palette, -+png_set_quantize(png_structrp png_ptr, png_colorp palette, - int num_palette, int maximum_colors, png_const_uint_16p histogram, - int full_quantize) - { - png_debug(1, "in png_set_quantize"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_QUANTIZE; - -- if (!full_quantize) -+ if (full_quantize == 0) - { - int i; - - png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, -- (png_uint_32)(num_palette * png_sizeof(png_byte))); -+ (png_uint_32)(num_palette * (sizeof (png_byte)))); - for (i = 0; i < num_palette; i++) - png_ptr->quantize_index[i] = (png_byte)i; - } -@@ -439,7 +471,7 @@ - - /* Initialize an array to sort colors */ - png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, -- (png_uint_32)(num_palette * png_sizeof(png_byte))); -+ (png_uint_32)(num_palette * (sizeof (png_byte)))); - - /* Initialize the quantize_sort array */ - for (i = 0; i < num_palette; i++) -@@ -472,12 +504,12 @@ - } - } - -- if (done) -+ if (done != 0) - break; - } - - /* Swap the palette around, and set up a table, if necessary */ -- if (full_quantize) -+ if (full_quantize != 0) - { - int j = num_palette; - -@@ -573,9 +605,9 @@ - - /* Initialize palette index arrays */ - png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, -- (png_uint_32)(num_palette * png_sizeof(png_byte))); -+ (png_uint_32)(num_palette * (sizeof (png_byte)))); - png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, -- (png_uint_32)(num_palette * png_sizeof(png_byte))); -+ (png_uint_32)(num_palette * (sizeof (png_byte)))); - - /* Initialize the sort array */ - for (i = 0; i < num_palette; i++) -@@ -585,7 +617,7 @@ - } - - hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * -- png_sizeof(png_dsortp))); -+ (sizeof (png_dsortp)))); - - num_new_palette = num_palette; - -@@ -615,7 +647,7 @@ - { - - t = (png_dsortp)png_malloc_warn(png_ptr, -- (png_uint_32)(png_sizeof(png_dsort))); -+ (png_uint_32)(sizeof (png_dsort))); - - if (t == NULL) - break; -@@ -660,7 +692,7 @@ - num_new_palette--; - palette[png_ptr->index_to_palette[j]] - = palette[num_new_palette]; -- if (!full_quantize) -+ if (full_quantize == 0) - { - int k; - -@@ -728,7 +760,7 @@ - } - png_ptr->num_palette = (png_uint_16)num_palette; - -- if (full_quantize) -+ if (full_quantize != 0) - { - int i; - png_bytep distance; -@@ -740,12 +772,12 @@ - png_size_t num_entries = ((png_size_t)1 << total_bits); - - png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, -- (png_uint_32)(num_entries * png_sizeof(png_byte))); -+ (png_uint_32)(num_entries * (sizeof (png_byte)))); - - distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * -- png_sizeof(png_byte))); -- -- png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); -+ (sizeof (png_byte)))); -+ -+ memset(distance, 0xff, num_entries * (sizeof (png_byte))); - - for (i = 0; i < num_palette; i++) - { -@@ -790,23 +822,22 @@ - png_free(png_ptr, distance); - } - } --#endif /* PNG_READ_QUANTIZE_SUPPORTED */ -+#endif /* READ_QUANTIZE */ - - #ifdef PNG_READ_GAMMA_SUPPORTED - void PNGFAPI --png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, -+png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, - png_fixed_point file_gamma) - { - png_debug(1, "in png_set_gamma_fixed"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - /* New in libpng-1.5.4 - reserve particular negative values as flags. */ - scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); - file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); - --#if PNG_LIBPNG_VER >= 10600 - /* Checking the gamma values for being >0 was added in 1.5.4 along with the - * premultiplied alpha support; this actually hides an undocumented feature - * of the previous implementation which allowed gamma processing to be -@@ -815,31 +846,32 @@ - * accept '0' for the gamma value it takes, because it isn't always used. - * - * Since this is an API change (albeit a very minor one that removes an -- * undocumented API feature) it will not be made until libpng-1.6.0. -+ * undocumented API feature) the following checks were only enabled in -+ * libpng-1.6.0. - */ - if (file_gamma <= 0) - png_error(png_ptr, "invalid file gamma in png_set_gamma"); - - if (scrn_gamma <= 0) - png_error(png_ptr, "invalid screen gamma in png_set_gamma"); --#endif - - /* Set the gamma values unconditionally - this overrides the value in the PNG - * file if a gAMA chunk was present. png_set_alpha_mode provides a - * different, easier, way to default the file gamma. - */ -- png_ptr->gamma = file_gamma; -+ png_ptr->colorspace.gamma = file_gamma; -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - png_ptr->screen_gamma = scrn_gamma; - } - - # ifdef PNG_FLOATING_POINT_SUPPORTED - void PNGAPI --png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) -+png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) - { - png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), - convert_gamma_value(png_ptr, file_gamma)); - } --# endif /* FLOATING_POINT_SUPPORTED */ -+# endif /* FLOATING_POINT */ - #endif /* READ_GAMMA */ - - #ifdef PNG_READ_EXPAND_SUPPORTED -@@ -848,15 +880,14 @@ - * to alpha channels. - */ - void PNGAPI --png_set_expand(png_structp png_ptr) -+png_set_expand(png_structrp png_ptr) - { - png_debug(1, "in png_set_expand"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - } - - /* GRR 19990627: the following three functions currently are identical -@@ -879,100 +910,95 @@ - - /* Expand paletted images to RGB. */ - void PNGAPI --png_set_palette_to_rgb(png_structp png_ptr) -+png_set_palette_to_rgb(png_structrp png_ptr) - { - png_debug(1, "in png_set_palette_to_rgb"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - } - - /* Expand grayscale images of less than 8-bit depth to 8 bits. */ - void PNGAPI --png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) -+png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) - { - png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_EXPAND; -- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - } - -- -- - /* Expand tRNS chunks to alpha channels. */ - void PNGAPI --png_set_tRNS_to_alpha(png_structp png_ptr) -+png_set_tRNS_to_alpha(png_structrp png_ptr) - { - png_debug(1, "in png_set_tRNS_to_alpha"); - -+ if (png_rtran_ok(png_ptr, 0) == 0) -+ return; -+ - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - } --#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ -+#endif /* READ_EXPAND */ - - #ifdef PNG_READ_EXPAND_16_SUPPORTED - /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise - * it may not work correctly.) - */ - void PNGAPI --png_set_expand_16(png_structp png_ptr) -+png_set_expand_16(png_structrp png_ptr) - { - png_debug(1, "in png_set_expand_16"); - -- if (png_ptr == NULL) -+ if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); -- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -- -- /* New API, make sure apps call the correct initializers: */ -- png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; - } - #endif - - #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - void PNGAPI --png_set_gray_to_rgb(png_structp png_ptr) -+png_set_gray_to_rgb(png_structrp png_ptr) - { - png_debug(1, "in png_set_gray_to_rgb"); - -- if (png_ptr != NULL) -- { -- /* Because rgb must be 8 bits or more: */ -- png_set_expand_gray_1_2_4_to_8(png_ptr); -- png_ptr->transformations |= PNG_GRAY_TO_RGB; -- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -- } -+ if (png_rtran_ok(png_ptr, 0) == 0) -+ return; -+ -+ /* Because rgb must be 8 bits or more: */ -+ png_set_expand_gray_1_2_4_to_8(png_ptr); -+ png_ptr->transformations |= PNG_GRAY_TO_RGB; - } - #endif - - #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - void PNGFAPI --png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, -+png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, - png_fixed_point red, png_fixed_point green) - { - png_debug(1, "in png_set_rgb_to_gray"); - -- if (png_ptr == NULL) -+ /* Need the IHDR here because of the check on color_type below. */ -+ /* TODO: fix this */ -+ if (png_rtran_ok(png_ptr, 1) == 0) - return; - -- switch(error_action) -+ switch (error_action) - { -- case 1: -+ case PNG_ERROR_ACTION_NONE: - png_ptr->transformations |= PNG_RGB_TO_GRAY; - break; - -- case 2: -+ case PNG_ERROR_ACTION_WARN: - png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; - break; - -- case 3: -+ case PNG_ERROR_ACTION_ERROR: - png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; - break; - -@@ -980,15 +1006,19 @@ - png_error(png_ptr, "invalid error action to rgb_to_gray"); - break; - } -+ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - #ifdef PNG_READ_EXPAND_SUPPORTED - png_ptr->transformations |= PNG_EXPAND; - #else - { -- png_warning(png_ptr, -+ /* Make this an error in 1.6 because otherwise the application may assume -+ * that it just worked and get a memory overwrite. -+ */ -+ png_error(png_ptr, - "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); - -- png_ptr->transformations &= ~PNG_RGB_TO_GRAY; -+ /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ - } - #endif - { -@@ -996,32 +1026,37 @@ - { - png_uint_16 red_int, green_int; - -- red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); -- green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); -+ /* NOTE: this calculation does not round, but this behavior is retained -+ * for consistency; the inaccuracy is very small. The code here always -+ * overwrites the coefficients, regardless of whether they have been -+ * defaulted or set already. -+ */ -+ red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); -+ green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); - - png_ptr->rgb_to_gray_red_coeff = red_int; - png_ptr->rgb_to_gray_green_coeff = green_int; -- png_ptr->rgb_to_gray_blue_coeff = -- (png_uint_16)(32768 - red_int - green_int); -+ png_ptr->rgb_to_gray_coefficients_set = 1; - } - - else - { - if (red >= 0 && green >= 0) -- png_warning(png_ptr, -+ png_app_warning(png_ptr, - "ignoring out of range rgb_to_gray coefficients"); - -- /* Use the defaults, from the cHRM chunk if set, else the built in Rec -- * 709 values (which correspond to sRGB, so we don't have to worry -- * about the sRGB chunk!) -+ /* Use the defaults, from the cHRM chunk if set, else the historical -+ * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See -+ * png_do_rgb_to_gray for more discussion of the values. In this case -+ * the coefficients are not marked as 'set' and are not overwritten if -+ * something has already provided a default. - */ - if (png_ptr->rgb_to_gray_red_coeff == 0 && -- png_ptr->rgb_to_gray_green_coeff == 0 && -- png_ptr->rgb_to_gray_blue_coeff == 0) -+ png_ptr->rgb_to_gray_green_coeff == 0) - { -- png_ptr->rgb_to_gray_red_coeff = 6968; /* .212671 * 32768 + .5 */ -- png_ptr->rgb_to_gray_green_coeff = 23434; /* .715160 * 32768 + .5 */ -- png_ptr->rgb_to_gray_blue_coeff = 2366; -+ png_ptr->rgb_to_gray_red_coeff = 6968; -+ png_ptr->rgb_to_gray_green_coeff = 23434; -+ /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ - } - } - } -@@ -1033,31 +1068,25 @@ - */ - - void PNGAPI --png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, -+png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, - double green) - { -- if (png_ptr == NULL) -- return; -- - png_set_rgb_to_gray_fixed(png_ptr, error_action, - png_fixed(png_ptr, red, "rgb to gray red coefficient"), - png_fixed(png_ptr, green, "rgb to gray green coefficient")); - } - #endif /* FLOATING POINT */ - --#endif -+#endif /* RGB_TO_GRAY */ - - #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - void PNGAPI --png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr -+png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - read_user_transform_fn) - { - png_debug(1, "in png_set_read_user_transform_fn"); - -- if (png_ptr == NULL) -- return; -- - #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_ptr->transformations |= PNG_USER_TRANSFORM; - png_ptr->read_user_transform_fn = read_user_transform_fn; -@@ -1091,13 +1120,13 @@ - * the palette. - */ - --/*For the moment 'png_init_palette_transformations' and -+/* For the moment 'png_init_palette_transformations' and - * 'png_init_rgb_transformations' only do some flag canceling optimizations. - * The intent is that these two routines should have palette or rgb operations - * extracted from 'png_init_read_transformations'. - */ - static void /* PRIVATE */ --png_init_palette_transformations(png_structp png_ptr) -+png_init_palette_transformations(png_structrp png_ptr) - { - /* Called to handle the (input) palette case. In png_do_read_transformations - * the first step is to expand the palette if requested, so this code must -@@ -1116,25 +1145,31 @@ - - /* Ignore if all the entries are opaque (unlikely!) */ - for (i=0; i<png_ptr->num_trans; ++i) -+ { - if (png_ptr->trans_alpha[i] == 255) - continue; - else if (png_ptr->trans_alpha[i] == 0) - input_has_transparency = 1; - else -+ { -+ input_has_transparency = 1; - input_has_alpha = 1; -+ break; -+ } -+ } - } - - /* If no alpha we can optimize. */ -- if (!input_has_alpha) -+ if (input_has_alpha == 0) - { - /* Any alpha means background and associative alpha processing is -- * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA -+ * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - -- if (!input_has_transparency) -+ if (input_has_transparency == 0) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -@@ -1147,8 +1182,8 @@ - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ -- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && -- (png_ptr->transformations & PNG_EXPAND)) -+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && -+ (png_ptr->transformations & PNG_EXPAND) != 0) - { - { - png_ptr->background.red = -@@ -1159,9 +1194,9 @@ - png_ptr->palette[png_ptr->background.index].blue; - - #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -- if (png_ptr->transformations & PNG_INVERT_ALPHA) -+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - { -- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) -+ if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) - { - /* Invert the alpha channel (in tRNS) unless the pixels are - * going to be expanded, in which case leave it for later -@@ -1173,14 +1208,14 @@ - png_ptr->trans_alpha[i]); - } - } --#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ -+#endif /* READ_INVERT_ALPHA */ - } - } /* background expand and (therefore) no alpha association. */ --#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ -+#endif /* READ_EXPAND && READ_BACKGROUND */ - } - - static void /* PRIVATE */ --png_init_rgb_transformations(png_structp png_ptr) -+png_init_rgb_transformations(png_structrp png_ptr) - { - /* Added to libpng-1.5.4: check the color type to determine whether there - * is any alpha or transparency in the image and simply cancel the -@@ -1190,10 +1225,10 @@ - int input_has_transparency = png_ptr->num_trans > 0; - - /* If no alpha we can optimize. */ -- if (!input_has_alpha) -+ if (input_has_alpha == 0) - { - /* Any alpha means background and associative alpha processing is -- * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA -+ * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ - # ifdef PNG_READ_ALPHA_MODE_SUPPORTED -@@ -1201,7 +1236,7 @@ - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - # endif - -- if (!input_has_transparency) -+ if (input_has_transparency == 0) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -@@ -1214,67 +1249,58 @@ - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ -- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && -- (png_ptr->transformations & PNG_EXPAND) && -- !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) -+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && -+ (png_ptr->transformations & PNG_EXPAND) != 0 && -+ (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - /* i.e., GRAY or GRAY_ALPHA */ - { - { - /* Expand background and tRNS chunks */ -+ int gray = png_ptr->background.gray; -+ int trans_gray = png_ptr->trans_color.gray; -+ - switch (png_ptr->bit_depth) - { - case 1: -- png_ptr->background.gray *= (png_uint_16)0xff; -- png_ptr->background.red = png_ptr->background.green -- = png_ptr->background.blue = png_ptr->background.gray; -- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) -- { -- png_ptr->trans_color.gray *= (png_uint_16)0xff; -- png_ptr->trans_color.red = png_ptr->trans_color.green -- = png_ptr->trans_color.blue = png_ptr->trans_color.gray; -- } -+ gray *= 0xff; -+ trans_gray *= 0xff; - break; - - case 2: -- png_ptr->background.gray *= (png_uint_16)0x55; -- png_ptr->background.red = png_ptr->background.green -- = png_ptr->background.blue = png_ptr->background.gray; -- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) -- { -- png_ptr->trans_color.gray *= (png_uint_16)0x55; -- png_ptr->trans_color.red = png_ptr->trans_color.green -- = png_ptr->trans_color.blue = png_ptr->trans_color.gray; -- } -+ gray *= 0x55; -+ trans_gray *= 0x55; - break; - - case 4: -- png_ptr->background.gray *= (png_uint_16)0x11; -- png_ptr->background.red = png_ptr->background.green -- = png_ptr->background.blue = png_ptr->background.gray; -- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) -- { -- png_ptr->trans_color.gray *= (png_uint_16)0x11; -- png_ptr->trans_color.red = png_ptr->trans_color.green -- = png_ptr->trans_color.blue = png_ptr->trans_color.gray; -- } -+ gray *= 0x11; -+ trans_gray *= 0x11; - break; - - default: - - case 8: -+ /* FALL THROUGH (Already 8 bits) */ - - case 16: -- png_ptr->background.red = png_ptr->background.green -- = png_ptr->background.blue = png_ptr->background.gray; -+ /* Already a full 16 bits */ - break; - } -+ -+ png_ptr->background.red = png_ptr->background.green = -+ png_ptr->background.blue = (png_uint_16)gray; -+ -+ if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) -+ { -+ png_ptr->trans_color.red = png_ptr->trans_color.green = -+ png_ptr->trans_color.blue = (png_uint_16)trans_gray; -+ } - } - } /* background expand and (therefore) no alpha association. */ --#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ -+#endif /* READ_EXPAND && READ_BACKGROUND */ - } - - void /* PRIVATE */ --png_init_read_transformations(png_structp png_ptr) -+png_init_read_transformations(png_structrp png_ptr) - { - png_debug(1, "in png_init_read_transformations"); - -@@ -1299,17 +1325,17 @@ - */ - int gamma_correction = 0; - -- if (png_ptr->gamma != 0) /* has been set */ -+ if (png_ptr->colorspace.gamma != 0) /* has been set */ - { - if (png_ptr->screen_gamma != 0) /* screen set too */ -- gamma_correction = png_gamma_threshold(png_ptr->gamma, -+ gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - - else - /* Assume the output matches the input; a long time default behavior - * of libpng, although the standard has nothing to say about this. - */ -- png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma); -+ png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); - } - - else if (png_ptr->screen_gamma != 0) -@@ -1318,7 +1344,7 @@ - * png_set_alpha_mode (even if the alpha handling mode isn't required - * or isn't changed from the default.) - */ -- png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma); -+ png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); - - else /* neither are set */ - /* Just in case the following prevents any processing - file and screen -@@ -1326,7 +1352,10 @@ - * third gamma value other than png_set_background with 'UNIQUE', and, - * prior to 1.5.4 - */ -- png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1; -+ png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; -+ -+ /* We have a gamma value now. */ -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Now turn the gamma transformation on or off as appropriate. Notice - * that PNG_GAMMA just refers to the file->screen correction. Alpha -@@ -1336,7 +1365,7 @@ - * the code immediately below if the transform can be handled outside the - * row loop. - */ -- if (gamma_correction) -+ if (gamma_correction != 0) - png_ptr->transformations |= PNG_GAMMA; - - else -@@ -1345,7 +1374,7 @@ - #endif - - /* Certain transformations have the effect of preventing other -- * transformations that happen afterward in png_do_read_transformations, -+ * transformations that happen afterward in png_do_read_transformations; - * resolve the interdependencies here. From the code of - * png_do_read_transformations the order is: - * -@@ -1363,19 +1392,19 @@ - * 12) PNG_EXPAND_16 - * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY - * 14) PNG_INVERT_MONO -- * 15) PNG_SHIFT -- * 16) PNG_PACK -- * 17) PNG_BGR -- * 18) PNG_PACKSWAP -- * 19) PNG_FILLER (includes PNG_ADD_ALPHA) -- * 20) PNG_INVERT_ALPHA -+ * 15) PNG_INVERT_ALPHA -+ * 16) PNG_SHIFT -+ * 17) PNG_PACK -+ * 18) PNG_BGR -+ * 19) PNG_PACKSWAP -+ * 20) PNG_FILLER (includes PNG_ADD_ALPHA) - * 21) PNG_SWAP_ALPHA - * 22) PNG_SWAP_BYTES - * 23) PNG_USER_TRANSFORM [must be last] - */ - #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -- if ((png_ptr->transformations & PNG_STRIP_ALPHA) && -- !(png_ptr->transformations & PNG_COMPOSE)) -+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && -+ (png_ptr->transformations & PNG_COMPOSE) == 0) - { - /* Stripping the alpha channel happens immediately after the 'expand' - * transformations, before all other transformation, so it cancels out -@@ -1401,16 +1430,23 @@ - /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA - * settings will have no effect. - */ -- if (!png_gamma_significant(png_ptr->screen_gamma)) -+ if (png_gamma_significant(png_ptr->screen_gamma) == 0) - { - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - } - #endif - --#if defined(PNG_READ_EXPAND_SUPPORTED) && \ -- defined(PNG_READ_BACKGROUND_SUPPORTED) && \ -- defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) -+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -+ /* Make sure the coefficients for the rgb to gray conversion are set -+ * appropriately. -+ */ -+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) -+ png_colorspace_set_rgb_coefficients(png_ptr); -+#endif -+ -+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* Detect gray background and attempt to enable optimization for - * gray --> RGB case. - * -@@ -1426,23 +1462,23 @@ - * png_set_background, along with the bit depth, then the code has a record - * of exactly what color space the background is currently in. - */ -- if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) -+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) - { - /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if -- * the file was greyscale the background value is gray. -+ * the file was grayscale the background value is gray. - */ -- if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) -+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - } - -- else if (png_ptr->transformations & PNG_COMPOSE) -+ else if ((png_ptr->transformations & PNG_COMPOSE) != 0) - { - /* PNG_COMPOSE: png_set_background was called with need_expand false, - * so the color is in the color space of the output or png_set_alpha_mode - * was called and the color is black. Ignore RGB_TO_GRAY because that - * happens before GRAY_TO_RGB. - */ -- if (png_ptr->transformations & PNG_GRAY_TO_RGB) -+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - { - if (png_ptr->background.red == png_ptr->background.green && - png_ptr->background.red == png_ptr->background.blue) -@@ -1452,7 +1488,8 @@ - } - } - } --#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ -+#endif /* READ_EXPAND && READ_BACKGROUND */ -+#endif /* READ_GRAY_TO_RGB */ - - /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations - * can be performed directly on the palette, and some (such as rgb to gray) -@@ -1473,10 +1510,10 @@ - - #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_READ_EXPAND_16_SUPPORTED) -- if ((png_ptr->transformations & PNG_EXPAND_16) && -- (png_ptr->transformations & PNG_COMPOSE) && -- !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && -- png_ptr->bit_depth != 16) -+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && -+ (png_ptr->transformations & PNG_COMPOSE) != 0 && -+ (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && -+ png_ptr->bit_depth != 16) - { - /* TODO: fix this. Because the expand_16 operation is after the compose - * handling the background color must be 8, not 16, bits deep, but the -@@ -1488,14 +1525,36 @@ - * NOTE: this discards the low 16 bits of the user supplied background - * color, but until expand_16 works properly there is no choice! - */ --# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16)) -+# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) - CHOP(png_ptr->background.red); - CHOP(png_ptr->background.green); - CHOP(png_ptr->background.blue); - CHOP(png_ptr->background.gray); - # undef CHOP - } --#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ -+#endif /* READ_BACKGROUND && READ_EXPAND_16 */ -+ -+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ -+ (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ -+ defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) -+ if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && -+ (png_ptr->transformations & PNG_COMPOSE) != 0 && -+ (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && -+ png_ptr->bit_depth == 16) -+ { -+ /* On the other hand, if a 16-bit file is to be reduced to 8-bits per -+ * component this will also happen after PNG_COMPOSE and so the background -+ * color must be pre-expanded here. -+ * -+ * TODO: fix this too. -+ */ -+ png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); -+ png_ptr->background.green = -+ (png_uint_16)(png_ptr->background.green * 257); -+ png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); -+ png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); -+ } -+#endif - - /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the - * background support (see the comments in scripts/pnglibconf.dfa), this -@@ -1524,27 +1583,36 @@ - * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the - * tables. - */ -- if ((png_ptr->transformations & PNG_GAMMA) -- || ((png_ptr->transformations & PNG_RGB_TO_GRAY) -- && (png_gamma_significant(png_ptr->gamma) || -- png_gamma_significant(png_ptr->screen_gamma))) -- || ((png_ptr->transformations & PNG_COMPOSE) -- && (png_gamma_significant(png_ptr->gamma) -- || png_gamma_significant(png_ptr->screen_gamma) -+ if ((png_ptr->transformations & PNG_GAMMA) != 0 || -+ ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && -+ (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || -+ png_gamma_significant(png_ptr->screen_gamma) != 0)) || -+ ((png_ptr->transformations & PNG_COMPOSE) != 0 && -+ (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || -+ png_gamma_significant(png_ptr->screen_gamma) != 0 - # ifdef PNG_READ_BACKGROUND_SUPPORTED -- || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE -- && png_gamma_significant(png_ptr->background_gamma)) -+ || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && -+ png_gamma_significant(png_ptr->background_gamma) != 0) - # endif -- )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) -- && png_gamma_significant(png_ptr->screen_gamma)) -- ) -+ )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && -+ png_gamma_significant(png_ptr->screen_gamma) != 0)) - { - png_build_gamma_table(png_ptr, png_ptr->bit_depth); - - #ifdef PNG_READ_BACKGROUND_SUPPORTED -- if (png_ptr->transformations & PNG_COMPOSE) -+ if ((png_ptr->transformations & PNG_COMPOSE) != 0) - { -- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -+ /* Issue a warning about this combination: because RGB_TO_GRAY is -+ * optimized to do the gamma transform if present yet do_background has -+ * to do the same thing if both options are set a -+ * double-gamma-correction happens. This is true in all versions of -+ * libpng to date. -+ */ -+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) -+ png_warning(png_ptr, -+ "libpng does not support gamma+background+rgb_to_gray"); -+ -+ if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) - { - /* We don't get to here unless there is a tRNS chunk with non-opaque - * entries - see the checking code at the start of this function. -@@ -1576,8 +1644,8 @@ - break; - - case PNG_BACKGROUND_GAMMA_FILE: -- g = png_reciprocal(png_ptr->gamma); -- gs = png_reciprocal2(png_ptr->gamma, -+ g = png_reciprocal(png_ptr->colorspace.gamma); -+ gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - break; - -@@ -1592,7 +1660,7 @@ - break; - } - -- if (png_gamma_significant(gs)) -+ if (png_gamma_significant(gs) != 0) - { - back.red = png_gamma_8bit_correct(png_ptr->background.red, - gs); -@@ -1609,7 +1677,7 @@ - back.blue = (png_byte)png_ptr->background.blue; - } - -- if (png_gamma_significant(g)) -+ if (png_gamma_significant(g) != 0) - { - back_1.red = png_gamma_8bit_correct(png_ptr->background.red, - g); -@@ -1663,7 +1731,7 @@ - - /* Prevent the transformations being done again. - * -- * NOTE: this is highly dubious; it zaps the transformations in -+ * NOTE: this is highly dubious; it removes the transformations in - * place. This seems inconsistent with the general treatment of the - * transformations elsewhere. - */ -@@ -1673,8 +1741,9 @@ - /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ - else /* color_type != PNG_COLOR_TYPE_PALETTE */ - { -- png_fixed_point g = PNG_FP_1; -- png_fixed_point gs = PNG_FP_1; -+ int gs_sig, g_sig; -+ png_fixed_point g = PNG_FP_1; /* Correction to linear */ -+ png_fixed_point gs = PNG_FP_1; /* Correction to screen */ - - switch (png_ptr->background_gamma_type) - { -@@ -1684,8 +1753,9 @@ - break; - - case PNG_BACKGROUND_GAMMA_FILE: -- g = png_reciprocal(png_ptr->gamma); -- gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); -+ g = png_reciprocal(png_ptr->colorspace.gamma); -+ gs = png_reciprocal2(png_ptr->colorspace.gamma, -+ png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: -@@ -1698,34 +1768,45 @@ - png_error(png_ptr, "invalid background gamma type"); - } - -- png_ptr->background_1.gray = png_gamma_correct(png_ptr, -- png_ptr->background.gray, g); -- -- png_ptr->background.gray = png_gamma_correct(png_ptr, -- png_ptr->background.gray, gs); -+ g_sig = png_gamma_significant(g); -+ gs_sig = png_gamma_significant(gs); -+ -+ if (g_sig != 0) -+ png_ptr->background_1.gray = png_gamma_correct(png_ptr, -+ png_ptr->background.gray, g); -+ -+ if (gs_sig != 0) -+ png_ptr->background.gray = png_gamma_correct(png_ptr, -+ png_ptr->background.gray, gs); - - if ((png_ptr->background.red != png_ptr->background.green) || - (png_ptr->background.red != png_ptr->background.blue) || - (png_ptr->background.red != png_ptr->background.gray)) - { - /* RGB or RGBA with color background */ -- png_ptr->background_1.red = png_gamma_correct(png_ptr, -- png_ptr->background.red, g); -- -- png_ptr->background_1.green = png_gamma_correct(png_ptr, -- png_ptr->background.green, g); -- -- png_ptr->background_1.blue = png_gamma_correct(png_ptr, -- png_ptr->background.blue, g); -- -- png_ptr->background.red = png_gamma_correct(png_ptr, -- png_ptr->background.red, gs); -- -- png_ptr->background.green = png_gamma_correct(png_ptr, -- png_ptr->background.green, gs); -- -- png_ptr->background.blue = png_gamma_correct(png_ptr, -- png_ptr->background.blue, gs); -+ if (g_sig != 0) -+ { -+ png_ptr->background_1.red = png_gamma_correct(png_ptr, -+ png_ptr->background.red, g); -+ -+ png_ptr->background_1.green = png_gamma_correct(png_ptr, -+ png_ptr->background.green, g); -+ -+ png_ptr->background_1.blue = png_gamma_correct(png_ptr, -+ png_ptr->background.blue, g); -+ } -+ -+ if (gs_sig != 0) -+ { -+ png_ptr->background.red = png_gamma_correct(png_ptr, -+ png_ptr->background.red, gs); -+ -+ png_ptr->background.green = png_gamma_correct(png_ptr, -+ png_ptr->background.green, gs); -+ -+ png_ptr->background.blue = png_gamma_correct(png_ptr, -+ png_ptr->background.blue, gs); -+ } - } - - else -@@ -1737,20 +1818,29 @@ - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - } -+ -+ /* The background is now in screen gamma: */ -+ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; - } /* color_type != PNG_COLOR_TYPE_PALETTE */ - }/* png_ptr->transformations & PNG_BACKGROUND */ - - else - /* Transformation does not include PNG_BACKGROUND */ --#endif /* PNG_READ_BACKGROUND_SUPPORTED */ -- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -+#endif /* READ_BACKGROUND */ -+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE -+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -+ /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ -+ && ((png_ptr->transformations & PNG_EXPAND) == 0 || -+ (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) -+#endif -+ ) - { - png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - -- /*NOTE: there are other transformations that should probably be in here -- * too. -+ /* NOTE: there are other transformations that should probably be in -+ * here too. - */ - for (i = 0; i < num_palette; i++) - { -@@ -1766,11 +1856,11 @@ - #ifdef PNG_READ_BACKGROUND_SUPPORTED - else - #endif --#endif /* PNG_READ_GAMMA_SUPPORTED */ -+#endif /* READ_GAMMA */ - - #ifdef PNG_READ_BACKGROUND_SUPPORTED - /* No GAMMA transformation (see the hanging else 4 lines above) */ -- if ((png_ptr->transformations & PNG_COMPOSE) && -+ if ((png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { - int i; -@@ -1805,35 +1895,53 @@ - - png_ptr->transformations &= ~PNG_COMPOSE; - } --#endif /* PNG_READ_BACKGROUND_SUPPORTED */ -+#endif /* READ_BACKGROUND */ - - #ifdef PNG_READ_SHIFT_SUPPORTED -- if ((png_ptr->transformations & PNG_SHIFT) && -+ if ((png_ptr->transformations & PNG_SHIFT) != 0 && -+ (png_ptr->transformations & PNG_EXPAND) == 0 && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { -- png_uint_16 i; -- png_uint_16 istop = png_ptr->num_palette; -- int sr = 8 - png_ptr->sig_bit.red; -- int sg = 8 - png_ptr->sig_bit.green; -- int sb = 8 - png_ptr->sig_bit.blue; -- -- if (sr < 0 || sr > 8) -- sr = 0; -- -- if (sg < 0 || sg > 8) -- sg = 0; -- -- if (sb < 0 || sb > 8) -- sb = 0; -- -- for (i = 0; i < istop; i++) -- { -- png_ptr->palette[i].red >>= sr; -- png_ptr->palette[i].green >>= sg; -- png_ptr->palette[i].blue >>= sb; -- } -+ int i; -+ int istop = png_ptr->num_palette; -+ int shift = 8 - png_ptr->sig_bit.red; -+ -+ png_ptr->transformations &= ~PNG_SHIFT; -+ -+ /* significant bits can be in the range 1 to 7 for a meaninful result, if -+ * the number of significant bits is 0 then no shift is done (this is an -+ * error condition which is silently ignored.) -+ */ -+ if (shift > 0 && shift < 8) -+ for (i=0; i<istop; ++i) -+ { -+ int component = png_ptr->palette[i].red; -+ -+ component >>= shift; -+ png_ptr->palette[i].red = (png_byte)component; -+ } -+ -+ shift = 8 - png_ptr->sig_bit.green; -+ if (shift > 0 && shift < 8) -+ for (i=0; i<istop; ++i) -+ { -+ int component = png_ptr->palette[i].green; -+ -+ component >>= shift; -+ png_ptr->palette[i].green = (png_byte)component; -+ } -+ -+ shift = 8 - png_ptr->sig_bit.blue; -+ if (shift > 0 && shift < 8) -+ for (i=0; i<istop; ++i) -+ { -+ int component = png_ptr->palette[i].blue; -+ -+ component >>= shift; -+ png_ptr->palette[i].blue = (png_byte)component; -+ } - } --#endif /* PNG_READ_SHIFT_SUPPORTED */ -+#endif /* READ_SHIFT */ - } - - /* Modify the info structure to reflect the transformations. The -@@ -1841,12 +1949,12 @@ - * assuming the transformations result in valid PNG data. - */ - void /* PRIVATE */ --png_read_transform_info(png_structp png_ptr, png_infop info_ptr) -+png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) - { - png_debug(1, "in png_read_transform_info"); - - #ifdef PNG_READ_EXPAND_SUPPORTED -- if (png_ptr->transformations & PNG_EXPAND) -+ if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { -@@ -1868,9 +1976,9 @@ - } - else - { -- if (png_ptr->num_trans) -+ if (png_ptr->num_trans != 0) - { -- if (png_ptr->transformations & PNG_EXPAND_tRNS) -+ if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } - if (info_ptr->bit_depth < 8) -@@ -1886,7 +1994,7 @@ - /* The following is almost certainly wrong unless the background value is in - * the screen space! - */ -- if (png_ptr->transformations & PNG_COMPOSE) -+ if ((png_ptr->transformations & PNG_COMPOSE) != 0) - info_ptr->background = png_ptr->background; - #endif - -@@ -1895,20 +2003,24 @@ - * however it seems that the code in png_init_read_transformations, which has - * been called before this from png_read_update_info->png_read_start_row - * sometimes does the gamma transform and cancels the flag. -+ * -+ * TODO: this looks wrong; the info_ptr should end up with a gamma equal to -+ * the screen_gamma value. The following probably results in weirdness if -+ * the info_ptr is used by the app after the rows have been read. - */ -- info_ptr->gamma = png_ptr->gamma; -+ info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; - #endif - - if (info_ptr->bit_depth == 16) - { - # ifdef PNG_READ_16BIT_SUPPORTED - # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -- if (png_ptr->transformations & PNG_SCALE_16_TO_8) -+ if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) - info_ptr->bit_depth = 8; - # endif - - # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -- if (png_ptr->transformations & PNG_16_TO_8) -+ if ((png_ptr->transformations & PNG_16_TO_8) != 0) - info_ptr->bit_depth = 8; - # endif - -@@ -1926,7 +2038,7 @@ - info_ptr->bit_depth = 8; - # else - --# if PNG_READ_SCALE_16_TO_8_SUPPORTED -+# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_ptr->transformations |= PNG_SCALE_16_TO_8; - info_ptr->bit_depth = 8; - # else -@@ -1934,25 +2046,27 @@ - CONFIGURATION ERROR: you must enable at least one 16 to 8 method - # endif - # endif --#endif /* !READ_16BIT_SUPPORTED */ -+#endif /* !READ_16BIT */ - } - - #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -- if (png_ptr->transformations & PNG_GRAY_TO_RGB) -- info_ptr->color_type |= PNG_COLOR_MASK_COLOR; -+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) -+ info_ptr->color_type = (png_byte)(info_ptr->color_type | -+ PNG_COLOR_MASK_COLOR); - #endif - - #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -- if (png_ptr->transformations & PNG_RGB_TO_GRAY) -- info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; -+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) -+ info_ptr->color_type = (png_byte)(info_ptr->color_type & -+ ~PNG_COLOR_MASK_COLOR); - #endif - - #ifdef PNG_READ_QUANTIZE_SUPPORTED -- if (png_ptr->transformations & PNG_QUANTIZE) -+ if ((png_ptr->transformations & PNG_QUANTIZE) != 0) - { - if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && -- png_ptr->palette_lookup && info_ptr->bit_depth == 8) -+ png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) - { - info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; - } -@@ -1960,54 +2074,57 @@ - #endif - - #ifdef PNG_READ_EXPAND_16_SUPPORTED -- if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && -- info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) -+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && -+ info_ptr->bit_depth == 8 && -+ info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - info_ptr->bit_depth = 16; - } - #endif - - #ifdef PNG_READ_PACK_SUPPORTED -- if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) -+ if ((png_ptr->transformations & PNG_PACK) != 0 && -+ (info_ptr->bit_depth < 8)) - info_ptr->bit_depth = 8; - #endif - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - -- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) -+ else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - - #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -- if (png_ptr->transformations & PNG_STRIP_ALPHA) -+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) - { -- info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; -+ info_ptr->color_type = (png_byte)(info_ptr->color_type & -+ ~PNG_COLOR_MASK_ALPHA); - info_ptr->num_trans = 0; - } - #endif - -- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) -+ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - info_ptr->channels++; - - #ifdef PNG_READ_FILLER_SUPPORTED - /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ -- if ((png_ptr->transformations & PNG_FILLER) && -- ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || -- (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) -+ if ((png_ptr->transformations & PNG_FILLER) != 0 && -+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB || -+ info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) - { - info_ptr->channels++; - /* If adding a true alpha channel not just filler */ -- if (png_ptr->transformations & PNG_ADD_ALPHA) -+ if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } - #endif - - #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ - defined(PNG_READ_USER_TRANSFORM_SUPPORTED) -- if (png_ptr->transformations & PNG_USER_TRANSFORM) -+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { - if (info_ptr->bit_depth < png_ptr->user_transform_depth) - info_ptr->bit_depth = png_ptr->user_transform_depth; -@@ -2031,291 +2148,11 @@ - png_ptr->info_rowbytes = info_ptr->rowbytes; - - #ifndef PNG_READ_EXPAND_SUPPORTED -- if (png_ptr) -+ if (png_ptr != NULL) - return; - #endif - } - --/* Transform the row. The order of transformations is significant, -- * and is very touchy. If you add a transformation, take care to -- * decide how it fits in with the other transformations here. -- */ --void /* PRIVATE */ --png_do_read_transformations(png_structp png_ptr) --{ -- png_debug(1, "in png_do_read_transformations"); -- -- if (png_ptr->row_buf == NULL) -- { -- /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this -- * error is incredibly rare and incredibly easy to debug without this -- * information. -- */ -- png_error(png_ptr, "NULL row buffer"); -- } -- -- /* The following is debugging; prior to 1.5.4 the code was never compiled in; -- * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro -- * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for -- * selected new APIs to ensure that there is no API change. -- */ -- if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && -- !(png_ptr->flags & PNG_FLAG_ROW_INIT)) -- { -- /* Application has failed to call either png_read_start_image() or -- * png_read_update_info() after setting transforms that expand pixels. -- * This check added to libpng-1.2.19 (but not enabled until 1.5.4). -- */ -- png_error(png_ptr, "Uninitialized row"); -- } -- --#ifdef PNG_READ_EXPAND_SUPPORTED -- if (png_ptr->transformations & PNG_EXPAND) -- { -- if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) -- { -- png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, -- png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); -- } -- -- else -- { -- if (png_ptr->num_trans && -- (png_ptr->transformations & PNG_EXPAND_tRNS)) -- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, -- &(png_ptr->trans_color)); -- -- else -- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, -- NULL); -- } -- } --#endif -- --#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -- if ((png_ptr->transformations & PNG_STRIP_ALPHA) && -- !(png_ptr->transformations & PNG_COMPOSE) && -- (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || -- png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) -- png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, -- 0 /* at_start == false, because SWAP_ALPHA happens later */); --#endif -- --#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -- if (png_ptr->transformations & PNG_RGB_TO_GRAY) -- { -- int rgb_error = -- png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), -- png_ptr->row_buf + 1); -- -- if (rgb_error) -- { -- png_ptr->rgb_to_gray_status=1; -- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == -- PNG_RGB_TO_GRAY_WARN) -- png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); -- -- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == -- PNG_RGB_TO_GRAY_ERR) -- png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); -- } -- } --#endif -- --/* From Andreas Dilger e-mail to png-implement, 26 March 1998: -- * -- * In most cases, the "simple transparency" should be done prior to doing -- * gray-to-RGB, or you will have to test 3x as many bytes to check if a -- * pixel is transparent. You would also need to make sure that the -- * transparency information is upgraded to RGB. -- * -- * To summarize, the current flow is: -- * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite -- * with background "in place" if transparent, -- * convert to RGB if necessary -- * - Gray + alpha -> composite with gray background and remove alpha bytes, -- * convert to RGB if necessary -- * -- * To support RGB backgrounds for gray images we need: -- * - Gray + simple transparency -> convert to RGB + simple transparency, -- * compare 3 or 6 bytes and composite with -- * background "in place" if transparent -- * (3x compare/pixel compared to doing -- * composite with gray bkgrnd) -- * - Gray + alpha -> convert to RGB + alpha, composite with background and -- * remove alpha bytes (3x float -- * operations/pixel compared with composite -- * on gray background) -- * -- * Greg's change will do this. The reason it wasn't done before is for -- * performance, as this increases the per-pixel operations. If we would check -- * in advance if the background was gray or RGB, and position the gray-to-RGB -- * transform appropriately, then it would save a lot of work/time. -- */ -- --#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -- /* If gray -> RGB, do so now only if background is non-gray; else do later -- * for performance reasons -- */ -- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && -- !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) -- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ -- (defined PNG_READ_ALPHA_MODE_SUPPORTED) -- if (png_ptr->transformations & PNG_COMPOSE) -- png_do_compose(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); --#endif -- --#ifdef PNG_READ_GAMMA_SUPPORTED -- if ((png_ptr->transformations & PNG_GAMMA) && --#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ -- (defined PNG_READ_ALPHA_MODE_SUPPORTED) -- !((png_ptr->transformations & PNG_COMPOSE) && -- ((png_ptr->num_trans != 0) || -- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && --#endif -- (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) -- png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); --#endif -- --#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -- if ((png_ptr->transformations & PNG_STRIP_ALPHA) && -- (png_ptr->transformations & PNG_COMPOSE) && -- (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || -- png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) -- png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, -- 0 /* at_start == false, because SWAP_ALPHA happens later */); --#endif -- --#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -- if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && -- (png_ptr->row_info.color_type & PNG_COLOR_MASK_ALPHA)) -- png_do_encode_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); --#endif -- --#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -- if (png_ptr->transformations & PNG_SCALE_16_TO_8) -- png_do_scale_16_to_8(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -- /* There is no harm in doing both of these because only one has any effect, -- * by putting the 'scale' option first if the app asks for scale (either by -- * calling the API or in a TRANSFORM flag) this is what happens. -- */ -- if (png_ptr->transformations & PNG_16_TO_8) -- png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_QUANTIZE_SUPPORTED -- if (png_ptr->transformations & PNG_QUANTIZE) -- { -- png_do_quantize(&(png_ptr->row_info), png_ptr->row_buf + 1, -- png_ptr->palette_lookup, png_ptr->quantize_index); -- -- if (png_ptr->row_info.rowbytes == 0) -- png_error(png_ptr, "png_do_quantize returned rowbytes=0"); -- } --#endif /* PNG_READ_QUANTIZE_SUPPORTED */ -- --#ifdef PNG_READ_EXPAND_16_SUPPORTED -- /* Do the expansion now, after all the arithmetic has been done. Notice -- * that previous transformations can handle the PNG_EXPAND_16 flag if this -- * is efficient (particularly true in the case of gamma correction, where -- * better accuracy results faster!) -- */ -- if (png_ptr->transformations & PNG_EXPAND_16) -- png_do_expand_16(&png_ptr->row_info, png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -- /*NOTE: moved here in 1.5.4 (from much later in this list.) */ -- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && -- (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) -- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_INVERT_SUPPORTED -- if (png_ptr->transformations & PNG_INVERT_MONO) -- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_SHIFT_SUPPORTED -- if (png_ptr->transformations & PNG_SHIFT) -- png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, -- &(png_ptr->shift)); --#endif -- --#ifdef PNG_READ_PACK_SUPPORTED -- if (png_ptr->transformations & PNG_PACK) -- png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_BGR_SUPPORTED -- if (png_ptr->transformations & PNG_BGR) -- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_PACKSWAP_SUPPORTED -- if (png_ptr->transformations & PNG_PACKSWAP) -- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_FILLER_SUPPORTED -- if (png_ptr->transformations & PNG_FILLER) -- png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, -- (png_uint_32)png_ptr->filler, png_ptr->flags); --#endif -- --#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -- if (png_ptr->transformations & PNG_INVERT_ALPHA) -- png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -- if (png_ptr->transformations & PNG_SWAP_ALPHA) -- png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_READ_16BIT_SUPPORTED --#ifdef PNG_READ_SWAP_SUPPORTED -- if (png_ptr->transformations & PNG_SWAP_BYTES) -- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif --#endif -- --#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -- if (png_ptr->transformations & PNG_USER_TRANSFORM) -- { -- if (png_ptr->read_user_transform_fn != NULL) -- (*(png_ptr->read_user_transform_fn)) /* User read transform function */ -- (png_ptr, /* png_ptr */ -- &(png_ptr->row_info), /* row_info: */ -- /* png_uint_32 width; width of row */ -- /* png_size_t rowbytes; number of bytes in row */ -- /* png_byte color_type; color type of pixels */ -- /* png_byte bit_depth; bit depth of samples */ -- /* png_byte channels; number of channels (1-4) */ -- /* png_byte pixel_depth; bits per pixel (depth*channels) */ -- png_ptr->row_buf + 1); /* start of pixel data for row */ --#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -- if (png_ptr->user_transform_depth) -- png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; -- -- if (png_ptr->user_transform_channels) -- png_ptr->row_info.channels = png_ptr->user_transform_channels; --#endif -- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * -- png_ptr->row_info.channels); -- -- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, -- png_ptr->row_info.width); -- } --#endif --} -- - #ifdef PNG_READ_PACK_SUPPORTED - /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, - * without changing the actual values. Thus, if you had a row with -@@ -2323,7 +2160,7 @@ - * the numbers 0 or 1. If you would rather they contain 0 and 255, use - * png_do_shift() after this. - */ --void /* PRIVATE */ -+static void - png_do_unpack(png_row_infop row_info, png_bytep row) - { - png_debug(1, "in png_do_unpack"); -@@ -2421,109 +2258,132 @@ - * a row of bit depth 8, but only 5 are significant, this will shift - * the values back to 0 through 31. - */ --void /* PRIVATE */ -+static void - png_do_unshift(png_row_infop row_info, png_bytep row, - png_const_color_8p sig_bits) - { -+ int color_type; -+ - png_debug(1, "in png_do_unshift"); - -- if ( -- row_info->color_type != PNG_COLOR_TYPE_PALETTE) -+ /* The palette case has already been handled in the _init routine. */ -+ color_type = row_info->color_type; -+ -+ if (color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift[4]; - int channels = 0; -- int c; -- png_uint_16 value = 0; -- png_uint_32 row_width = row_info->width; -- -- if (row_info->color_type & PNG_COLOR_MASK_COLOR) -+ int bit_depth = row_info->bit_depth; -+ -+ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { -- shift[channels++] = row_info->bit_depth - sig_bits->red; -- shift[channels++] = row_info->bit_depth - sig_bits->green; -- shift[channels++] = row_info->bit_depth - sig_bits->blue; -+ shift[channels++] = bit_depth - sig_bits->red; -+ shift[channels++] = bit_depth - sig_bits->green; -+ shift[channels++] = bit_depth - sig_bits->blue; - } - - else - { -- shift[channels++] = row_info->bit_depth - sig_bits->gray; -+ shift[channels++] = bit_depth - sig_bits->gray; - } - -- if (row_info->color_type & PNG_COLOR_MASK_ALPHA) -+ if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) - { -- shift[channels++] = row_info->bit_depth - sig_bits->alpha; -+ shift[channels++] = bit_depth - sig_bits->alpha; - } - -- for (c = 0; c < channels; c++) - { -- if (shift[c] <= 0) -- shift[c] = 0; -- -- else -- value = 1; -+ int c, have_shift; -+ -+ for (c = have_shift = 0; c < channels; ++c) -+ { -+ /* A shift of more than the bit depth is an error condition but it -+ * gets ignored here. -+ */ -+ if (shift[c] <= 0 || shift[c] >= bit_depth) -+ shift[c] = 0; -+ -+ else -+ have_shift = 1; -+ } -+ -+ if (have_shift == 0) -+ return; - } - -- if (!value) -- return; -- -- switch (row_info->bit_depth) -+ switch (bit_depth) - { - default: -+ /* Must be 1bpp gray: should not be here! */ -+ /* NOTREACHED */ - break; - - case 2: -+ /* Must be 2bpp gray */ -+ /* assert(channels == 1 && shift[0] == 1) */ - { -- png_bytep bp; -- png_size_t i; -- png_size_t istop = row_info->rowbytes; -- -- for (bp = row, i = 0; i < istop; i++) -+ png_bytep bp = row; -+ png_bytep bp_end = bp + row_info->rowbytes; -+ -+ while (bp < bp_end) - { -- *bp >>= 1; -- *bp++ &= 0x55; -+ int b = (*bp >> 1) & 0x55; -+ *bp++ = (png_byte)b; - } - break; - } - - case 4: -+ /* Must be 4bpp gray */ -+ /* assert(channels == 1) */ - { - png_bytep bp = row; -- png_size_t i; -- png_size_t istop = row_info->rowbytes; -- png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | -- (png_byte)((int)0xf >> shift[0])); -- -- for (i = 0; i < istop; i++) -+ png_bytep bp_end = bp + row_info->rowbytes; -+ int gray_shift = shift[0]; -+ int mask = 0xf >> gray_shift; -+ -+ mask |= mask << 4; -+ -+ while (bp < bp_end) - { -- *bp >>= shift[0]; -- *bp++ &= mask; -+ int b = (*bp >> gray_shift) & mask; -+ *bp++ = (png_byte)b; - } - break; - } - - case 8: -+ /* Single byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; -- png_uint_32 i; -- png_uint_32 istop = row_width * channels; -- -- for (i = 0; i < istop; i++) -+ png_bytep bp_end = bp + row_info->rowbytes; -+ int channel = 0; -+ -+ while (bp < bp_end) - { -- *bp++ >>= shift[i%channels]; -+ int b = *bp >> shift[channel]; -+ if (++channel >= channels) -+ channel = 0; -+ *bp++ = (png_byte)b; - } - break; - } - - #ifdef PNG_READ_16BIT_SUPPORTED - case 16: -+ /* Double byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; -- png_uint_32 i; -- png_uint_32 istop = channels * row_width; -- -- for (i = 0; i < istop; i++) -+ png_bytep bp_end = bp + row_info->rowbytes; -+ int channel = 0; -+ -+ while (bp < bp_end) - { -- value = (png_uint_16)((*bp << 8) + *(bp + 1)); -- value >>= shift[i%channels]; -+ int value = (bp[0] << 8) + bp[1]; -+ -+ value >>= shift[channel]; -+ if (++channel >= channels) -+ channel = 0; - *bp++ = (png_byte)(value >> 8); - *bp++ = (png_byte)(value & 0xff); - } -@@ -2537,7 +2397,7 @@ - - #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - /* Scale rows of bit depth 16 down to 8 accurately */ --void /* PRIVATE */ -+static void - png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) - { - png_debug(1, "in png_do_scale_16_to_8"); -@@ -2545,7 +2405,7 @@ - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ -- png_bytep dp = row; /* destinaton */ -+ png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) -@@ -2595,7 +2455,7 @@ - #endif - - #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED --void /* PRIVATE */ -+static void - /* Simply discard the low byte. This was the default behavior prior - * to libpng-1.5.4. - */ -@@ -2606,7 +2466,7 @@ - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ -- png_bytep dp = row; /* destinaton */ -+ png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) -@@ -2623,7 +2483,7 @@ - #endif - - #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED --void /* PRIVATE */ -+static void - png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) - { - png_debug(1, "in png_do_read_swap_alpha"); -@@ -2720,7 +2580,7 @@ - #endif - - #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED --void /* PRIVATE */ -+static void - png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) - { - png_uint_32 row_width; -@@ -2822,7 +2682,7 @@ - - #ifdef PNG_READ_FILLER_SUPPORTED - /* Add filler channel if we have RGB color */ --void /* PRIVATE */ -+static void - png_do_read_filler(png_row_infop row_info, png_bytep row, - png_uint_32 filler, png_uint_32 flags) - { -@@ -2841,7 +2701,7 @@ - { - if (row_info->bit_depth == 8) - { -- if (flags & PNG_FLAG_FILLER_AFTER) -+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from G to GX */ - png_bytep sp = row + (png_size_t)row_width; -@@ -2876,7 +2736,7 @@ - #ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { -- if (flags & PNG_FLAG_FILLER_AFTER) -+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from GG to GGXX */ - png_bytep sp = row + (png_size_t)row_width * 2; -@@ -2918,7 +2778,7 @@ - { - if (row_info->bit_depth == 8) - { -- if (flags & PNG_FLAG_FILLER_AFTER) -+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from RGB to RGBX */ - png_bytep sp = row + (png_size_t)row_width * 3; -@@ -2957,7 +2817,7 @@ - #ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { -- if (flags & PNG_FLAG_FILLER_AFTER) -+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from RRGGBB to RRGGBBXX */ - png_bytep sp = row + (png_size_t)row_width * 6; -@@ -3009,7 +2869,7 @@ - - #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* Expand grayscale files to RGB, with or without alpha */ --void /* PRIVATE */ -+static void - png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) - { - png_uint_32 i; -@@ -3018,7 +2878,7 @@ - png_debug(1, "in png_do_gray_to_rgb"); - - if (row_info->bit_depth >= 8 && -- !(row_info->color_type & PNG_COLOR_MASK_COLOR)) -+ (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { -@@ -3086,7 +2946,7 @@ - } - } - } -- row_info->channels += (png_byte)2; -+ row_info->channels = (png_byte)(row_info->channels + 2); - row_info->color_type |= PNG_COLOR_MASK_COLOR; - row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); -@@ -3097,269 +2957,242 @@ - - #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Reduce RGB files to grayscale, with or without alpha -- * using the equation given in Poynton's ColorFAQ at -- * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008) -- * New link: -- * <http://www.poynton.com/notes/colour_and_gamma/> -+ * using the equation given in Poynton's ColorFAQ of 1998-01-04 at -+ * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but -+ * versions dated 1998 through November 2002 have been archived at -+ * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ -+ * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) - * Charles Poynton poynton at poynton.com - * - * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B - * -- * We approximate this with -- * -- * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B -- * - * which can be expressed with integers as - * - * Y = (6969 * R + 23434 * G + 2365 * B)/32768 - * -- * The calculation is to be done in a linear colorspace. -+ * Poynton's current link (as of January 2003 through July 2011): -+ * <http://www.poynton.com/notes/colour_and_gamma/> -+ * has changed the numbers slightly: - * -- * Other integer coefficents can be used via png_set_rgb_to_gray(). -+ * Y = 0.2126*R + 0.7152*G + 0.0722*B -+ * -+ * which can be expressed with integers as -+ * -+ * Y = (6966 * R + 23436 * G + 2366 * B)/32768 -+ * -+ * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 -+ * end point chromaticities and the D65 white point. Depending on the -+ * precision used for the D65 white point this produces a variety of different -+ * numbers, however if the four decimal place value used in ITU-R Rec 709 is -+ * used (0.3127,0.3290) the Y calculation would be: -+ * -+ * Y = (6968 * R + 23435 * G + 2366 * B)/32768 -+ * -+ * While this is correct the rounding results in an overflow for white, because -+ * the sum of the rounded coefficients is 32769, not 32768. Consequently -+ * libpng uses, instead, the closest non-overflowing approximation: -+ * -+ * Y = (6968 * R + 23434 * G + 2366 * B)/32768 -+ * -+ * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk -+ * (including an sRGB chunk) then the chromaticities are used to calculate the -+ * coefficients. See the chunk handling in pngrutil.c for more information. -+ * -+ * In all cases the calculation is to be done in a linear colorspace. If no -+ * gamma information is available to correct the encoding of the original RGB -+ * values this results in an implicit assumption that the original PNG RGB -+ * values were linear. -+ * -+ * Other integer coefficents can be used via png_set_rgb_to_gray(). Because -+ * the API takes just red and green coefficients the blue coefficient is -+ * calculated to make the sum 32768. This will result in different rounding -+ * to that used above. - */ --int /* PRIVATE */ --png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) -+static int -+png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) - - { -- png_uint_32 i; -- -- png_uint_32 row_width = row_info->width; - int rgb_error = 0; - - png_debug(1, "in png_do_rgb_to_gray"); - -- if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && -- (row_info->color_type & PNG_COLOR_MASK_COLOR)) -+ if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && -+ (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { -- png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; -- png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; -- png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; -- -- if (row_info->color_type == PNG_COLOR_TYPE_RGB) -+ PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; -+ PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; -+ PNG_CONST png_uint_32 bc = 32768 - rc - gc; -+ PNG_CONST png_uint_32 row_width = row_info->width; -+ PNG_CONST int have_alpha = -+ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; -+ -+ if (row_info->bit_depth == 8) - { -- if (row_info->bit_depth == 8) -+#ifdef PNG_READ_GAMMA_SUPPORTED -+ /* Notice that gamma to/from 1 are not necessarily inverses (if -+ * there is an overall gamma correction). Prior to 1.5.5 this code -+ * checked the linearized values for equality; this doesn't match -+ * the documentation, the original values must be checked. -+ */ -+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) - { --#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) -+ png_bytep sp = row; -+ png_bytep dp = row; -+ png_uint_32 i; -+ -+ for (i = 0; i < row_width; i++) - { -- png_bytep sp = row; -- png_bytep dp = row; -- -- for (i = 0; i < row_width; i++) -+ png_byte red = *(sp++); -+ png_byte green = *(sp++); -+ png_byte blue = *(sp++); -+ -+ if (red != green || red != blue) - { -- png_byte red = png_ptr->gamma_to_1[*(sp++)]; -- png_byte green = png_ptr->gamma_to_1[*(sp++)]; -- png_byte blue = png_ptr->gamma_to_1[*(sp++)]; -- -- if (red != green || red != blue) -- { -- rgb_error |= 1; -- *(dp++) = png_ptr->gamma_from_1[ -- (rc*red + gc*green + bc*blue)>>15]; -- } -+ red = png_ptr->gamma_to_1[red]; -+ green = png_ptr->gamma_to_1[green]; -+ blue = png_ptr->gamma_to_1[blue]; -+ -+ rgb_error |= 1; -+ *(dp++) = png_ptr->gamma_from_1[ -+ (rc*red + gc*green + bc*blue + 16384)>>15]; -+ } -+ -+ else -+ { -+ /* If there is no overall correction the table will not be -+ * set. -+ */ -+ if (png_ptr->gamma_table != NULL) -+ red = png_ptr->gamma_table[red]; -+ -+ *(dp++) = red; -+ } -+ -+ if (have_alpha != 0) -+ *(dp++) = *(sp++); -+ } -+ } -+ else -+#endif -+ { -+ png_bytep sp = row; -+ png_bytep dp = row; -+ png_uint_32 i; -+ -+ for (i = 0; i < row_width; i++) -+ { -+ png_byte red = *(sp++); -+ png_byte green = *(sp++); -+ png_byte blue = *(sp++); -+ -+ if (red != green || red != blue) -+ { -+ rgb_error |= 1; -+ /* NOTE: this is the historical approach which simply -+ * truncates the results. -+ */ -+ *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); -+ } -+ -+ else -+ *(dp++) = red; -+ -+ if (have_alpha != 0) -+ *(dp++) = *(sp++); -+ } -+ } -+ } -+ -+ else /* RGB bit_depth == 16 */ -+ { -+#ifdef PNG_READ_GAMMA_SUPPORTED -+ if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) -+ { -+ png_bytep sp = row; -+ png_bytep dp = row; -+ png_uint_32 i; -+ -+ for (i = 0; i < row_width; i++) -+ { -+ png_uint_16 red, green, blue, w; -+ -+ red = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; -+ green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; -+ blue = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; -+ -+ if (red == green && red == blue) -+ { -+ if (png_ptr->gamma_16_table != NULL) -+ w = png_ptr->gamma_16_table[(red & 0xff) -+ >> png_ptr->gamma_shift][red >> 8]; - - else -- *(dp++) = *(sp - 1); -+ w = red; - } -- } -- else --#endif -- { -- png_bytep sp = row; -- png_bytep dp = row; -- for (i = 0; i < row_width; i++) -+ -+ else - { -- png_byte red = *(sp++); -- png_byte green = *(sp++); -- png_byte blue = *(sp++); -- -- if (red != green || red != blue) -- { -- rgb_error |= 1; -- *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); -- } -- -- else -- *(dp++) = *(sp - 1); -+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) -+ >> png_ptr->gamma_shift][red>>8]; -+ png_uint_16 green_1 = -+ png_ptr->gamma_16_to_1[(green&0xff) >> -+ png_ptr->gamma_shift][green>>8]; -+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) -+ >> png_ptr->gamma_shift][blue>>8]; -+ png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 -+ + bc*blue_1 + 16384)>>15); -+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >> -+ png_ptr->gamma_shift][gray16 >> 8]; -+ rgb_error |= 1; -+ } -+ -+ *(dp++) = (png_byte)((w>>8) & 0xff); -+ *(dp++) = (png_byte)(w & 0xff); -+ -+ if (have_alpha != 0) -+ { -+ *(dp++) = *(sp++); -+ *(dp++) = *(sp++); - } - } - } -- -- else /* RGB bit_depth == 16 */ -+ else -+#endif - { --#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -- if (png_ptr->gamma_16_to_1 != NULL && -- png_ptr->gamma_16_from_1 != NULL) -+ png_bytep sp = row; -+ png_bytep dp = row; -+ png_uint_32 i; -+ -+ for (i = 0; i < row_width; i++) - { -- png_bytep sp = row; -- png_bytep dp = row; -- for (i = 0; i < row_width; i++) -+ png_uint_16 red, green, blue, gray16; -+ -+ red = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; -+ green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; -+ blue = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; -+ -+ if (red != green || red != blue) -+ rgb_error |= 1; -+ -+ /* From 1.5.5 in the 16 bit case do the accurate conversion even -+ * in the 'fast' case - this is because this is where the code -+ * ends up when handling linear 16 bit data. -+ */ -+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> -+ 15); -+ *(dp++) = (png_byte)((gray16 >> 8) & 0xff); -+ *(dp++) = (png_byte)(gray16 & 0xff); -+ -+ if (have_alpha != 0) - { -- png_uint_16 red, green, blue, w; -- -- red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- -- if (red == green && red == blue) -- w = red; -- -- else -- { -- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) -- >> png_ptr->gamma_shift][red>>8]; -- png_uint_16 green_1 = -- png_ptr->gamma_16_to_1[(green&0xff) >> -- png_ptr->gamma_shift][green>>8]; -- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) -- >> png_ptr->gamma_shift][blue>>8]; -- png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 -- + bc*blue_1)>>15); -- w = png_ptr->gamma_16_from_1[(gray16&0xff) >> -- png_ptr->gamma_shift][gray16 >> 8]; -- rgb_error |= 1; -- } -- -- *(dp++) = (png_byte)((w>>8) & 0xff); -- *(dp++) = (png_byte)(w & 0xff); -- } -- } -- else --#endif -- { -- png_bytep sp = row; -- png_bytep dp = row; -- for (i = 0; i < row_width; i++) -- { -- png_uint_16 red, green, blue, gray16; -- -- red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- -- if (red != green || red != blue) -- rgb_error |= 1; -- -- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); -- *(dp++) = (png_byte)((gray16>>8) & 0xff); -- *(dp++) = (png_byte)(gray16 & 0xff); -- } -- } -- } -- } -- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -- { -- if (row_info->bit_depth == 8) -- { --#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) -- { -- png_bytep sp = row; -- png_bytep dp = row; -- for (i = 0; i < row_width; i++) -- { -- png_byte red = png_ptr->gamma_to_1[*(sp++)]; -- png_byte green = png_ptr->gamma_to_1[*(sp++)]; -- png_byte blue = png_ptr->gamma_to_1[*(sp++)]; -- -- if (red != green || red != blue) -- rgb_error |= 1; -- -- *(dp++) = png_ptr->gamma_from_1 -- [(rc*red + gc*green + bc*blue)>>15]; -- -- *(dp++) = *(sp++); /* alpha */ -- } -- } -- else --#endif -- { -- png_bytep sp = row; -- png_bytep dp = row; -- for (i = 0; i < row_width; i++) -- { -- png_byte red = *(sp++); -- png_byte green = *(sp++); -- png_byte blue = *(sp++); -- if (red != green || red != blue) -- rgb_error |= 1; -- -- *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); -- *(dp++) = *(sp++); /* alpha */ -- } -- } -- } -- else /* RGBA bit_depth == 16 */ -- { --#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -- if (png_ptr->gamma_16_to_1 != NULL && -- png_ptr->gamma_16_from_1 != NULL) -- { -- png_bytep sp = row; -- png_bytep dp = row; -- for (i = 0; i < row_width; i++) -- { -- png_uint_16 red, green, blue, w; -- -- red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; -- -- if (red == green && red == blue) -- w = red; -- -- else -- { -- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> -- png_ptr->gamma_shift][red>>8]; -- -- png_uint_16 green_1 = -- png_ptr->gamma_16_to_1[(green&0xff) >> -- png_ptr->gamma_shift][green>>8]; -- -- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> -- png_ptr->gamma_shift][blue>>8]; -- -- png_uint_16 gray16 = (png_uint_16)((rc * red_1 -- + gc * green_1 + bc * blue_1)>>15); -- -- w = png_ptr->gamma_16_from_1[(gray16&0xff) >> -- png_ptr->gamma_shift][gray16 >> 8]; -- -- rgb_error |= 1; -- } -- -- *(dp++) = (png_byte)((w>>8) & 0xff); -- *(dp++) = (png_byte)(w & 0xff); -- *(dp++) = *(sp++); /* alpha */ - *(dp++) = *(sp++); -- } -- } -- else --#endif -- { -- png_bytep sp = row; -- png_bytep dp = row; -- for (i = 0; i < row_width; i++) -- { -- png_uint_16 red, green, blue, gray16; -- red = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; -- green = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; -- blue = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; -- -- if (red != green || red != blue) -- rgb_error |= 1; -- -- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); -- *(dp++) = (png_byte)((gray16>>8) & 0xff); -- *(dp++) = (png_byte)(gray16 & 0xff); -- *(dp++) = *(sp++); /* alpha */ - *(dp++) = *(sp++); - } - } - } - } -- row_info->channels -= 2; -+ -+ row_info->channels = (png_byte)(row_info->channels - 2); - row_info->color_type = (png_byte)(row_info->color_type & - ~PNG_COLOR_MASK_COLOR); - row_info->pixel_depth = (png_byte)(row_info->channels * -@@ -3369,73 +3202,15 @@ - return rgb_error; - } - #endif --#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ -- --#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED --/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth -- * large of png_color. This lets grayscale images be treated as -- * paletted. Most useful for gamma correction and simplification -- * of code. This API is not used internally. -- */ --void PNGAPI --png_build_grayscale_palette(int bit_depth, png_colorp palette) --{ -- int num_palette; -- int color_inc; -- int i; -- int v; -- -- png_debug(1, "in png_do_build_grayscale_palette"); -- -- if (palette == NULL) -- return; -- -- switch (bit_depth) -- { -- case 1: -- num_palette = 2; -- color_inc = 0xff; -- break; -- -- case 2: -- num_palette = 4; -- color_inc = 0x55; -- break; -- -- case 4: -- num_palette = 16; -- color_inc = 0x11; -- break; -- -- case 8: -- num_palette = 256; -- color_inc = 1; -- break; -- -- default: -- num_palette = 0; -- color_inc = 0; -- break; -- } -- -- for (i = 0, v = 0; i < num_palette; i++, v += color_inc) -- { -- palette[i].red = (png_byte)v; -- palette[i].green = (png_byte)v; -- palette[i].blue = (png_byte)v; -- } --} --#endif -- -- --#ifdef PNG_READ_TRANSFORMS_SUPPORTED --#ifdef PNG_READ_BACKGROUND_SUPPORTED -+ -+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ -+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) - /* Replace any alpha or transparency with the supplied background color. - * "background" is already in the screen gamma, while "background_1" is - * at a gamma of 1.0. Paletted files have already been taken care of. - */ --void /* PRIVATE */ --png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) -+static void -+png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) - { - #ifdef PNG_READ_GAMMA_SUPPORTED - png_const_bytep gamma_table = png_ptr->gamma_table; -@@ -3445,12 +3220,12 @@ - png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; - png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; - int gamma_shift = png_ptr->gamma_shift; -+ int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; - #endif - - png_bytep sp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; -- int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; - int shift; - - png_debug(1, "in png_do_compose"); -@@ -3471,11 +3246,12 @@ - if ((png_uint_16)((*sp >> shift) & 0x01) - == png_ptr->trans_color.gray) - { -- *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); -- *sp |= (png_byte)(png_ptr->background.gray << shift); -+ unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); -+ tmp |= png_ptr->background.gray << shift; -+ *sp = (png_byte)(tmp & 0xff); - } - -- if (!shift) -+ if (shift == 0) - { - shift = 7; - sp++; -@@ -3499,20 +3275,22 @@ - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { -- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); -- *sp |= (png_byte)(png_ptr->background.gray << shift); -+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); -+ tmp |= png_ptr->background.gray << shift; -+ *sp = (png_byte)(tmp & 0xff); - } - - else - { -- png_byte p = (png_byte)((*sp >> shift) & 0x03); -- png_byte g = (png_byte)((gamma_table [p | (p << 2) | -- (p << 4) | (p << 6)] >> 6) & 0x03); -- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); -- *sp |= (png_byte)(g << shift); -+ unsigned int p = (*sp >> shift) & 0x03; -+ unsigned int g = (gamma_table [p | (p << 2) | -+ (p << 4) | (p << 6)] >> 6) & 0x03; -+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); -+ tmp |= g << shift; -+ *sp = (png_byte)(tmp & 0xff); - } - -- if (!shift) -+ if (shift == 0) - { - shift = 6; - sp++; -@@ -3533,11 +3311,12 @@ - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { -- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); -- *sp |= (png_byte)(png_ptr->background.gray << shift); -+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); -+ tmp |= png_ptr->background.gray << shift; -+ *sp = (png_byte)(tmp & 0xff); - } - -- if (!shift) -+ if (shift == 0) - { - shift = 6; - sp++; -@@ -3562,20 +3341,22 @@ - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { -- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); -- *sp |= (png_byte)(png_ptr->background.gray << shift); -+ unsigned int tmp = *sp & (0xf0f >> (4 - shift)); -+ tmp |= png_ptr->background.gray << shift; -+ *sp = (png_byte)(tmp & 0xff); - } - - else - { -- png_byte p = (png_byte)((*sp >> shift) & 0x0f); -- png_byte g = (png_byte)((gamma_table[p | -- (p << 4)] >> 4) & 0x0f); -- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); -- *sp |= (png_byte)(g << shift); -+ unsigned int p = (*sp >> shift) & 0x0f; -+ unsigned int g = (gamma_table[p | (p << 4)] >> 4) & -+ 0x0f; -+ unsigned int tmp = *sp & (0xf0f >> (4 - shift)); -+ tmp |= g << shift; -+ *sp = (png_byte)(tmp & 0xff); - } - -- if (!shift) -+ if (shift == 0) - { - shift = 4; - sp++; -@@ -3596,11 +3377,12 @@ - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { -- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); -- *sp |= (png_byte)(png_ptr->background.gray << shift); -+ unsigned int tmp = *sp & (0xf0f >> (4 - shift)); -+ tmp |= png_ptr->background.gray << shift; -+ *sp = (png_byte)(tmp & 0xff); - } - -- if (!shift) -+ if (shift == 0) - { - shift = 4; - sp++; -@@ -3656,8 +3438,10 @@ - if (v == png_ptr->trans_color.gray) - { - /* Background is already in screen gamma */ -- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); -- *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); -+ *sp = (png_byte)((png_ptr->background.gray >> 8) -+ & 0xff); -+ *(sp + 1) = (png_byte)(png_ptr->background.gray -+ & 0xff); - } - - else -@@ -3680,8 +3464,10 @@ - - if (v == png_ptr->trans_color.gray) - { -- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); -- *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); -+ *sp = (png_byte)((png_ptr->background.gray >> 8) -+ & 0xff); -+ *(sp + 1) = (png_byte)(png_ptr->background.gray -+ & 0xff); - } - } - } -@@ -3761,9 +3547,12 @@ - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); -- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); -- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); -- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); -+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) -+ & 0xff); -+ *(sp + 3) = (png_byte)(png_ptr->background.green -+ & 0xff); -+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) -+ & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - -@@ -3804,9 +3593,12 @@ - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); -- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); -- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); -- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); -+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) -+ & 0xff); -+ *(sp + 3) = (png_byte)(png_ptr->background.green -+ & 0xff); -+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) -+ & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - } -@@ -3843,7 +3635,7 @@ - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.gray); -- if (!optimize) -+ if (optimize == 0) - w = gamma_from_1[w]; - *sp = w; - } -@@ -3861,7 +3653,7 @@ - *sp = (png_byte)png_ptr->background.gray; - - else if (a < 0xff) -- png_composite(*sp, *sp, a, png_ptr->background_1.gray); -+ png_composite(*sp, *sp, a, png_ptr->background.gray); - } - } - } -@@ -3889,7 +3681,8 @@ - else if (a == 0) - { - /* Background is already in screen gamma */ -- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); -+ *sp = (png_byte)((png_ptr->background.gray >> 8) -+ & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - -@@ -3899,7 +3692,7 @@ - - g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(v, g, a, png_ptr->background_1.gray); -- if (optimize) -+ if (optimize != 0) - w = v; - else - w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; -@@ -3919,7 +3712,8 @@ - - if (a == 0) - { -- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); -+ *sp = (png_byte)((png_ptr->background.gray >> 8) -+ & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - -@@ -3928,7 +3722,7 @@ - png_uint_16 g, v; - - g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); -- png_composite_16(v, g, a, png_ptr->background_1.gray); -+ png_composite_16(v, g, a, png_ptr->background.gray); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } -@@ -3972,17 +3766,17 @@ - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.red); -- if (!optimize) w = gamma_from_1[w]; -+ if (optimize == 0) w = gamma_from_1[w]; - *sp = w; - - v = gamma_to_1[*(sp + 1)]; - png_composite(w, v, a, png_ptr->background_1.green); -- if (!optimize) w = gamma_from_1[w]; -+ if (optimize == 0) w = gamma_from_1[w]; - *(sp + 1) = w; - - v = gamma_to_1[*(sp + 2)]; - png_composite(w, v, a, png_ptr->background_1.blue); -- if (!optimize) w = gamma_from_1[w]; -+ if (optimize == 0) w = gamma_from_1[w]; - *(sp + 2) = w; - } - } -@@ -4049,9 +3843,12 @@ - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); -- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); -- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); -- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); -+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) -+ & 0xff); -+ *(sp + 3) = (png_byte)(png_ptr->background.green -+ & 0xff); -+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) -+ & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - -@@ -4061,23 +3858,26 @@ - - v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(w, v, a, png_ptr->background_1.red); -- if (!optimize) -- w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; -+ if (optimize == 0) -+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> -+ 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; - png_composite_16(w, v, a, png_ptr->background_1.green); -- if (!optimize) -- w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; -+ if (optimize == 0) -+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> -+ 8]; - - *(sp + 2) = (png_byte)((w >> 8) & 0xff); - *(sp + 3) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; - png_composite_16(w, v, a, png_ptr->background_1.blue); -- if (!optimize) -- w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; -+ if (optimize == 0) -+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> -+ 8]; - - *(sp + 4) = (png_byte)((w >> 8) & 0xff); - *(sp + 5) = (png_byte)(w & 0xff); -@@ -4098,9 +3898,12 @@ - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); -- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); -- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); -- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); -+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) -+ & 0xff); -+ *(sp + 3) = (png_byte)(png_ptr->background.green -+ & 0xff); -+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) -+ & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - -@@ -4137,7 +3940,7 @@ - } - } - } --#endif -+#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ - - #ifdef PNG_READ_GAMMA_SUPPORTED - /* Gamma correct the image, avoiding the alpha channel. Make sure -@@ -4146,8 +3949,8 @@ - * is 16, use gamma_16_table and gamma_shift. Build these with - * build_gamma_table(). - */ --void /* PRIVATE */ --png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) -+static void -+png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) - { - png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; -@@ -4347,14 +4150,14 @@ - * linear.) Called only with color types that have an alpha channel. Needs the - * from_1 tables. - */ --void /* PRIVATE */ --png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) -+static void -+png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) - { - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_encode_alpha"); - -- if (row_info->color_type & PNG_COLOR_MASK_ALPHA) -+ if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - if (row_info->bit_depth == 8) - { -@@ -4413,7 +4216,7 @@ - /* Expands a palette row to an RGB or RGBA row depending - * upon whether you supply trans and num_trans. - */ --void /* PRIVATE */ -+static void - png_do_expand_palette(png_row_infop row_info, png_bytep row, - png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) - { -@@ -4566,7 +4369,7 @@ - /* If the bit depth < 8, it is expanded to 8. Also, if the already - * expanded transparency value is supplied, an alpha channel is built. - */ --void /* PRIVATE */ -+static void - png_do_expand(png_row_infop row_info, png_bytep row, - png_const_color_16p trans_color) - { -@@ -4580,7 +4383,7 @@ - { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { -- png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0); -+ unsigned int gray = trans_color != NULL ? trans_color->gray : 0; - - if (row_info->bit_depth < 8) - { -@@ -4588,7 +4391,7 @@ - { - case 1: - { -- gray = (png_uint_16)((gray & 0x01) * 0xff); -+ gray = (gray & 0x01) * 0xff; - sp = row + (png_size_t)((row_width - 1) >> 3); - dp = row + (png_size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); -@@ -4616,7 +4419,7 @@ - - case 2: - { -- gray = (png_uint_16)((gray & 0x03) * 0x55); -+ gray = (gray & 0x03) * 0x55; - sp = row + (png_size_t)((row_width - 1) >> 2); - dp = row + (png_size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); -@@ -4641,7 +4444,7 @@ - - case 4: - { -- gray = (png_uint_16)((gray & 0x0f) * 0x11); -+ gray = (gray & 0x0f) * 0x11; - sp = row + (png_size_t)((row_width - 1) >> 1); - dp = row + (png_size_t)row_width - 1; - shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); -@@ -4694,8 +4497,8 @@ - - else if (row_info->bit_depth == 16) - { -- png_byte gray_high = (png_byte)((gray >> 8) & 0xff); -- png_byte gray_low = (png_byte)(gray & 0xff); -+ unsigned int gray_high = (gray >> 8) & 0xff; -+ unsigned int gray_low = gray & 0xff; - sp = row + row_info->rowbytes - 1; - dp = row + (row_info->rowbytes << 1) - 1; - for (i = 0; i < row_width; i++) -@@ -4724,7 +4527,8 @@ - row_width); - } - } -- else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) -+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB && -+ trans_color != NULL) - { - if (row_info->bit_depth == 8) - { -@@ -4793,10 +4597,10 @@ - #endif - - #ifdef PNG_READ_EXPAND_16_SUPPORTED --/* If the bit depth is 8 and the colour type is not a palette type expand the -+/* If the bit depth is 8 and the color type is not a palette type expand the - * whole row to 16 bits. Has no effect otherwise. - */ --void /* PRIVATE */ -+static void - png_do_expand_16(png_row_infop row_info, png_bytep row) - { - if (row_info->bit_depth == 8 && -@@ -4824,7 +4628,7 @@ - #endif - - #ifdef PNG_READ_QUANTIZE_SUPPORTED --void /* PRIVATE */ -+static void - png_do_quantize(png_row_infop row_info, png_bytep row, - png_const_bytep palette_lookup, png_const_bytep quantize_lookup) - { -@@ -4915,70 +4719,304 @@ - } - } - } --#endif /* PNG_READ_QUANTIZE_SUPPORTED */ --#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ -- --#ifdef PNG_MNG_FEATURES_SUPPORTED --/* Undoes intrapixel differencing */ -+#endif /* READ_QUANTIZE */ -+ -+/* Transform the row. The order of transformations is significant, -+ * and is very touchy. If you add a transformation, take care to -+ * decide how it fits in with the other transformations here. -+ */ - void /* PRIVATE */ --png_do_read_intrapixel(png_row_infop row_info, png_bytep row) -+png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) - { -- png_debug(1, "in png_do_read_intrapixel"); -- -- if ( -- (row_info->color_type & PNG_COLOR_MASK_COLOR)) -+ png_debug(1, "in png_do_read_transformations"); -+ -+ if (png_ptr->row_buf == NULL) - { -- int bytes_per_pixel; -- png_uint_32 row_width = row_info->width; -- -- if (row_info->bit_depth == 8) -+ /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this -+ * error is incredibly rare and incredibly easy to debug without this -+ * information. -+ */ -+ png_error(png_ptr, "NULL row buffer"); -+ } -+ -+ /* The following is debugging; prior to 1.5.4 the code was never compiled in; -+ * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro -+ * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for -+ * all transformations, however in practice the ROW_INIT always gets done on -+ * demand, if necessary. -+ */ -+ if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && -+ (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) -+ { -+ /* Application has failed to call either png_read_start_image() or -+ * png_read_update_info() after setting transforms that expand pixels. -+ * This check added to libpng-1.2.19 (but not enabled until 1.5.4). -+ */ -+ png_error(png_ptr, "Uninitialized row"); -+ } -+ -+#ifdef PNG_READ_EXPAND_SUPPORTED -+ if ((png_ptr->transformations & PNG_EXPAND) != 0) -+ { -+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { -- png_bytep rp; -- png_uint_32 i; -- -- if (row_info->color_type == PNG_COLOR_TYPE_RGB) -- bytes_per_pixel = 3; -- -- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -- bytes_per_pixel = 4; -+ png_do_expand_palette(row_info, png_ptr->row_buf + 1, -+ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); -+ } -+ -+ else -+ { -+ if (png_ptr->num_trans != 0 && -+ (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) -+ png_do_expand(row_info, png_ptr->row_buf + 1, -+ &(png_ptr->trans_color)); - - else -- return; -- -- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -- { -- *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); -- *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); -- } -- } -- else if (row_info->bit_depth == 16) -- { -- png_bytep rp; -- png_uint_32 i; -- -- if (row_info->color_type == PNG_COLOR_TYPE_RGB) -- bytes_per_pixel = 6; -- -- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -- bytes_per_pixel = 8; -- -- else -- return; -- -- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -- { -- png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); -- png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); -- png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); -- png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL); -- png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL); -- *(rp ) = (png_byte)((red >> 8) & 0xff); -- *(rp + 1) = (png_byte)(red & 0xff); -- *(rp + 4) = (png_byte)((blue >> 8) & 0xff); -- *(rp + 5) = (png_byte)(blue & 0xff); -- } -+ png_do_expand(row_info, png_ptr->row_buf + 1, -+ NULL); - } - } -+#endif -+ -+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && -+ (png_ptr->transformations & PNG_COMPOSE) == 0 && -+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || -+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) -+ png_do_strip_channel(row_info, png_ptr->row_buf + 1, -+ 0 /* at_start == false, because SWAP_ALPHA happens later */); -+#endif -+ -+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) -+ { -+ int rgb_error = -+ png_do_rgb_to_gray(png_ptr, row_info, -+ png_ptr->row_buf + 1); -+ -+ if (rgb_error != 0) -+ { -+ png_ptr->rgb_to_gray_status=1; -+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == -+ PNG_RGB_TO_GRAY_WARN) -+ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); -+ -+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == -+ PNG_RGB_TO_GRAY_ERR) -+ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); -+ } -+ } -+#endif -+ -+/* From Andreas Dilger e-mail to png-implement, 26 March 1998: -+ * -+ * In most cases, the "simple transparency" should be done prior to doing -+ * gray-to-RGB, or you will have to test 3x as many bytes to check if a -+ * pixel is transparent. You would also need to make sure that the -+ * transparency information is upgraded to RGB. -+ * -+ * To summarize, the current flow is: -+ * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite -+ * with background "in place" if transparent, -+ * convert to RGB if necessary -+ * - Gray + alpha -> composite with gray background and remove alpha bytes, -+ * convert to RGB if necessary -+ * -+ * To support RGB backgrounds for gray images we need: -+ * - Gray + simple transparency -> convert to RGB + simple transparency, -+ * compare 3 or 6 bytes and composite with -+ * background "in place" if transparent -+ * (3x compare/pixel compared to doing -+ * composite with gray bkgrnd) -+ * - Gray + alpha -> convert to RGB + alpha, composite with background and -+ * remove alpha bytes (3x float -+ * operations/pixel compared with composite -+ * on gray background) -+ * -+ * Greg's change will do this. The reason it wasn't done before is for -+ * performance, as this increases the per-pixel operations. If we would check -+ * in advance if the background was gray or RGB, and position the gray-to-RGB -+ * transform appropriately, then it would save a lot of work/time. -+ */ -+ -+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -+ /* If gray -> RGB, do so now only if background is non-gray; else do later -+ * for performance reasons -+ */ -+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && -+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) -+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ -+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) -+ if ((png_ptr->transformations & PNG_COMPOSE) != 0) -+ png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); -+#endif -+ -+#ifdef PNG_READ_GAMMA_SUPPORTED -+ if ((png_ptr->transformations & PNG_GAMMA) != 0 && -+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -+ /* Because RGB_TO_GRAY does the gamma transform. */ -+ (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && -+#endif -+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ -+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) -+ /* Because PNG_COMPOSE does the gamma transform if there is something to -+ * do (if there is an alpha channel or transparency.) -+ */ -+ !((png_ptr->transformations & PNG_COMPOSE) && -+ ((png_ptr->num_trans != 0) || -+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && -+#endif -+ /* Because png_init_read_transformations transforms the palette, unless -+ * RGB_TO_GRAY will do the transform. -+ */ -+ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) -+ png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); -+#endif -+ -+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && -+ (png_ptr->transformations & PNG_COMPOSE) != 0 && -+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || -+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) -+ png_do_strip_channel(row_info, png_ptr->row_buf + 1, -+ 0 /* at_start == false, because SWAP_ALPHA happens later */); -+#endif -+ -+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -+ if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && -+ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) -+ png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); -+#endif -+ -+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -+ if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) -+ png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -+ /* There is no harm in doing both of these because only one has any effect, -+ * by putting the 'scale' option first if the app asks for scale (either by -+ * calling the API or in a TRANSFORM flag) this is what happens. -+ */ -+ if ((png_ptr->transformations & PNG_16_TO_8) != 0) -+ png_do_chop(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_QUANTIZE_SUPPORTED -+ if ((png_ptr->transformations & PNG_QUANTIZE) != 0) -+ { -+ png_do_quantize(row_info, png_ptr->row_buf + 1, -+ png_ptr->palette_lookup, png_ptr->quantize_index); -+ -+ if (row_info->rowbytes == 0) -+ png_error(png_ptr, "png_do_quantize returned rowbytes=0"); -+ } -+#endif /* READ_QUANTIZE */ -+ -+#ifdef PNG_READ_EXPAND_16_SUPPORTED -+ /* Do the expansion now, after all the arithmetic has been done. Notice -+ * that previous transformations can handle the PNG_EXPAND_16 flag if this -+ * is efficient (particularly true in the case of gamma correction, where -+ * better accuracy results faster!) -+ */ -+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0) -+ png_do_expand_16(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -+ /* NOTE: moved here in 1.5.4 (from much later in this list.) */ -+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && -+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) -+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_INVERT_SUPPORTED -+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) -+ png_do_invert(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) -+ png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_SHIFT_SUPPORTED -+ if ((png_ptr->transformations & PNG_SHIFT) != 0) -+ png_do_unshift(row_info, png_ptr->row_buf + 1, -+ &(png_ptr->shift)); -+#endif -+ -+#ifdef PNG_READ_PACK_SUPPORTED -+ if ((png_ptr->transformations & PNG_PACK) != 0) -+ png_do_unpack(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED -+ /* Added at libpng-1.5.10 */ -+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && -+ png_ptr->num_palette_max >= 0) -+ png_do_check_palette_indexes(png_ptr, row_info); -+#endif -+ -+#ifdef PNG_READ_BGR_SUPPORTED -+ if ((png_ptr->transformations & PNG_BGR) != 0) -+ png_do_bgr(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_PACKSWAP_SUPPORTED -+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) -+ png_do_packswap(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_FILLER_SUPPORTED -+ if ((png_ptr->transformations & PNG_FILLER) != 0) -+ png_do_read_filler(row_info, png_ptr->row_buf + 1, -+ (png_uint_32)png_ptr->filler, png_ptr->flags); -+#endif -+ -+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -+ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) -+ png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_READ_16BIT_SUPPORTED -+#ifdef PNG_READ_SWAP_SUPPORTED -+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) -+ png_do_swap(row_info, png_ptr->row_buf + 1); -+#endif -+#endif -+ -+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) -+ { -+ if (png_ptr->read_user_transform_fn != NULL) -+ (*(png_ptr->read_user_transform_fn)) /* User read transform function */ -+ (png_ptr, /* png_ptr */ -+ row_info, /* row_info: */ -+ /* png_uint_32 width; width of row */ -+ /* png_size_t rowbytes; number of bytes in row */ -+ /* png_byte color_type; color type of pixels */ -+ /* png_byte bit_depth; bit depth of samples */ -+ /* png_byte channels; number of channels (1-4) */ -+ /* png_byte pixel_depth; bits per pixel (depth*channels) */ -+ png_ptr->row_buf + 1); /* start of pixel data for row */ -+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -+ if (png_ptr->user_transform_depth != 0) -+ row_info->bit_depth = png_ptr->user_transform_depth; -+ -+ if (png_ptr->user_transform_channels != 0) -+ row_info->channels = png_ptr->user_transform_channels; -+#endif -+ row_info->pixel_depth = (png_byte)(row_info->bit_depth * -+ row_info->channels); -+ -+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); -+ } -+#endif - } --#endif /* PNG_MNG_FEATURES_SUPPORTED */ --#endif /* PNG_READ_SUPPORTED */ -+ -+#endif /* READ_TRANSFORMS */ -+#endif /* READ */ ---- ./jdk/src/share/native/sun/awt/libpng/pngrutil.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngrutil.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -46,10 +46,8 @@ - - #ifdef PNG_READ_SUPPORTED - --#define png_strtod(p,a,b) strtod(a,b) -- - png_uint_32 PNGAPI --png_get_uint_31(png_structp png_ptr, png_const_bytep buf) -+png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) - { - png_uint_32 uval = png_get_uint_32(buf); - -@@ -68,7 +66,7 @@ - #define PNG_FIXED_ERROR (-1) - - static png_fixed_point /* PRIVATE */ --png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) -+png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) - { - png_uint_32 uval = png_get_uint_32(buf); - -@@ -115,10 +113,10 @@ - png_get_int_32)(png_const_bytep buf) - { - png_uint_32 uval = png_get_uint_32(buf); -- if ((uval & 0x80000000L) == 0) /* non-negative */ -+ if ((uval & 0x80000000) == 0) /* non-negative */ - return uval; - -- uval = (uval ^ 0xffffffffL) + 1; /* 2's complement: -x = ~x+1 */ -+ uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ - return -(png_int_32)uval; - } - -@@ -126,7 +124,7 @@ - png_uint_16 (PNGAPI - png_get_uint_16)(png_const_bytep buf) - { -- /* ANSI-C requires an int value to accommodate at least 16 bits so this -+ /* ANSI-C requires an int value to accomodate at least 16 bits so this - * works and allows the compiler not to worry about possible narrowing - * on 32 bit systems. (Pre-ANSI systems did not make integers smaller - * than 16 bits either.) -@@ -138,11 +136,11 @@ - return (png_uint_16)val; - } - --#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ -+#endif /* READ_INT_FUNCTIONS */ - - /* Read and check the PNG file signature */ - void /* PRIVATE */ --png_read_sig(png_structp png_ptr, png_infop info_ptr) -+png_read_sig(png_structrp png_ptr, png_inforp info_ptr) - { - png_size_t num_checked, num_to_check; - -@@ -161,7 +159,7 @@ - png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); - png_ptr->sig_bytes = 8; - -- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) -+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) -@@ -177,7 +175,7 @@ - * Put the type name into png_ptr->chunk_name, and return the length. - */ - png_uint_32 /* PRIVATE */ --png_read_chunk_header(png_structp png_ptr) -+png_read_chunk_header(png_structrp png_ptr) - { - png_byte buf[8]; - png_uint_32 length; -@@ -193,14 +191,14 @@ - length = png_get_uint_31(png_ptr, buf); - - /* Put the chunk name into png_ptr->chunk_name. */ -- png_memcpy(png_ptr->chunk_name, buf + 4, 4); -- -- png_debug2(0, "Reading %s chunk, length = %u", -- png_ptr->chunk_name, length); -+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); -+ -+ png_debug2(0, "Reading %lx chunk, length = %lu", -+ (unsigned long)png_ptr->chunk_name, (unsigned long)length); - - /* Reset the crc and run it over the chunk name. */ - png_reset_crc(png_ptr); -- png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); -+ png_calculate_crc(png_ptr, buf + 4, 4); - - /* Check to see if chunk name is valid. */ - png_check_chunk_name(png_ptr, png_ptr->chunk_name); -@@ -214,7 +212,7 @@ - - /* Read data, and (optionally) run it through the CRC. */ - void /* PRIVATE */ --png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) -+png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) - { - if (png_ptr == NULL) - return; -@@ -224,41 +222,40 @@ - } - - /* Optionally skip data and then check the CRC. Depending on whether we -- * are reading a ancillary or critical chunk, and how the program has set -+ * are reading an ancillary or critical chunk, and how the program has set - * things up, we may calculate the CRC on the data and print a message. - * Returns '1' if there was a CRC error, '0' otherwise. - */ - int /* PRIVATE */ --png_crc_finish(png_structp png_ptr, png_uint_32 skip) -+png_crc_finish(png_structrp png_ptr, png_uint_32 skip) - { -- png_size_t i; -- png_size_t istop = png_ptr->zbuf_size; -- -- for (i = (png_size_t)skip; i > istop; i -= istop) -+ /* The size of the local buffer for inflate is a good guess as to a -+ * reasonable size to use for buffering reads from the application. -+ */ -+ while (skip > 0) - { -- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); -+ png_uint_32 len; -+ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; -+ -+ len = (sizeof tmpbuf); -+ if (len > skip) -+ len = skip; -+ skip -= len; -+ -+ png_crc_read(png_ptr, tmpbuf, len); - } - -- if (i) -+ if (png_crc_error(png_ptr) != 0) - { -- png_crc_read(png_ptr, png_ptr->zbuf, i); -- } -- -- if (png_crc_error(png_ptr)) -- { -- if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ -- !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || -- (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ -- (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) -+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? -+ (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : -+ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) - { - png_chunk_warning(png_ptr, "CRC error"); - } - - else -- { -- png_chunk_benign_error(png_ptr, "CRC error"); -- return (0); -- } -+ png_chunk_error(png_ptr, "CRC error"); - - return (1); - } -@@ -270,22 +267,22 @@ - * the data it has read thus far. - */ - int /* PRIVATE */ --png_crc_error(png_structp png_ptr) -+png_crc_error(png_structrp png_ptr) - { - png_byte crc_bytes[4]; - png_uint_32 crc; - int need_crc = 1; - -- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ -+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - -- else /* critical */ -+ else /* critical */ - { -- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) -+ if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) - need_crc = 0; - } - -@@ -296,7 +293,7 @@ - /* The chunk CRC must be serialized in a single I/O call. */ - png_read_data(png_ptr, crc_bytes, 4); - -- if (need_crc) -+ if (need_crc != 0) - { - crc = png_get_uint_32(crc_bytes); - return ((int)(crc != png_ptr->crc)); -@@ -306,252 +303,522 @@ - return (0); - } - -+#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ -+ defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ -+ defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ -+ defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) -+/* Manage the read buffer; this simply reallocates the buffer if it is not small -+ * enough (or if it is not allocated). The routine returns a pointer to the -+ * buffer; if an error occurs and 'warn' is set the routine returns NULL, else -+ * it will call png_error (via png_malloc) on failure. (warn == 2 means -+ * 'silent'). -+ */ -+static png_bytep -+png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) -+{ -+ png_bytep buffer = png_ptr->read_buffer; -+ -+ if (buffer != NULL && new_size > png_ptr->read_buffer_size) -+ { -+ png_ptr->read_buffer = NULL; -+ png_ptr->read_buffer = NULL; -+ png_ptr->read_buffer_size = 0; -+ png_free(png_ptr, buffer); -+ buffer = NULL; -+ } -+ -+ if (buffer == NULL) -+ { -+ buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); -+ -+ if (buffer != NULL) -+ { -+ png_ptr->read_buffer = buffer; -+ png_ptr->read_buffer_size = new_size; -+ } -+ -+ else if (warn < 2) /* else silent */ -+ { -+ if (warn != 0) -+ png_chunk_warning(png_ptr, "insufficient memory to read chunk"); -+ -+ else -+ png_chunk_error(png_ptr, "insufficient memory to read chunk"); -+ } -+ } -+ -+ return buffer; -+} -+#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ -+ -+/* png_inflate_claim: claim the zstream for some nefarious purpose that involves -+ * decompression. Returns Z_OK on success, else a zlib error code. It checks -+ * the owner but, in final release builds, just issues a warning if some other -+ * chunk apparently owns the stream. Prior to release it does a png_error. -+ */ -+static int -+png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) -+{ -+ if (png_ptr->zowner != 0) -+ { -+ char msg[64]; -+ -+ PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); -+ /* So the message that results is "<chunk> using zstream"; this is an -+ * internal error, but is very useful for debugging. i18n requirements -+ * are minimal. -+ */ -+ (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); -+#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC -+ png_chunk_warning(png_ptr, msg); -+ png_ptr->zowner = 0; -+#else -+ png_chunk_error(png_ptr, msg); -+#endif -+ } -+ -+ /* Implementation note: unlike 'png_deflate_claim' this internal function -+ * does not take the size of the data as an argument. Some efficiency could -+ * be gained by using this when it is known *if* the zlib stream itself does -+ * not record the number; however, this is an illusion: the original writer -+ * of the PNG may have selected a lower window size, and we really must -+ * follow that because, for systems with with limited capabilities, we -+ * would otherwise reject the application's attempts to use a smaller window -+ * size (zlib doesn't have an interface to say "this or lower"!). -+ * -+ * inflateReset2 was added to zlib 1.2.4; before this the window could not be -+ * reset, therefore it is necessary to always allocate the maximum window -+ * size with earlier zlibs just in case later compressed chunks need it. -+ */ -+ { -+ int ret; /* zlib return code */ -+#if PNG_ZLIB_VERNUM >= 0x1240 -+ -+# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) -+ int window_bits; -+ -+ if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == -+ PNG_OPTION_ON) -+ window_bits = 15; -+ -+ else -+ window_bits = 0; -+# else -+# define window_bits 0 -+# endif -+#endif -+ -+ /* Set this for safety, just in case the previous owner left pointers to -+ * memory allocations. -+ */ -+ png_ptr->zstream.next_in = NULL; -+ png_ptr->zstream.avail_in = 0; -+ png_ptr->zstream.next_out = NULL; -+ png_ptr->zstream.avail_out = 0; -+ -+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) -+ { -+#if PNG_ZLIB_VERNUM < 0x1240 -+ ret = inflateReset(&png_ptr->zstream); -+#else -+ ret = inflateReset2(&png_ptr->zstream, window_bits); -+#endif -+ } -+ -+ else -+ { -+#if PNG_ZLIB_VERNUM < 0x1240 -+ ret = inflateInit(&png_ptr->zstream); -+#else -+ ret = inflateInit2(&png_ptr->zstream, window_bits); -+#endif -+ -+ if (ret == Z_OK) -+ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; -+ } -+ -+ if (ret == Z_OK) -+ png_ptr->zowner = owner; -+ -+ else -+ png_zstream_error(png_ptr, ret); -+ -+ return ret; -+ } -+ -+#ifdef window_bits -+# undef window_bits -+#endif -+} -+ - #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED --static png_size_t --png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, -- png_bytep output, png_size_t output_size) -+/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to -+ * allow the caller to do multiple calls if required. If the 'finish' flag is -+ * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must -+ * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and -+ * Z_OK or Z_STREAM_END will be returned on success. -+ * -+ * The input and output sizes are updated to the actual amounts of data consumed -+ * or written, not the amount available (as in a z_stream). The data pointers -+ * are not changed, so the next input is (data+input_size) and the next -+ * available output is (output+output_size). -+ */ -+static int -+png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, -+ /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, -+ /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) - { -- png_size_t count = 0; -- -- /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't -- * even necessarily handle 65536 bytes) because the type uInt is "16 bits or -- * more". Consequently it is necessary to chunk the input to zlib. This -- * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value -- * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a -- * lower value in pngpriv.h and this may sometimes have a performance -- * advantage, because it forces access of the input data to be separated from -- * at least some of the use by some period of time. -- */ -- png_ptr->zstream.next_in = data; -- /* avail_in is set below from 'size' */ -- png_ptr->zstream.avail_in = 0; -- -- while (1) -+ if (png_ptr->zowner == owner) /* Else not claimed */ - { -- int ret, avail; -- -- /* The setting of 'avail_in' used to be outside the loop, by setting it -- * inside it is possible to chunk the input to zlib and simply rely on -- * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o -- * data to be passed through zlib at the unavoidable cost of requiring a -- * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX -- * input bytes. -+ int ret; -+ png_alloc_size_t avail_out = *output_size_ptr; -+ png_uint_32 avail_in = *input_size_ptr; -+ -+ /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it -+ * can't even necessarily handle 65536 bytes) because the type uInt is -+ * "16 bits or more". Consequently it is necessary to chunk the input to -+ * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the -+ * maximum value that can be stored in a uInt.) It is possible to set -+ * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have -+ * a performance advantage, because it reduces the amount of data accessed -+ * at each step and that may give the OS more time to page it in. - */ -- if (png_ptr->zstream.avail_in == 0 && size > 0) -+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); -+ /* avail_in and avail_out are set below from 'size' */ -+ png_ptr->zstream.avail_in = 0; -+ png_ptr->zstream.avail_out = 0; -+ -+ /* Read directly into the output if it is available (this is set to -+ * a local buffer below if output is NULL). -+ */ -+ if (output != NULL) -+ png_ptr->zstream.next_out = output; -+ -+ do - { -- if (size <= ZLIB_IO_MAX) -+ uInt avail; -+ Byte local_buffer[PNG_INFLATE_BUF_SIZE]; -+ -+ /* zlib INPUT BUFFER */ -+ /* The setting of 'avail_in' used to be outside the loop; by setting it -+ * inside it is possible to chunk the input to zlib and simply rely on -+ * zlib to advance the 'next_in' pointer. This allows arbitrary -+ * amounts of data to be passed through zlib at the unavoidable cost of -+ * requiring a window save (memcpy of up to 32768 output bytes) -+ * every ZLIB_IO_MAX input bytes. -+ */ -+ avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ -+ -+ avail = ZLIB_IO_MAX; -+ -+ if (avail_in < avail) -+ avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ -+ -+ avail_in -= avail; -+ png_ptr->zstream.avail_in = avail; -+ -+ /* zlib OUTPUT BUFFER */ -+ avail_out += png_ptr->zstream.avail_out; /* not written last time */ -+ -+ avail = ZLIB_IO_MAX; /* maximum zlib can process */ -+ -+ if (output == NULL) - { -- /* The value is less than ZLIB_IO_MAX so the cast is safe: */ -- png_ptr->zstream.avail_in = (uInt)size; -- size = 0; -+ /* Reset the output buffer each time round if output is NULL and -+ * make available the full buffer, up to 'remaining_space' -+ */ -+ png_ptr->zstream.next_out = local_buffer; -+ if ((sizeof local_buffer) < avail) -+ avail = (sizeof local_buffer); - } - -- else -- { -- png_ptr->zstream.avail_in = ZLIB_IO_MAX; -- size -= ZLIB_IO_MAX; -- } -- } -- -- /* Reset the output buffer each time round - we empty it -- * after every inflate call. -+ if (avail_out < avail) -+ avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ -+ -+ png_ptr->zstream.avail_out = avail; -+ avail_out -= avail; -+ -+ /* zlib inflate call */ -+ /* In fact 'avail_out' may be 0 at this point, that happens at the end -+ * of the read when the final LZ end code was not passed at the end of -+ * the previous chunk of input data. Tell zlib if we have reached the -+ * end of the output buffer. -+ */ -+ ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : -+ (finish ? Z_FINISH : Z_SYNC_FLUSH)); -+ } while (ret == Z_OK); -+ -+ /* For safety kill the local buffer pointer now */ -+ if (output == NULL) -+ png_ptr->zstream.next_out = NULL; -+ -+ /* Claw back the 'size' and 'remaining_space' byte counts. */ -+ avail_in += png_ptr->zstream.avail_in; -+ avail_out += png_ptr->zstream.avail_out; -+ -+ /* Update the input and output sizes; the updated values are the amount -+ * consumed or written, effectively the inverse of what zlib uses. - */ -- png_ptr->zstream.next_out = png_ptr->zbuf; -- png_ptr->zstream.avail_out = png_ptr->zbuf_size; -- -- ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); -- avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; -- -- /* First copy/count any new output - but only if we didn't -- * get an error code. -+ if (avail_out > 0) -+ *output_size_ptr -= avail_out; -+ -+ if (avail_in > 0) -+ *input_size_ptr -= avail_in; -+ -+ /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ -+ png_zstream_error(png_ptr, ret); -+ return ret; -+ } -+ -+ else -+ { -+ /* This is a bad internal error. The recovery assigns to the zstream msg -+ * pointer, which is not owned by the caller, but this is safe; it's only -+ * used on errors! - */ -- if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) -- { -- png_size_t space = avail; /* > 0, see above */ -- -- if (output != 0 && output_size > count) -- { -- png_size_t copy = output_size - count; -- -- if (space < copy) -- copy = space; -- -- png_memcpy(output + count, png_ptr->zbuf, copy); -- } -- count += space; -- } -- -- if (ret == Z_OK) -- continue; -- -- /* Termination conditions - always reset the zstream, it -- * must be left in inflateInit state. -- */ -- png_ptr->zstream.avail_in = 0; -- inflateReset(&png_ptr->zstream); -- -- if (ret == Z_STREAM_END) -- return count; /* NOTE: may be zero. */ -- -- /* Now handle the error codes - the API always returns 0 -- * and the error message is dumped into the uncompressed -- * buffer if available. -- */ --# ifdef PNG_WARNINGS_SUPPORTED -- { -- png_const_charp msg; -- -- if (png_ptr->zstream.msg != 0) -- msg = png_ptr->zstream.msg; -- -- else switch (ret) -- { -- case Z_BUF_ERROR: -- msg = "Buffer error in compressed datastream"; -- break; -- -- case Z_DATA_ERROR: -- msg = "Data error in compressed datastream"; -- break; -- -- default: -- msg = "Incomplete compressed datastream"; -- break; -- } -- -- png_chunk_warning(png_ptr, msg); -- } --# endif -- -- /* 0 means an error - notice that this code simply ignores -- * zero length compressed chunks as a result. -- */ -- return 0; -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); -+ return Z_STREAM_ERROR; - } - } - - /* -- * Decompress trailing data in a chunk. The assumption is that chunkdata -+ * Decompress trailing data in a chunk. The assumption is that read_buffer - * points at an allocated area holding the contents of a chunk with a - * trailing compressed part. What we get back is an allocated area - * holding the original prefix part and an uncompressed version of the - * trailing part (the malloc area passed in is freed). - */ -+static int -+png_decompress_chunk(png_structrp png_ptr, -+ png_uint_32 chunklength, png_uint_32 prefix_size, -+ png_alloc_size_t *newlength /* must be initialized to the maximum! */, -+ int terminate /*add a '\0' to the end of the uncompressed data*/) -+{ -+ /* TODO: implement different limits for different types of chunk. -+ * -+ * The caller supplies *newlength set to the maximum length of the -+ * uncompressed data, but this routine allocates space for the prefix and -+ * maybe a '\0' terminator too. We have to assume that 'prefix_size' is -+ * limited only by the maximum chunk size. -+ */ -+ png_alloc_size_t limit = PNG_SIZE_MAX; -+ -+# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED -+ if (png_ptr->user_chunk_malloc_max > 0 && -+ png_ptr->user_chunk_malloc_max < limit) -+ limit = png_ptr->user_chunk_malloc_max; -+# elif PNG_USER_CHUNK_MALLOC_MAX > 0 -+ if (PNG_USER_CHUNK_MALLOC_MAX < limit) -+ limit = PNG_USER_CHUNK_MALLOC_MAX; -+# endif -+ -+ if (limit >= prefix_size + (terminate != 0)) -+ { -+ int ret; -+ -+ limit -= prefix_size + (terminate != 0); -+ -+ if (limit < *newlength) -+ *newlength = limit; -+ -+ /* Now try to claim the stream. */ -+ ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); -+ -+ if (ret == Z_OK) -+ { -+ png_uint_32 lzsize = chunklength - prefix_size; -+ -+ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, -+ /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, -+ /* output: */ NULL, newlength); -+ -+ if (ret == Z_STREAM_END) -+ { -+ /* Use 'inflateReset' here, not 'inflateReset2' because this -+ * preserves the previously decided window size (otherwise it would -+ * be necessary to store the previous window size.) In practice -+ * this doesn't matter anyway, because png_inflate will call inflate -+ * with Z_FINISH in almost all cases, so the window will not be -+ * maintained. -+ */ -+ if (inflateReset(&png_ptr->zstream) == Z_OK) -+ { -+ /* Because of the limit checks above we know that the new, -+ * expanded, size will fit in a size_t (let alone an -+ * png_alloc_size_t). Use png_malloc_base here to avoid an -+ * extra OOM message. -+ */ -+ png_alloc_size_t new_size = *newlength; -+ png_alloc_size_t buffer_size = prefix_size + new_size + -+ (terminate != 0); -+ png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, -+ buffer_size)); -+ -+ if (text != NULL) -+ { -+ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, -+ png_ptr->read_buffer + prefix_size, &lzsize, -+ text + prefix_size, newlength); -+ -+ if (ret == Z_STREAM_END) -+ { -+ if (new_size == *newlength) -+ { -+ if (terminate != 0) -+ text[prefix_size + *newlength] = 0; -+ -+ if (prefix_size > 0) -+ memcpy(text, png_ptr->read_buffer, prefix_size); -+ -+ { -+ png_bytep old_ptr = png_ptr->read_buffer; -+ -+ png_ptr->read_buffer = text; -+ png_ptr->read_buffer_size = buffer_size; -+ text = old_ptr; /* freed below */ -+ } -+ } -+ -+ else -+ { -+ /* The size changed on the second read, there can be no -+ * guarantee that anything is correct at this point. -+ * The 'msg' pointer has been set to "unexpected end of -+ * LZ stream", which is fine, but return an error code -+ * that the caller won't accept. -+ */ -+ ret = PNG_UNEXPECTED_ZLIB_RETURN; -+ } -+ } -+ -+ else if (ret == Z_OK) -+ ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ -+ -+ /* Free the text pointer (this is the old read_buffer on -+ * success) -+ */ -+ png_free(png_ptr, text); -+ text = NULL; -+ -+ /* This really is very benign, but it's still an error because -+ * the extra space may otherwise be used as a Trojan Horse. -+ */ -+ if (ret == Z_STREAM_END && -+ chunklength - prefix_size != lzsize) -+ png_chunk_benign_error(png_ptr, "extra compressed data"); -+ } -+ -+ else -+ { -+ /* Out of memory allocating the buffer */ -+ ret = Z_MEM_ERROR; -+ png_zstream_error(png_ptr, Z_MEM_ERROR); -+ } -+ } -+ -+ else -+ { -+ /* inflateReset failed, store the error message */ -+ png_zstream_error(png_ptr, ret); -+ -+ if (ret == Z_STREAM_END) -+ ret = PNG_UNEXPECTED_ZLIB_RETURN; -+ } -+ } -+ -+ else if (ret == Z_OK) -+ ret = PNG_UNEXPECTED_ZLIB_RETURN; -+ -+ /* Release the claimed stream */ -+ png_ptr->zowner = 0; -+ } -+ -+ else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ -+ ret = PNG_UNEXPECTED_ZLIB_RETURN; -+ -+ return ret; -+ } -+ -+ else -+ { -+ /* Application/configuration limits exceeded */ -+ png_zstream_error(png_ptr, Z_MEM_ERROR); -+ return Z_MEM_ERROR; -+ } -+} -+#endif /* READ_COMPRESSED_TEXT */ -+ -+#ifdef PNG_READ_iCCP_SUPPORTED -+/* Perform a partial read and decompress, producing 'avail_out' bytes and -+ * reading from the current chunk as required. -+ */ -+static int -+png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, -+ png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, -+ int finish) -+{ -+ if (png_ptr->zowner == png_ptr->chunk_name) -+ { -+ int ret; -+ -+ /* next_in and avail_in must have been initialized by the caller. */ -+ png_ptr->zstream.next_out = next_out; -+ png_ptr->zstream.avail_out = 0; /* set in the loop */ -+ -+ do -+ { -+ if (png_ptr->zstream.avail_in == 0) -+ { -+ if (read_size > *chunk_bytes) -+ read_size = (uInt)*chunk_bytes; -+ *chunk_bytes -= read_size; -+ -+ if (read_size > 0) -+ png_crc_read(png_ptr, read_buffer, read_size); -+ -+ png_ptr->zstream.next_in = read_buffer; -+ png_ptr->zstream.avail_in = read_size; -+ } -+ -+ if (png_ptr->zstream.avail_out == 0) -+ { -+ uInt avail = ZLIB_IO_MAX; -+ if (avail > *out_size) -+ avail = (uInt)*out_size; -+ *out_size -= avail; -+ -+ png_ptr->zstream.avail_out = avail; -+ } -+ -+ /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all -+ * the available output is produced; this allows reading of truncated -+ * streams. -+ */ -+ ret = inflate(&png_ptr->zstream, -+ *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); -+ } -+ while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); -+ -+ *out_size += png_ptr->zstream.avail_out; -+ png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ -+ -+ /* Ensure the error message pointer is always set: */ -+ png_zstream_error(png_ptr, ret); -+ return ret; -+ } -+ -+ else -+ { -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); -+ return Z_STREAM_ERROR; -+ } -+} -+#endif -+ -+/* Read and check the IDHR chunk */ -+ - void /* PRIVATE */ --png_decompress_chunk(png_structp png_ptr, int comp_type, -- png_size_t chunklength, -- png_size_t prefix_size, png_size_t *newlength) --{ -- /* The caller should guarantee this */ -- if (prefix_size > chunklength) -- { -- /* The recovery is to delete the chunk. */ -- png_warning(png_ptr, "invalid chunklength"); -- prefix_size = 0; /* To delete everything */ -- } -- -- else if (comp_type == PNG_COMPRESSION_TYPE_BASE) -- { -- png_size_t expanded_size = png_inflate(png_ptr, -- (png_bytep)(png_ptr->chunkdata + prefix_size), -- chunklength - prefix_size, -- 0, /* output */ -- 0); /* output size */ -- -- /* Now check the limits on this chunk - if the limit fails the -- * compressed data will be removed, the prefix will remain. -- */ --#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED -- if (png_ptr->user_chunk_malloc_max && -- (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) --#else --# ifdef PNG_USER_CHUNK_MALLOC_MAX -- if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && -- prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) --# endif --#endif -- png_warning(png_ptr, "Exceeded size limit while expanding chunk"); -- -- /* If the size is zero either there was an error and a message -- * has already been output (warning) or the size really is zero -- * and we have nothing to do - the code will exit through the -- * error case below. -- */ --#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ -- defined(PNG_USER_CHUNK_MALLOC_MAX) -- else if (expanded_size > 0) --#else -- if (expanded_size > 0) --#endif -- { -- /* Success (maybe) - really uncompress the chunk. */ -- png_size_t new_size = 0; -- png_charp text = png_malloc_warn(png_ptr, -- prefix_size + expanded_size + 1); -- -- if (text != NULL) -- { -- png_memcpy(text, png_ptr->chunkdata, prefix_size); -- new_size = png_inflate(png_ptr, -- (png_bytep)(png_ptr->chunkdata + prefix_size), -- chunklength - prefix_size, -- (png_bytep)(text + prefix_size), expanded_size); -- text[prefix_size + expanded_size] = 0; /* just in case */ -- -- if (new_size == expanded_size) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = text; -- *newlength = prefix_size + expanded_size; -- return; /* The success return! */ -- } -- -- png_warning(png_ptr, "png_inflate logic error"); -- png_free(png_ptr, text); -- } -- -- else -- png_warning(png_ptr, "Not enough memory to decompress chunk"); -- } -- } -- -- else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ -- { -- PNG_WARNING_PARAMETERS(p) -- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type); -- png_formatted_warning(png_ptr, p, "Unknown zTXt compression type @1"); -- -- /* The recovery is to simply drop the data. */ -- } -- -- /* Generic error return - leave the prefix, delete the compressed -- * data, reallocate the chunkdata to remove the potentially large -- * amount of compressed data. -- */ -- { -- png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); -- -- if (text != NULL) -- { -- if (prefix_size > 0) -- png_memcpy(text, png_ptr->chunkdata, prefix_size); -- -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = text; -- -- /* This is an extra zero in the 'uncompressed' part. */ -- *(png_ptr->chunkdata + prefix_size) = 0x00; -- } -- /* Ignore a malloc error here - it is safe. */ -- } -- -- *newlength = prefix_size; --} --#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ -- --/* Read and check the IDHR chunk */ --void /* PRIVATE */ --png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_byte buf[13]; - png_uint_32 width, height; -@@ -560,12 +827,12 @@ - - png_debug(1, "in png_handle_IHDR"); - -- if (png_ptr->mode & PNG_HAVE_IHDR) -- png_error(png_ptr, "Out of place IHDR"); -+ if ((png_ptr->mode & PNG_HAVE_IHDR) != 0) -+ png_chunk_error(png_ptr, "out of place"); - - /* Check the length */ - if (length != 13) -- png_error(png_ptr, "Invalid IHDR chunk"); -+ png_chunk_error(png_ptr, "invalid"); - - png_ptr->mode |= PNG_HAVE_IHDR; - -@@ -614,8 +881,7 @@ - } - - /* Set up other useful info */ -- png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * -- png_ptr->channels); -+ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); - png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); - png_debug1(3, "channels = %d", png_ptr->channels); -@@ -626,7 +892,7 @@ - - /* Read and check the palette */ - void /* PRIVATE */ --png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_color palette[PNG_MAX_PALETTE_LENGTH]; - int num, i; -@@ -636,26 +902,33 @@ - - png_debug(1, "in png_handle_PLTE"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before PLTE"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ /* Moved to before the 'after IDAT' check below because otherwise duplicate -+ * PLTE chunks are potentially ignored (the spec says there shall not be more -+ * than one PLTE, the error is not treated as benign, so this check trumps -+ * the requirement that PLTE appears before IDAT.) -+ */ -+ else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) -+ png_chunk_error(png_ptr, "duplicate"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { -- png_warning(png_ptr, "Invalid PLTE after IDAT"); -+ /* This is benign because the non-benign error happened before, when an -+ * IDAT was encountered in a color-mapped image with no PLTE. -+ */ - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- else if (png_ptr->mode & PNG_HAVE_PLTE) -- png_error(png_ptr, "Duplicate PLTE chunk"); -- - png_ptr->mode |= PNG_HAVE_PLTE; - -- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) -+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { -- png_warning(png_ptr, -- "Ignoring PLTE chunk in grayscale PNG"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); - return; - } - -@@ -669,19 +942,18 @@ - - if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) - { -+ png_crc_finish(png_ptr, length); -+ - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) -- { -- png_warning(png_ptr, "Invalid palette chunk"); -- png_crc_finish(png_ptr, length); -- return; -- } -+ png_chunk_benign_error(png_ptr, "invalid"); - - else -- { -- png_error(png_ptr, "Invalid palette chunk"); -- } -+ png_chunk_error(png_ptr, "invalid"); -+ -+ return; - } - -+ /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ - num = (int)length / 3; - - #ifdef PNG_POINTER_INDEXING_SUPPORTED -@@ -720,214 +992,196 @@ - } - - #ifndef PNG_READ_OPT_PLTE_SUPPORTED -- else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ -+ else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */ - { - /* If we don't want to use the data from an ancillary chunk, - * we have two options: an error abort, or a warning and we - * ignore the data in this chunk (which should be OK, since - * it's considered ancillary for a RGB or RGBA image). -+ * -+ * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the -+ * chunk type to determine whether to check the ancillary or the critical -+ * flags. - */ -- if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) -+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0) - { -- if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) -- { -- png_chunk_benign_error(png_ptr, "CRC error"); -- } -+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0) -+ return; - - else -- { -- png_chunk_warning(png_ptr, "CRC error"); -- return; -- } -+ png_chunk_error(png_ptr, "CRC error"); - } - - /* Otherwise, we (optionally) emit a warning and use the chunk. */ -- else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) -- { -+ else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0) - png_chunk_warning(png_ptr, "CRC error"); -- } - } - #endif - -+ /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its -+ * own copy of the palette. This has the side effect that when png_start_row -+ * is called (this happens after any call to png_read_update_info) the -+ * info_ptr palette gets changed. This is extremely unexpected and -+ * confusing. -+ * -+ * Fix this by not sharing the palette in this way. -+ */ - png_set_PLTE(png_ptr, info_ptr, palette, num); - -+ /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before -+ * IDAT. Prior to 1.6.0 this was not checked; instead the code merely -+ * checked the apparent validity of a tRNS chunk inserted before PLTE on a -+ * palette PNG. 1.6.0 attempts to rigorously follow the standard and -+ * therefore does a benign error if the erroneous condition is detected *and* -+ * cancels the tRNS if the benign error returns. The alternative is to -+ * amend the standard since it would be rather hypocritical of the standards -+ * maintainers to ignore it. -+ */ - #ifdef PNG_READ_tRNS_SUPPORTED -- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -+ if (png_ptr->num_trans > 0 || -+ (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) - { -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) -- { -- if (png_ptr->num_trans > (png_uint_16)num) -- { -- png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); -- png_ptr->num_trans = (png_uint_16)num; -- } -- -- if (info_ptr->num_trans > (png_uint_16)num) -- { -- png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); -- info_ptr->num_trans = (png_uint_16)num; -- } -- } -+ /* Cancel this because otherwise it would be used if the transforms -+ * require it. Don't cancel the 'valid' flag because this would prevent -+ * detection of duplicate chunks. -+ */ -+ png_ptr->num_trans = 0; -+ -+ if (info_ptr != NULL) -+ info_ptr->num_trans = 0; -+ -+ png_chunk_benign_error(png_ptr, "tRNS must be after"); - } - #endif - -+#ifdef PNG_READ_hIST_SUPPORTED -+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) -+ png_chunk_benign_error(png_ptr, "hIST must be after"); -+#endif -+ -+#ifdef PNG_READ_bKGD_SUPPORTED -+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) -+ png_chunk_benign_error(png_ptr, "bKGD must be after"); -+#endif - } - - void /* PRIVATE */ --png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_debug(1, "in png_handle_IEND"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) -- { -- png_error(png_ptr, "No image in file"); -- } -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 || -+ (png_ptr->mode & PNG_HAVE_IDAT) == 0) -+ png_chunk_error(png_ptr, "out of place"); - - png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); - -+ png_crc_finish(png_ptr, length); -+ - if (length != 0) -- { -- png_warning(png_ptr, "Incorrect IEND chunk length"); -- } -- -- png_crc_finish(png_ptr, length); -- -- PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ -+ png_chunk_benign_error(png_ptr, "invalid"); -+ -+ PNG_UNUSED(info_ptr) - } - - #ifdef PNG_READ_gAMA_SUPPORTED - void /* PRIVATE */ --png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_fixed_point igamma; - png_byte buf[4]; - - png_debug(1, "in png_handle_gAMA"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before gAMA"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { -- png_warning(png_ptr, "Invalid gAMA after IDAT"); -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); -+ return; -+ } -+ -+ if (length != 4) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); -+ return; -+ } -+ -+ png_crc_read(png_ptr, buf, 4); -+ -+ if (png_crc_finish(png_ptr, 0) != 0) -+ return; -+ -+ igamma = png_get_fixed_point(NULL, buf); -+ -+ png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); -+ png_colorspace_sync(png_ptr, info_ptr); -+} -+#endif -+ -+#ifdef PNG_READ_sBIT_SUPPORTED -+void /* PRIVATE */ -+png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -+{ -+ unsigned int truelen, i; -+ png_byte sample_depth; -+ png_byte buf[4]; -+ -+ png_debug(1, "in png_handle_sBIT"); -+ -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); -+ return; -+ } -+ -+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); -+ return; -+ } -+ -+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -+ { -+ truelen = 3; -+ sample_depth = 8; -+ } -+ -+ else -+ { -+ truelen = png_ptr->channels; -+ sample_depth = png_ptr->bit_depth; -+ } -+ -+ if (length != truelen || length > 4) -+ { -+ png_chunk_benign_error(png_ptr, "invalid"); - png_crc_finish(png_ptr, length); - return; - } - -- else if (png_ptr->mode & PNG_HAVE_PLTE) -- /* Should be an error, but we can cope with it */ -- png_warning(png_ptr, "Out of place gAMA chunk"); -- -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) --#ifdef PNG_READ_sRGB_SUPPORTED -- && !(info_ptr->valid & PNG_INFO_sRGB) --#endif -- ) -- { -- png_warning(png_ptr, "Duplicate gAMA chunk"); -- png_crc_finish(png_ptr, length); -+ buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; -+ png_crc_read(png_ptr, buf, truelen); -+ -+ if (png_crc_finish(png_ptr, 0) != 0) - return; -- } -- -- if (length != 4) -- { -- png_warning(png_ptr, "Incorrect gAMA chunk length"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- png_crc_read(png_ptr, buf, 4); -- -- if (png_crc_finish(png_ptr, 0)) -- return; -- -- igamma = png_get_fixed_point(NULL, buf); -- -- /* Check for zero gamma or an error. */ -- if (igamma <= 0) -- { -- png_warning(png_ptr, -- "Ignoring gAMA chunk with out of range gamma"); -- -- return; -- } -- --# ifdef PNG_READ_sRGB_SUPPORTED -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) -- { -- if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) -+ -+ for (i=0; i<truelen; ++i) -+ if (buf[i] == 0 || buf[i] > sample_depth) - { -- PNG_WARNING_PARAMETERS(p) -- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); -- png_formatted_warning(png_ptr, p, -- "Ignoring incorrect gAMA value @1 when sRGB is also present"); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } -- } --# endif /* PNG_READ_sRGB_SUPPORTED */ -- --# ifdef PNG_READ_GAMMA_SUPPORTED -- /* Gamma correction on read is supported. */ -- png_ptr->gamma = igamma; --# endif -- /* And set the 'info' structure members. */ -- png_set_gAMA_fixed(png_ptr, info_ptr, igamma); --} --#endif -- --#ifdef PNG_READ_sBIT_SUPPORTED --void /* PRIVATE */ --png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) --{ -- png_size_t truelen; -- png_byte buf[4]; -- -- png_debug(1, "in png_handle_sBIT"); -- -- buf[0] = buf[1] = buf[2] = buf[3] = 0; -- -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before sBIT"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -- { -- png_warning(png_ptr, "Invalid sBIT after IDAT"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- else if (png_ptr->mode & PNG_HAVE_PLTE) -- { -- /* Should be an error, but we can cope with it */ -- png_warning(png_ptr, "Out of place sBIT chunk"); -- } -- -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) -- { -- png_warning(png_ptr, "Duplicate sBIT chunk"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -- truelen = 3; -- -- else -- truelen = (png_size_t)png_ptr->channels; -- -- if (length != truelen || length > 4) -- { -- png_warning(png_ptr, "Incorrect sBIT chunk length"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- png_crc_read(png_ptr, buf, truelen); -- -- if (png_crc_finish(png_ptr, 0)) -- return; -- -- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) -+ -+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[1]; -@@ -950,377 +1204,416 @@ - - #ifdef PNG_READ_cHRM_SUPPORTED - void /* PRIVATE */ --png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_byte buf[32]; -- png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, -- y_blue; -+ png_xy xy; - - png_debug(1, "in png_handle_cHRM"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before cHRM"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { -- png_warning(png_ptr, "Invalid cHRM after IDAT"); -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); -+ return; -+ } -+ -+ if (length != 32) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); -+ return; -+ } -+ -+ png_crc_read(png_ptr, buf, 32); -+ -+ if (png_crc_finish(png_ptr, 0) != 0) -+ return; -+ -+ xy.whitex = png_get_fixed_point(NULL, buf); -+ xy.whitey = png_get_fixed_point(NULL, buf + 4); -+ xy.redx = png_get_fixed_point(NULL, buf + 8); -+ xy.redy = png_get_fixed_point(NULL, buf + 12); -+ xy.greenx = png_get_fixed_point(NULL, buf + 16); -+ xy.greeny = png_get_fixed_point(NULL, buf + 20); -+ xy.bluex = png_get_fixed_point(NULL, buf + 24); -+ xy.bluey = png_get_fixed_point(NULL, buf + 28); -+ -+ if (xy.whitex == PNG_FIXED_ERROR || -+ xy.whitey == PNG_FIXED_ERROR || -+ xy.redx == PNG_FIXED_ERROR || -+ xy.redy == PNG_FIXED_ERROR || -+ xy.greenx == PNG_FIXED_ERROR || -+ xy.greeny == PNG_FIXED_ERROR || -+ xy.bluex == PNG_FIXED_ERROR || -+ xy.bluey == PNG_FIXED_ERROR) -+ { -+ png_chunk_benign_error(png_ptr, "invalid values"); -+ return; -+ } -+ -+ /* If a colorspace error has already been output skip this chunk */ -+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) -+ return; -+ -+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0) -+ { -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; -+ png_colorspace_sync(png_ptr, info_ptr); -+ png_chunk_benign_error(png_ptr, "duplicate"); -+ return; -+ } -+ -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; -+ (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, -+ 1/*prefer cHRM values*/); -+ png_colorspace_sync(png_ptr, info_ptr); -+} -+#endif -+ -+#ifdef PNG_READ_sRGB_SUPPORTED -+void /* PRIVATE */ -+png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -+{ -+ png_byte intent; -+ -+ png_debug(1, "in png_handle_sRGB"); -+ -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); -+ return; -+ } -+ -+ if (length != 1) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); -+ return; -+ } -+ -+ png_crc_read(png_ptr, &intent, 1); -+ -+ if (png_crc_finish(png_ptr, 0) != 0) -+ return; -+ -+ /* If a colorspace error has already been output skip this chunk */ -+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) -+ return; -+ -+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect -+ * this. -+ */ -+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0) -+ { -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; -+ png_colorspace_sync(png_ptr, info_ptr); -+ png_chunk_benign_error(png_ptr, "too many profiles"); -+ return; -+ } -+ -+ (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); -+ png_colorspace_sync(png_ptr, info_ptr); -+} -+#endif /* READ_sRGB */ -+ -+#ifdef PNG_READ_iCCP_SUPPORTED -+void /* PRIVATE */ -+png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -+/* Note: this does not properly handle profiles that are > 64K under DOS */ -+{ -+ png_const_charp errmsg = NULL; /* error message output, or no error */ -+ int finished = 0; /* crc checked */ -+ -+ png_debug(1, "in png_handle_iCCP"); -+ -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); -+ return; -+ } -+ -+ /* Consistent with all the above colorspace handling an obviously *invalid* -+ * chunk is just ignored, so does not invalidate the color space. An -+ * alternative is to set the 'invalid' flags at the start of this routine -+ * and only clear them in they were not set before and all the tests pass. -+ * The minimum 'deflate' stream is assumed to be just the 2 byte header and -+ * 4 byte checksum. The keyword must be at least one character and there is -+ * a terminator (0) byte and the compression method. -+ */ -+ if (length < 9) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "too short"); -+ return; -+ } -+ -+ /* If a colorspace error has already been output skip this chunk */ -+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) -+ { - png_crc_finish(png_ptr, length); - return; - } - -- else if (png_ptr->mode & PNG_HAVE_PLTE) -- /* Should be an error, but we can cope with it */ -- png_warning(png_ptr, "Missing PLTE before cHRM"); -- -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) --# ifdef PNG_READ_sRGB_SUPPORTED -- && !(info_ptr->valid & PNG_INFO_sRGB) --# endif -- ) -+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect -+ * this. -+ */ -+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) - { -- png_warning(png_ptr, "Duplicate cHRM chunk"); -+ uInt read_length, keyword_length; -+ char keyword[81]; -+ -+ /* Find the keyword; the keyword plus separator and compression method -+ * bytes can be at most 81 characters long. -+ */ -+ read_length = 81; /* maximum */ -+ if (read_length > length) -+ read_length = (uInt)length; -+ -+ png_crc_read(png_ptr, (png_bytep)keyword, read_length); -+ length -= read_length; -+ -+ keyword_length = 0; -+ while (keyword_length < 80 && keyword_length < read_length && -+ keyword[keyword_length] != 0) -+ ++keyword_length; -+ -+ /* TODO: make the keyword checking common */ -+ if (keyword_length >= 1 && keyword_length <= 79) -+ { -+ /* We only understand '0' compression - deflate - so if we get a -+ * different value we can't safely decode the chunk. -+ */ -+ if (keyword_length+1 < read_length && -+ keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) -+ { -+ read_length -= keyword_length+2; -+ -+ if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) -+ { -+ Byte profile_header[132]; -+ Byte local_buffer[PNG_INFLATE_BUF_SIZE]; -+ png_alloc_size_t size = (sizeof profile_header); -+ -+ png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); -+ png_ptr->zstream.avail_in = read_length; -+ (void)png_inflate_read(png_ptr, local_buffer, -+ (sizeof local_buffer), &length, profile_header, &size, -+ 0/*finish: don't, because the output is too small*/); -+ -+ if (size == 0) -+ { -+ /* We have the ICC profile header; do the basic header checks. -+ */ -+ const png_uint_32 profile_length = -+ png_get_uint_32(profile_header); -+ -+ if (png_icc_check_length(png_ptr, &png_ptr->colorspace, -+ keyword, profile_length) != 0) -+ { -+ /* The length is apparently ok, so we can check the 132 -+ * byte header. -+ */ -+ if (png_icc_check_header(png_ptr, &png_ptr->colorspace, -+ keyword, profile_length, profile_header, -+ png_ptr->color_type) != 0) -+ { -+ /* Now read the tag table; a variable size buffer is -+ * needed at this point, allocate one for the whole -+ * profile. The header check has already validated -+ * that none of these stuff will overflow. -+ */ -+ const png_uint_32 tag_count = png_get_uint_32( -+ profile_header+128); -+ png_bytep profile = png_read_buffer(png_ptr, -+ profile_length, 2/*silent*/); -+ -+ if (profile != NULL) -+ { -+ memcpy(profile, profile_header, -+ (sizeof profile_header)); -+ -+ size = 12 * tag_count; -+ -+ (void)png_inflate_read(png_ptr, local_buffer, -+ (sizeof local_buffer), &length, -+ profile + (sizeof profile_header), &size, 0); -+ -+ /* Still expect a buffer error because we expect -+ * there to be some tag data! -+ */ -+ if (size == 0) -+ { -+ if (png_icc_check_tag_table(png_ptr, -+ &png_ptr->colorspace, keyword, profile_length, -+ profile) != 0) -+ { -+ /* The profile has been validated for basic -+ * security issues, so read the whole thing in. -+ */ -+ size = profile_length - (sizeof profile_header) -+ - 12 * tag_count; -+ -+ (void)png_inflate_read(png_ptr, local_buffer, -+ (sizeof local_buffer), &length, -+ profile + (sizeof profile_header) + -+ 12 * tag_count, &size, 1/*finish*/); -+ -+ if (length > 0 && !(png_ptr->flags & -+ PNG_FLAG_BENIGN_ERRORS_WARN)) -+ errmsg = "extra compressed data"; -+ -+ /* But otherwise allow extra data: */ -+ else if (size == 0) -+ { -+ if (length > 0) -+ { -+ /* This can be handled completely, so -+ * keep going. -+ */ -+ png_chunk_warning(png_ptr, -+ "extra compressed data"); -+ } -+ -+ png_crc_finish(png_ptr, length); -+ finished = 1; -+ -+# ifdef PNG_sRGB_SUPPORTED -+ /* Check for a match against sRGB */ -+ png_icc_set_sRGB(png_ptr, -+ &png_ptr->colorspace, profile, -+ png_ptr->zstream.adler); -+# endif -+ -+ /* Steal the profile for info_ptr. */ -+ if (info_ptr != NULL) -+ { -+ png_free_data(png_ptr, info_ptr, -+ PNG_FREE_ICCP, 0); -+ -+ info_ptr->iccp_name = png_voidcast(char*, -+ png_malloc_base(png_ptr, -+ keyword_length+1)); -+ if (info_ptr->iccp_name != NULL) -+ { -+ memcpy(info_ptr->iccp_name, keyword, -+ keyword_length+1); -+ info_ptr->iccp_proflen = -+ profile_length; -+ info_ptr->iccp_profile = profile; -+ png_ptr->read_buffer = NULL; /*steal*/ -+ info_ptr->free_me |= PNG_FREE_ICCP; -+ info_ptr->valid |= PNG_INFO_iCCP; -+ } -+ -+ else -+ { -+ png_ptr->colorspace.flags |= -+ PNG_COLORSPACE_INVALID; -+ errmsg = "out of memory"; -+ } -+ } -+ -+ /* else the profile remains in the read -+ * buffer which gets reused for subsequent -+ * chunks. -+ */ -+ -+ if (info_ptr != NULL) -+ png_colorspace_sync(png_ptr, info_ptr); -+ -+ if (errmsg == NULL) -+ { -+ png_ptr->zowner = 0; -+ return; -+ } -+ } -+ -+ else if (size > 0) -+ errmsg = "truncated"; -+ -+ else -+ errmsg = png_ptr->zstream.msg; -+ } -+ -+ /* else png_icc_check_tag_table output an error */ -+ } -+ -+ else /* profile truncated */ -+ errmsg = png_ptr->zstream.msg; -+ } -+ -+ else -+ errmsg = "out of memory"; -+ } -+ -+ /* else png_icc_check_header output an error */ -+ } -+ -+ /* else png_icc_check_length output an error */ -+ } -+ -+ else /* profile truncated */ -+ errmsg = png_ptr->zstream.msg; -+ -+ /* Release the stream */ -+ png_ptr->zowner = 0; -+ } -+ -+ else /* png_inflate_claim failed */ -+ errmsg = png_ptr->zstream.msg; -+ } -+ -+ else -+ errmsg = "bad compression method"; /* or missing */ -+ } -+ -+ else -+ errmsg = "bad keyword"; -+ } -+ -+ else -+ errmsg = "too many profiles"; -+ -+ /* Failure: the reason is in 'errmsg' */ -+ if (finished == 0) - png_crc_finish(png_ptr, length); -- return; -- } -- -- if (length != 32) -- { -- png_warning(png_ptr, "Incorrect cHRM chunk length"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- png_crc_read(png_ptr, buf, 32); -- -- if (png_crc_finish(png_ptr, 0)) -- return; -- -- x_white = png_get_fixed_point(NULL, buf); -- y_white = png_get_fixed_point(NULL, buf + 4); -- x_red = png_get_fixed_point(NULL, buf + 8); -- y_red = png_get_fixed_point(NULL, buf + 12); -- x_green = png_get_fixed_point(NULL, buf + 16); -- y_green = png_get_fixed_point(NULL, buf + 20); -- x_blue = png_get_fixed_point(NULL, buf + 24); -- y_blue = png_get_fixed_point(NULL, buf + 28); -- -- if (x_white == PNG_FIXED_ERROR || -- y_white == PNG_FIXED_ERROR || -- x_red == PNG_FIXED_ERROR || -- y_red == PNG_FIXED_ERROR || -- x_green == PNG_FIXED_ERROR || -- y_green == PNG_FIXED_ERROR || -- x_blue == PNG_FIXED_ERROR || -- y_blue == PNG_FIXED_ERROR) -- { -- png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); -- return; -- } -- --#ifdef PNG_READ_sRGB_SUPPORTED -- if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) -- { -- if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || -- PNG_OUT_OF_RANGE(y_white, 32900, 1000) || -- PNG_OUT_OF_RANGE(x_red, 64000L, 1000) || -- PNG_OUT_OF_RANGE(y_red, 33000, 1000) || -- PNG_OUT_OF_RANGE(x_green, 30000, 1000) || -- PNG_OUT_OF_RANGE(y_green, 60000L, 1000) || -- PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || -- PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) -- { -- PNG_WARNING_PARAMETERS(p) -- -- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white); -- png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white); -- png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red); -- png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red); -- png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green); -- png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green); -- png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue); -- png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue); -- -- png_formatted_warning(png_ptr, p, -- "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) " -- "when sRGB is also present"); -- } -- return; -- } --#endif /* PNG_READ_sRGB_SUPPORTED */ -- --#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -- /* Store the _white values as default coefficients for the rgb to gray -- * operation if it is supported. -- */ -- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) -- { -- /* png_set_background has not been called, the coefficients must be in -- * range for the following to work without overflow. -- */ -- if (y_red <= (1<<17) && y_green <= (1<<17) && y_blue <= (1<<17)) -- { -- /* The y values are chromaticities: Y/X+Y+Z, the weights for the gray -- * transformation are simply the normalized Y values for red, green and -- * blue scaled by 32768. -- */ -- png_uint_32 w = y_red + y_green + y_blue; -- -- png_ptr->rgb_to_gray_red_coeff = (png_uint_16)(((png_uint_32)y_red * -- 32768)/w); -- png_ptr->rgb_to_gray_green_coeff = (png_uint_16)(((png_uint_32)y_green -- * 32768)/w); -- png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(((png_uint_32)y_blue * -- 32768)/w); -- } -- } --#endif -- -- png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, -- x_green, y_green, x_blue, y_blue); -+ -+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; -+ png_colorspace_sync(png_ptr, info_ptr); -+ if (errmsg != NULL) /* else already output */ -+ png_chunk_benign_error(png_ptr, errmsg); - } --#endif -- --#ifdef PNG_READ_sRGB_SUPPORTED -+#endif /* READ_iCCP */ -+ -+#ifdef PNG_READ_sPLT_SUPPORTED - void /* PRIVATE */ --png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) --{ -- int intent; -- png_byte buf[1]; -- -- png_debug(1, "in png_handle_sRGB"); -- -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before sRGB"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -- { -- png_warning(png_ptr, "Invalid sRGB after IDAT"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- else if (png_ptr->mode & PNG_HAVE_PLTE) -- /* Should be an error, but we can cope with it */ -- png_warning(png_ptr, "Out of place sRGB chunk"); -- -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) -- { -- png_warning(png_ptr, "Duplicate sRGB chunk"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- if (length != 1) -- { -- png_warning(png_ptr, "Incorrect sRGB chunk length"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- png_crc_read(png_ptr, buf, 1); -- -- if (png_crc_finish(png_ptr, 0)) -- return; -- -- intent = buf[0]; -- -- /* Check for bad intent */ -- if (intent >= PNG_sRGB_INTENT_LAST) -- { -- png_warning(png_ptr, "Unknown sRGB intent"); -- return; -- } -- --#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) -- { -- if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500)) -- { -- PNG_WARNING_PARAMETERS(p) -- -- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, -- info_ptr->gamma); -- -- png_formatted_warning(png_ptr, p, -- "Ignoring incorrect gAMA value @1 when sRGB is also present"); -- } -- } --#endif /* PNG_READ_gAMA_SUPPORTED */ -- --#ifdef PNG_READ_cHRM_SUPPORTED -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) -- if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || -- PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || -- PNG_OUT_OF_RANGE(info_ptr->x_red, 64000L, 1000) || -- PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || -- PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || -- PNG_OUT_OF_RANGE(info_ptr->y_green, 60000L, 1000) || -- PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || -- PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) -- { -- png_warning(png_ptr, -- "Ignoring incorrect cHRM value when sRGB is also present"); -- } --#endif /* PNG_READ_cHRM_SUPPORTED */ -- -- png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); --} --#endif /* PNG_READ_sRGB_SUPPORTED */ -- --#ifdef PNG_READ_iCCP_SUPPORTED --void /* PRIVATE */ --png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - /* Note: this does not properly handle chunks that are > 64K under DOS */ - { -- png_byte compression_type; -- png_bytep pC; -- png_charp profile; -- png_uint_32 skip = 0; -- png_uint_32 profile_size; -- png_alloc_size_t profile_length; -- png_size_t slength, prefix_length, data_length; -- -- png_debug(1, "in png_handle_iCCP"); -- -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before iCCP"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -- { -- png_warning(png_ptr, "Invalid iCCP after IDAT"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- else if (png_ptr->mode & PNG_HAVE_PLTE) -- /* Should be an error, but we can cope with it */ -- png_warning(png_ptr, "Out of place iCCP chunk"); -- -- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) -- { -- png_warning(png_ptr, "Duplicate iCCP chunk"); -- png_crc_finish(png_ptr, length); -- return; -- } -- --#ifdef PNG_MAX_MALLOC_64K -- if (length > (png_uint_32)65535L) -- { -- png_warning(png_ptr, "iCCP chunk too large to fit in memory"); -- skip = length - (png_uint_32)65535L; -- length = (png_uint_32)65535L; -- } --#endif -- -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); -- slength = (png_size_t)length; -- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); -- -- if (png_crc_finish(png_ptr, skip)) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- png_ptr->chunkdata[slength] = 0x00; -- -- for (profile = png_ptr->chunkdata; *profile; profile++) -- /* Empty loop to find end of name */ ; -- -- ++profile; -- -- /* There should be at least one zero (the compression type byte) -- * following the separator, and we should be on it -- */ -- if (profile >= png_ptr->chunkdata + slength - 1) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- png_warning(png_ptr, "Malformed iCCP chunk"); -- return; -- } -- -- /* Compression_type should always be zero */ -- compression_type = *profile++; -- -- if (compression_type) -- { -- png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); -- compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 -- wrote nonzero) */ -- } -- -- prefix_length = profile - png_ptr->chunkdata; -- png_decompress_chunk(png_ptr, compression_type, -- slength, prefix_length, &data_length); -- -- profile_length = data_length - prefix_length; -- -- if (prefix_length > data_length || profile_length < 4) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- png_warning(png_ptr, "Profile size field missing from iCCP chunk"); -- return; -- } -- -- /* Check the profile_size recorded in the first 32 bits of the ICC profile */ -- pC = (png_bytep)(png_ptr->chunkdata + prefix_length); -- profile_size = ((*(pC )) << 24) | -- ((*(pC + 1)) << 16) | -- ((*(pC + 2)) << 8) | -- ((*(pC + 3)) ); -- -- /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, -- * because profile_size is a 32 bit value. -- */ -- if (profile_size < profile_length) -- profile_length = profile_size; -- -- /* And the following guarantees that profile_size == profile_length. */ -- if (profile_size > profile_length) -- { -- PNG_WARNING_PARAMETERS(p) -- -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- -- png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size); -- png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length); -- png_formatted_warning(png_ptr, p, -- "Ignoring iCCP chunk with declared size = @1 and actual length = @2"); -- return; -- } -- -- png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, -- compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, -- profile_size); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; --} --#endif /* PNG_READ_iCCP_SUPPORTED */ -- --#ifdef PNG_READ_sPLT_SUPPORTED --void /* PRIVATE */ --png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) --/* Note: this does not properly handle chunks that are > 64K under DOS */ --{ -- png_bytep entry_start; -+ png_bytep entry_start, buffer; - png_sPLT_t new_palette; - png_sPLT_entryp pp; - png_uint_32 data_length; - int entry_size, i; - png_uint_32 skip = 0; -- png_size_t slength; - png_uint_32 dl; - png_size_t max_dl; - - png_debug(1, "in png_handle_sPLT"); - - #ifdef PNG_USER_LIMITS_SUPPORTED -- - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) -@@ -1338,55 +1631,53 @@ - } - #endif - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before sPLT"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { -- png_warning(png_ptr, "Invalid sPLT after IDAT"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - #ifdef PNG_MAX_MALLOC_64K -- if (length > (png_uint_32)65535L) -+ if (length > 65535U) - { -- png_warning(png_ptr, "sPLT chunk too large to fit in memory"); -- skip = length - (png_uint_32)65535L; -- length = (png_uint_32)65535L; -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "too large to fit in memory"); -+ return; - } - #endif - -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); -+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); -+ if (buffer == NULL) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of memory"); -+ return; -+ } -+ - - /* WARNING: this may break if size_t is less than 32 bits; it is assumed - * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a - * potential breakage point if the types in pngconf.h aren't exactly right. - */ -- slength = (png_size_t)length; -- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); -- -- if (png_crc_finish(png_ptr, skip)) -+ png_crc_read(png_ptr, buffer, length); -+ -+ if (png_crc_finish(png_ptr, skip) != 0) -+ return; -+ -+ buffer[length] = 0; -+ -+ for (entry_start = buffer; *entry_start; entry_start++) -+ /* Empty loop to find end of name */ ; -+ -+ ++entry_start; -+ -+ /* A sample depth should follow the separator, and we should be on it */ -+ if (entry_start > buffer + length - 2) - { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- png_ptr->chunkdata[slength] = 0x00; -- -- for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; -- entry_start++) -- /* Empty loop to find end of name */ ; -- -- ++entry_start; -- -- /* A sample depth should follow the separator, and we should be on it */ -- if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; - png_warning(png_ptr, "malformed sPLT chunk"); - return; - } -@@ -1394,23 +1685,19 @@ - new_palette.depth = *entry_start++; - entry_size = (new_palette.depth == 8 ? 6 : 10); - /* This must fit in a png_uint_32 because it is derived from the original -- * chunk data length (and use 'length', not 'slength' here for clarity - -- * they are guaranteed to be the same, see the tests above.) -+ * chunk data length. - */ -- data_length = length - (png_uint_32)(entry_start - -- (png_bytep)png_ptr->chunkdata); -+ data_length = length - (png_uint_32)(entry_start - buffer); - - /* Integrity-check the data length */ -- if (data_length % entry_size) -+ if ((data_length % entry_size) != 0) - { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; - png_warning(png_ptr, "sPLT chunk has bad length"); - return; - } - - dl = (png_int_32)(data_length / entry_size); -- max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); -+ max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); - - if (dl > max_dl) - { -@@ -1421,7 +1708,7 @@ - new_palette.nentries = (png_int_32)(data_length / entry_size); - - new_palette.entries = (png_sPLT_entryp)png_malloc_warn( -- png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); -+ png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry))); - - if (new_palette.entries == NULL) - { -@@ -1479,38 +1766,36 @@ - #endif - - /* Discard all chunk data except the name and stash that */ -- new_palette.name = png_ptr->chunkdata; -+ new_palette.name = (png_charp)buffer; - - png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); - -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; - png_free(png_ptr, new_palette.entries); - } --#endif /* PNG_READ_sPLT_SUPPORTED */ -+#endif /* READ_sPLT */ - - #ifdef PNG_READ_tRNS_SUPPORTED - void /* PRIVATE */ --png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_tRNS"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before tRNS"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { -- png_warning(png_ptr, "Invalid tRNS after IDAT"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) - { -- png_warning(png_ptr, "Duplicate tRNS chunk"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - -@@ -1520,8 +1805,8 @@ - - if (length != 2) - { -- png_warning(png_ptr, "Incorrect tRNS chunk length"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - -@@ -1536,12 +1821,12 @@ - - if (length != 6) - { -- png_warning(png_ptr, "Incorrect tRNS chunk length"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - -- png_crc_read(png_ptr, buf, (png_size_t)length); -+ png_crc_read(png_ptr, buf, length); - png_ptr->num_trans = 1; - png_ptr->trans_color.red = png_get_uint_16(buf); - png_ptr->trans_color.green = png_get_uint_16(buf + 2); -@@ -1550,44 +1835,43 @@ - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { -- if (!(png_ptr->mode & PNG_HAVE_PLTE)) -+ if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) - { -- /* Should be an error, but we can cope with it. */ -- png_warning(png_ptr, "Missing PLTE before tRNS"); -- } -- -- if (length > (png_uint_32)png_ptr->num_palette || -- length > PNG_MAX_PALETTE_LENGTH) -- { -- png_warning(png_ptr, "Incorrect tRNS chunk length"); -+ /* TODO: is this actually an error in the ISO spec? */ - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- if (length == 0) -+ if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH || -+ length == 0) - { -- png_warning(png_ptr, "Zero length tRNS chunk"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - -- png_crc_read(png_ptr, readbuf, (png_size_t)length); -+ png_crc_read(png_ptr, readbuf, length); - png_ptr->num_trans = (png_uint_16)length; - } - - else - { -- png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid with alpha channel"); - return; - } - -- if (png_crc_finish(png_ptr, 0)) -+ if (png_crc_finish(png_ptr, 0) != 0) - { - png_ptr->num_trans = 0; - return; - } - -+ /* TODO: this is a horrible side effect in the palette case because the -+ * png_struct ends up with a pointer to the tRNS buffer owned by the -+ * png_info. Fix this. -+ */ - png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, - &(png_ptr->trans_color)); - } -@@ -1595,58 +1879,52 @@ - - #ifdef PNG_READ_bKGD_SUPPORTED - void /* PRIVATE */ --png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { -- png_size_t truelen; -+ unsigned int truelen; - png_byte buf[6]; - png_color_16 background; - - png_debug(1, "in png_handle_bKGD"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before bKGD"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || -+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -+ (png_ptr->mode & PNG_HAVE_PLTE) == 0)) - { -- png_warning(png_ptr, "Invalid bKGD after IDAT"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && -- !(png_ptr->mode & PNG_HAVE_PLTE)) -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) - { -- png_warning(png_ptr, "Missing PLTE before bKGD"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) -+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -+ truelen = 1; -+ -+ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) -+ truelen = 6; -+ -+ else -+ truelen = 2; -+ -+ if (length != truelen) - { -- png_warning(png_ptr, "Duplicate bKGD chunk"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - -- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -- truelen = 1; -- -- else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) -- truelen = 6; -- -- else -- truelen = 2; -- -- if (length != truelen) -- { -- png_warning(png_ptr, "Incorrect bKGD chunk length"); -- png_crc_finish(png_ptr, length); -- return; -- } -- - png_crc_read(png_ptr, buf, truelen); - -- if (png_crc_finish(png_ptr, 0)) -+ if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* We convert the index value into RGB components so that we can allow -@@ -1658,11 +1936,11 @@ - { - background.index = buf[0]; - -- if (info_ptr && info_ptr->num_palette) -+ if (info_ptr != NULL && info_ptr->num_palette != 0) - { - if (buf[0] >= info_ptr->num_palette) - { -- png_warning(png_ptr, "Incorrect bKGD chunk index value"); -+ png_chunk_benign_error(png_ptr, "invalid index"); - return; - } - -@@ -1677,7 +1955,7 @@ - background.gray = 0; - } - -- else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ -+ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ - { - background.index = 0; - background.red = -@@ -1701,44 +1979,37 @@ - - #ifdef PNG_READ_hIST_SUPPORTED - void /* PRIVATE */ --png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - unsigned int num, i; - png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_hIST"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before hIST"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || -+ (png_ptr->mode & PNG_HAVE_PLTE) == 0) - { -- png_warning(png_ptr, "Invalid hIST after IDAT"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- else if (!(png_ptr->mode & PNG_HAVE_PLTE)) -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) - { -- png_warning(png_ptr, "Missing PLTE before hIST"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) -+ num = length / 2 ; -+ -+ if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH) - { -- png_warning(png_ptr, "Duplicate hIST chunk"); - png_crc_finish(png_ptr, length); -- return; -- } -- -- num = length / 2 ; -- -- if (num != (unsigned int)png_ptr->num_palette || num > -- (unsigned int)PNG_MAX_PALETTE_LENGTH) -- { -- png_warning(png_ptr, "Incorrect hIST chunk length"); -- png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - -@@ -1750,7 +2021,7 @@ - readbuf[i] = png_get_uint_16(buf); - } - -- if (png_crc_finish(png_ptr, 0)) -+ if (png_crc_finish(png_ptr, 0) != 0) - return; - - png_set_hIST(png_ptr, info_ptr, readbuf); -@@ -1759,7 +2030,7 @@ - - #ifdef PNG_READ_pHYs_SUPPORTED - void /* PRIVATE */ --png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_byte buf[9]; - png_uint_32 res_x, res_y; -@@ -1767,33 +2038,33 @@ - - png_debug(1, "in png_handle_pHYs"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before pHYs"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { -- png_warning(png_ptr, "Invalid pHYs after IDAT"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) - { -- png_warning(png_ptr, "Duplicate pHYs chunk"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { -- png_warning(png_ptr, "Incorrect pHYs chunk length"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 9); - -- if (png_crc_finish(png_ptr, 0)) -+ if (png_crc_finish(png_ptr, 0) != 0) - return; - - res_x = png_get_uint_32(buf); -@@ -1805,7 +2076,7 @@ - - #ifdef PNG_READ_oFFs_SUPPORTED - void /* PRIVATE */ --png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_byte buf[9]; - png_int_32 offset_x, offset_y; -@@ -1813,33 +2084,33 @@ - - png_debug(1, "in png_handle_oFFs"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before oFFs"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { -- png_warning(png_ptr, "Invalid oFFs after IDAT"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) - { -- png_warning(png_ptr, "Duplicate oFFs chunk"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { -- png_warning(png_ptr, "Incorrect oFFs chunk length"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 9); - -- if (png_crc_finish(png_ptr, 0)) -+ if (png_crc_finish(png_ptr, 0) != 0) - return; - - offset_x = png_get_int_32(buf); -@@ -1852,71 +2123,64 @@ - #ifdef PNG_READ_pCAL_SUPPORTED - /* Read the pCAL chunk (described in the PNG Extensions document) */ - void /* PRIVATE */ --png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_int_32 X0, X1; - png_byte type, nparams; -- png_charp buf, units, endptr; -+ png_bytep buffer, buf, units, endptr; - png_charpp params; -- png_size_t slength; - int i; - - png_debug(1, "in png_handle_pCAL"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before pCAL"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { -- png_warning(png_ptr, "Invalid pCAL after IDAT"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0) - { -- png_warning(png_ptr, "Duplicate pCAL chunk"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", - length + 1); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); -- -- if (png_ptr->chunkdata == NULL) -+ -+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); -+ -+ if (buffer == NULL) - { -- png_warning(png_ptr, "No memory for pCAL purpose"); -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - -- slength = (png_size_t)length; -- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); -- -- if (png_crc_finish(png_ptr, 0)) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -+ png_crc_read(png_ptr, buffer, length); -+ -+ if (png_crc_finish(png_ptr, 0) != 0) - return; -- } -- -- png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ -+ -+ buffer[length] = 0; /* Null terminate the last string */ - - png_debug(3, "Finding end of pCAL purpose string"); -- for (buf = png_ptr->chunkdata; *buf; buf++) -+ for (buf = buffer; *buf; buf++) - /* Empty loop */ ; - -- endptr = png_ptr->chunkdata + slength; -+ endptr = buffer + length; - - /* We need to have at least 12 bytes after the purpose string - * in order to get the parameter information. - */ - if (endptr <= buf + 12) - { -- png_warning(png_ptr, "Invalid pCAL data"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - -@@ -1936,15 +2200,13 @@ - (type == PNG_EQUATION_ARBITRARY && nparams != 3) || - (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) - { -- png_warning(png_ptr, "Invalid pCAL parameters for equation type"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -+ png_chunk_benign_error(png_ptr, "invalid parameter count"); - return; - } - - else if (type >= PNG_EQUATION_LAST) - { -- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); -+ png_chunk_benign_error(png_ptr, "unrecognized equation type"); - } - - for (buf = units; *buf; buf++) -@@ -1952,43 +2214,37 @@ - - png_debug(3, "Allocating pCAL parameters array"); - -- params = (png_charpp)png_malloc_warn(png_ptr, -- (png_size_t)(nparams * png_sizeof(png_charp))); -+ params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, -+ nparams * (sizeof (png_charp)))); - - if (params == NULL) - { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- png_warning(png_ptr, "No memory for pCAL params"); -+ png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - /* Get pointers to the start of each parameter string. */ -- for (i = 0; i < (int)nparams; i++) -+ for (i = 0; i < nparams; i++) - { - buf++; /* Skip the null string terminator from previous parameter. */ - - png_debug1(3, "Reading pCAL parameter %d", i); - -- for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) -+ for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) - /* Empty loop to move past each parameter string */ ; - - /* Make sure we haven't run out of data yet */ - if (buf > endptr) - { -- png_warning(png_ptr, "Invalid pCAL data"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; - png_free(png_ptr, params); -+ png_chunk_benign_error(png_ptr, "invalid data"); - return; - } - } - -- png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, -- units, params); -- -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -+ png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, -+ (png_charp)units, params); -+ - png_free(png_ptr, params); - } - #endif -@@ -1996,67 +2252,61 @@ - #ifdef PNG_READ_sCAL_SUPPORTED - /* Read the sCAL chunk */ - void /* PRIVATE */ --png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { -- png_size_t slength, i; -+ png_bytep buffer; -+ png_size_t i; - int state; - - png_debug(1, "in png_handle_sCAL"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before sCAL"); -- -- else if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { -- png_warning(png_ptr, "Invalid sCAL after IDAT"); -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of place"); -+ return; -+ } -+ -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); -+ return; -+ } -+ -+ /* Need unit type, width, \0, height: minimum 4 bytes */ -+ else if (length < 4) -+ { -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); -+ return; -+ } -+ -+ png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", -+ length + 1); -+ -+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); -+ -+ if (buffer == NULL) -+ { -+ png_chunk_benign_error(png_ptr, "out of memory"); - png_crc_finish(png_ptr, length); - return; - } - -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) -+ png_crc_read(png_ptr, buffer, length); -+ buffer[length] = 0; /* Null terminate the last string */ -+ -+ if (png_crc_finish(png_ptr, 0) != 0) -+ return; -+ -+ /* Validate the unit. */ -+ if (buffer[0] != 1 && buffer[0] != 2) - { -- png_warning(png_ptr, "Duplicate sCAL chunk"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- /* Need unit type, width, \0, height: minimum 4 bytes */ -- else if (length < 4) -- { -- png_warning(png_ptr, "sCAL chunk too short"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", -- length + 1); -- -- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); -- -- if (png_ptr->chunkdata == NULL) -- { -- png_warning(png_ptr, "Out of memory while processing sCAL chunk"); -- png_crc_finish(png_ptr, length); -- return; -- } -- -- slength = (png_size_t)length; -- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); -- png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ -- -- if (png_crc_finish(png_ptr, 0)) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- /* Validate the unit. */ -- if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) -- { -- png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -+ png_chunk_benign_error(png_ptr, "invalid unit"); - return; - } - -@@ -2066,70 +2316,65 @@ - i = 1; - state = 0; - -- if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || -- i >= slength || png_ptr->chunkdata[i++] != 0) -- png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); -- -- else if (!PNG_FP_IS_POSITIVE(state)) -- png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width"); -+ if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 || -+ i >= length || buffer[i++] != 0) -+ png_chunk_benign_error(png_ptr, "bad width format"); -+ -+ else if (PNG_FP_IS_POSITIVE(state) == 0) -+ png_chunk_benign_error(png_ptr, "non-positive width"); - - else - { - png_size_t heighti = i; - - state = 0; -- if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || -- i != slength) -- png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); -- -- else if (!PNG_FP_IS_POSITIVE(state)) -- png_warning(png_ptr, -- "Invalid sCAL chunk ignored: non-positive height"); -+ if (png_check_fp_number((png_const_charp)buffer, length, -+ &state, &i) == 0 || i != length) -+ png_chunk_benign_error(png_ptr, "bad height format"); -+ -+ else if (PNG_FP_IS_POSITIVE(state) == 0) -+ png_chunk_benign_error(png_ptr, "non-positive height"); - - else - /* This is the (only) success case. */ -- png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], -- png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); -+ png_set_sCAL_s(png_ptr, info_ptr, buffer[0], -+ (png_charp)buffer+1, (png_charp)buffer+heighti); - } -- -- /* Clean up - just free the temporarily allocated buffer. */ -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; - } - #endif - - #ifdef PNG_READ_tIME_SUPPORTED - void /* PRIVATE */ --png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { - png_byte buf[7]; - png_time mod_time; - - png_debug(1, "in png_handle_tIME"); - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Out of place tIME chunk"); -- -- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0) - { -- png_warning(png_ptr, "Duplicate tIME chunk"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - -- if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - if (length != 7) - { -- png_warning(png_ptr, "Incorrect tIME chunk length"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 7); - -- if (png_crc_finish(png_ptr, 0)) -+ if (png_crc_finish(png_ptr, 0) != 0) - return; - - mod_time.second = buf[6]; -@@ -2146,14 +2391,13 @@ - #ifdef PNG_READ_tEXt_SUPPORTED - /* Note: this does not properly handle chunks that are > 64K under DOS */ - void /* PRIVATE */ --png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { -- png_textp text_ptr; -+ png_text text_info; -+ png_bytep buffer; - png_charp key; - png_charp text; - png_uint_32 skip = 0; -- png_size_t slength; -- int ret; - - png_debug(1, "in png_handle_tEXt"); - -@@ -2168,84 +2412,59 @@ - - if (--png_ptr->user_chunk_cache_max == 1) - { -- png_warning(png_ptr, "No space in chunk cache for tEXt"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } - #endif - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before tEXt"); -- -- if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - #ifdef PNG_MAX_MALLOC_64K -- if (length > (png_uint_32)65535L) -+ if (length > 65535U) - { -- png_warning(png_ptr, "tEXt chunk too large to fit in memory"); -- skip = length - (png_uint_32)65535L; -- length = (png_uint_32)65535L; -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "too large to fit in memory"); -+ return; - } - #endif - -- png_free(png_ptr, png_ptr->chunkdata); -- -- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); -- -- if (png_ptr->chunkdata == NULL) -+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); -+ -+ if (buffer == NULL) - { -- png_warning(png_ptr, "No memory to process text chunk"); -+ png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - -- slength = (png_size_t)length; -- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); -- -- if (png_crc_finish(png_ptr, skip)) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -+ png_crc_read(png_ptr, buffer, length); -+ -+ if (png_crc_finish(png_ptr, skip) != 0) - return; -- } -- -- key = png_ptr->chunkdata; -- -- key[slength] = 0x00; -+ -+ key = (png_charp)buffer; -+ key[length] = 0; - - for (text = key; *text; text++) - /* Empty loop to find end of key */ ; - -- if (text != key + slength) -+ if (text != key + length) - text++; - -- text_ptr = (png_textp)png_malloc_warn(png_ptr, -- png_sizeof(png_text)); -- -- if (text_ptr == NULL) -- { -- png_warning(png_ptr, "Not enough memory to process text chunk"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; -- text_ptr->key = key; -- text_ptr->lang = NULL; -- text_ptr->lang_key = NULL; -- text_ptr->itxt_length = 0; -- text_ptr->text = text; -- text_ptr->text_length = png_strlen(text); -- -- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); -- -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- png_free(png_ptr, text_ptr); -- -- if (ret) -+ text_info.compression = PNG_TEXT_COMPRESSION_NONE; -+ text_info.key = key; -+ text_info.lang = NULL; -+ text_info.lang_key = NULL; -+ text_info.itxt_length = 0; -+ text_info.text = text; -+ text_info.text_length = strlen(text); -+ -+ if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0) - png_warning(png_ptr, "Insufficient memory to process text chunk"); - } - #endif -@@ -2253,13 +2472,11 @@ - #ifdef PNG_READ_zTXt_SUPPORTED - /* Note: this does not correctly handle chunks that are > 64K under DOS */ - void /* PRIVATE */ --png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { -- png_textp text_ptr; -- png_charp text; -- int comp_type; -- int ret; -- png_size_t slength, prefix_len, data_len; -+ png_const_charp errmsg = NULL; -+ png_bytep buffer; -+ png_uint_32 keyword_length; - - png_debug(1, "in png_handle_zTXt"); - -@@ -2274,123 +2491,101 @@ - - if (--png_ptr->user_chunk_cache_max == 1) - { -- png_warning(png_ptr, "No space in chunk cache for zTXt"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } - #endif - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before zTXt"); -- -- if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - --#ifdef PNG_MAX_MALLOC_64K -- /* We will no doubt have problems with chunks even half this size, but -- * there is no hard and fast rule to tell us where to stop. -- */ -- if (length > (png_uint_32)65535L) -+ buffer = png_read_buffer(png_ptr, length, 2/*silent*/); -+ -+ if (buffer == NULL) - { -- png_warning(png_ptr, "zTXt chunk too large to fit in memory"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of memory"); - return; - } --#endif -- -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); -- -- if (png_ptr->chunkdata == NULL) -- { -- png_warning(png_ptr, "Out of memory processing zTXt chunk"); -+ -+ png_crc_read(png_ptr, buffer, length); -+ -+ if (png_crc_finish(png_ptr, 0) != 0) - return; -- } -- -- slength = (png_size_t)length; -- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); -- -- if (png_crc_finish(png_ptr, 0)) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- png_ptr->chunkdata[slength] = 0x00; -- -- for (text = png_ptr->chunkdata; *text; text++) -- /* Empty loop */ ; -- -- /* zTXt must have some text after the chunkdataword */ -- if (text >= png_ptr->chunkdata + slength - 2) -- { -- png_warning(png_ptr, "Truncated zTXt chunk"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -+ -+ /* TODO: also check that the keyword contents match the spec! */ -+ for (keyword_length = 0; -+ keyword_length < length && buffer[keyword_length] != 0; -+ ++keyword_length) -+ /* Empty loop to find end of name */ ; -+ -+ if (keyword_length > 79 || keyword_length < 1) -+ errmsg = "bad keyword"; -+ -+ /* zTXt must have some LZ data after the keyword, although it may expand to -+ * zero bytes; we need a '\0' at the end of the keyword, the compression type -+ * then the LZ data: -+ */ -+ else if (keyword_length + 3 > length) -+ errmsg = "truncated"; -+ -+ else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) -+ errmsg = "unknown compression type"; - - else - { -- comp_type = *(++text); -- -- if (comp_type != PNG_TEXT_COMPRESSION_zTXt) -- { -- png_warning(png_ptr, "Unknown compression type in zTXt chunk"); -- comp_type = PNG_TEXT_COMPRESSION_zTXt; -- } -- -- text++; /* Skip the compression_method byte */ -+ png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; -+ -+ /* TODO: at present png_decompress_chunk imposes a single application -+ * level memory limit, this should be split to different values for iCCP -+ * and text chunks. -+ */ -+ if (png_decompress_chunk(png_ptr, length, keyword_length+2, -+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) -+ { -+ png_text text; -+ -+ /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except -+ * for the extra compression type byte and the fact that it isn't -+ * necessarily '\0' terminated. -+ */ -+ buffer = png_ptr->read_buffer; -+ buffer[uncompressed_length+(keyword_length+2)] = 0; -+ -+ text.compression = PNG_TEXT_COMPRESSION_zTXt; -+ text.key = (png_charp)buffer; -+ text.text = (png_charp)(buffer + keyword_length+2); -+ text.text_length = uncompressed_length; -+ text.itxt_length = 0; -+ text.lang = NULL; -+ text.lang_key = NULL; -+ -+ if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) -+ errmsg = "insufficient memory"; -+ } -+ -+ else -+ errmsg = png_ptr->zstream.msg; - } - -- prefix_len = text - png_ptr->chunkdata; -- -- png_decompress_chunk(png_ptr, comp_type, -- (png_size_t)length, prefix_len, &data_len); -- -- text_ptr = (png_textp)png_malloc_warn(png_ptr, -- png_sizeof(png_text)); -- -- if (text_ptr == NULL) -- { -- png_warning(png_ptr, "Not enough memory to process zTXt chunk"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- text_ptr->compression = comp_type; -- text_ptr->key = png_ptr->chunkdata; -- text_ptr->lang = NULL; -- text_ptr->lang_key = NULL; -- text_ptr->itxt_length = 0; -- text_ptr->text = png_ptr->chunkdata + prefix_len; -- text_ptr->text_length = data_len; -- -- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); -- -- png_free(png_ptr, text_ptr); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- -- if (ret) -- png_error(png_ptr, "Insufficient memory to store zTXt chunk"); -+ if (errmsg != NULL) -+ png_chunk_benign_error(png_ptr, errmsg); - } - #endif - - #ifdef PNG_READ_iTXt_SUPPORTED - /* Note: this does not correctly handle chunks that are > 64K under DOS */ - void /* PRIVATE */ --png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) - { -- png_textp text_ptr; -- png_charp key, lang, text, lang_key; -- int comp_flag; -- int comp_type = 0; -- int ret; -- png_size_t slength, prefix_len, data_len; -+ png_const_charp errmsg = NULL; -+ png_bytep buffer; -+ png_uint_32 prefix_length; - - png_debug(1, "in png_handle_iTXt"); - -@@ -2405,274 +2600,393 @@ - - if (--png_ptr->user_chunk_cache_max == 1) - { -- png_warning(png_ptr, "No space in chunk cache for iTXt"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } - #endif - -- if (!(png_ptr->mode & PNG_HAVE_IHDR)) -- png_error(png_ptr, "Missing IHDR before iTXt"); -- -- if (png_ptr->mode & PNG_HAVE_IDAT) -+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) -+ png_chunk_error(png_ptr, "missing IHDR"); -+ -+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - --#ifdef PNG_MAX_MALLOC_64K -- /* We will no doubt have problems with chunks even half this size, but -- * there is no hard and fast rule to tell us where to stop. -- */ -- if (length > (png_uint_32)65535L) -+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); -+ -+ if (buffer == NULL) - { -- png_warning(png_ptr, "iTXt chunk too large to fit in memory"); - png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "out of memory"); - return; - } --#endif -- -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); -- -- if (png_ptr->chunkdata == NULL) -+ -+ png_crc_read(png_ptr, buffer, length); -+ -+ if (png_crc_finish(png_ptr, 0) != 0) -+ return; -+ -+ /* First the keyword. */ -+ for (prefix_length=0; -+ prefix_length < length && buffer[prefix_length] != 0; -+ ++prefix_length) -+ /* Empty loop */ ; -+ -+ /* Perform a basic check on the keyword length here. */ -+ if (prefix_length > 79 || prefix_length < 1) -+ errmsg = "bad keyword"; -+ -+ /* Expect keyword, compression flag, compression type, language, translated -+ * keyword (both may be empty but are 0 terminated) then the text, which may -+ * be empty. -+ */ -+ else if (prefix_length + 5 > length) -+ errmsg = "truncated"; -+ -+ else if (buffer[prefix_length+1] == 0 || -+ (buffer[prefix_length+1] == 1 && -+ buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) - { -- png_warning(png_ptr, "No memory to process iTXt chunk"); -- return; -+ int compressed = buffer[prefix_length+1] != 0; -+ png_uint_32 language_offset, translated_keyword_offset; -+ png_alloc_size_t uncompressed_length = 0; -+ -+ /* Now the language tag */ -+ prefix_length += 3; -+ language_offset = prefix_length; -+ -+ for (; prefix_length < length && buffer[prefix_length] != 0; -+ ++prefix_length) -+ /* Empty loop */ ; -+ -+ /* WARNING: the length may be invalid here, this is checked below. */ -+ translated_keyword_offset = ++prefix_length; -+ -+ for (; prefix_length < length && buffer[prefix_length] != 0; -+ ++prefix_length) -+ /* Empty loop */ ; -+ -+ /* prefix_length should now be at the trailing '\0' of the translated -+ * keyword, but it may already be over the end. None of this arithmetic -+ * can overflow because chunks are at most 2^31 bytes long, but on 16-bit -+ * systems the available allocation may overflow. -+ */ -+ ++prefix_length; -+ -+ if (compressed == 0 && prefix_length <= length) -+ uncompressed_length = length - prefix_length; -+ -+ else if (compressed != 0 && prefix_length < length) -+ { -+ uncompressed_length = PNG_SIZE_MAX; -+ -+ /* TODO: at present png_decompress_chunk imposes a single application -+ * level memory limit, this should be split to different values for -+ * iCCP and text chunks. -+ */ -+ if (png_decompress_chunk(png_ptr, length, prefix_length, -+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) -+ buffer = png_ptr->read_buffer; -+ -+ else -+ errmsg = png_ptr->zstream.msg; -+ } -+ -+ else -+ errmsg = "truncated"; -+ -+ if (errmsg == NULL) -+ { -+ png_text text; -+ -+ buffer[uncompressed_length+prefix_length] = 0; -+ -+ if (compressed == 0) -+ text.compression = PNG_ITXT_COMPRESSION_NONE; -+ -+ else -+ text.compression = PNG_ITXT_COMPRESSION_zTXt; -+ -+ text.key = (png_charp)buffer; -+ text.lang = (png_charp)buffer + language_offset; -+ text.lang_key = (png_charp)buffer + translated_keyword_offset; -+ text.text = (png_charp)buffer + prefix_length; -+ text.text_length = 0; -+ text.itxt_length = uncompressed_length; -+ -+ if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) -+ errmsg = "insufficient memory"; -+ } - } - -- slength = (png_size_t)length; -- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); -- -- if (png_crc_finish(png_ptr, 0)) -- { -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- png_ptr->chunkdata[slength] = 0x00; -- -- for (lang = png_ptr->chunkdata; *lang; lang++) -- /* Empty loop */ ; -- -- lang++; /* Skip NUL separator */ -- -- /* iTXt must have a language tag (possibly empty), two compression bytes, -- * translated keyword (possibly empty), and possibly some text after the -- * keyword -- */ -- -- if (lang >= png_ptr->chunkdata + slength - 3) -- { -- png_warning(png_ptr, "Truncated iTXt chunk"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- - else -- { -- comp_flag = *lang++; -- comp_type = *lang++; -- } -- -- for (lang_key = lang; *lang_key; lang_key++) -- /* Empty loop */ ; -- -- lang_key++; /* Skip NUL separator */ -- -- if (lang_key >= png_ptr->chunkdata + slength) -- { -- png_warning(png_ptr, "Truncated iTXt chunk"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- for (text = lang_key; *text; text++) -- /* Empty loop */ ; -- -- text++; /* Skip NUL separator */ -- -- if (text >= png_ptr->chunkdata + slength) -- { -- png_warning(png_ptr, "Malformed iTXt chunk"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- prefix_len = text - png_ptr->chunkdata; -- -- key=png_ptr->chunkdata; -- -- if (comp_flag) -- png_decompress_chunk(png_ptr, comp_type, -- (size_t)length, prefix_len, &data_len); -- -- else -- data_len = png_strlen(png_ptr->chunkdata + prefix_len); -- -- text_ptr = (png_textp)png_malloc_warn(png_ptr, -- png_sizeof(png_text)); -- -- if (text_ptr == NULL) -- { -- png_warning(png_ptr, "Not enough memory to process iTXt chunk"); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- return; -- } -- -- text_ptr->compression = (int)comp_flag + 1; -- text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); -- text_ptr->lang = png_ptr->chunkdata + (lang - key); -- text_ptr->itxt_length = data_len; -- text_ptr->text_length = 0; -- text_ptr->key = png_ptr->chunkdata; -- text_ptr->text = png_ptr->chunkdata + prefix_len; -- -- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); -- -- png_free(png_ptr, text_ptr); -- png_free(png_ptr, png_ptr->chunkdata); -- png_ptr->chunkdata = NULL; -- -- if (ret) -- png_error(png_ptr, "Insufficient memory to store iTXt chunk"); -+ errmsg = "bad compression info"; -+ -+ if (errmsg != NULL) -+ png_chunk_benign_error(png_ptr, errmsg); - } - #endif - --/* This function is called when we haven't found a handler for a -- * chunk. If there isn't a problem with the chunk itself (ie bad -- * chunk name, CRC, or a critical chunk), the chunk is silently ignored -- * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which -- * case it will be saved away to be written out later. -- */ --void /* PRIVATE */ --png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -+/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ -+static int -+png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) - { -- png_uint_32 skip = 0; -- -- png_debug(1, "in png_handle_unknown"); -- --#ifdef PNG_USER_LIMITS_SUPPORTED -- if (png_ptr->user_chunk_cache_max != 0) -+ png_alloc_size_t limit = PNG_SIZE_MAX; -+ -+ if (png_ptr->unknown_chunk.data != NULL) - { -- if (png_ptr->user_chunk_cache_max == 1) -- { -- png_crc_finish(png_ptr, length); -- return; -- } -- -- if (--png_ptr->user_chunk_cache_max == 1) -- { -- png_warning(png_ptr, "No space in chunk cache for unknown chunk"); -- png_crc_finish(png_ptr, length); -- return; -- } -- } --#endif -- -- if (png_ptr->mode & PNG_HAVE_IDAT) -- { -- PNG_IDAT; -- -- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ -- png_ptr->mode |= PNG_AFTER_IDAT; -- } -- -- if (!(png_ptr->chunk_name[0] & 0x20)) -- { --#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != -- PNG_HANDLE_CHUNK_ALWAYS --#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -- && png_ptr->read_user_chunk_fn == NULL --#endif -- ) --#endif -- png_chunk_error(png_ptr, "unknown critical chunk"); -- } -- --#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -- if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) --#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -- || (png_ptr->read_user_chunk_fn != NULL) --#endif -- ) -- { --#ifdef PNG_MAX_MALLOC_64K -- if (length > (png_uint_32)65535L) -- { -- png_warning(png_ptr, "unknown chunk too large to fit in memory"); -- skip = length - (png_uint_32)65535L; -- length = (png_uint_32)65535L; -- } --#endif -- -- png_memcpy((png_charp)png_ptr->unknown_chunk.name, -- (png_charp)png_ptr->chunk_name, -- png_sizeof(png_ptr->unknown_chunk.name)); -- -- png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] -- = '\0'; -- -- png_ptr->unknown_chunk.size = (png_size_t)length; -- -- if (length == 0) -- png_ptr->unknown_chunk.data = NULL; -- -- else -- { -- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); -- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); -- } -- --#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -- if (png_ptr->read_user_chunk_fn != NULL) -- { -- /* Callback to user unknown chunk handler */ -- int ret; -- -- ret = (*(png_ptr->read_user_chunk_fn)) -- (png_ptr, &png_ptr->unknown_chunk); -- -- if (ret < 0) -- png_chunk_error(png_ptr, "error in user chunk"); -- -- if (ret == 0) -- { -- if (!(png_ptr->chunk_name[0] & 0x20)) -- { --#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != -- PNG_HANDLE_CHUNK_ALWAYS) --#endif -- png_chunk_error(png_ptr, "unknown critical chunk"); -- } -- -- png_set_unknown_chunks(png_ptr, info_ptr, -- &png_ptr->unknown_chunk, 1); -- } -- } -- -- else --#endif -- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); -- - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - } - -+# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED -+ if (png_ptr->user_chunk_malloc_max > 0 && -+ png_ptr->user_chunk_malloc_max < limit) -+ limit = png_ptr->user_chunk_malloc_max; -+ -+# elif PNG_USER_CHUNK_MALLOC_MAX > 0 -+ if (PNG_USER_CHUNK_MALLOC_MAX < limit) -+ limit = PNG_USER_CHUNK_MALLOC_MAX; -+# endif -+ -+ if (length <= limit) -+ { -+ PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); -+ /* The following is safe because of the PNG_SIZE_MAX init above */ -+ png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/; -+ /* 'mode' is a flag array, only the bottom four bits matter here */ -+ png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; -+ -+ if (length == 0) -+ png_ptr->unknown_chunk.data = NULL; -+ -+ else -+ { -+ /* Do a 'warn' here - it is handled below. */ -+ png_ptr->unknown_chunk.data = png_voidcast(png_bytep, -+ png_malloc_warn(png_ptr, length)); -+ } -+ } -+ -+ if (png_ptr->unknown_chunk.data == NULL && length > 0) -+ { -+ /* This is benign because we clean up correctly */ -+ png_crc_finish(png_ptr, length); -+ png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); -+ return 0; -+ } -+ - else --#endif -- skip = length; -- -- png_crc_finish(png_ptr, skip); -- --#ifndef PNG_READ_USER_CHUNKS_SUPPORTED -- PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ --#endif -+ { -+ if (length > 0) -+ png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); -+ png_crc_finish(png_ptr, 0); -+ return 1; -+ } -+} -+#endif /* READ_UNKNOWN_CHUNKS */ -+ -+/* Handle an unknown, or known but disabled, chunk */ -+void /* PRIVATE */ -+png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, -+ png_uint_32 length, int keep) -+{ -+ int handled = 0; /* the chunk was handled */ -+ -+ png_debug(1, "in png_handle_unknown"); -+ -+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -+ /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing -+ * the bug which meant that setting a non-default behavior for a specific -+ * chunk would be ignored (the default was always used unless a user -+ * callback was installed). -+ * -+ * 'keep' is the value from the png_chunk_unknown_handling, the setting for -+ * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it -+ * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. -+ * This is just an optimization to avoid multiple calls to the lookup -+ * function. -+ */ -+# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+ keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); -+# endif -+# endif -+ -+ /* One of the following methods will read the chunk or skip it (at least one -+ * of these is always defined because this is the only way to switch on -+ * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) -+ */ -+# ifdef PNG_READ_USER_CHUNKS_SUPPORTED -+ /* The user callback takes precedence over the chunk keep value, but the -+ * keep value is still required to validate a save of a critical chunk. -+ */ -+ if (png_ptr->read_user_chunk_fn != NULL) -+ { -+ if (png_cache_unknown_chunk(png_ptr, length) != 0) -+ { -+ /* Callback to user unknown chunk handler */ -+ int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, -+ &png_ptr->unknown_chunk); -+ -+ /* ret is: -+ * negative: An error occured, png_chunk_error will be called. -+ * zero: The chunk was not handled, the chunk will be discarded -+ * unless png_set_keep_unknown_chunks has been used to set -+ * a 'keep' behavior for this particular chunk, in which -+ * case that will be used. A critical chunk will cause an -+ * error at this point unless it is to be saved. -+ * positive: The chunk was handled, libpng will ignore/discard it. -+ */ -+ if (ret < 0) -+ png_chunk_error(png_ptr, "error in user chunk"); -+ -+ else if (ret == 0) -+ { -+ /* If the keep value is 'default' or 'never' override it, but -+ * still error out on critical chunks unless the keep value is -+ * 'always' While this is weird it is the behavior in 1.4.12. -+ * A possible improvement would be to obey the value set for the -+ * chunk, but this would be an API change that would probably -+ * damage some applications. -+ * -+ * The png_app_warning below catches the case that matters, where -+ * the application has not set specific save or ignore for this -+ * chunk or global save or ignore. -+ */ -+ if (keep < PNG_HANDLE_CHUNK_IF_SAFE) -+ { -+# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+ if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) -+ { -+ png_chunk_warning(png_ptr, "Saving unknown chunk:"); -+ png_app_warning(png_ptr, -+ "forcing save of an unhandled chunk;" -+ " please call png_set_keep_unknown_chunks"); -+ /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ -+ } -+# endif -+ keep = PNG_HANDLE_CHUNK_IF_SAFE; -+ } -+ } -+ -+ else /* chunk was handled */ -+ { -+ handled = 1; -+ /* Critical chunks can be safely discarded at this point. */ -+ keep = PNG_HANDLE_CHUNK_NEVER; -+ } -+ } -+ -+ else -+ keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ -+ } -+ -+ else -+ /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ -+# endif /* READ_USER_CHUNKS */ -+ -+# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED -+ { -+ /* keep is currently just the per-chunk setting, if there was no -+ * setting change it to the global default now (not that this may -+ * still be AS_DEFAULT) then obtain the cache of the chunk if required, -+ * if not simply skip the chunk. -+ */ -+ if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) -+ keep = png_ptr->unknown_default; -+ -+ if (keep == PNG_HANDLE_CHUNK_ALWAYS || -+ (keep == PNG_HANDLE_CHUNK_IF_SAFE && -+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) -+ { -+ if (png_cache_unknown_chunk(png_ptr, length) == 0) -+ keep = PNG_HANDLE_CHUNK_NEVER; -+ } -+ -+ else -+ png_crc_finish(png_ptr, length); -+ } -+# else -+# ifndef PNG_READ_USER_CHUNKS_SUPPORTED -+# error no method to support READ_UNKNOWN_CHUNKS -+# endif -+ -+ { -+ /* If here there is no read callback pointer set and no support is -+ * compiled in to just save the unknown chunks, so simply skip this -+ * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then -+ * the app has erroneously asked for unknown chunk saving when there -+ * is no support. -+ */ -+ if (keep > PNG_HANDLE_CHUNK_NEVER) -+ png_app_error(png_ptr, "no unknown chunk support available"); -+ -+ png_crc_finish(png_ptr, length); -+ } -+# endif -+ -+# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -+ /* Now store the chunk in the chunk list if appropriate, and if the limits -+ * permit it. -+ */ -+ if (keep == PNG_HANDLE_CHUNK_ALWAYS || -+ (keep == PNG_HANDLE_CHUNK_IF_SAFE && -+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) -+ { -+# ifdef PNG_USER_LIMITS_SUPPORTED -+ switch (png_ptr->user_chunk_cache_max) -+ { -+ case 2: -+ png_ptr->user_chunk_cache_max = 1; -+ png_chunk_benign_error(png_ptr, "no space in chunk cache"); -+ /* FALL THROUGH */ -+ case 1: -+ /* NOTE: prior to 1.6.0 this case resulted in an unknown critical -+ * chunk being skipped, now there will be a hard error below. -+ */ -+ break; -+ -+ default: /* not at limit */ -+ --(png_ptr->user_chunk_cache_max); -+ /* FALL THROUGH */ -+ case 0: /* no limit */ -+# endif /* USER_LIMITS */ -+ /* Here when the limit isn't reached or when limits are compiled -+ * out; store the chunk. -+ */ -+ png_set_unknown_chunks(png_ptr, info_ptr, -+ &png_ptr->unknown_chunk, 1); -+ handled = 1; -+# ifdef PNG_USER_LIMITS_SUPPORTED -+ break; -+ } -+# endif -+ } -+# else /* no store support: the chunk must be handled by the user callback */ -+ PNG_UNUSED(info_ptr) -+# endif -+ -+ /* Regardless of the error handling below the cached data (if any) can be -+ * freed now. Notice that the data is not freed if there is a png_error, but -+ * it will be freed by destroy_read_struct. -+ */ -+ if (png_ptr->unknown_chunk.data != NULL) -+ png_free(png_ptr, png_ptr->unknown_chunk.data); -+ png_ptr->unknown_chunk.data = NULL; -+ -+#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ -+ /* There is no support to read an unknown chunk, so just skip it. */ -+ png_crc_finish(png_ptr, length); -+ PNG_UNUSED(info_ptr) -+ PNG_UNUSED(keep) -+#endif /* !READ_UNKNOWN_CHUNKS */ -+ -+ /* Check for unhandled critical chunks */ -+ if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) -+ png_chunk_error(png_ptr, "unhandled critical chunk"); - } - - /* This function is called to verify that a chunk name is valid. -@@ -2682,267 +2996,527 @@ - * the chunk name itself is valid. - */ - --#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -+/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: -+ * -+ * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -+ */ - - void /* PRIVATE */ --png_check_chunk_name(png_structp png_ptr, png_const_bytep chunk_name) -+png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name) - { -+ int i; -+ - png_debug(1, "in png_check_chunk_name"); -- if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || -- isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) -+ -+ for (i=1; i<=4; ++i) - { -- png_chunk_error(png_ptr, "invalid chunk type"); -+ int c = chunk_name & 0xff; -+ -+ if (c < 65 || c > 122 || (c > 90 && c < 97)) -+ png_chunk_error(png_ptr, "invalid chunk type"); -+ -+ chunk_name >>= 8; - } - } - --/* Combines the row recently read in with the existing pixels in the -- * row. This routine takes care of alpha and transparency if requested. -- * This routine also handles the two methods of progressive display -- * of interlaced images, depending on the mask value. -- * The mask value describes which pixels are to be combined with -- * the row. The pattern always repeats every 8 pixels, so just 8 -- * bits are needed. A one indicates the pixel is to be combined, -- * a zero indicates the pixel is to be skipped. This is in addition -- * to any alpha or transparency value associated with the pixel. If -- * you want all pixels to be combined, pass 0xff (255) in mask. -+/* Combines the row recently read in with the existing pixels in the row. This -+ * routine takes care of alpha and transparency if requested. This routine also -+ * handles the two methods of progressive display of interlaced images, -+ * depending on the 'display' value; if 'display' is true then the whole row -+ * (dp) is filled from the start by replicating the available pixels. If -+ * 'display' is false only those pixels present in the pass are filled in. - */ -- - void /* PRIVATE */ --png_combine_row(png_structp png_ptr, png_bytep row, int mask) -+png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) - { -+ unsigned int pixel_depth = png_ptr->transformed_pixel_depth; -+ png_const_bytep sp = png_ptr->row_buf + 1; -+ png_alloc_size_t row_width = png_ptr->width; -+ unsigned int pass = png_ptr->pass; -+ png_bytep end_ptr = 0; -+ png_byte end_byte = 0; -+ unsigned int end_mask; -+ - png_debug(1, "in png_combine_row"); - -- /* Added in 1.5.4: the row_info should match the information returned by any -- * call to png_read_update_info at this point. Do not continue if we got -+ /* Added in 1.5.6: it should not be possible to enter this routine until at -+ * least one row has been read from the PNG data and transformed. -+ */ -+ if (pixel_depth == 0) -+ png_error(png_ptr, "internal row logic error"); -+ -+ /* Added in 1.5.4: the pixel depth should match the information returned by -+ * any call to png_read_update_info at this point. Do not continue if we got - * this wrong. - */ - if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != -- PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)) -+ PNG_ROWBYTES(pixel_depth, row_width)) - png_error(png_ptr, "internal row size calculation error"); - -- if (mask == 0xff) -+ /* Don't expect this to ever happen: */ -+ if (row_width == 0) -+ png_error(png_ptr, "internal row width error"); -+ -+ /* Preserve the last byte in cases where only part of it will be overwritten, -+ * the multiply below may overflow, we don't care because ANSI-C guarantees -+ * we get the low bits. -+ */ -+ end_mask = (pixel_depth * row_width) & 7; -+ if (end_mask != 0) - { -- png_memcpy(row, png_ptr->row_buf + 1, -- PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); -+ /* end_ptr == NULL is a flag to say do nothing */ -+ end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; -+ end_byte = *end_ptr; -+# ifdef PNG_READ_PACKSWAP_SUPPORTED -+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) -+ /* little-endian byte */ -+ end_mask = 0xff << end_mask; -+ -+ else /* big-endian byte */ -+# endif -+ end_mask = 0xff >> end_mask; -+ /* end_mask is now the bits to *keep* from the destination row */ - } - -- else -+ /* For non-interlaced images this reduces to a memcpy(). A memcpy() -+ * will also happen if interlacing isn't supported or if the application -+ * does not call png_set_interlace_handling(). In the latter cases the -+ * caller just gets a sequence of the unexpanded rows from each interlace -+ * pass. -+ */ -+#ifdef PNG_READ_INTERLACING_SUPPORTED -+ if (png_ptr->interlaced != 0 && -+ (png_ptr->transformations & PNG_INTERLACE) != 0 && -+ pass < 6 && (display == 0 || -+ /* The following copies everything for 'display' on passes 0, 2 and 4. */ -+ (display == 1 && (pass & 1) != 0))) - { -- switch (png_ptr->row_info.pixel_depth) -+ /* Narrow images may have no bits in a pass; the caller should handle -+ * this, but this test is cheap: -+ */ -+ if (row_width <= PNG_PASS_START_COL(pass)) -+ return; -+ -+ if (pixel_depth < 8) - { -- case 1: -+ /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit -+ * into 32 bits, then a single loop over the bytes using the four byte -+ * values in the 32-bit mask can be used. For the 'display' option the -+ * expanded mask may also not require any masking within a byte. To -+ * make this work the PACKSWAP option must be taken into account - it -+ * simply requires the pixels to be reversed in each byte. -+ * -+ * The 'regular' case requires a mask for each of the first 6 passes, -+ * the 'display' case does a copy for the even passes in the range -+ * 0..6. This has already been handled in the test above. -+ * -+ * The masks are arranged as four bytes with the first byte to use in -+ * the lowest bits (little-endian) regardless of the order (PACKSWAP or -+ * not) of the pixels in each byte. -+ * -+ * NOTE: the whole of this logic depends on the caller of this function -+ * only calling it on rows appropriate to the pass. This function only -+ * understands the 'x' logic; the 'y' logic is handled by the caller. -+ * -+ * The following defines allow generation of compile time constant bit -+ * masks for each pixel depth and each possibility of swapped or not -+ * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, -+ * is in the range 0..7; and the result is 1 if the pixel is to be -+ * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' -+ * for the block method. -+ * -+ * With some compilers a compile time expression of the general form: -+ * -+ * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) -+ * -+ * Produces warnings with values of 'shift' in the range 33 to 63 -+ * because the right hand side of the ?: expression is evaluated by -+ * the compiler even though it isn't used. Microsoft Visual C (various -+ * versions) and the Intel C compiler are known to do this. To avoid -+ * this the following macros are used in 1.5.6. This is a temporary -+ * solution to avoid destabilizing the code during the release process. -+ */ -+# if PNG_USE_COMPILE_TIME_MASKS -+# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) -+# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) -+# else -+# define PNG_LSR(x,s) ((x)>>(s)) -+# define PNG_LSL(x,s) ((x)<<(s)) -+# endif -+# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ -+ PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) -+# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ -+ PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) -+ -+ /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is -+ * little endian - the first pixel is at bit 0 - however the extra -+ * parameter 's' can be set to cause the mask position to be swapped -+ * within each byte, to match the PNG format. This is done by XOR of -+ * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. -+ */ -+# define PIXEL_MASK(p,x,d,s) \ -+ (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) -+ -+ /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. -+ */ -+# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) -+# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) -+ -+ /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp -+ * cases the result needs replicating, for the 4-bpp case the above -+ * generates a full 32 bits. -+ */ -+# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) -+ -+# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ -+ S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ -+ S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) -+ -+# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ -+ B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ -+ B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) -+ -+#if PNG_USE_COMPILE_TIME_MASKS -+ /* Utility macros to construct all the masks for a depth/swap -+ * combination. The 's' parameter says whether the format is PNG -+ * (big endian bytes) or not. Only the three odd-numbered passes are -+ * required for the display/block algorithm. -+ */ -+# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ -+ S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } -+ -+# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) } -+ -+# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) -+ -+ /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and -+ * then pass: -+ */ -+ static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = - { -- png_bytep sp = png_ptr->row_buf + 1; -- png_bytep dp = row; -- int s_inc, s_start, s_end; -- int m = 0x80; -- int shift; -- png_uint_32 i; -- png_uint_32 row_width = png_ptr->width; -- --#ifdef PNG_READ_PACKSWAP_SUPPORTED -- if (png_ptr->transformations & PNG_PACKSWAP) -+ /* Little-endian byte masks for PACKSWAP */ -+ { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, -+ /* Normal (big-endian byte) masks - PNG format */ -+ { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } -+ }; -+ -+ /* display_mask has only three entries for the odd passes, so index by -+ * pass>>1. -+ */ -+ static PNG_CONST png_uint_32 display_mask[2][3][3] = -+ { -+ /* Little-endian byte masks for PACKSWAP */ -+ { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, -+ /* Normal (big-endian byte) masks - PNG format */ -+ { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } -+ }; -+ -+# define MASK(pass,depth,display,png)\ -+ ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ -+ row_mask[png][DEPTH_INDEX(depth)][pass]) -+ -+#else /* !PNG_USE_COMPILE_TIME_MASKS */ -+ /* This is the runtime alternative: it seems unlikely that this will -+ * ever be either smaller or faster than the compile time approach. -+ */ -+# define MASK(pass,depth,display,png)\ -+ ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) -+#endif /* !USE_COMPILE_TIME_MASKS */ -+ -+ /* Use the appropriate mask to copy the required bits. In some cases -+ * the byte mask will be 0 or 0xff; optimize these cases. row_width is -+ * the number of pixels, but the code copies bytes, so it is necessary -+ * to special case the end. -+ */ -+ png_uint_32 pixels_per_byte = 8 / pixel_depth; -+ png_uint_32 mask; -+ -+# ifdef PNG_READ_PACKSWAP_SUPPORTED -+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) -+ mask = MASK(pass, pixel_depth, display, 0); -+ -+ else -+# endif -+ mask = MASK(pass, pixel_depth, display, 1); -+ -+ for (;;) -+ { -+ png_uint_32 m; -+ -+ /* It doesn't matter in the following if png_uint_32 has more than -+ * 32 bits because the high bits always match those in m<<24; it is, -+ * however, essential to use OR here, not +, because of this. -+ */ -+ m = mask; -+ mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ -+ m &= 0xff; -+ -+ if (m != 0) /* something to copy */ - { -- s_start = 0; -- s_end = 7; -- s_inc = 1; -+ if (m != 0xff) -+ *dp = (png_byte)((*dp & ~m) | (*sp & m)); -+ else -+ *dp = *sp; - } - -- else --#endif -- { -- s_start = 7; -- s_end = 0; -- s_inc = -1; -- } -- -- shift = s_start; -- -- for (i = 0; i < row_width; i++) -- { -- if (m & mask) -- { -- int value; -- -- value = (*sp >> shift) & 0x01; -- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); -- *dp |= (png_byte)(value << shift); -- } -- -- if (shift == s_end) -- { -- shift = s_start; -- sp++; -- dp++; -- } -- -- else -- shift += s_inc; -- -- if (m == 1) -- m = 0x80; -- -- else -- m >>= 1; -- } -- break; -- } -- -- case 2: -- { -- png_bytep sp = png_ptr->row_buf + 1; -- png_bytep dp = row; -- int s_start, s_end, s_inc; -- int m = 0x80; -- int shift; -- png_uint_32 i; -- png_uint_32 row_width = png_ptr->width; -- int value; -- --#ifdef PNG_READ_PACKSWAP_SUPPORTED -- if (png_ptr->transformations & PNG_PACKSWAP) -- { -- s_start = 0; -- s_end = 6; -- s_inc = 2; -- } -- -- else --#endif -- { -- s_start = 6; -- s_end = 0; -- s_inc = -2; -- } -- -- shift = s_start; -- -- for (i = 0; i < row_width; i++) -- { -- if (m & mask) -- { -- value = (*sp >> shift) & 0x03; -- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); -- *dp |= (png_byte)(value << shift); -- } -- -- if (shift == s_end) -- { -- shift = s_start; -- sp++; -- dp++; -- } -- -- else -- shift += s_inc; -- -- if (m == 1) -- m = 0x80; -- -- else -- m >>= 1; -- } -- break; -- } -- -- case 4: -- { -- png_bytep sp = png_ptr->row_buf + 1; -- png_bytep dp = row; -- int s_start, s_end, s_inc; -- int m = 0x80; -- int shift; -- png_uint_32 i; -- png_uint_32 row_width = png_ptr->width; -- int value; -- --#ifdef PNG_READ_PACKSWAP_SUPPORTED -- if (png_ptr->transformations & PNG_PACKSWAP) -- { -- s_start = 0; -- s_end = 4; -- s_inc = 4; -- } -- -- else --#endif -- { -- s_start = 4; -- s_end = 0; -- s_inc = -4; -- } -- shift = s_start; -- -- for (i = 0; i < row_width; i++) -- { -- if (m & mask) -- { -- value = (*sp >> shift) & 0xf; -- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); -- *dp |= (png_byte)(value << shift); -- } -- -- if (shift == s_end) -- { -- shift = s_start; -- sp++; -- dp++; -- } -- -- else -- shift += s_inc; -- -- if (m == 1) -- m = 0x80; -- -- else -- m >>= 1; -- } -- break; -- } -- -- default: -- { -- png_bytep sp = png_ptr->row_buf + 1; -- png_bytep dp = row; -- png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); -- png_uint_32 i; -- png_uint_32 row_width = png_ptr->width; -- png_byte m = 0x80; -- -- for (i = 0; i < row_width; i++) -- { -- if (m & mask) -- { -- png_memcpy(dp, sp, pixel_bytes); -- } -- -- sp += pixel_bytes; -- dp += pixel_bytes; -- -- if (m == 1) -- m = 0x80; -- -- else -- m >>= 1; -- } -- break; -+ /* NOTE: this may overwrite the last byte with garbage if the image -+ * is not an exact number of bytes wide; libpng has always done -+ * this. -+ */ -+ if (row_width <= pixels_per_byte) -+ break; /* May need to restore part of the last byte */ -+ -+ row_width -= pixels_per_byte; -+ ++dp; -+ ++sp; - } - } -+ -+ else /* pixel_depth >= 8 */ -+ { -+ unsigned int bytes_to_copy, bytes_to_jump; -+ -+ /* Validate the depth - it must be a multiple of 8 */ -+ if (pixel_depth & 7) -+ png_error(png_ptr, "invalid user transform pixel depth"); -+ -+ pixel_depth >>= 3; /* now in bytes */ -+ row_width *= pixel_depth; -+ -+ /* Regardless of pass number the Adam 7 interlace always results in a -+ * fixed number of pixels to copy then to skip. There may be a -+ * different number of pixels to skip at the start though. -+ */ -+ { -+ unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; -+ -+ row_width -= offset; -+ dp += offset; -+ sp += offset; -+ } -+ -+ /* Work out the bytes to copy. */ -+ if (display != 0) -+ { -+ /* When doing the 'block' algorithm the pixel in the pass gets -+ * replicated to adjacent pixels. This is why the even (0,2,4,6) -+ * passes are skipped above - the entire expanded row is copied. -+ */ -+ bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; -+ -+ /* But don't allow this number to exceed the actual row width. */ -+ if (bytes_to_copy > row_width) -+ bytes_to_copy = (unsigned int)/*SAFE*/row_width; -+ } -+ -+ else /* normal row; Adam7 only ever gives us one pixel to copy. */ -+ bytes_to_copy = pixel_depth; -+ -+ /* In Adam7 there is a constant offset between where the pixels go. */ -+ bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; -+ -+ /* And simply copy these bytes. Some optimization is possible here, -+ * depending on the value of 'bytes_to_copy'. Special case the low -+ * byte counts, which we know to be frequent. -+ * -+ * Notice that these cases all 'return' rather than 'break' - this -+ * avoids an unnecessary test on whether to restore the last byte -+ * below. -+ */ -+ switch (bytes_to_copy) -+ { -+ case 1: -+ for (;;) -+ { -+ *dp = *sp; -+ -+ if (row_width <= bytes_to_jump) -+ return; -+ -+ dp += bytes_to_jump; -+ sp += bytes_to_jump; -+ row_width -= bytes_to_jump; -+ } -+ -+ case 2: -+ /* There is a possibility of a partial copy at the end here; this -+ * slows the code down somewhat. -+ */ -+ do -+ { -+ dp[0] = sp[0], dp[1] = sp[1]; -+ -+ if (row_width <= bytes_to_jump) -+ return; -+ -+ sp += bytes_to_jump; -+ dp += bytes_to_jump; -+ row_width -= bytes_to_jump; -+ } -+ while (row_width > 1); -+ -+ /* And there can only be one byte left at this point: */ -+ *dp = *sp; -+ return; -+ -+ case 3: -+ /* This can only be the RGB case, so each copy is exactly one -+ * pixel and it is not necessary to check for a partial copy. -+ */ -+ for (;;) -+ { -+ dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; -+ -+ if (row_width <= bytes_to_jump) -+ return; -+ -+ sp += bytes_to_jump; -+ dp += bytes_to_jump; -+ row_width -= bytes_to_jump; -+ } -+ -+ default: -+#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE -+ /* Check for double byte alignment and, if possible, use a -+ * 16-bit copy. Don't attempt this for narrow images - ones that -+ * are less than an interlace panel wide. Don't attempt it for -+ * wide bytes_to_copy either - use the memcpy there. -+ */ -+ if (bytes_to_copy < 16 /*else use memcpy*/ && -+ png_isaligned(dp, png_uint_16) && -+ png_isaligned(sp, png_uint_16) && -+ bytes_to_copy % (sizeof (png_uint_16)) == 0 && -+ bytes_to_jump % (sizeof (png_uint_16)) == 0) -+ { -+ /* Everything is aligned for png_uint_16 copies, but try for -+ * png_uint_32 first. -+ */ -+ if (png_isaligned(dp, png_uint_32) != 0 && -+ png_isaligned(sp, png_uint_32) != 0 && -+ bytes_to_copy % (sizeof (png_uint_32)) == 0 && -+ bytes_to_jump % (sizeof (png_uint_32)) == 0) -+ { -+ png_uint_32p dp32 = png_aligncast(png_uint_32p,dp); -+ png_const_uint_32p sp32 = png_aligncastconst( -+ png_const_uint_32p, sp); -+ size_t skip = (bytes_to_jump-bytes_to_copy) / -+ (sizeof (png_uint_32)); -+ -+ do -+ { -+ size_t c = bytes_to_copy; -+ do -+ { -+ *dp32++ = *sp32++; -+ c -= (sizeof (png_uint_32)); -+ } -+ while (c > 0); -+ -+ if (row_width <= bytes_to_jump) -+ return; -+ -+ dp32 += skip; -+ sp32 += skip; -+ row_width -= bytes_to_jump; -+ } -+ while (bytes_to_copy <= row_width); -+ -+ /* Get to here when the row_width truncates the final copy. -+ * There will be 1-3 bytes left to copy, so don't try the -+ * 16-bit loop below. -+ */ -+ dp = (png_bytep)dp32; -+ sp = (png_const_bytep)sp32; -+ do -+ *dp++ = *sp++; -+ while (--row_width > 0); -+ return; -+ } -+ -+ /* Else do it in 16-bit quantities, but only if the size is -+ * not too large. -+ */ -+ else -+ { -+ png_uint_16p dp16 = png_aligncast(png_uint_16p, dp); -+ png_const_uint_16p sp16 = png_aligncastconst( -+ png_const_uint_16p, sp); -+ size_t skip = (bytes_to_jump-bytes_to_copy) / -+ (sizeof (png_uint_16)); -+ -+ do -+ { -+ size_t c = bytes_to_copy; -+ do -+ { -+ *dp16++ = *sp16++; -+ c -= (sizeof (png_uint_16)); -+ } -+ while (c > 0); -+ -+ if (row_width <= bytes_to_jump) -+ return; -+ -+ dp16 += skip; -+ sp16 += skip; -+ row_width -= bytes_to_jump; -+ } -+ while (bytes_to_copy <= row_width); -+ -+ /* End of row - 1 byte left, bytes_to_copy > row_width: */ -+ dp = (png_bytep)dp16; -+ sp = (png_const_bytep)sp16; -+ do -+ *dp++ = *sp++; -+ while (--row_width > 0); -+ return; -+ } -+ } -+#endif /* ALIGN_TYPE code */ -+ -+ /* The true default - use a memcpy: */ -+ for (;;) -+ { -+ memcpy(dp, sp, bytes_to_copy); -+ -+ if (row_width <= bytes_to_jump) -+ return; -+ -+ sp += bytes_to_jump; -+ dp += bytes_to_jump; -+ row_width -= bytes_to_jump; -+ if (bytes_to_copy > row_width) -+ bytes_to_copy = (unsigned int)/*SAFE*/row_width; -+ } -+ } -+ -+ /* NOT REACHED*/ -+ } /* pixel_depth >= 8 */ -+ -+ /* Here if pixel_depth < 8 to check 'end_ptr' below. */ - } -+ else -+#endif /* READ_INTERLACING */ -+ -+ /* If here then the switch above wasn't used so just memcpy the whole row -+ * from the temporary row buffer (notice that this overwrites the end of the -+ * destination row if it is a partial byte.) -+ */ -+ memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); -+ -+ /* Restore the overwritten bits from the last byte if necessary. */ -+ if (end_ptr != NULL) -+ *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); - } - - #ifdef PNG_READ_INTERLACING_SUPPORTED - void /* PRIVATE */ --png_do_read_interlace(png_structp png_ptr) -+png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, -+ png_uint_32 transformations /* Because these may affect the byte layout */) - { -- png_row_infop row_info = &(png_ptr->row_info); -- png_bytep row = png_ptr->row_buf + 1; -- int pass = png_ptr->pass; -- png_uint_32 transformations = png_ptr->transformations; - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* Offset to next interlace block */ -- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_read_interlace"); - if (row != NULL && row_info != NULL) -@@ -2965,7 +3539,7 @@ - int j; - - #ifdef PNG_READ_PACKSWAP_SUPPORTED -- if (transformations & PNG_PACKSWAP) -+ if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = (int)((row_info->width + 7) & 0x07); - dshift = (int)((final_width + 7) & 0x07); -@@ -2989,8 +3563,9 @@ - v = (png_byte)((*sp >> sshift) & 0x01); - for (j = 0; j < jstop; j++) - { -- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); -- *dp |= (png_byte)(v << dshift); -+ unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); -+ tmp |= v << dshift; -+ *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { -@@ -3024,7 +3599,7 @@ - png_uint_32 i; - - #ifdef PNG_READ_PACKSWAP_SUPPORTED -- if (transformations & PNG_PACKSWAP) -+ if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = (int)(((row_info->width + 3) & 0x03) << 1); - dshift = (int)(((final_width + 3) & 0x03) << 1); -@@ -3051,8 +3626,9 @@ - v = (png_byte)((*sp >> sshift) & 0x03); - for (j = 0; j < jstop; j++) - { -- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); -- *dp |= (png_byte)(v << dshift); -+ unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); -+ tmp |= v << dshift; -+ *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { -@@ -3086,7 +3662,7 @@ - int jstop = png_pass_inc[pass]; - - #ifdef PNG_READ_PACKSWAP_SUPPORTED -- if (transformations & PNG_PACKSWAP) -+ if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = (int)(((row_info->width + 1) & 0x01) << 2); - dshift = (int)(((final_width + 1) & 0x01) << 2); -@@ -3107,13 +3683,14 @@ - - for (i = 0; i < row_info->width; i++) - { -- png_byte v = (png_byte)((*sp >> sshift) & 0xf); -+ png_byte v = (png_byte)((*sp >> sshift) & 0x0f); - int j; - - for (j = 0; j < jstop; j++) - { -- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); -- *dp |= (png_byte)(v << dshift); -+ unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); -+ tmp |= v << dshift; -+ *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { -@@ -3136,6 +3713,7 @@ - } - break; - } -+ - default: - { - png_size_t pixel_bytes = (row_info->pixel_depth >> 3); -@@ -3150,14 +3728,14 @@ - - for (i = 0; i < row_info->width; i++) - { -- png_byte v[8]; -+ png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */ - int j; - -- png_memcpy(v, sp, pixel_bytes); -+ memcpy(v, sp, pixel_bytes); - - for (j = 0; j < jstop; j++) - { -- png_memcpy(dp, v, pixel_bytes); -+ memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - -@@ -3166,6 +3744,7 @@ - break; - } - } -+ - row_info->width = final_width; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); - } -@@ -3173,167 +3752,427 @@ - PNG_UNUSED(transformations) /* Silence compiler warning */ - #endif - } --#endif /* PNG_READ_INTERLACING_SUPPORTED */ -+#endif /* READ_INTERLACING */ -+ -+static void -+png_read_filter_row_sub(png_row_infop row_info, png_bytep row, -+ png_const_bytep prev_row) -+{ -+ png_size_t i; -+ png_size_t istop = row_info->rowbytes; -+ unsigned int bpp = (row_info->pixel_depth + 7) >> 3; -+ png_bytep rp = row + bpp; -+ -+ PNG_UNUSED(prev_row) -+ -+ for (i = bpp; i < istop; i++) -+ { -+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); -+ rp++; -+ } -+} -+ -+static void -+png_read_filter_row_up(png_row_infop row_info, png_bytep row, -+ png_const_bytep prev_row) -+{ -+ png_size_t i; -+ png_size_t istop = row_info->rowbytes; -+ png_bytep rp = row; -+ png_const_bytep pp = prev_row; -+ -+ for (i = 0; i < istop; i++) -+ { -+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); -+ rp++; -+ } -+} -+ -+static void -+png_read_filter_row_avg(png_row_infop row_info, png_bytep row, -+ png_const_bytep prev_row) -+{ -+ png_size_t i; -+ png_bytep rp = row; -+ png_const_bytep pp = prev_row; -+ unsigned int bpp = (row_info->pixel_depth + 7) >> 3; -+ png_size_t istop = row_info->rowbytes - bpp; -+ -+ for (i = 0; i < bpp; i++) -+ { -+ *rp = (png_byte)(((int)(*rp) + -+ ((int)(*pp++) / 2 )) & 0xff); -+ -+ rp++; -+ } -+ -+ for (i = 0; i < istop; i++) -+ { -+ *rp = (png_byte)(((int)(*rp) + -+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); -+ -+ rp++; -+ } -+} -+ -+static void -+png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, -+ png_const_bytep prev_row) -+{ -+ png_bytep rp_end = row + row_info->rowbytes; -+ int a, c; -+ -+ /* First pixel/byte */ -+ c = *prev_row++; -+ a = *row + c; -+ *row++ = (png_byte)a; -+ -+ /* Remainder */ -+ while (row < rp_end) -+ { -+ int b, pa, pb, pc, p; -+ -+ a &= 0xff; /* From previous iteration or start */ -+ b = *prev_row++; -+ -+ p = b - c; -+ pc = a - c; -+ -+# ifdef PNG_USE_ABS -+ pa = abs(p); -+ pb = abs(pc); -+ pc = abs(p + pc); -+# else -+ pa = p < 0 ? -p : p; -+ pb = pc < 0 ? -pc : pc; -+ pc = (p + pc) < 0 ? -(p + pc) : p + pc; -+# endif -+ -+ /* Find the best predictor, the least of pa, pb, pc favoring the earlier -+ * ones in the case of a tie. -+ */ -+ if (pb < pa) pa = pb, a = b; -+ if (pc < pa) a = c; -+ -+ /* Calculate the current pixel in a, and move the previous row pixel to c -+ * for the next time round the loop -+ */ -+ c = b; -+ a += *row; -+ *row++ = (png_byte)a; -+ } -+} -+ -+static void -+png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, -+ png_const_bytep prev_row) -+{ -+ int bpp = (row_info->pixel_depth + 7) >> 3; -+ png_bytep rp_end = row + bpp; -+ -+ /* Process the first pixel in the row completely (this is the same as 'up' -+ * because there is only one candidate predictor for the first row). -+ */ -+ while (row < rp_end) -+ { -+ int a = *row + *prev_row++; -+ *row++ = (png_byte)a; -+ } -+ -+ /* Remainder */ -+ rp_end += row_info->rowbytes - bpp; -+ -+ while (row < rp_end) -+ { -+ int a, b, c, pa, pb, pc, p; -+ -+ c = *(prev_row - bpp); -+ a = *(row - bpp); -+ b = *prev_row++; -+ -+ p = b - c; -+ pc = a - c; -+ -+# ifdef PNG_USE_ABS -+ pa = abs(p); -+ pb = abs(pc); -+ pc = abs(p + pc); -+# else -+ pa = p < 0 ? -p : p; -+ pb = pc < 0 ? -pc : pc; -+ pc = (p + pc) < 0 ? -(p + pc) : p + pc; -+# endif -+ -+ if (pb < pa) pa = pb, a = b; -+ if (pc < pa) a = c; -+ -+ a += *row; -+ *row++ = (png_byte)a; -+ } -+} -+ -+static void -+png_init_filter_functions(png_structrp pp) -+ /* This function is called once for every PNG image (except for PNG images -+ * that only use PNG_FILTER_VALUE_NONE for all rows) to set the -+ * implementations required to reverse the filtering of PNG rows. Reversing -+ * the filter is the first transformation performed on the row data. It is -+ * performed in place, therefore an implementation can be selected based on -+ * the image pixel format. If the implementation depends on image width then -+ * take care to ensure that it works correctly if the image is interlaced - -+ * interlacing causes the actual row width to vary. -+ */ -+{ -+ unsigned int bpp = (pp->pixel_depth + 7) >> 3; -+ -+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; -+ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; -+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; -+ if (bpp == 1) -+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = -+ png_read_filter_row_paeth_1byte_pixel; -+ else -+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = -+ png_read_filter_row_paeth_multibyte_pixel; -+ -+#ifdef PNG_FILTER_OPTIMIZATIONS -+ /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to -+ * call to install hardware optimizations for the above functions; simply -+ * replace whatever elements of the pp->read_filter[] array with a hardware -+ * specific (or, for that matter, generic) optimization. -+ * -+ * To see an example of this examine what configure.ac does when -+ * --enable-arm-neon is specified on the command line. -+ */ -+ PNG_FILTER_OPTIMIZATIONS(pp, bpp); -+#endif -+} - - void /* PRIVATE */ --png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, -- png_const_bytep prev_row, int filter) -+png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, -+ png_const_bytep prev_row, int filter) - { -- png_debug(1, "in png_read_filter_row"); -- png_debug2(2, "row = %u, filter = %d", png_ptr->row_number, filter); -- switch (filter) -+ /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define -+ * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic -+ * implementations. See png_init_filter_functions above. -+ */ -+ if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) - { -- case PNG_FILTER_VALUE_NONE: -- break; -- -- case PNG_FILTER_VALUE_SUB: -+ if (pp->read_filter[0] == NULL) -+ png_init_filter_functions(pp); -+ -+ pp->read_filter[filter-1](row_info, row, prev_row); -+ } -+} -+ -+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+void /* PRIVATE */ -+png_read_IDAT_data(png_structrp png_ptr, png_bytep output, -+ png_alloc_size_t avail_out) -+{ -+ /* Loop reading IDATs and decompressing the result into output[avail_out] */ -+ png_ptr->zstream.next_out = output; -+ png_ptr->zstream.avail_out = 0; /* safety: set below */ -+ -+ if (output == NULL) -+ avail_out = 0; -+ -+ do -+ { -+ int ret; -+ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; -+ -+ if (png_ptr->zstream.avail_in == 0) - { -- png_size_t i; -- png_size_t istop = row_info->rowbytes; -- unsigned int bpp = (row_info->pixel_depth + 7) >> 3; -- png_bytep rp = row + bpp; -- png_bytep lp = row; -- -- for (i = bpp; i < istop; i++) -+ uInt avail_in; -+ png_bytep buffer; -+ -+ while (png_ptr->idat_size == 0) - { -- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); -- rp++; -+ png_crc_finish(png_ptr, 0); -+ -+ png_ptr->idat_size = png_read_chunk_header(png_ptr); -+ /* This is an error even in the 'check' case because the code just -+ * consumed a non-IDAT header. -+ */ -+ if (png_ptr->chunk_name != png_IDAT) -+ png_error(png_ptr, "Not enough image data"); - } -+ -+ avail_in = png_ptr->IDAT_read_size; -+ -+ if (avail_in > png_ptr->idat_size) -+ avail_in = (uInt)png_ptr->idat_size; -+ -+ /* A PNG with a gradually increasing IDAT size will defeat this attempt -+ * to minimize memory usage by causing lots of re-allocs, but -+ * realistically doing IDAT_read_size re-allocs is not likely to be a -+ * big problem. -+ */ -+ buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); -+ -+ png_crc_read(png_ptr, buffer, avail_in); -+ png_ptr->idat_size -= avail_in; -+ -+ png_ptr->zstream.next_in = buffer; -+ png_ptr->zstream.avail_in = avail_in; -+ } -+ -+ /* And set up the output side. */ -+ if (output != NULL) /* standard read */ -+ { -+ uInt out = ZLIB_IO_MAX; -+ -+ if (out > avail_out) -+ out = (uInt)avail_out; -+ -+ avail_out -= out; -+ png_ptr->zstream.avail_out = out; -+ } -+ -+ else /* after last row, checking for end */ -+ { -+ png_ptr->zstream.next_out = tmpbuf; -+ png_ptr->zstream.avail_out = (sizeof tmpbuf); -+ } -+ -+ /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the -+ * process. If the LZ stream is truncated the sequential reader will -+ * terminally damage the stream, above, by reading the chunk header of the -+ * following chunk (it then exits with png_error). -+ * -+ * TODO: deal more elegantly with truncated IDAT lists. -+ */ -+ ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); -+ -+ /* Take the unconsumed output back. */ -+ if (output != NULL) -+ avail_out += png_ptr->zstream.avail_out; -+ -+ else /* avail_out counts the extra bytes */ -+ avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; -+ -+ png_ptr->zstream.avail_out = 0; -+ -+ if (ret == Z_STREAM_END) -+ { -+ /* Do this for safety; we won't read any more into this row. */ -+ png_ptr->zstream.next_out = NULL; -+ -+ png_ptr->mode |= PNG_AFTER_IDAT; -+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; -+ -+ if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) -+ png_chunk_benign_error(png_ptr, "Extra compressed data"); - break; - } -- case PNG_FILTER_VALUE_UP: -+ -+ if (ret != Z_OK) - { -- png_size_t i; -- png_size_t istop = row_info->rowbytes; -- png_bytep rp = row; -- png_const_bytep pp = prev_row; -- -- for (i = 0; i < istop; i++) -+ png_zstream_error(png_ptr, ret); -+ -+ if (output != NULL) -+ png_chunk_error(png_ptr, png_ptr->zstream.msg); -+ -+ else /* checking */ - { -- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); -- rp++; -+ png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); -+ return; - } -- break; - } -- case PNG_FILTER_VALUE_AVG: -- { -- png_size_t i; -- png_bytep rp = row; -- png_const_bytep pp = prev_row; -- png_bytep lp = row; -- unsigned int bpp = (row_info->pixel_depth + 7) >> 3; -- png_size_t istop = row_info->rowbytes - bpp; -- -- for (i = 0; i < bpp; i++) -- { -- *rp = (png_byte)(((int)(*rp) + -- ((int)(*pp++) / 2 )) & 0xff); -- -- rp++; -- } -- -- for (i = 0; i < istop; i++) -- { -- *rp = (png_byte)(((int)(*rp) + -- (int)(*pp++ + *lp++) / 2 ) & 0xff); -- -- rp++; -- } -- break; -- } -- case PNG_FILTER_VALUE_PAETH: -- { -- png_size_t i; -- png_bytep rp = row; -- png_const_bytep pp = prev_row; -- png_bytep lp = row; -- png_const_bytep cp = prev_row; -- unsigned int bpp = (row_info->pixel_depth + 7) >> 3; -- png_size_t istop=row_info->rowbytes - bpp; -- -- for (i = 0; i < bpp; i++) -- { -- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); -- rp++; -- } -- -- for (i = 0; i < istop; i++) /* Use leftover rp,pp */ -- { -- int a, b, c, pa, pb, pc, p; -- -- a = *lp++; -- b = *pp++; -- c = *cp++; -- -- p = b - c; -- pc = a - c; -- --#ifdef PNG_USE_ABS -- pa = abs(p); -- pb = abs(pc); -- pc = abs(p + pc); --#else -- pa = p < 0 ? -p : p; -- pb = pc < 0 ? -pc : pc; -- pc = (p + pc) < 0 ? -(p + pc) : p + pc; --#endif -- -- /* -- if (pa <= pb && pa <= pc) -- p = a; -- -- else if (pb <= pc) -- p = b; -- -- else -- p = c; -- */ -- -- p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; -- -- *rp = (png_byte)(((int)(*rp) + p) & 0xff); -- rp++; -- } -- break; -- } -- default: -- png_error(png_ptr, "Ignoring bad adaptive filter type"); -- /*NOT REACHED */ -- break; -+ } while (avail_out > 0); -+ -+ if (avail_out > 0) -+ { -+ /* The stream ended before the image; this is the same as too few IDATs so -+ * should be handled the same way. -+ */ -+ if (output != NULL) -+ png_error(png_ptr, "Not enough image data"); -+ -+ else /* the deflate stream contained extra data */ -+ png_chunk_benign_error(png_ptr, "Too much image data"); - } - } - --#ifdef PNG_SEQUENTIAL_READ_SUPPORTED - void /* PRIVATE */ --png_read_finish_row(png_structp png_ptr) -+png_read_finish_IDAT(png_structrp png_ptr) - { --#ifdef PNG_READ_INTERLACING_SUPPORTED -+ /* We don't need any more data and the stream should have ended, however the -+ * LZ end code may actually not have been processed. In this case we must -+ * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk -+ * may still remain to be consumed. -+ */ -+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) -+ { -+ /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in -+ * the compressed stream, but the stream may be damaged too, so even after -+ * this call we may need to terminate the zstream ownership. -+ */ -+ png_read_IDAT_data(png_ptr, NULL, 0); -+ png_ptr->zstream.next_out = NULL; /* safety */ -+ -+ /* Now clear everything out for safety; the following may not have been -+ * done. -+ */ -+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) -+ { -+ png_ptr->mode |= PNG_AFTER_IDAT; -+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; -+ } -+ } -+ -+ /* If the zstream has not been released do it now *and* terminate the reading -+ * of the final IDAT chunk. -+ */ -+ if (png_ptr->zowner == png_IDAT) -+ { -+ /* Always do this; the pointers otherwise point into the read buffer. */ -+ png_ptr->zstream.next_in = NULL; -+ png_ptr->zstream.avail_in = 0; -+ -+ /* Now we no longer own the zstream. */ -+ png_ptr->zowner = 0; -+ -+ /* The slightly weird semantics of the sequential IDAT reading is that we -+ * are always in or at the end of an IDAT chunk, so we always need to do a -+ * crc_finish here. If idat_size is non-zero we also need to read the -+ * spurious bytes at the end of the chunk now. -+ */ -+ (void)png_crc_finish(png_ptr, png_ptr->idat_size); -+ } -+} -+ -+void /* PRIVATE */ -+png_read_finish_row(png_structrp png_ptr) -+{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ -- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; -+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ -- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ -- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; -+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ -- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; --#endif /* PNG_READ_INTERLACING_SUPPORTED */ -+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - - png_debug(1, "in png_read_finish_row"); - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - --#ifdef PNG_READ_INTERLACING_SUPPORTED -- if (png_ptr->interlaced) -+ if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; - -- png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); -+ /* TO DO: don't do this if prev_row isn't needed (requires -+ * read-ahead of the next row's filter byte. -+ */ -+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { -@@ -3347,7 +4186,7 @@ - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - -- if (!(png_ptr->transformations & PNG_INTERLACE)) -+ if ((png_ptr->transformations & PNG_INTERLACE) == 0) - { - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - -@@ -3363,108 +4202,40 @@ - if (png_ptr->pass < 7) - return; - } --#endif /* PNG_READ_INTERLACING_SUPPORTED */ -- -- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) -- { -- PNG_IDAT; -- char extra; -- int ret; -- -- png_ptr->zstream.next_out = (Byte *)&extra; -- png_ptr->zstream.avail_out = (uInt)1; -- -- for (;;) -- { -- if (!(png_ptr->zstream.avail_in)) -- { -- while (!png_ptr->idat_size) -- { -- png_crc_finish(png_ptr, 0); -- png_ptr->idat_size = png_read_chunk_header(png_ptr); -- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -- png_error(png_ptr, "Not enough image data"); -- } -- -- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; -- png_ptr->zstream.next_in = png_ptr->zbuf; -- -- if (png_ptr->zbuf_size > png_ptr->idat_size) -- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; -- -- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); -- png_ptr->idat_size -= png_ptr->zstream.avail_in; -- } -- -- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); -- -- if (ret == Z_STREAM_END) -- { -- if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || -- png_ptr->idat_size) -- png_warning(png_ptr, "Extra compressed data"); -- -- png_ptr->mode |= PNG_AFTER_IDAT; -- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -- break; -- } -- -- if (ret != Z_OK) -- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : -- "Decompression Error"); -- -- if (!(png_ptr->zstream.avail_out)) -- { -- png_warning(png_ptr, "Extra compressed data"); -- png_ptr->mode |= PNG_AFTER_IDAT; -- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -- break; -- } -- -- } -- png_ptr->zstream.avail_out = 0; -- } -- -- if (png_ptr->idat_size || png_ptr->zstream.avail_in) -- png_warning(png_ptr, "Extra compression data"); -- -- inflateReset(&png_ptr->zstream); -- -- png_ptr->mode |= PNG_AFTER_IDAT; -+ -+ /* Here after at the end of the last row of the last pass. */ -+ png_read_finish_IDAT(png_ptr); - } --#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ -+#endif /* SEQUENTIAL_READ */ - - void /* PRIVATE */ --png_read_start_row(png_structp png_ptr) -+png_read_start_row(png_structrp png_ptr) - { --#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ -- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; -+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ -- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ -- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; -+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ -- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; --#endif -+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - - int max_pixel_depth; - png_size_t row_bytes; - - png_debug(1, "in png_read_start_row"); -- png_ptr->zstream.avail_in = 0; -+ - #ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_init_read_transformations(png_ptr); - #endif --#ifdef PNG_READ_INTERLACING_SUPPORTED -- if (png_ptr->interlaced) -+ if (png_ptr->interlaced != 0) - { -- if (!(png_ptr->transformations & PNG_INTERLACE)) -+ if ((png_ptr->transformations & PNG_INTERLACE) == 0) - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - -@@ -3478,7 +4249,6 @@ - } - - else --#endif /* PNG_READ_INTERLACING_SUPPORTED */ - { - png_ptr->num_rows = png_ptr->height; - png_ptr->iwidth = png_ptr->width; -@@ -3486,17 +4256,27 @@ - - max_pixel_depth = png_ptr->pixel_depth; - -+ /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of -+ * calculations to calculate the final pixel depth, then -+ * png_do_read_transforms actually does the transforms. This means that the -+ * code which effectively calculates this value is actually repeated in three -+ * separate places. They must all match. Innocent changes to the order of -+ * transformations can and will break libpng in a way that causes memory -+ * overwrites. -+ * -+ * TODO: fix this. -+ */ - #ifdef PNG_READ_PACK_SUPPORTED -- if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) -+ if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8) - max_pixel_depth = 8; - #endif - - #ifdef PNG_READ_EXPAND_SUPPORTED -- if (png_ptr->transformations & PNG_EXPAND) -+ if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { -- if (png_ptr->num_trans) -+ if (png_ptr->num_trans != 0) - max_pixel_depth = 32; - - else -@@ -3508,13 +4288,13 @@ - if (max_pixel_depth < 8) - max_pixel_depth = 8; - -- if (png_ptr->num_trans) -+ if (png_ptr->num_trans != 0) - max_pixel_depth *= 2; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { -- if (png_ptr->num_trans) -+ if (png_ptr->num_trans != 0) - { - max_pixel_depth *= 4; - max_pixel_depth /= 3; -@@ -3524,13 +4304,13 @@ - #endif - - #ifdef PNG_READ_EXPAND_16_SUPPORTED -- if (png_ptr->transformations & PNG_EXPAND_16) -+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0) - { - # ifdef PNG_READ_EXPAND_SUPPORTED - /* In fact it is an error if it isn't supported, but checking is - * the safe way. - */ -- if (png_ptr->transformations & PNG_EXPAND) -+ if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (png_ptr->bit_depth < 16) - max_pixel_depth *= 2; -@@ -3542,12 +4322,9 @@ - #endif - - #ifdef PNG_READ_FILLER_SUPPORTED -- if (png_ptr->transformations & (PNG_FILLER)) -+ if ((png_ptr->transformations & (PNG_FILLER)) != 0) - { -- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -- max_pixel_depth = 32; -- -- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) -+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - if (max_pixel_depth <= 8) - max_pixel_depth = 16; -@@ -3556,7 +4333,8 @@ - max_pixel_depth = 32; - } - -- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) -+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || -+ png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (max_pixel_depth <= 32) - max_pixel_depth = 32; -@@ -3568,14 +4346,15 @@ - #endif - - #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -- if (png_ptr->transformations & PNG_GRAY_TO_RGB) -+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - { - if ( - #ifdef PNG_READ_EXPAND_SUPPORTED -- (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || -+ (png_ptr->num_trans != 0 && -+ (png_ptr->transformations & PNG_EXPAND) != 0) || - #endif - #ifdef PNG_READ_FILLER_SUPPORTED -- (png_ptr->transformations & (PNG_FILLER)) || -+ (png_ptr->transformations & (PNG_FILLER)) != 0 || - #endif - png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { -@@ -3608,16 +4387,22 @@ - - #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ - defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) -- if (png_ptr->transformations & PNG_USER_TRANSFORM) -+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { -- int user_pixel_depth = png_ptr->user_transform_depth* -+ int user_pixel_depth = png_ptr->user_transform_depth * - png_ptr->user_transform_channels; - - if (user_pixel_depth > max_pixel_depth) -- max_pixel_depth=user_pixel_depth; -+ max_pixel_depth = user_pixel_depth; - } - #endif - -+ /* This value is stored in png_struct and double checked in the row read -+ * code. -+ */ -+ png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; -+ png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ -+ - /* Align the width on the next larger 8 pixels. Mainly used - * for interlacing - */ -@@ -3636,28 +4421,39 @@ - if (row_bytes + 48 > png_ptr->old_big_row_buf_size) - { - png_free(png_ptr, png_ptr->big_row_buf); -- -- if (png_ptr->interlaced) -+ png_free(png_ptr, png_ptr->big_prev_row); -+ -+ if (png_ptr->interlaced != 0) - png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, - row_bytes + 48); - - else -- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, -- row_bytes + 48); -- -- png_ptr->old_big_row_buf_size = row_bytes + 48; -+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); -+ -+ png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - - #ifdef PNG_ALIGNED_MEMORY_SUPPORTED - /* Use 16-byte aligned memory for row_buf with at least 16 bytes -- * of padding before and after row_buf. -+ * of padding before and after row_buf; treat prev_row similarly. -+ * NOTE: the alignment is to the start of the pixels, one beyond the start -+ * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this -+ * was incorrect; the filter byte was aligned, which had the exact -+ * opposite effect of that intended. - */ -- png_ptr->row_buf = png_ptr->big_row_buf + 32 - -- (((png_alloc_size_t)png_ptr->big_row_buf + 15) & 0x0F); -- -- png_ptr->old_big_row_buf_size = row_bytes + 48; -+ { -+ png_bytep temp = png_ptr->big_row_buf + 32; -+ int extra = (int)((temp - (png_bytep)0) & 0x0f); -+ png_ptr->row_buf = temp - extra - 1/*filter byte*/; -+ -+ temp = png_ptr->big_prev_row + 32; -+ extra = (int)((temp - (png_bytep)0) & 0x0f); -+ png_ptr->prev_row = temp - extra - 1/*filter byte*/; -+ } -+ - #else -- /* Use 32 bytes of padding before and 16 bytes after row_buf. */ -- png_ptr->row_buf = png_ptr->big_row_buf + 32; -+ /* Use 31 bytes of padding before and 17 bytes after row_buf. */ -+ png_ptr->row_buf = png_ptr->big_row_buf + 31; -+ png_ptr->prev_row = png_ptr->big_prev_row + 31; - #endif - png_ptr->old_big_row_buf_size = row_bytes + 48; - } -@@ -3670,16 +4466,7 @@ - if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) - png_error(png_ptr, "Row has too many bytes to allocate in memory"); - -- if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size) -- { -- png_free(png_ptr, png_ptr->prev_row); -- -- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); -- -- png_ptr->old_prev_row_size = png_ptr->rowbytes + 1; -- } -- -- png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); -+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - png_debug1(3, "width = %u,", png_ptr->width); - png_debug1(3, "height = %u,", png_ptr->height); -@@ -3689,6 +4476,27 @@ - png_debug1(3, "irowbytes = %lu", - (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); - -+ /* The sequential reader needs a buffer for IDAT, but the progressive reader -+ * does not, so free the read buffer now regardless; the sequential reader -+ * reallocates it on demand. -+ */ -+ if (png_ptr->read_buffer != 0) -+ { -+ png_bytep buffer = png_ptr->read_buffer; -+ -+ png_ptr->read_buffer_size = 0; -+ png_ptr->read_buffer = NULL; -+ png_free(png_ptr, buffer); -+ } -+ -+ /* Finally claim the zstream for the inflate of the IDAT data, use the bits -+ * value from the stream (note that this will result in a fatal error if the -+ * IDAT stream has a bogus deflate header window_bits value, but this should -+ * not be happening any longer!) -+ */ -+ if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) -+ png_error(png_ptr, png_ptr->zstream.msg); -+ - png_ptr->flags |= PNG_FLAG_ROW_INIT; - } --#endif /* PNG_READ_SUPPORTED */ -+#endif /* READ */ ---- ./jdk/src/share/native/sun/awt/libpng/pngset.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngset.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -50,51 +50,84 @@ - - #ifdef PNG_bKGD_SUPPORTED - void PNGAPI --png_set_bKGD(png_structp png_ptr, png_infop info_ptr, -+png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_16p background) - { - png_debug1(1, "in %s storage function", "bKGD"); - -- if (png_ptr == NULL || info_ptr == NULL) -+ if (png_ptr == NULL || info_ptr == NULL || background == NULL) - return; - -- png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); -+ info_ptr->background = *background; - info_ptr->valid |= PNG_INFO_bKGD; - } - #endif - - #ifdef PNG_cHRM_SUPPORTED - void PNGFAPI --png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, -+png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, - png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, - png_fixed_point blue_x, png_fixed_point blue_y) - { -+ png_xy xy; -+ - png_debug1(1, "in %s storage function", "cHRM fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - --# ifdef PNG_CHECK_cHRM_SUPPORTED -- if (png_check_cHRM_fixed(png_ptr, -- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) --# endif -- { -- info_ptr->x_white = white_x; -- info_ptr->y_white = white_y; -- info_ptr->x_red = red_x; -- info_ptr->y_red = red_y; -- info_ptr->x_green = green_x; -- info_ptr->y_green = green_y; -- info_ptr->x_blue = blue_x; -- info_ptr->y_blue = blue_y; -- info_ptr->valid |= PNG_INFO_cHRM; -- } -+ xy.redx = red_x; -+ xy.redy = red_y; -+ xy.greenx = green_x; -+ xy.greeny = green_y; -+ xy.bluex = blue_x; -+ xy.bluey = blue_y; -+ xy.whitex = white_x; -+ xy.whitey = white_y; -+ -+ if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, -+ 2/* override with app values*/) != 0) -+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; -+ -+ png_colorspace_sync_info(png_ptr, info_ptr); -+} -+ -+void PNGFAPI -+png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, -+ png_fixed_point int_red_X, png_fixed_point int_red_Y, -+ png_fixed_point int_red_Z, png_fixed_point int_green_X, -+ png_fixed_point int_green_Y, png_fixed_point int_green_Z, -+ png_fixed_point int_blue_X, png_fixed_point int_blue_Y, -+ png_fixed_point int_blue_Z) -+{ -+ png_XYZ XYZ; -+ -+ png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); -+ -+ if (png_ptr == NULL || info_ptr == NULL) -+ return; -+ -+ XYZ.red_X = int_red_X; -+ XYZ.red_Y = int_red_Y; -+ XYZ.red_Z = int_red_Z; -+ XYZ.green_X = int_green_X; -+ XYZ.green_Y = int_green_Y; -+ XYZ.green_Z = int_green_Z; -+ XYZ.blue_X = int_blue_X; -+ XYZ.blue_Y = int_blue_Y; -+ XYZ.blue_Z = int_blue_Z; -+ -+ if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, -+ &XYZ, 2) != 0) -+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; -+ -+ png_colorspace_sync_info(png_ptr, info_ptr); - } - - # ifdef PNG_FLOATING_POINT_SUPPORTED - void PNGAPI --png_set_cHRM(png_structp png_ptr, png_infop info_ptr, -+png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, - double green_x, double green_y, double blue_x, double blue_y) - { -@@ -108,41 +141,44 @@ - png_fixed(png_ptr, blue_x, "cHRM Blue X"), - png_fixed(png_ptr, blue_y, "cHRM Blue Y")); - } --# endif /* PNG_FLOATING_POINT_SUPPORTED */ - --#endif /* PNG_cHRM_SUPPORTED */ -+void PNGAPI -+png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, -+ double red_Y, double red_Z, double green_X, double green_Y, double green_Z, -+ double blue_X, double blue_Y, double blue_Z) -+{ -+ png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, -+ png_fixed(png_ptr, red_X, "cHRM Red X"), -+ png_fixed(png_ptr, red_Y, "cHRM Red Y"), -+ png_fixed(png_ptr, red_Z, "cHRM Red Z"), -+ png_fixed(png_ptr, green_X, "cHRM Red X"), -+ png_fixed(png_ptr, green_Y, "cHRM Red Y"), -+ png_fixed(png_ptr, green_Z, "cHRM Red Z"), -+ png_fixed(png_ptr, blue_X, "cHRM Red X"), -+ png_fixed(png_ptr, blue_Y, "cHRM Red Y"), -+ png_fixed(png_ptr, blue_Z, "cHRM Red Z")); -+} -+# endif /* FLOATING_POINT */ -+ -+#endif /* cHRM */ - - #ifdef PNG_gAMA_SUPPORTED - void PNGFAPI --png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point -- file_gamma) -+png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, -+ png_fixed_point file_gamma) - { - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -- /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't -- * occur. Since the fixed point representation is assymetrical it is -- * possible for 1/gamma to overflow the limit of 21474 and this means the -- * gamma value must be at least 5/100000 and hence at most 20000.0. For -- * safety the limits here are a little narrower. The values are 0.00016 to -- * 6250.0, which are truely ridiculous gammma values (and will produce -- * displays that are all black or all white.) -- */ -- if (file_gamma < 16 || file_gamma > 625000000) -- png_warning(png_ptr, "Out of range gamma value ignored"); -- -- else -- { -- info_ptr->gamma = file_gamma; -- info_ptr->valid |= PNG_INFO_gAMA; -- } -+ png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); -+ png_colorspace_sync_info(png_ptr, info_ptr); - } - - # ifdef PNG_FLOATING_POINT_SUPPORTED - void PNGAPI --png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) -+png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) - { - png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, - "png_set_gAMA")); -@@ -152,7 +188,8 @@ - - #ifdef PNG_hIST_SUPPORTED - void PNGAPI --png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) -+png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, -+ png_const_uint_16p hist) - { - int i; - -@@ -175,26 +212,26 @@ - /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in - * version 1.2.1 - */ -- png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, -- PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); -+ info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, -+ PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); - -- if (png_ptr->hist == NULL) -+ if (info_ptr->hist == NULL) - { - png_warning(png_ptr, "Insufficient memory for hIST chunk data"); - return; - } - -+ info_ptr->free_me |= PNG_FREE_HIST; -+ - for (i = 0; i < info_ptr->num_palette; i++) -- png_ptr->hist[i] = hist[i]; -+ info_ptr->hist[i] = hist[i]; - -- info_ptr->hist = png_ptr->hist; - info_ptr->valid |= PNG_INFO_hIST; -- info_ptr->free_me |= PNG_FREE_HIST; - } - #endif - - void PNGAPI --png_set_IHDR(png_structp png_ptr, png_infop info_ptr, -+png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -@@ -219,32 +256,23 @@ - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - -- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) -+ else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - -- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) -+ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - info_ptr->channels++; - - info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); - -- /* Check for potential overflow */ -- if (width > -- (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */ -- - 48 /* bigrowbuf hack */ -- - 1 /* filter byte */ -- - 7*8 /* rounding of width to multiple of 8 pixels */ -- - 8) /* extra max_pixel_depth pad */ -- info_ptr->rowbytes = 0; -- else -- info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); -+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); - } - - #ifdef PNG_oFFs_SUPPORTED - void PNGAPI --png_set_oFFs(png_structp png_ptr, png_infop info_ptr, -+png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, - png_int_32 offset_x, png_int_32 offset_y, int unit_type) - { - png_debug1(1, "in %s storage function", "oFFs"); -@@ -261,7 +289,7 @@ - - #ifdef PNG_pCAL_SUPPORTED - void PNGAPI --png_set_pCAL(png_structp png_ptr, png_infop info_ptr, -+png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, - int nparams, png_const_charp units, png_charpp params) - { -@@ -270,10 +298,11 @@ - - png_debug1(1, "in %s storage function", "pCAL"); - -- if (png_ptr == NULL || info_ptr == NULL) -+ if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL -+ || (nparams > 0 && params == NULL)) - return; - -- length = png_strlen(purpose) + 1; -+ length = strlen(purpose) + 1; - png_debug1(3, "allocating purpose for info (%lu bytes)", - (unsigned long)length); - -@@ -283,12 +312,19 @@ - if (type < 0 || type > 3) - png_error(png_ptr, "Invalid pCAL equation type"); - -+ if (nparams < 0 || nparams > 255) -+ png_error(png_ptr, "Invalid pCAL parameter count"); -+ - /* Validate params[nparams] */ - for (i=0; i<nparams; ++i) -- if (!png_check_fp_string(params[i], png_strlen(params[i]))) -+ { -+ if (params[i] == NULL || -+ !png_check_fp_string(params[i], strlen(params[i]))) - png_error(png_ptr, "Invalid format for pCAL parameter"); -+ } - -- info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); -+ info_ptr->pcal_purpose = png_voidcast(png_charp, -+ png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_purpose == NULL) - { -@@ -296,7 +332,7 @@ - return; - } - -- png_memcpy(info_ptr->pcal_purpose, purpose, length); -+ memcpy(info_ptr->pcal_purpose, purpose, length); - - png_debug(3, "storing X0, X1, type, and nparams in info"); - info_ptr->pcal_X0 = X0; -@@ -304,11 +340,12 @@ - info_ptr->pcal_type = (png_byte)type; - info_ptr->pcal_nparams = (png_byte)nparams; - -- length = png_strlen(units) + 1; -+ length = strlen(units) + 1; - png_debug1(3, "allocating units for info (%lu bytes)", - (unsigned long)length); - -- info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); -+ info_ptr->pcal_units = png_voidcast(png_charp, -+ png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_units == NULL) - { -@@ -316,10 +353,10 @@ - return; - } - -- png_memcpy(info_ptr->pcal_units, units, length); -+ memcpy(info_ptr->pcal_units, units, length); - -- info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, -- (png_size_t)((nparams + 1) * png_sizeof(png_charp))); -+ info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, -+ (png_size_t)((nparams + 1) * (sizeof (png_charp))))); - - if (info_ptr->pcal_params == NULL) - { -@@ -327,11 +364,11 @@ - return; - } - -- png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); -+ memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); - - for (i = 0; i < nparams; i++) - { -- length = png_strlen(params[i]) + 1; -+ length = strlen(params[i]) + 1; - png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, - (unsigned long)length); - -@@ -343,7 +380,7 @@ - return; - } - -- png_memcpy(info_ptr->pcal_params[i], params[i], length); -+ memcpy(info_ptr->pcal_params[i], params[i], length); - } - - info_ptr->valid |= PNG_INFO_pCAL; -@@ -353,7 +390,7 @@ - - #ifdef PNG_sCAL_SUPPORTED - void PNGAPI --png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, -+png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, - int unit, png_const_charp swidth, png_const_charp sheight) - { - png_size_t lengthw = 0, lengthh = 0; -@@ -369,11 +406,11 @@ - if (unit != 1 && unit != 2) - png_error(png_ptr, "Invalid sCAL unit"); - -- if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 || -+ if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || - swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) - png_error(png_ptr, "Invalid sCAL width"); - -- if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 || -+ if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || - sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) - png_error(png_ptr, "Invalid sCAL height"); - -@@ -383,7 +420,8 @@ - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); - -- info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); -+ info_ptr->scal_s_width = png_voidcast(png_charp, -+ png_malloc_warn(png_ptr, lengthw)); - - if (info_ptr->scal_s_width == NULL) - { -@@ -391,13 +429,14 @@ - return; - } - -- png_memcpy(info_ptr->scal_s_width, swidth, lengthw); -+ memcpy(info_ptr->scal_s_width, swidth, lengthw); - - ++lengthh; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); - -- info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); -+ info_ptr->scal_s_height = png_voidcast(png_charp, -+ png_malloc_warn(png_ptr, lengthh)); - - if (info_ptr->scal_s_height == NULL) - { -@@ -408,7 +447,7 @@ - return; - } - -- png_memcpy(info_ptr->scal_s_height, sheight, lengthh); -+ memcpy(info_ptr->scal_s_height, sheight, lengthh); - - info_ptr->valid |= PNG_INFO_sCAL; - info_ptr->free_me |= PNG_FREE_SCAL; -@@ -416,8 +455,8 @@ - - # ifdef PNG_FLOATING_POINT_SUPPORTED - void PNGAPI --png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, -- double height) -+png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, -+ double width, double height) - { - png_debug1(1, "in %s storage function", "sCAL"); - -@@ -434,9 +473,9 @@ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - -- png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, -+ png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, - PNG_sCAL_PRECISION); -- png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, -+ png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, - PNG_sCAL_PRECISION); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); -@@ -446,7 +485,7 @@ - - # ifdef PNG_FIXED_POINT_SUPPORTED - void PNGAPI --png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, -+png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, - png_fixed_point width, png_fixed_point height) - { - png_debug1(1, "in %s storage function", "sCAL"); -@@ -464,8 +503,8 @@ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - -- png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); -- png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); -+ png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); -+ png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -@@ -475,7 +514,7 @@ - - #ifdef PNG_pHYs_SUPPORTED - void PNGAPI --png_set_pHYs(png_structp png_ptr, png_infop info_ptr, -+png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 res_x, png_uint_32 res_y, int unit_type) - { - png_debug1(1, "in %s storage function", "pHYs"); -@@ -491,7 +530,7 @@ - #endif - - void PNGAPI --png_set_PLTE(png_structp png_ptr, png_infop info_ptr, -+png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, - png_const_colorp palette, int num_palette) - { - -@@ -526,6 +565,9 @@ - /* It may not actually be necessary to set png_ptr->palette here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. -+ * -+ * 1.6.0: the above statement appears to be incorrect; something has to set -+ * the palette inside png_struct on read. - */ - png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); - -@@ -533,10 +575,11 @@ - * of num_palette entries, in case of an invalid PNG file that has - * too-large sample values. - */ -- png_ptr->palette = (png_colorp)png_calloc(png_ptr, -- PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); -+ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, -+ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); - -- png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); -+ if (num_palette > 0) -+ memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color))); - info_ptr->palette = png_ptr->palette; - info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; - -@@ -547,34 +590,34 @@ - - #ifdef PNG_sBIT_SUPPORTED - void PNGAPI --png_set_sBIT(png_structp png_ptr, png_infop info_ptr, -+png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_8p sig_bit) - { - png_debug1(1, "in %s storage function", "sBIT"); - -- if (png_ptr == NULL || info_ptr == NULL) -+ if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) - return; - -- png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); -+ info_ptr->sig_bit = *sig_bit; - info_ptr->valid |= PNG_INFO_sBIT; - } - #endif - - #ifdef PNG_sRGB_SUPPORTED - void PNGAPI --png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent) -+png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) - { - png_debug1(1, "in %s storage function", "sRGB"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -- info_ptr->srgb_intent = (png_byte)srgb_intent; -- info_ptr->valid |= PNG_INFO_sRGB; -+ (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); -+ png_colorspace_sync_info(png_ptr, info_ptr); - } - - void PNGAPI --png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, -+png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - int srgb_intent) - { - png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); -@@ -582,71 +625,87 @@ - if (png_ptr == NULL || info_ptr == NULL) - return; - -- png_set_sRGB(png_ptr, info_ptr, srgb_intent); -+ if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, -+ srgb_intent) != 0) -+ { -+ /* This causes the gAMA and cHRM to be written too */ -+ info_ptr->colorspace.flags |= -+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; -+ } - --# ifdef PNG_gAMA_SUPPORTED -- png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); --# endif -- --# ifdef PNG_cHRM_SUPPORTED -- png_set_cHRM_fixed(png_ptr, info_ptr, -- /* color x y */ -- /* white */ 31270L, 32900L, -- /* red */ 64000L, 33000L, -- /* green */ 30000L, 60000L, -- /* blue */ 15000L, 6000L -- ); --# endif /* cHRM */ -+ png_colorspace_sync_info(png_ptr, info_ptr); - } - #endif /* sRGB */ - - - #ifdef PNG_iCCP_SUPPORTED - void PNGAPI --png_set_iCCP(png_structp png_ptr, png_infop info_ptr, -+png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen) - { - png_charp new_iccp_name; - png_bytep new_iccp_profile; -- png_uint_32 length; -+ png_size_t length; - - png_debug1(1, "in %s storage function", "iCCP"); - - if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) - return; - -- length = png_strlen(name)+1; -- new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); -+ if (compression_type != PNG_COMPRESSION_TYPE_BASE) -+ png_app_error(png_ptr, "Invalid iCCP compression method"); -+ -+ /* Set the colorspace first because this validates the profile; do not -+ * override previously set app cHRM or gAMA here (because likely as not the -+ * application knows better than libpng what the correct values are.) Pass -+ * the info_ptr color_type field to png_colorspace_set_ICC because in the -+ * write case it has not yet been stored in png_ptr. -+ */ -+ { -+ int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, -+ proflen, profile, info_ptr->color_type); -+ -+ png_colorspace_sync_info(png_ptr, info_ptr); -+ -+ /* Don't do any of the copying if the profile was bad, or inconsistent. */ -+ if (result == 0) -+ return; -+ -+ /* But do write the gAMA and cHRM chunks from the profile. */ -+ info_ptr->colorspace.flags |= -+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; -+ } -+ -+ length = strlen(name)+1; -+ new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); - - if (new_iccp_name == NULL) - { -- png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); -+ png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); - return; - } - -- png_memcpy(new_iccp_name, name, length); -- new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); -+ memcpy(new_iccp_name, name, length); -+ new_iccp_profile = png_voidcast(png_bytep, -+ png_malloc_warn(png_ptr, proflen)); - - if (new_iccp_profile == NULL) - { -- png_free (png_ptr, new_iccp_name); -- png_warning(png_ptr, -+ png_free(png_ptr, new_iccp_name); -+ new_iccp_name = NULL; -+ png_benign_error(png_ptr, - "Insufficient memory to process iCCP profile"); - return; - } - -- png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); -+ memcpy(new_iccp_profile, profile, proflen); - - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); - - info_ptr->iccp_proflen = proflen; - info_ptr->iccp_name = new_iccp_name; - info_ptr->iccp_profile = new_iccp_profile; -- /* Compression is always zero but is here so the API and info structure -- * does not have to change if we introduce multiple compression types -- */ -- info_ptr->iccp_compression = (png_byte)compression_type; - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; - } -@@ -654,74 +713,81 @@ - - #ifdef PNG_TEXT_SUPPORTED - void PNGAPI --png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, -- int num_text) -+png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, -+ png_const_textp text_ptr, int num_text) - { - int ret; - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); - -- if (ret) -+ if (ret != 0) - png_error(png_ptr, "Insufficient memory to store text"); - } - - int /* PRIVATE */ --png_set_text_2(png_structp png_ptr, png_infop info_ptr, -+png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_textp text_ptr, int num_text) - { - int i; - -- png_debug1(1, "in %s storage function", ((png_ptr == NULL || -- png_ptr->chunk_name[0] == '\0') ? -- "text" : (png_const_charp)png_ptr->chunk_name)); -+ png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : -+ (unsigned long)png_ptr->chunk_name); - -- if (png_ptr == NULL || info_ptr == NULL || num_text == 0) -+ if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) - return(0); - - /* Make sure we have enough space in the "text" array in info_struct -- * to hold all of the incoming text_ptr objects. -+ * to hold all of the incoming text_ptr objects. This compare can't overflow -+ * because max_text >= num_text (anyway, subtract of two positive integers -+ * can't overflow in any case.) - */ -- if (info_ptr->num_text + num_text > info_ptr->max_text) -+ if (num_text > info_ptr->max_text - info_ptr->num_text) - { -- if (info_ptr->text != NULL) -+ int old_num_text = info_ptr->num_text; -+ int max_text; -+ png_textp new_text = NULL; -+ -+ /* Calculate an appropriate max_text, checking for overflow. */ -+ max_text = old_num_text; -+ if (num_text <= INT_MAX - max_text) - { -- png_textp old_text; -- int old_max; -+ max_text += num_text; - -- old_max = info_ptr->max_text; -- info_ptr->max_text = info_ptr->num_text + num_text + 8; -- old_text = info_ptr->text; -- info_ptr->text = (png_textp)png_malloc_warn(png_ptr, -- (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); -+ /* Round up to a multiple of 8 */ -+ if (max_text < INT_MAX-8) -+ max_text = (max_text + 8) & ~0x7; - -- if (info_ptr->text == NULL) -- { -- png_free(png_ptr, old_text); -- return(1); -- } -+ else -+ max_text = INT_MAX; - -- png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * -- png_sizeof(png_text))); -- png_free(png_ptr, old_text); -+ /* Now allocate a new array and copy the old members in; this does all -+ * the overflow checks. -+ */ -+ new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, -+ info_ptr->text, old_num_text, max_text-old_num_text, -+ sizeof *new_text)); - } - -- else -+ if (new_text == NULL) - { -- info_ptr->max_text = num_text + 8; -- info_ptr->num_text = 0; -- info_ptr->text = (png_textp)png_malloc_warn(png_ptr, -- (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); -- if (info_ptr->text == NULL) -- return(1); -- info_ptr->free_me |= PNG_FREE_TEXT; -+ png_chunk_report(png_ptr, "too many text chunks", -+ PNG_CHUNK_WRITE_ERROR); -+ return 1; - } - -- png_debug1(3, "allocated %d entries for info_ptr->text", -- info_ptr->max_text); -+ png_free(png_ptr, info_ptr->text); -+ -+ info_ptr->text = new_text; -+ info_ptr->free_me |= PNG_FREE_TEXT; -+ info_ptr->max_text = max_text; -+ /* num_text is adjusted below as the entries are copied in */ -+ -+ png_debug1(3, "allocated %d entries for info_ptr->text", max_text); - } -+ - for (i = 0; i < num_text; i++) - { -- png_size_t text_length, key_len; -- png_size_t lang_len, lang_key_len; -+ size_t text_length, key_len; -+ size_t lang_len, lang_key_len; - png_textp textp = &(info_ptr->text[info_ptr->num_text]); - - if (text_ptr[i].key == NULL) -@@ -730,11 +796,12 @@ - if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || - text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) - { -- png_warning(png_ptr, "text compression mode is out of range"); -+ png_chunk_report(png_ptr, "text compression mode is out of range", -+ PNG_CHUNK_WRITE_ERROR); - continue; - } - -- key_len = png_strlen(text_ptr[i].key); -+ key_len = strlen(text_ptr[i].key); - - if (text_ptr[i].compression <= 0) - { -@@ -748,20 +815,21 @@ - /* Set iTXt data */ - - if (text_ptr[i].lang != NULL) -- lang_len = png_strlen(text_ptr[i].lang); -+ lang_len = strlen(text_ptr[i].lang); - - else - lang_len = 0; - - if (text_ptr[i].lang_key != NULL) -- lang_key_len = png_strlen(text_ptr[i].lang_key); -+ lang_key_len = strlen(text_ptr[i].lang_key); - - else - lang_key_len = 0; - } - # else /* PNG_iTXt_SUPPORTED */ - { -- png_warning(png_ptr, "iTXt chunk not supported"); -+ png_chunk_report(png_ptr, "iTXt chunk not supported", -+ PNG_CHUNK_WRITE_ERROR); - continue; - } - # endif -@@ -780,32 +848,35 @@ - - else - { -- text_length = png_strlen(text_ptr[i].text); -+ text_length = strlen(text_ptr[i].text); - textp->compression = text_ptr[i].compression; - } - -- textp->key = (png_charp)png_malloc_warn(png_ptr, -- (png_size_t) -- (key_len + text_length + lang_len + lang_key_len + 4)); -+ textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, -+ key_len + text_length + lang_len + lang_key_len + 4)); - - if (textp->key == NULL) -- return(1); -+ { -+ png_chunk_report(png_ptr, "text chunk: out of memory", -+ PNG_CHUNK_WRITE_ERROR); -+ return 1; -+ } - - png_debug2(2, "Allocated %lu bytes at %p in png_set_text", - (unsigned long)(png_uint_32) - (key_len + lang_len + lang_key_len + text_length + 4), - textp->key); - -- png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); -+ memcpy(textp->key, text_ptr[i].key, key_len); - *(textp->key + key_len) = '\0'; - - if (text_ptr[i].compression > 0) - { - textp->lang = textp->key + key_len + 1; -- png_memcpy(textp->lang, text_ptr[i].lang, lang_len); -+ memcpy(textp->lang, text_ptr[i].lang, lang_len); - *(textp->lang + lang_len) = '\0'; - textp->lang_key = textp->lang + lang_len + 1; -- png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); -+ memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); - *(textp->lang_key + lang_key_len) = '\0'; - textp->text = textp->lang_key + lang_key_len + 1; - } -@@ -817,9 +888,8 @@ - textp->text = textp->key + key_len + 1; - } - -- if (text_length) -- png_memcpy(textp->text, text_ptr[i].text, -- (png_size_t)(text_length)); -+ if (text_length != 0) -+ memcpy(textp->text, text_ptr[i].text, text_length); - - *(textp->text + text_length) = '\0'; - -@@ -840,28 +910,39 @@ - info_ptr->num_text++; - png_debug1(3, "transferred text chunk %d", info_ptr->num_text); - } -+ - return(0); - } - #endif - - #ifdef PNG_tIME_SUPPORTED - void PNGAPI --png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) -+png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, -+ png_const_timep mod_time) - { - png_debug1(1, "in %s storage function", "tIME"); - -- if (png_ptr == NULL || info_ptr == NULL || -- (png_ptr->mode & PNG_WROTE_tIME)) -+ if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL || -+ (png_ptr->mode & PNG_WROTE_tIME) != 0) - return; - -- png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); -+ if (mod_time->month == 0 || mod_time->month > 12 || -+ mod_time->day == 0 || mod_time->day > 31 || -+ mod_time->hour > 23 || mod_time->minute > 59 || -+ mod_time->second > 60) -+ { -+ png_warning(png_ptr, "Ignoring invalid time value"); -+ return; -+ } -+ -+ info_ptr->mod_time = *mod_time; - info_ptr->valid |= PNG_INFO_tIME; - } - #endif - - #ifdef PNG_tRNS_SUPPORTED - void PNGAPI --png_set_tRNS(png_structp png_ptr, png_infop info_ptr, -+png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, - png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) - { - png_debug1(1, "in %s storage function", "tRNS"); -@@ -874,16 +955,20 @@ - /* It may not actually be necessary to set png_ptr->trans_alpha here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. -+ * -+ * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively -+ * relies on png_set_tRNS storing the information in png_struct -+ * (otherwise it won't be there for the code in pngrtran.c). - */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ -- png_ptr->trans_alpha = info_ptr->trans_alpha = -- (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); -+ png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep, -+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); - - if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) -- png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); -+ memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); - } - - if (trans_color != NULL) -@@ -891,16 +976,15 @@ - int sample_max = (1 << info_ptr->bit_depth); - - if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && -- (int)trans_color->gray > sample_max) || -+ trans_color->gray > sample_max) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB && -- ((int)trans_color->red > sample_max || -- (int)trans_color->green > sample_max || -- (int)trans_color->blue > sample_max))) -+ (trans_color->red > sample_max || -+ trans_color->green > sample_max || -+ trans_color->blue > sample_max))) - png_warning(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth"); - -- png_memcpy(&(info_ptr->trans_color), trans_color, -- png_sizeof(png_color_16)); -+ info_ptr->trans_color = *trans_color; - - if (num_trans == 0) - num_trans = 1; -@@ -918,8 +1002,8 @@ - - #ifdef PNG_sPLT_SUPPORTED - void PNGAPI --png_set_sPLT(png_structp png_ptr, -- png_infop info_ptr, png_const_sPLT_tp entries, int nentries) -+png_set_sPLT(png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) - /* - * entries - array of png_sPLT_t structures - * to be added to the list of palettes -@@ -930,220 +1014,455 @@ - */ - { - png_sPLT_tp np; -- int i; - -- if (png_ptr == NULL || info_ptr == NULL) -+ if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) - return; - -- np = (png_sPLT_tp)png_malloc_warn(png_ptr, -- (info_ptr->splt_palettes_num + nentries) * -- (png_size_t)png_sizeof(png_sPLT_t)); -+ /* Use the internal realloc function, which checks for all the possible -+ * overflows. Notice that the parameters are (int) and (size_t) -+ */ -+ np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, -+ info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, -+ sizeof *np)); - - if (np == NULL) - { -- png_warning(png_ptr, "No memory for sPLT palettes"); -+ /* Out of memory or too many chunks */ -+ png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); - return; - } - -- png_memcpy(np, info_ptr->splt_palettes, -- info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); -+ png_free(png_ptr, info_ptr->splt_palettes); -+ info_ptr->splt_palettes = np; -+ info_ptr->free_me |= PNG_FREE_SPLT; - -- png_free(png_ptr, info_ptr->splt_palettes); -- info_ptr->splt_palettes=NULL; -+ np += info_ptr->splt_palettes_num; - -- for (i = 0; i < nentries; i++) -+ do - { -- png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; -- png_const_sPLT_tp from = entries + i; -- png_uint_32 length; -+ png_size_t length; - -- length = png_strlen(from->name) + 1; -- to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length); -- -- if (to->name == NULL) -+ /* Skip invalid input entries */ -+ if (entries->name == NULL || entries->entries == NULL) - { -- png_warning(png_ptr, -- "Out of memory while processing sPLT chunk"); -+ /* png_handle_sPLT doesn't do this, so this is an app error */ -+ png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); -+ /* Just skip the invalid entry */ - continue; - } - -- png_memcpy(to->name, from->name, length); -- to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, -- (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry))); -+ np->depth = entries->depth; - -- if (to->entries == NULL) -+ /* In the event of out-of-memory just return - there's no point keeping -+ * on trying to add sPLT chunks. -+ */ -+ length = strlen(entries->name) + 1; -+ np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); -+ -+ if (np->name == NULL) -+ break; -+ -+ memcpy(np->name, entries->name, length); -+ -+ /* IMPORTANT: we have memory now that won't get freed if something else -+ * goes wrong; this code must free it. png_malloc_array produces no -+ * warnings; use a png_chunk_report (below) if there is an error. -+ */ -+ np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, -+ entries->nentries, sizeof (png_sPLT_entry))); -+ -+ if (np->entries == NULL) - { -- png_warning(png_ptr, -- "Out of memory while processing sPLT chunk"); -- png_free(png_ptr, to->name); -- to->name = NULL; -- continue; -+ png_free(png_ptr, np->name); -+ np->name = NULL; -+ break; - } - -- png_memcpy(to->entries, from->entries, -- from->nentries * png_sizeof(png_sPLT_entry)); -+ np->nentries = entries->nentries; -+ /* This multiply can't overflow because png_malloc_array has already -+ * checked it when doing the allocation. -+ */ -+ memcpy(np->entries, entries->entries, -+ entries->nentries * sizeof (png_sPLT_entry)); - -- to->nentries = from->nentries; -- to->depth = from->depth; -+ /* Note that 'continue' skips the advance of the out pointer and out -+ * count, so an invalid entry is not added. -+ */ -+ info_ptr->valid |= PNG_INFO_sPLT; -+ ++(info_ptr->splt_palettes_num); -+ ++np; -+ } -+ while (++entries, --nentries); -+ -+ if (nentries > 0) -+ png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); -+} -+#endif /* sPLT */ -+ -+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -+static png_byte -+check_location(png_const_structrp png_ptr, int location) -+{ -+ location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); -+ -+ /* New in 1.6.0; copy the location and check it. This is an API -+ * change; previously the app had to use the -+ * png_set_unknown_chunk_location API below for each chunk. -+ */ -+ if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0) -+ { -+ /* Write struct, so unknown chunks come from the app */ -+ png_app_warning(png_ptr, -+ "png_set_unknown_chunks now expects a valid location"); -+ /* Use the old behavior */ -+ location = (png_byte)(png_ptr->mode & -+ (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); - } - -- info_ptr->splt_palettes = np; -- info_ptr->splt_palettes_num += nentries; -- info_ptr->valid |= PNG_INFO_sPLT; -- info_ptr->free_me |= PNG_FREE_SPLT; -+ /* This need not be an internal error - if the app calls -+ * png_set_unknown_chunks on a read pointer it must get the location right. -+ */ -+ if (location == 0) -+ png_error(png_ptr, "invalid location in png_set_unknown_chunks"); -+ -+ /* Now reduce the location to the top-most set bit by removing each least -+ * significant bit in turn. -+ */ -+ while (location != (location & -location)) -+ location &= ~(location & -location); -+ -+ /* The cast is safe because 'location' is a bit mask and only the low four -+ * bits are significant. -+ */ -+ return (png_byte)location; - } --#endif /* PNG_sPLT_SUPPORTED */ - --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - void PNGAPI --png_set_unknown_chunks(png_structp png_ptr, -- png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) -+png_set_unknown_chunks(png_const_structrp png_ptr, -+ png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) - { - png_unknown_chunkp np; -- int i; - -- if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) -+ if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || -+ unknowns == NULL) - return; - -- np = (png_unknown_chunkp)png_malloc_warn(png_ptr, -- (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * -- png_sizeof(png_unknown_chunk)); -+ /* Check for the failure cases where support has been disabled at compile -+ * time. This code is hardly ever compiled - it's here because -+ * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this -+ * code) but may be meaningless if the read or write handling of unknown -+ * chunks is not compiled in. -+ */ -+# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ -+ defined(PNG_READ_SUPPORTED) -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -+ { -+ png_app_error(png_ptr, "no unknown chunk support on read"); -+ return; -+ } -+# endif -+# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ -+ defined(PNG_WRITE_SUPPORTED) -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) -+ { -+ png_app_error(png_ptr, "no unknown chunk support on write"); -+ return; -+ } -+# endif -+ -+ /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that -+ * unknown critical chunks could be lost with just a warning resulting in -+ * undefined behavior. Now png_chunk_report is used to provide behavior -+ * appropriate to read or write. -+ */ -+ np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, -+ info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, -+ sizeof *np)); - - if (np == NULL) - { -- png_warning(png_ptr, -- "Out of memory while processing unknown chunk"); -+ png_chunk_report(png_ptr, "too many unknown chunks", -+ PNG_CHUNK_WRITE_ERROR); - return; - } - -- png_memcpy(np, info_ptr->unknown_chunks, -- (png_size_t)info_ptr->unknown_chunks_num * -- png_sizeof(png_unknown_chunk)); -+ png_free(png_ptr, info_ptr->unknown_chunks); -+ info_ptr->unknown_chunks = np; /* safe because it is initialized */ -+ info_ptr->free_me |= PNG_FREE_UNKN; - -- png_free(png_ptr, info_ptr->unknown_chunks); -- info_ptr->unknown_chunks = NULL; -+ np += info_ptr->unknown_chunks_num; - -- for (i = 0; i < num_unknowns; i++) -+ /* Increment unknown_chunks_num each time round the loop to protect the -+ * just-allocated chunk data. -+ */ -+ for (; num_unknowns > 0; --num_unknowns, ++unknowns) - { -- png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; -- png_const_unknown_chunkp from = unknowns + i; -+ memcpy(np->name, unknowns->name, (sizeof np->name)); -+ np->name[(sizeof np->name)-1] = '\0'; -+ np->location = check_location(png_ptr, unknowns->location); - -- png_memcpy(to->name, from->name, png_sizeof(from->name)); -- to->name[png_sizeof(to->name)-1] = '\0'; -- to->size = from->size; -- -- /* Note our location in the read or write sequence */ -- to->location = (png_byte)(png_ptr->mode & 0xff); -- -- if (from->size == 0) -- to->data=NULL; -+ if (unknowns->size == 0) -+ { -+ np->data = NULL; -+ np->size = 0; -+ } - - else - { -- to->data = (png_bytep)png_malloc_warn(png_ptr, -- (png_size_t)from->size); -+ np->data = png_voidcast(png_bytep, -+ png_malloc_base(png_ptr, unknowns->size)); - -- if (to->data == NULL) -+ if (np->data == NULL) - { -- png_warning(png_ptr, -- "Out of memory while processing unknown chunk"); -- to->size = 0; -+ png_chunk_report(png_ptr, "unknown chunk: out of memory", -+ PNG_CHUNK_WRITE_ERROR); -+ /* But just skip storing the unknown chunk */ -+ continue; - } - -- else -- png_memcpy(to->data, from->data, from->size); -+ memcpy(np->data, unknowns->data, unknowns->size); -+ np->size = unknowns->size; - } -+ -+ /* These increments are skipped on out-of-memory for the data - the -+ * unknown chunk entry gets overwritten if the png_chunk_report returns. -+ * This is correct in the read case (the chunk is just dropped.) -+ */ -+ ++np; -+ ++(info_ptr->unknown_chunks_num); - } -- -- info_ptr->unknown_chunks = np; -- info_ptr->unknown_chunks_num += num_unknowns; -- info_ptr->free_me |= PNG_FREE_UNKN; - } - - void PNGAPI --png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, -+png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, - int chunk, int location) - { -- if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < -- info_ptr->unknown_chunks_num) -- info_ptr->unknown_chunks[chunk].location = (png_byte)location; -+ /* This API is pretty pointless in 1.6.0 because the location can be set -+ * before the call to png_set_unknown_chunks. -+ * -+ * TODO: add a png_app_warning in 1.7 -+ */ -+ if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && -+ chunk < info_ptr->unknown_chunks_num) -+ { -+ if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) -+ { -+ png_app_error(png_ptr, "invalid unknown chunk location"); -+ /* Fake out the pre 1.6.0 behavior: */ -+ if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */ -+ location = PNG_AFTER_IDAT; -+ -+ else -+ location = PNG_HAVE_IHDR; /* also undocumented */ -+ } -+ -+ info_ptr->unknown_chunks[chunk].location = -+ check_location(png_ptr, location); -+ } - } - #endif - - - #ifdef PNG_MNG_FEATURES_SUPPORTED - png_uint_32 PNGAPI --png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) -+png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features) - { - png_debug(1, "in png_permit_mng_features"); - - if (png_ptr == NULL) -- return (png_uint_32)0; -+ return 0; - -- png_ptr->mng_features_permitted = -- (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); -+ png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; - -- return (png_uint_32)png_ptr->mng_features_permitted; -+ return png_ptr->mng_features_permitted; - } - #endif - - #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -+static unsigned int -+add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) -+{ -+ unsigned int i; -+ -+ /* Utility function: update the 'keep' state of a chunk if it is already in -+ * the list, otherwise add it to the list. -+ */ -+ for (i=0; i<count; ++i, list += 5) -+ { -+ if (memcmp(list, add, 4) == 0) -+ { -+ list[4] = (png_byte)keep; -+ return count; -+ } -+ } -+ -+ if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT) -+ { -+ ++count; -+ memcpy(list, add, 4); -+ list[4] = (png_byte)keep; -+ } -+ -+ return count; -+} -+ - void PNGAPI --png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep -- chunk_list, int num_chunks) -+png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, -+ png_const_bytep chunk_list, int num_chunks_in) - { -- png_bytep new_list, p; -- int i, old_num_chunks; -+ png_bytep new_list; -+ unsigned int num_chunks, old_num_chunks; -+ - if (png_ptr == NULL) - return; - -- if (num_chunks == 0) -+ if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST) - { -- if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) -- png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; -- -- else -- png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; -- -- if (keep == PNG_HANDLE_CHUNK_ALWAYS) -- png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; -- -- else -- png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; -- -+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); - return; - } - -- if (chunk_list == NULL) -- return; -+ if (num_chunks_in <= 0) -+ { -+ png_ptr->unknown_default = keep; -+ -+ /* '0' means just set the flags, so stop here */ -+ if (num_chunks_in == 0) -+ return; -+ } -+ -+ if (num_chunks_in < 0) -+ { -+ /* Ignore all unknown chunks and all chunks recognized by -+ * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND -+ */ -+ static PNG_CONST png_byte chunks_to_ignore[] = { -+ 98, 75, 71, 68, '\0', /* bKGD */ -+ 99, 72, 82, 77, '\0', /* cHRM */ -+ 103, 65, 77, 65, '\0', /* gAMA */ -+ 104, 73, 83, 84, '\0', /* hIST */ -+ 105, 67, 67, 80, '\0', /* iCCP */ -+ 105, 84, 88, 116, '\0', /* iTXt */ -+ 111, 70, 70, 115, '\0', /* oFFs */ -+ 112, 67, 65, 76, '\0', /* pCAL */ -+ 112, 72, 89, 115, '\0', /* pHYs */ -+ 115, 66, 73, 84, '\0', /* sBIT */ -+ 115, 67, 65, 76, '\0', /* sCAL */ -+ 115, 80, 76, 84, '\0', /* sPLT */ -+ 115, 84, 69, 82, '\0', /* sTER */ -+ 115, 82, 71, 66, '\0', /* sRGB */ -+ 116, 69, 88, 116, '\0', /* tEXt */ -+ 116, 73, 77, 69, '\0', /* tIME */ -+ 122, 84, 88, 116, '\0' /* zTXt */ -+ }; -+ -+ chunk_list = chunks_to_ignore; -+ num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U; -+ } -+ -+ else /* num_chunks_in > 0 */ -+ { -+ if (chunk_list == NULL) -+ { -+ /* Prior to 1.6.0 this was silently ignored, now it is an app_error -+ * which can be switched off. -+ */ -+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); -+ return; -+ } -+ -+ num_chunks = num_chunks_in; -+ } - - old_num_chunks = png_ptr->num_chunk_list; -- new_list=(png_bytep)png_malloc(png_ptr, -- (png_size_t)(5*(num_chunks + old_num_chunks))); -+ if (png_ptr->chunk_list == NULL) -+ old_num_chunks = 0; - -- if (png_ptr->chunk_list != NULL) -+ /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. -+ */ -+ if (num_chunks + old_num_chunks > UINT_MAX/5) - { -- png_memcpy(new_list, png_ptr->chunk_list, -- (png_size_t)(5*old_num_chunks)); -- png_free(png_ptr, png_ptr->chunk_list); -- png_ptr->chunk_list=NULL; -+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); -+ return; - } - -- png_memcpy(new_list + 5*old_num_chunks, chunk_list, -- (png_size_t)(5*num_chunks)); -+ /* If these chunks are being reset to the default then no more memory is -+ * required because add_one_chunk above doesn't extend the list if the 'keep' -+ * parameter is the default. -+ */ -+ if (keep != 0) -+ { -+ new_list = png_voidcast(png_bytep, png_malloc(png_ptr, -+ 5 * (num_chunks + old_num_chunks))); - -- for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5) -- *p=(png_byte)keep; -+ if (old_num_chunks > 0) -+ memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); -+ } - -- png_ptr->num_chunk_list = old_num_chunks + num_chunks; -- png_ptr->chunk_list = new_list; -- png_ptr->free_me |= PNG_FREE_LIST; -+ else if (old_num_chunks > 0) -+ new_list = png_ptr->chunk_list; -+ -+ else -+ new_list = NULL; -+ -+ /* Add the new chunks together with each one's handling code. If the chunk -+ * already exists the code is updated, otherwise the chunk is added to the -+ * end. (In libpng 1.6.0 order no longer matters because this code enforces -+ * the earlier convention that the last setting is the one that is used.) -+ */ -+ if (new_list != NULL) -+ { -+ png_const_bytep inlist; -+ png_bytep outlist; -+ unsigned int i; -+ -+ for (i=0; i<num_chunks; ++i) -+ { -+ old_num_chunks = add_one_chunk(new_list, old_num_chunks, -+ chunk_list+5*i, keep); -+ } -+ -+ /* Now remove any spurious 'default' entries. */ -+ num_chunks = 0; -+ for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5) -+ { -+ if (inlist[4]) -+ { -+ if (outlist != inlist) -+ memcpy(outlist, inlist, 5); -+ outlist += 5; -+ ++num_chunks; -+ } -+ } -+ -+ /* This means the application has removed all the specialized handling. */ -+ if (num_chunks == 0) -+ { -+ if (png_ptr->chunk_list != new_list) -+ png_free(png_ptr, new_list); -+ -+ new_list = NULL; -+ } -+ } -+ -+ else -+ num_chunks = 0; -+ -+ png_ptr->num_chunk_list = num_chunks; -+ -+ if (png_ptr->chunk_list != new_list) -+ { -+ if (png_ptr->chunk_list != NULL) -+ png_free(png_ptr, png_ptr->chunk_list); -+ -+ png_ptr->chunk_list = new_list; -+ } - } - #endif - - #ifdef PNG_READ_USER_CHUNKS_SUPPORTED - void PNGAPI --png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, -+png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr, - png_user_chunk_ptr read_user_chunk_fn) - { - png_debug(1, "in png_set_read_user_chunk_fn"); -@@ -1158,64 +1477,90 @@ - - #ifdef PNG_INFO_IMAGE_SUPPORTED - void PNGAPI --png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) -+png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, -+ png_bytepp row_pointers) - { - png_debug1(1, "in %s storage function", "rows"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -- if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) -+ if (info_ptr->row_pointers != NULL && -+ (info_ptr->row_pointers != row_pointers)) - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - - info_ptr->row_pointers = row_pointers; - -- if (row_pointers) -+ if (row_pointers != NULL) - info_ptr->valid |= PNG_INFO_IDAT; - } - #endif - - void PNGAPI --png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) -+png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) - { - if (png_ptr == NULL) - return; - -- png_free(png_ptr, png_ptr->zbuf); -+ if (size == 0 || size > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid compression buffer size"); - -- if (size > ZLIB_IO_MAX) -- { -- png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); -- png_ptr->zbuf_size = ZLIB_IO_MAX; -- size = ZLIB_IO_MAX; /* must fit */ -- } -+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -+ { -+ png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ -+ return; -+ } -+# endif - -- else -- png_ptr->zbuf_size = (uInt)size; -+# ifdef PNG_WRITE_SUPPORTED -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) -+ { -+ if (png_ptr->zowner != 0) -+ { -+ png_warning(png_ptr, -+ "Compression buffer size cannot be changed because it is in use"); -+ return; -+ } - -- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); -+ if (size > ZLIB_IO_MAX) -+ { -+ png_warning(png_ptr, -+ "Compression buffer size limited to system maximum"); -+ size = ZLIB_IO_MAX; /* must fit */ -+ } - -- /* The following ensures a relatively safe failure if this gets called while -- * the buffer is actually in use. -- */ -- png_ptr->zstream.next_out = png_ptr->zbuf; -- png_ptr->zstream.avail_out = 0; -- png_ptr->zstream.avail_in = 0; -+ else if (size < 6) -+ { -+ /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH -+ * if this is permitted. -+ */ -+ png_warning(png_ptr, -+ "Compression buffer size cannot be reduced below 6"); -+ return; -+ } -+ -+ if (png_ptr->zbuffer_size != size) -+ { -+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); -+ png_ptr->zbuffer_size = (uInt)size; -+ } -+ } -+# endif - } - - void PNGAPI --png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) -+png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) - { -- if (png_ptr && info_ptr) -+ if (png_ptr != NULL && info_ptr != NULL) - info_ptr->valid &= ~mask; - } - - -- - #ifdef PNG_SET_USER_LIMITS_SUPPORTED - /* This function was added to libpng 1.2.6 */ - void PNGAPI --png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, -+png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, - png_uint_32 user_height_max) - { - /* Images with dimensions larger than these limits will be -@@ -1231,35 +1576,64 @@ - - /* This function was added to libpng 1.4.0 */ - void PNGAPI --png_set_chunk_cache_max (png_structp png_ptr, -- png_uint_32 user_chunk_cache_max) -+png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) - { -- if (png_ptr) -+ if (png_ptr != NULL) - png_ptr->user_chunk_cache_max = user_chunk_cache_max; - } - - /* This function was added to libpng 1.4.1 */ - void PNGAPI --png_set_chunk_malloc_max (png_structp png_ptr, -+png_set_chunk_malloc_max (png_structrp png_ptr, - png_alloc_size_t user_chunk_malloc_max) - { -- if (png_ptr) -+ if (png_ptr != NULL) - png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; - } --#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ -+#endif /* ?SET_USER_LIMITS */ - - - #ifdef PNG_BENIGN_ERRORS_SUPPORTED - void PNGAPI --png_set_benign_errors(png_structp png_ptr, int allowed) -+png_set_benign_errors(png_structrp png_ptr, int allowed) - { - png_debug(1, "in png_set_benign_errors"); - -- if (allowed) -- png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; -+ /* If allowed is 1, png_benign_error() is treated as a warning. -+ * -+ * If allowed is 0, png_benign_error() is treated as an error (which -+ * is the default behavior if png_set_benign_errors() is not called). -+ */ -+ -+ if (allowed != 0) -+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | -+ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; - - else -- png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; -+ png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | -+ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); - } --#endif /* PNG_BENIGN_ERRORS_SUPPORTED */ --#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ -+#endif /* BENIGN_ERRORS */ -+ -+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -+ /* Whether to report invalid palette index; added at libng-1.5.10. -+ * It is possible for an indexed (color-type==3) PNG file to contain -+ * pixels with invalid (out-of-range) indexes if the PLTE chunk has -+ * fewer entries than the image's bit-depth would allow. We recover -+ * from this gracefully by filling any incomplete palette with zeros -+ * (opaque black). By default, when this occurs libpng will issue -+ * a benign error. This API can be used to override that behavior. -+ */ -+void PNGAPI -+png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) -+{ -+ png_debug(1, "in png_set_check_for_invalid_index"); -+ -+ if (allowed > 0) -+ png_ptr->num_palette_max = 0; -+ -+ else -+ png_ptr->num_palette_max = -1; -+} -+#endif -+#endif /* READ || WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pngstruct.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngstruct.h Thu Feb 05 13:00:26 2015 +0100 -@@ -29,11 +29,11 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -+ * Last changed in libpng 1.6.1 [March 28, 2013] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer -@@ -52,13 +52,130 @@ - * in this structure and is required for decompressing the LZ compressed - * data in PNG files. - */ -+#ifndef ZLIB_CONST -+ /* We must ensure that zlib uses 'const' in declarations. */ -+# define ZLIB_CONST -+#endif - #include "zlib.h" -+#ifdef const -+ /* zlib.h sometimes #defines const to nothing, undo this. */ -+# undef const -+#endif -+ -+/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility -+ * with older builds. -+ */ -+#if ZLIB_VERNUM < 0x1260 -+# define PNGZ_MSG_CAST(s) png_constcast(char*,s) -+# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) -+#else -+# define PNGZ_MSG_CAST(s) (s) -+# define PNGZ_INPUT_CAST(b) (b) -+#endif -+ -+/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib -+ * can handle at once. This type need be no larger than 16 bits (so maximum of -+ * 65535), this define allows us to discover how big it is, but limited by the -+ * maximuum for png_size_t. The value can be overriden in a library build -+ * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably -+ * lower value (e.g. 255 works). A lower value may help memory usage (slightly) -+ * and may even improve performance on some systems (and degrade it on others.) -+ */ -+#ifndef ZLIB_IO_MAX -+# define ZLIB_IO_MAX ((uInt)-1) -+#endif -+ -+#ifdef PNG_WRITE_SUPPORTED -+/* The type of a compression buffer list used by the write code. */ -+typedef struct png_compression_buffer -+{ -+ struct png_compression_buffer *next; -+ png_byte output[1]; /* actually zbuf_size */ -+} png_compression_buffer, *png_compression_bufferp; -+ -+#define PNG_COMPRESSION_BUFFER_SIZE(pp)\ -+ (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size) -+#endif -+ -+/* Colorspace support; structures used in png_struct, png_info and in internal -+ * functions to hold and communicate information about the color space. -+ * -+ * PNG_COLORSPACE_SUPPORTED is only required if the application will perform -+ * colorspace corrections, otherwise all the colorspace information can be -+ * skipped and the size of libpng can be reduced (significantly) by compiling -+ * out the colorspace support. -+ */ -+#ifdef PNG_COLORSPACE_SUPPORTED -+/* The chromaticities of the red, green and blue colorants and the chromaticity -+ * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). -+ */ -+typedef struct png_xy -+{ -+ png_fixed_point redx, redy; -+ png_fixed_point greenx, greeny; -+ png_fixed_point bluex, bluey; -+ png_fixed_point whitex, whitey; -+} png_xy; -+ -+/* The same data as above but encoded as CIE XYZ values. When this data comes -+ * from chromaticities the sum of the Y values is assumed to be 1.0 -+ */ -+typedef struct png_XYZ -+{ -+ png_fixed_point red_X, red_Y, red_Z; -+ png_fixed_point green_X, green_Y, green_Z; -+ png_fixed_point blue_X, blue_Y, blue_Z; -+} png_XYZ; -+#endif /* COLORSPACE */ -+ -+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) -+/* A colorspace is all the above plus, potentially, profile information, -+ * however at present libpng does not use the profile internally so it is only -+ * stored in the png_info struct (if iCCP is supported.) The rendering intent -+ * is retained here and is checked. -+ * -+ * The file gamma encoding information is also stored here and gamma correction -+ * is done by libpng, whereas color correction must currently be done by the -+ * application. -+ */ -+typedef struct png_colorspace -+{ -+#ifdef PNG_GAMMA_SUPPORTED -+ png_fixed_point gamma; /* File gamma */ -+#endif -+ -+#ifdef PNG_COLORSPACE_SUPPORTED -+ png_xy end_points_xy; /* End points as chromaticities */ -+ png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ -+ png_uint_16 rendering_intent; /* Rendering intent of a profile */ -+#endif -+ -+ /* Flags are always defined to simplify the code. */ -+ png_uint_16 flags; /* As defined below */ -+} png_colorspace, * PNG_RESTRICT png_colorspacerp; -+ -+typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; -+ -+/* General flags for the 'flags' field */ -+#define PNG_COLORSPACE_HAVE_GAMMA 0x0001 -+#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002 -+#define PNG_COLORSPACE_HAVE_INTENT 0x0004 -+#define PNG_COLORSPACE_FROM_gAMA 0x0008 -+#define PNG_COLORSPACE_FROM_cHRM 0x0010 -+#define PNG_COLORSPACE_FROM_sRGB 0x0020 -+#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 -+#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ -+#define PNG_COLORSPACE_INVALID 0x8000 -+#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) -+#endif /* COLORSPACE || GAMMA */ - - struct png_struct_def - { - #ifdef PNG_SETJMP_SUPPORTED -- jmp_buf longjmp_buffer; /* used in png_error */ -+ jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */ - png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ -+ jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ -+ size_t jmp_buf_size; /* size of the above, if allocated */ - #endif - png_error_ptr error_fn; /* function for printing errors and aborting */ - #ifdef PNG_WARNINGS_SUPPORTED -@@ -91,22 +208,12 @@ - png_uint_32 flags; /* flags indicating various things to libpng */ - png_uint_32 transformations; /* which transformations to perform */ - -- z_stream zstream; /* pointer to decompression structure (below) */ -- png_bytep zbuf; /* buffer for zlib */ -- uInt zbuf_size; /* size of zbuf (typically 65536) */ -+ png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ -+ z_stream zstream; /* decompression structure */ -+ - #ifdef PNG_WRITE_SUPPORTED -- --/* Added in 1.5.4: state to keep track of whether the zstream has been -- * initialized and if so whether it is for IDAT or some other chunk. -- */ --#define PNG_ZLIB_UNINITIALIZED 0 --#define PNG_ZLIB_FOR_IDAT 1 --#define PNG_ZLIB_FOR_TEXT 2 /* anything other than IDAT */ --#define PNG_ZLIB_USE_MASK 3 /* bottom two bits */ --#define PNG_ZLIB_IN_USE 4 /* a flag value */ -- -- png_uint_32 zlib_state; /* State of zlib initialization */ --/* End of material added at libpng 1.5.4 */ -+ png_compression_bufferp zbuffer_list; /* Created on demand during write */ -+ uInt zbuffer_size; /* size of the actual buffer */ - - int zlib_level; /* holds zlib compression level */ - int zlib_method; /* holds zlib compression method */ -@@ -115,8 +222,7 @@ - int zlib_strategy; /* holds zlib compression strategy */ - #endif - /* Added at libpng 1.5.4 */ --#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \ -- defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED) -+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - int zlib_text_level; /* holds zlib compression level */ - int zlib_text_method; /* holds zlib compression method */ - int zlib_text_window_bits; /* holds zlib compression window bits */ -@@ -124,6 +230,14 @@ - int zlib_text_strategy; /* holds zlib compression strategy */ - #endif - /* End of material added at libpng 1.5.4 */ -+/* Added at libpng 1.6.0 */ -+#ifdef PNG_WRITE_SUPPORTED -+ int zlib_set_level; /* Actual values set into the zstream on write */ -+ int zlib_set_method; -+ int zlib_set_window_bits; -+ int zlib_set_mem_level; -+ int zlib_set_strategy; -+#endif - - png_uint_32 width; /* width of image in pixels */ - png_uint_32 height; /* height of image in pixels */ -@@ -132,21 +246,32 @@ - png_size_t rowbytes; /* size of row in bytes */ - png_uint_32 iwidth; /* width of current interlaced row in pixels */ - png_uint_32 row_number; /* current row in interlace pass */ -- png_bytep prev_row; /* buffer to save previous (unfiltered) row */ -- png_bytep row_buf; /* buffer to save current (unfiltered) row */ -+ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ -+ png_bytep prev_row; /* buffer to save previous (unfiltered) row. -+ * This is a pointer into big_prev_row -+ */ -+ png_bytep row_buf; /* buffer to save current (unfiltered) row. -+ * This is a pointer into big_row_buf -+ */ -+#ifdef PNG_WRITE_SUPPORTED - png_bytep sub_row; /* buffer to save "sub" row when filtering */ - png_bytep up_row; /* buffer to save "up" row when filtering */ - png_bytep avg_row; /* buffer to save "avg" row when filtering */ - png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ -- png_row_info row_info; /* used for transformation routines */ -+#endif - png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ - - png_uint_32 idat_size; /* current IDAT size for read */ - png_uint_32 crc; /* current chunk CRC value */ - png_colorp palette; /* palette from the input file */ - png_uint_16 num_palette; /* number of color entries in palette */ -+ -+/* Added at libpng-1.5.10 */ -+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -+ int num_palette_max; /* maximum palette index found in IDAT */ -+#endif -+ - png_uint_16 num_trans; /* number of transparency values */ -- png_byte chunk_name[5]; /* null-terminated name of current chunk */ - png_byte compression; /* file compression type (always 0) */ - png_byte filter; /* file filter type (always 0) */ - png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ -@@ -154,12 +279,17 @@ - png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ - png_byte color_type; /* color type of file */ - png_byte bit_depth; /* bit depth of file */ -- png_byte usr_bit_depth; /* bit depth of users row */ -+ png_byte usr_bit_depth; /* bit depth of users row: write only */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte channels; /* number of channels in file */ -- png_byte usr_channels; /* channels at start of write */ -+#ifdef PNG_WRITE_SUPPORTED -+ png_byte usr_channels; /* channels at start of write: write only */ -+#endif - png_byte sig_bytes; /* magic bytes read/written from start of file */ -- -+ png_byte maximum_pixel_depth; -+ /* pixel depth used for the row buffers */ -+ png_byte transformed_pixel_depth; -+ /* pixel depth after read/write transforms */ - #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) - png_uint_16 filler; /* filler bytes for pixel expansion */ - #endif -@@ -172,7 +302,7 @@ - #ifdef PNG_READ_GAMMA_SUPPORTED - png_color_16 background_1; /* background normalized to gamma 1.0 */ - #endif --#endif /* PNG_bKGD_SUPPORTED */ -+#endif /* bKGD */ - - #ifdef PNG_WRITE_FLUSH_SUPPORTED - png_flush_ptr output_flush_fn; /* Function for flushing output */ -@@ -180,19 +310,20 @@ - png_uint_32 flush_rows; /* number of rows written since last flush */ - #endif - --#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) -+#ifdef PNG_READ_GAMMA_SUPPORTED - int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ -- png_fixed_point gamma; /* file gamma value */ - png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ --#endif - --#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_bytep gamma_table; /* gamma table for 8-bit depth files */ -+ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ -+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ -+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ -+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_bytep gamma_from_1; /* converts from 1.0 to screen */ - png_bytep gamma_to_1; /* converts from file to 1.0 */ -- png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ - png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ - png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ -+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - #endif - - #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) -@@ -228,14 +359,7 @@ - int process_mode; /* what push library is currently doing */ - int cur_palette; /* current push library palette index */ - --# ifdef PNG_TEXT_SUPPORTED -- png_size_t current_text_size; /* current size of text input data */ -- png_size_t current_text_left; /* how much text left to read in input */ -- png_charp current_text; /* current text chunk buffer */ -- png_charp current_text_ptr; /* current location in current_text */ --# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ -- --#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -+#endif /* PROGRESSIVE_READ */ - - #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) - /* For the Borland special 64K segment handler */ -@@ -251,10 +375,6 @@ - png_bytep quantize_index; /* index translation for palette files */ - #endif - --#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED) -- png_uint_16p hist; /* histogram */ --#endif -- - #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_byte heuristic_method; /* heuristic for row filter selection */ - png_byte num_prev_filters; /* number of weights for previous rows */ -@@ -265,9 +385,17 @@ - png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ - #endif - -+ /* Options */ -+#ifdef PNG_SET_OPTION_SUPPORTED -+ png_byte options; /* On/off state (up to 4 options) */ -+#endif -+ -+#if PNG_LIBPNG_VER < 10700 -+/* To do: remove this from libpng-1.7 */ - #ifdef PNG_TIME_RFC1123_SUPPORTED - char time_buffer[29]; /* String to hold RFC 1123 time text */ - #endif -+#endif - - /* New members added in libpng-1.0.6 */ - -@@ -275,27 +403,31 @@ - - #ifdef PNG_USER_CHUNKS_SUPPORTED - png_voidp user_chunk_ptr; -+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ - #endif -+#endif - --#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- int num_chunk_list; -- png_bytep chunk_list; -+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+ int unknown_default; /* As PNG_HANDLE_* */ -+ unsigned int num_chunk_list; /* Number of entries in the list */ -+ png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name -+ * followed by a PNG_HANDLE_* byte */ - #endif - - /* New members added in libpng-1.0.3 */ - #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - png_byte rgb_to_gray_status; -+ /* Added in libpng 1.5.5 to record setting of coefficients: */ -+ png_byte rgb_to_gray_coefficients_set; - /* These were changed from png_byte in libpng-1.0.6 */ - png_uint_16 rgb_to_gray_red_coeff; - png_uint_16 rgb_to_gray_green_coeff; -- png_uint_16 rgb_to_gray_blue_coeff; -+ /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ - #endif - - /* New member added in libpng-1.0.4 (renamed in 1.0.9) */ --#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ -- defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ -- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) -+#if defined(PNG_MNG_FEATURES_SUPPORTED) - /* Changed from png_byte to png_uint_32 at version 1.2.0 */ - png_uint_32 mng_features_permitted; - #endif -@@ -345,21 +477,41 @@ - #endif - - /* New member added in libpng-1.0.25 and 1.2.17 */ --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -- /* Storage for unknown chunk that the library doesn't recognize. */ -+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -+ /* Temporary storage for unknown chunk that the library doesn't recognize, -+ * used while reading the chunk. -+ */ - png_unknown_chunk unknown_chunk; - #endif - --/* New members added in libpng-1.2.26 */ -+/* New member added in libpng-1.2.26 */ - png_size_t old_big_row_buf_size; -- png_size_t old_prev_row_size; - -+#ifdef PNG_READ_SUPPORTED - /* New member added in libpng-1.2.30 */ -- png_charp chunkdata; /* buffer for reading chunk data */ -+ png_bytep read_buffer; /* buffer for reading chunk data */ -+ png_alloc_size_t read_buffer_size; /* current size of the buffer */ -+#endif -+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -+ uInt IDAT_read_size; /* limit on read buffer size for IDAT */ -+#endif - - #ifdef PNG_IO_STATE_SUPPORTED - /* New member added in libpng-1.4.0 */ - png_uint_32 io_state; - #endif -+ -+/* New member added in libpng-1.5.6 */ -+ png_bytep big_prev_row; -+ -+/* New member added in libpng-1.5.7 */ -+ void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, -+ png_bytep row, png_const_bytep prev_row); -+ -+#ifdef PNG_READ_SUPPORTED -+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) -+ png_colorspace colorspace; -+#endif -+#endif - }; - #endif /* PNGSTRUCT_H */ ---- ./jdk/src/share/native/sun/awt/libpng/pngtest.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngtest.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -61,16 +61,50 @@ - - #define _POSIX_SOURCE 1 - --#include "zlib.h" -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+ -+/* Defined so I can write to a file on gui/windowing platforms */ -+/* #define STDERR stderr */ -+#define STDERR stdout /* For DOS */ -+ - #include "png.h" -+ -+/* Known chunks that exist in pngtest.png must be supported or pngtest will fail -+ * simply as a result of re-ordering them. This may be fixed in 1.7 -+ * -+ * pngtest allocates a single row buffer for each row and overwrites it, -+ * therefore if the write side doesn't support the writing of interlaced images -+ * nothing can be done for an interlaced image (and the code below will fail -+ * horribly trying to write extra data after writing garbage). -+ */ -+#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\ -+ defined PNG_READ_bKGD_SUPPORTED &&\ -+ defined PNG_READ_cHRM_SUPPORTED &&\ -+ defined PNG_READ_gAMA_SUPPORTED &&\ -+ defined PNG_READ_oFFs_SUPPORTED &&\ -+ defined PNG_READ_pCAL_SUPPORTED &&\ -+ defined PNG_READ_pHYs_SUPPORTED &&\ -+ defined PNG_READ_sBIT_SUPPORTED &&\ -+ defined PNG_READ_sCAL_SUPPORTED &&\ -+ defined PNG_READ_sRGB_SUPPORTED &&\ -+ defined PNG_READ_tEXt_SUPPORTED &&\ -+ defined PNG_READ_tIME_SUPPORTED &&\ -+ defined PNG_READ_zTXt_SUPPORTED &&\ -+ defined PNG_WRITE_INTERLACING_SUPPORTED -+ -+#ifdef PNG_ZLIB_HEADER -+# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ -+#else -+# include "zlib.h" -+#endif -+ - /* Copied from pngpriv.h but only used in error messages below. */ - #ifndef PNG_ZBUF_SIZE - # define PNG_ZBUF_SIZE 8192 - #endif --# include <stdio.h> --# include <stdlib.h> --# include <string.h> --# define FCLOSE(file) fclose(file) -+#define FCLOSE(file) fclose(file) - - #ifndef PNG_STDIO_SUPPORTED - typedef FILE * png_FILE_p; -@@ -95,17 +129,6 @@ - # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ - #endif - --/* The code uses memcmp and memcpy on large objects (typically row pointers) so -- * it is necessary to do soemthing special on certain architectures, note that -- * the actual support for this was effectively removed in 1.4, so only the -- * memory remains in this program: -- */ --#define CVT_PTR(ptr) (ptr) --#define CVT_PTR_NOCHECK(ptr) (ptr) --#define png_memcmp memcmp --#define png_memcpy memcpy --#define png_memset memset -- - /* Turn on CPU timing - #define PNGTEST_TIMING - */ -@@ -126,30 +149,34 @@ - #endif - - static int verbose = 0; -- --int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); -- --#ifdef __TURBOC__ --#include <mem.h> --#endif -- --/* Defined so I can write to a file on gui/windowing platforms */ --/* #define STDERR stderr */ --#define STDERR stdout /* For DOS */ -+static int strict = 0; -+static int relaxed = 0; -+static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ -+static int error_count = 0; /* count calls to png_error */ -+static int warning_count = 0; /* count calls to png_warning */ - - /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ - #ifndef png_jmpbuf - # define png_jmpbuf(png_ptr) png_ptr->jmpbuf - #endif - -+/* Defines for unknown chunk handling if required. */ -+#ifndef PNG_HANDLE_CHUNK_ALWAYS -+# define PNG_HANDLE_CHUNK_ALWAYS 3 -+#endif -+#ifndef PNG_HANDLE_CHUNK_IF_SAFE -+# define PNG_HANDLE_CHUNK_IF_SAFE 2 -+#endif -+ -+/* Utility to save typing/errors, the argument must be a name */ -+#define MEMZERO(var) ((void)memset(&var, 0, sizeof var)) -+ - /* Example of using row callbacks to make a simple progress meter */ - static int status_pass = 1; - static int status_dots_requested = 0; - static int status_dots = 1; - --void PNGCBAPI --read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); --void PNGCBAPI -+static void PNGCBAPI - read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) - { - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) -@@ -173,9 +200,8 @@ - fprintf(stdout, "r"); - } - --void PNGCBAPI --write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); --void PNGCBAPI -+#ifdef PNG_WRITE_SUPPORTED -+static void PNGCBAPI - write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) - { - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) -@@ -183,6 +209,7 @@ - - fprintf(stdout, "w"); - } -+#endif - - - #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -@@ -191,9 +218,7 @@ - * 5 in case illegal filter values are present.) - */ - static png_uint_32 filters_used[256]; --void PNGCBAPI --count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); --void PNGCBAPI -+static void PNGCBAPI - count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) - { - if (png_ptr != NULL && row_info != NULL) -@@ -208,9 +233,7 @@ - - static png_uint_32 zero_samples; - --void PNGCBAPI --count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); --void PNGCBAPI -+static void PNGCBAPI - count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) - { - png_bytep dp = data; -@@ -288,7 +311,8 @@ - png_uint_32 n, nstop; - int channel; - int color_channels = row_info->channels; -- if (row_info->color_type > 3)color_channels--; -+ if (row_info->color_type > 3) -+ color_channels--; - - for (n = 0, nstop=row_info->width; n<nstop; n++) - { -@@ -315,9 +339,7 @@ - } - } - } --#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */ -- --static int wrote_question = 0; -+#endif /* WRITE_USER_TRANSFORM */ - - #ifndef PNG_STDIO_SUPPORTED - /* START of code to validate stdio-free compilation */ -@@ -366,12 +388,11 @@ - default: - err = 1; /* uninitialized */ - } -- if (err) -+ if (err != 0) - png_error(png_ptr, "Bad I/O state or buffer size"); - } - #endif - --#ifndef USE_FAR_KEYWORD - static void PNGCBAPI - pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) - { -@@ -396,59 +417,6 @@ - pngtest_check_io_state(png_ptr, length, PNG_IO_READING); - #endif - } --#else --/* This is the model-independent version. Since the standard I/O library -- can't handle far buffers in the medium and small models, we have to copy -- the data. --*/ -- --#define NEAR_BUF_SIZE 1024 --#define MIN(a,b) (a <= b ? a : b) -- --static void PNGCBAPI --pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) --{ -- png_size_t check; -- png_byte *n_data; -- png_FILE_p io_ptr; -- -- /* Check if data really is near. If so, use usual code. */ -- n_data = (png_byte *)CVT_PTR_NOCHECK(data); -- io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); -- if ((png_bytep)n_data == data) -- { -- check = fread(n_data, 1, length, io_ptr); -- } -- else -- { -- png_byte buf[NEAR_BUF_SIZE]; -- png_size_t read, remaining, err; -- check = 0; -- remaining = length; -- -- do -- { -- read = MIN(NEAR_BUF_SIZE, remaining); -- err = fread(buf, 1, 1, io_ptr); -- png_memcpy(data, buf, read); /* Copy far buffer to near buffer */ -- if (err != read) -- break; -- else -- check += err; -- data += read; -- remaining -= read; -- } -- while (remaining != 0); -- } -- -- if (check != length) -- png_error(png_ptr, "Read Error"); -- --#ifdef PNG_IO_STATE_SUPPORTED -- pngtest_check_io_state(png_ptr, length, PNG_IO_READING); --#endif --} --#endif /* USE_FAR_KEYWORD */ - - #ifdef PNG_WRITE_FLUSH_SUPPORTED - static void PNGCBAPI -@@ -464,7 +432,6 @@ - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ --#ifndef USE_FAR_KEYWORD - static void PNGCBAPI - pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) - { -@@ -481,81 +448,31 @@ - pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); - #endif - } --#else --/* This is the model-independent version. Since the standard I/O library -- can't handle far buffers in the medium and small models, we have to copy -- the data. --*/ -- --#define NEAR_BUF_SIZE 1024 --#define MIN(a,b) (a <= b ? a : b) -- --static void PNGCBAPI --pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) --{ -- png_size_t check; -- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ -- png_FILE_p io_ptr; -- -- /* Check if data really is near. If so, use usual code. */ -- near_data = (png_byte *)CVT_PTR_NOCHECK(data); -- io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); -- -- if ((png_bytep)near_data == data) -- { -- check = fwrite(near_data, 1, length, io_ptr); -- } -- -- else -- { -- png_byte buf[NEAR_BUF_SIZE]; -- png_size_t written, remaining, err; -- check = 0; -- remaining = length; -- -- do -- { -- written = MIN(NEAR_BUF_SIZE, remaining); -- png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ -- err = fwrite(buf, 1, written, io_ptr); -- if (err != written) -- break; -- else -- check += err; -- data += written; -- remaining -= written; -- } -- while (remaining != 0); -- } -- -- if (check != length) -- { -- png_error(png_ptr, "Write Error"); -- } -- --#ifdef PNG_IO_STATE_SUPPORTED -- pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); --#endif --} --#endif /* USE_FAR_KEYWORD */ -+#endif /* !STDIO */ - - /* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -+typedef struct -+{ -+ PNG_CONST char *file_name; -+} pngtest_error_parameters; -+ - static void PNGCBAPI - pngtest_warning(png_structp png_ptr, png_const_charp message) - { - PNG_CONST char *name = "UNKNOWN (ERROR!)"; -- char *test; -- test = png_get_error_ptr(png_ptr); -+ pngtest_error_parameters *test = -+ (pngtest_error_parameters*)png_get_error_ptr(png_ptr); - -- if (test == NULL) -- fprintf(STDERR, "%s: libpng warning: %s\n", name, message); -+ ++warning_count; - -- else -- fprintf(STDERR, "%s: libpng warning: %s\n", test, message); -+ if (test != NULL && test->file_name != NULL) -+ name = test->file_name; -+ -+ fprintf(STDERR, "%s: libpng warning: %s\n", name, message); - } - - /* This is the default error handling function. Note that replacements for -@@ -566,12 +483,14 @@ - static void PNGCBAPI - pngtest_error(png_structp png_ptr, png_const_charp message) - { -+ ++error_count; -+ - pngtest_warning(png_ptr, message); - /* We can return because png_error calls the default handler, which is - * actually OK in this case. - */ - } --#endif /* !PNG_STDIO_SUPPORTED */ -+ - /* END of code to validate stdio-free compilation */ - - /* START of code to validate memory allocation and deallocation */ -@@ -590,9 +509,9 @@ - { - png_alloc_size_t size; - png_voidp pointer; -- struct memory_information FAR *next; -+ struct memory_information *next; - } memory_information; --typedef memory_information FAR *memory_infop; -+typedef memory_information *memory_infop; - - static memory_infop pinformation = NULL; - static int current_allocation = 0; -@@ -622,7 +541,7 @@ - memory_infop pinfo; - png_set_mem_fn(png_ptr, NULL, NULL, NULL); - pinfo = (memory_infop)png_malloc(png_ptr, -- png_sizeof(*pinfo)); -+ (sizeof *pinfo)); - pinfo->size = size; - current_allocation += size; - total_allocation += size; -@@ -648,9 +567,9 @@ - pinfo->next = pinformation; - pinformation = pinfo; - /* Make sure the caller isn't assuming zeroed memory. */ -- png_memset(pinfo->pointer, 0xdd, pinfo->size); -+ memset(pinfo->pointer, 0xdd, pinfo->size); - -- if (verbose) -+ if (verbose != 0) - printf("png_malloc %lu bytes at %p\n", (unsigned long)size, - pinfo->pointer); - -@@ -675,7 +594,7 @@ - - /* Unlink the element from the list. */ - { -- memory_infop FAR *ppinfo = &pinformation; -+ memory_infop *ppinfo = &pinformation; - - for (;;) - { -@@ -689,15 +608,16 @@ - fprintf(STDERR, "Duplicate free of memory\n"); - /* We must free the list element too, but first kill - the memory that is to be freed. */ -- png_memset(ptr, 0x55, pinfo->size); -- png_free_default(png_ptr, pinfo); -+ memset(ptr, 0x55, pinfo->size); -+ if (pinfo != NULL) -+ free(pinfo); - pinfo = NULL; - break; - } - - if (pinfo->next == NULL) - { -- fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); -+ fprintf(STDERR, "Pointer %p not found\n", ptr); - break; - } - -@@ -706,35 +626,84 @@ - } - - /* Finally free the data. */ -- if (verbose) -+ if (verbose != 0) - printf("Freeing %p\n", ptr); - -- png_free_default(png_ptr, ptr); -+ if (ptr != NULL) -+ free(ptr); - ptr = NULL; - } --#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ -+#endif /* USER_MEM && DEBUG */ - /* END of code to test memory allocation/deallocation */ - - -+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* Demonstration of user chunk support of the sTER and vpAg chunks */ --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - - /* (sTER is a public chunk not yet known by libpng. vpAg is a private - chunk used in ImageMagick to store "virtual page" size). */ - --static png_uint_32 user_chunk_data[4]; -+static struct user_chunk_data -+{ -+ png_const_infop info_ptr; -+ png_uint_32 vpAg_width, vpAg_height; -+ png_byte vpAg_units; -+ png_byte sTER_mode; -+ int location[2]; -+} -+user_chunk_data; - -- /* 0: sTER mode + 1 -- * 1: vpAg width -- * 2: vpAg height -- * 3: vpAg units -- */ -+/* Used for location and order; zero means nothing. */ -+#define have_sTER 0x01 -+#define have_vpAg 0x02 -+#define before_PLTE 0x10 -+#define before_IDAT 0x20 -+#define after_IDAT 0x40 - --static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, -- png_unknown_chunkp chunk) -+static void -+init_callback_info(png_const_infop info_ptr) - { -- png_uint_32 -- *my_user_chunk_data; -+ MEMZERO(user_chunk_data); -+ user_chunk_data.info_ptr = info_ptr; -+} -+ -+static int -+set_location(png_structp png_ptr, struct user_chunk_data *data, int what) -+{ -+ int location; -+ -+ if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0) -+ return 0; /* already have one of these */ -+ -+ /* Find where we are (the code below zeroes info_ptr to indicate that the -+ * chunks before the first IDAT have been read.) -+ */ -+ if (data->info_ptr == NULL) /* after IDAT */ -+ location = what | after_IDAT; -+ -+ else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0) -+ location = what | before_IDAT; -+ -+ else -+ location = what | before_PLTE; -+ -+ if (data->location[0] == 0) -+ data->location[0] = location; -+ -+ else -+ data->location[1] = location; -+ -+ return 1; /* handled */ -+} -+ -+static int PNGCBAPI -+read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) -+{ -+ struct user_chunk_data *my_user_chunk_data = -+ (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); -+ -+ if (my_user_chunk_data == NULL) -+ png_error(png_ptr, "lost user chunk pointer"); - - /* Return one of the following: - * return (-n); chunk had an error -@@ -759,9 +728,14 @@ - if (chunk->data[0] != 0 && chunk->data[0] != 1) - return (-1); /* Invalid mode */ - -- my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); -- my_user_chunk_data[0]=chunk->data[0]+1; -- return (1); -+ if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0) -+ { -+ my_user_chunk_data->sTER_mode=chunk->data[0]; -+ return (1); -+ } -+ -+ else -+ return (0); /* duplicate sTER - give it to libpng */ - } - - if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ -@@ -773,30 +747,126 @@ - if (chunk->size != 9) - return (-1); /* Error return */ - -- my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); -+ if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) -+ return (0); /* duplicate vpAg */ - -- my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data); -- my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4); -- my_user_chunk_data[3]=(png_uint_32)chunk->data[8]; -+ my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); -+ my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); -+ my_user_chunk_data->vpAg_units = chunk->data[8]; - - return (1); -+} - -+#ifdef PNG_WRITE_SUPPORTED -+static void -+write_sTER_chunk(png_structp write_ptr) -+{ -+ png_byte sTER[5] = {115, 84, 69, 82, '\0'}; -+ -+ if (verbose != 0) -+ fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode); -+ -+ png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1); - } -+ -+static void -+write_vpAg_chunk(png_structp write_ptr) -+{ -+ png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; -+ -+ png_byte vpag_chunk_data[9]; -+ -+ if (verbose != 0) -+ fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", -+ (unsigned long)user_chunk_data.vpAg_width, -+ (unsigned long)user_chunk_data.vpAg_height, -+ user_chunk_data.vpAg_units); -+ -+ png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); -+ png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); -+ vpag_chunk_data[8] = user_chunk_data.vpAg_units; -+ png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); -+} -+ -+static void -+write_chunks(png_structp write_ptr, int location) -+{ -+ int i; -+ -+ /* Notice that this preserves the original chunk order, however chunks -+ * intercepted by the callback will be written *after* chunks passed to -+ * libpng. This will actually reverse a pair of sTER chunks or a pair of -+ * vpAg chunks, resulting in an error later. This is not worth worrying -+ * about - the chunks should not be duplicated! -+ */ -+ for (i=0; i<2; ++i) -+ { -+ if (user_chunk_data.location[i] == (location | have_sTER)) -+ write_sTER_chunk(write_ptr); -+ -+ else if (user_chunk_data.location[i] == (location | have_vpAg)) -+ write_vpAg_chunk(write_ptr); -+ } -+} -+#endif /* WRITE */ -+#else /* !READ_USER_CHUNKS */ -+# define write_chunks(pp,loc) ((void)0) - #endif - /* END of code to demonstrate user chunk support */ - -+/* START of code to check that libpng has the required text support; this only -+ * checks for the write support because if read support is missing the chunk -+ * will simply not be reported back to pngtest. -+ */ -+#ifdef PNG_TEXT_SUPPORTED -+static void -+pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr, -+ int num_text) -+{ -+ while (num_text > 0) -+ { -+ switch (text_ptr[--num_text].compression) -+ { -+ case PNG_TEXT_COMPRESSION_NONE: -+ break; -+ -+ case PNG_TEXT_COMPRESSION_zTXt: -+# ifndef PNG_WRITE_zTXt_SUPPORTED -+ ++unsupported_chunks; -+# endif -+ break; -+ -+ case PNG_ITXT_COMPRESSION_NONE: -+ case PNG_ITXT_COMPRESSION_zTXt: -+# ifndef PNG_WRITE_iTXt_SUPPORTED -+ ++unsupported_chunks; -+# endif -+ break; -+ -+ default: -+ /* This is an error */ -+ png_error(png_ptr, "invalid text chunk compression field"); -+ break; -+ } -+ } -+} -+#endif -+/* END of code to check that libpng has the required text support */ -+ - /* Test one file */ --int -+static int - test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) - { - static png_FILE_p fpin; - static png_FILE_p fpout; /* "static" prevents setjmp corruption */ -+ pngtest_error_parameters error_parameters; - png_structp read_ptr; - png_infop read_info_ptr, end_info_ptr; - #ifdef PNG_WRITE_SUPPORTED - png_structp write_ptr; - png_infop write_info_ptr; - png_infop write_end_info_ptr; -+ int interlace_preserved = 1; - #else - png_structp write_ptr = NULL; - png_infop write_info_ptr = NULL; -@@ -805,17 +875,11 @@ - png_bytep row_buf; - png_uint_32 y; - png_uint_32 width, height; -- int num_pass, pass; -+ int num_pass = 1, pass; - int bit_depth, color_type; --#ifdef PNG_SETJMP_SUPPORTED --#ifdef USE_FAR_KEYWORD -- jmp_buf tmp_jmpbuf; --#endif --#endif -- -- char inbuf[256], outbuf[256]; - - row_buf = NULL; -+ error_parameters.file_name = inname; - - if ((fpin = fopen(inname, "rb")) == NULL) - { -@@ -839,20 +903,9 @@ - read_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - #endif --#ifndef PNG_STDIO_SUPPORTED -- png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, -- pngtest_warning); --#endif -+ png_set_error_fn(read_ptr, &error_parameters, pngtest_error, -+ pngtest_warning); - --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -- user_chunk_data[0] = 0; -- user_chunk_data[1] = 0; -- user_chunk_data[2] = 0; -- user_chunk_data[3] = 0; -- png_set_read_user_chunk_fn(read_ptr, user_chunk_data, -- read_user_chunk_callback); -- --#endif - #ifdef PNG_WRITE_SUPPORTED - #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - write_ptr = -@@ -862,10 +915,8 @@ - write_ptr = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - #endif --#ifndef PNG_STDIO_SUPPORTED -- png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, -- pngtest_warning); --#endif -+ png_set_error_fn(write_ptr, &error_parameters, pngtest_error, -+ pngtest_warning); - #endif - pngtest_debug("Allocating read_info, write_info and end_info structures"); - read_info_ptr = png_create_info_struct(read_ptr); -@@ -875,13 +926,15 @@ - write_end_info_ptr = png_create_info_struct(write_ptr); - #endif - -+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -+ init_callback_info(read_info_ptr); -+ png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, -+ read_user_chunk_callback); -+#endif -+ - #ifdef PNG_SETJMP_SUPPORTED - pngtest_debug("Setting jmpbuf for read struct"); --#ifdef USE_FAR_KEYWORD -- if (setjmp(tmp_jmpbuf)) --#else - if (setjmp(png_jmpbuf(read_ptr))) --#endif - { - fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); - png_free(read_ptr, row_buf); -@@ -895,18 +948,11 @@ - FCLOSE(fpout); - return (1); - } --#ifdef USE_FAR_KEYWORD -- png_memcpy(png_jmpbuf(read_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); --#endif - - #ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Setting jmpbuf for write struct"); --#ifdef USE_FAR_KEYWORD - -- if (setjmp(tmp_jmpbuf)) --#else - if (setjmp(png_jmpbuf(write_ptr))) --#endif - { - fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -@@ -918,12 +964,34 @@ - FCLOSE(fpout); - return (1); - } -+#endif -+#endif - --#ifdef USE_FAR_KEYWORD -- png_memcpy(png_jmpbuf(write_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); -+ if (strict != 0) -+ { -+ /* Treat png_benign_error() as errors on read */ -+ png_set_benign_errors(read_ptr, 0); -+ -+#ifdef PNG_WRITE_SUPPORTED -+ /* Treat them as errors on write */ -+ png_set_benign_errors(write_ptr, 0); - #endif -+ -+ /* if strict is not set, then app warnings and errors are treated as -+ * warnings in release builds, but not in unstable builds; this can be -+ * changed with '--relaxed'. -+ */ -+ } -+ -+ else if (relaxed != 0) -+ { -+ /* Allow application (pngtest) errors and warnings to pass */ -+ png_set_benign_errors(read_ptr, 1); -+ -+#ifdef PNG_WRITE_SUPPORTED -+ png_set_benign_errors(write_ptr, 1); - #endif --#endif -+ } - - pngtest_debug("Initializing input and output streams"); - #ifdef PNG_STDIO_SUPPORTED -@@ -943,14 +1011,6 @@ - # endif - #endif - --#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -- /* Normally one would use Z_DEFAULT_STRATEGY for text compression. -- * This is here just to make pngtest replicate the results from libpng -- * versions prior to 1.5.4, and to test this new API. -- */ -- png_set_text_compression_strategy(write_ptr, Z_FILTERED); --#endif -- - if (status_dots_requested == 1) - { - #ifdef PNG_WRITE_SUPPORTED -@@ -982,36 +1042,65 @@ - png_set_write_user_transform_fn(write_ptr, count_zero_samples); - #endif - --#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED --# ifndef PNG_HANDLE_CHUNK_ALWAYS --# define PNG_HANDLE_CHUNK_ALWAYS 3 --# endif -+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+ /* Preserve all the unknown chunks, if possible. If this is disabled then, -+ * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use -+ * libpng to *save* the unknown chunks on read (because we can't switch the -+ * save option on!) -+ * -+ * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all -+ * unknown chunks and write will write them all. -+ */ -+#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); - #endif - #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED --# ifndef PNG_HANDLE_CHUNK_IF_SAFE --# define PNG_HANDLE_CHUNK_IF_SAFE 2 --# endif -- png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, -+ png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); - #endif -+#endif - - pngtest_debug("Reading info struct"); - png_read_info(read_ptr, read_info_ptr); - -+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -+ /* This is a bit of a hack; there is no obvious way in the callback function -+ * to determine that the chunks before the first IDAT have been read, so -+ * remove the info_ptr (which is only used to determine position relative to -+ * PLTE) here to indicate that we are after the IDAT. -+ */ -+ user_chunk_data.info_ptr = NULL; -+#endif -+ - pngtest_debug("Transferring info struct"); - { - int interlace_type, compression_type, filter_type; - - if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, -- &color_type, &interlace_type, &compression_type, &filter_type)) -+ &color_type, &interlace_type, &compression_type, &filter_type) != 0) - { - png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, --#ifdef PNG_WRITE_INTERLACING_SUPPORTED - color_type, interlace_type, compression_type, filter_type); --#else -- color_type, PNG_INTERLACE_NONE, compression_type, filter_type); -+#ifndef PNG_READ_INTERLACING_SUPPORTED -+ /* num_pass will not be set below, set it here if the image is -+ * interlaced: what happens is that write interlacing is *not* turned -+ * on an the partial interlaced rows are written directly. -+ */ -+ switch (interlace_type) -+ { -+ case PNG_INTERLACE_NONE: -+ num_pass = 1; -+ break; -+ -+ case PNG_INTERLACE_ADAM7: -+ num_pass = 7; -+ break; -+ -+ default: -+ png_error(read_ptr, "invalid interlace type"); -+ /*NOT REACHED*/ -+ } - #endif - } - } -@@ -1022,7 +1111,7 @@ - blue_y; - - if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, -- &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) -+ &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); -@@ -1033,7 +1122,7 @@ - { - png_fixed_point gamma; - -- if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) -+ if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); - } - #endif -@@ -1045,7 +1134,7 @@ - blue_y; - - if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, -- &red_y, &green_x, &green_y, &blue_x, &blue_y)) -+ &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); -@@ -1056,7 +1145,7 @@ - { - double gamma; - -- if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) -+ if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA(write_ptr, write_info_ptr, gamma); - } - #endif -@@ -1070,7 +1159,7 @@ - int compression_type; - - if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, -- &profile, &proflen)) -+ &profile, &proflen) != 0) - { - png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, - profile, proflen); -@@ -1081,7 +1170,7 @@ - { - int intent; - -- if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) -+ if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) - png_set_sRGB(write_ptr, write_info_ptr, intent); - } - #endif -@@ -1089,14 +1178,14 @@ - png_colorp palette; - int num_palette; - -- if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) -+ if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) - png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); - } - #ifdef PNG_bKGD_SUPPORTED - { - png_color_16p background; - -- if (png_get_bKGD(read_ptr, read_info_ptr, &background)) -+ if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) - { - png_set_bKGD(write_ptr, write_info_ptr, background); - } -@@ -1106,7 +1195,7 @@ - { - png_uint_16p hist; - -- if (png_get_hIST(read_ptr, read_info_ptr, &hist)) -+ if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) - png_set_hIST(write_ptr, write_info_ptr, hist); - } - #endif -@@ -1116,7 +1205,7 @@ - int unit_type; - - if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, -- &unit_type)) -+ &unit_type) != 0) - { - png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); - } -@@ -1130,7 +1219,7 @@ - int type, nparams; - - if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, -- &nparams, &units, ¶ms)) -+ &nparams, &units, ¶ms) != 0) - { - png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, - nparams, units, params); -@@ -1142,7 +1231,8 @@ - png_uint_32 res_x, res_y; - int unit_type; - -- if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) -+ if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, -+ &unit_type) != 0) - png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); - } - #endif -@@ -1150,18 +1240,19 @@ - { - png_color_8p sig_bit; - -- if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) -+ if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) - png_set_sBIT(write_ptr, write_info_ptr, sig_bit); - } - #endif - #ifdef PNG_sCAL_SUPPORTED --#ifdef PNG_FLOATING_POINT_SUPPORTED -+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ -+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - { - int unit; - double scal_width, scal_height; - - if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, -- &scal_height)) -+ &scal_height) != 0) - { - png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); - } -@@ -1173,7 +1264,7 @@ - png_charp scal_width, scal_height; - - if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, -- &scal_height)) -+ &scal_height) != 0) - { - png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, - scal_height); -@@ -1190,6 +1281,21 @@ - if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); -+ -+ pngtest_check_text_support(read_ptr, text_ptr, num_text); -+ -+ if (verbose != 0) -+ { -+ int i; -+ -+ printf("\n"); -+ for (i=0; i<num_text; i++) -+ { -+ printf(" Text compression[%d]=%d\n", -+ i, text_ptr[i].compression); -+ } -+ } -+ - png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); - } - } -@@ -1198,21 +1304,21 @@ - { - png_timep mod_time; - -- if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) -+ if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0) - { - png_set_tIME(write_ptr, write_info_ptr, mod_time); - #ifdef PNG_TIME_RFC1123_SUPPORTED -- /* We have to use png_memcpy instead of "=" because the string -- * pointed to by png_convert_to_rfc1123() gets free'ed before -- * we use it. -- */ -- png_memcpy(tIME_string, -- png_convert_to_rfc1123(read_ptr, mod_time), -- png_sizeof(tIME_string)); -+ if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) -+ tIME_string[(sizeof tIME_string) - 1] = '\0'; - -- tIME_string[png_sizeof(tIME_string) - 1] = '\0'; -+ else -+ { -+ strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string)); -+ tIME_string[(sizeof tIME_string) - 1] = '\0'; -+ } -+ - tIME_chunk_present++; --#endif /* PNG_TIME_RFC1123_SUPPORTED */ -+#endif /* TIME_RFC1123 */ - } - } - #endif -@@ -1223,7 +1329,7 @@ - png_color_16p trans_color; - - if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, -- &trans_color)) -+ &trans_color) != 0) - { - int sample_max = (1 << bit_depth); - /* libpng doesn't reject a tRNS chunk with out-of-range samples */ -@@ -1244,18 +1350,22 @@ - int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, - &unknowns); - -- if (num_unknowns) -+ if (num_unknowns != 0) - { -- int i; - png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, - num_unknowns); -+#if PNG_LIBPNG_VER < 10600 - /* Copy the locations from the read_info_ptr. The automatically -- * generated locations in write_info_ptr are wrong because we -- * haven't written anything yet. -+ * generated locations in write_end_info_ptr are wrong prior to 1.6.0 -+ * because they are reset from the write pointer (removed in 1.6.0). - */ -- for (i = 0; i < num_unknowns; i++) -- png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, -- unknowns[i].location); -+ { -+ int i; -+ for (i = 0; i < num_unknowns; i++) -+ png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, -+ unknowns[i].location); -+ } -+#endif - } - } - #endif -@@ -1263,47 +1373,16 @@ - #ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Writing info struct"); - --/* If we wanted, we could write info in two steps: -- * png_write_info_before_PLTE(write_ptr, write_info_ptr); -- */ -+ /* Write the info in two steps so that if we write the 'unknown' chunks here -+ * they go to the correct place. -+ */ -+ png_write_info_before_PLTE(write_ptr, write_info_ptr); -+ -+ write_chunks(write_ptr, before_PLTE); /* before PLTE */ -+ - png_write_info(write_ptr, write_info_ptr); - --#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -- if (user_chunk_data[0] != 0) -- { -- png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}; -- -- unsigned char -- ster_chunk_data[1]; -- -- if (verbose) -- fprintf(STDERR, "\n stereo mode = %lu\n", -- (unsigned long)(user_chunk_data[0] - 1)); -- -- ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1); -- png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1); -- } -- -- if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0) -- { -- png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'}; -- -- unsigned char -- vpag_chunk_data[9]; -- -- if (verbose) -- fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n", -- (unsigned long)user_chunk_data[1], -- (unsigned long)user_chunk_data[2], -- (unsigned long)user_chunk_data[3]); -- -- png_save_uint_32(vpag_chunk_data, user_chunk_data[1]); -- png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]); -- vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff); -- png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9); -- } -- --#endif -+ write_chunks(write_ptr, before_IDAT); /* after PLTE */ - #endif - - #ifdef SINGLE_ROWBUF_ALLOC -@@ -1315,14 +1394,10 @@ - #endif /* SINGLE_ROWBUF_ALLOC */ - pngtest_debug("Writing row data"); - --#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ -- defined(PNG_WRITE_INTERLACING_SUPPORTED) -+#ifdef PNG_READ_INTERLACING_SUPPORTED - num_pass = png_set_interlace_handling(read_ptr); --# ifdef PNG_WRITE_SUPPORTED -- png_set_interlace_handling(write_ptr); --# endif --#else -- num_pass = 1; -+ if (png_set_interlace_handling(write_ptr) != num_pass) -+ png_error(write_ptr, "png_set_interlace_handling: inconsistent num_pass"); - #endif - - #ifdef PNGTEST_TIMING -@@ -1337,11 +1412,12 @@ - { - #ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); -+ - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - -- pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf, -- png_get_rowbytes(read_ptr, read_info_ptr)); -+ pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf, -+ (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); - - #endif /* !SINGLE_ROWBUF_ALLOC */ - png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); -@@ -1358,7 +1434,7 @@ - t_encode += (t_stop - t_start); - t_start = t_stop; - #endif --#endif /* PNG_WRITE_SUPPORTED */ -+#endif /* WRITE */ - - #ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); -@@ -1368,11 +1444,13 @@ - } - } - --#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -- png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); --#endif --#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -- png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); -+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -+# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -+ png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); -+# endif -+# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -+ png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); -+# endif - #endif - - pngtest_debug("Reading and writing end_info data"); -@@ -1386,6 +1464,21 @@ - if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); -+ -+ pngtest_check_text_support(read_ptr, text_ptr, num_text); -+ -+ if (verbose != 0) -+ { -+ int i; -+ -+ printf("\n"); -+ for (i=0; i<num_text; i++) -+ { -+ printf(" Text compression[%d]=%d\n", -+ i, text_ptr[i].compression); -+ } -+ } -+ - png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); - } - } -@@ -1394,20 +1487,21 @@ - { - png_timep mod_time; - -- if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) -+ if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0) - { - png_set_tIME(write_ptr, write_end_info_ptr, mod_time); - #ifdef PNG_TIME_RFC1123_SUPPORTED -- /* We have to use png_memcpy instead of "=" because the string -- pointed to by png_convert_to_rfc1123() gets free'ed before -- we use it */ -- png_memcpy(tIME_string, -- png_convert_to_rfc1123(read_ptr, mod_time), -- png_sizeof(tIME_string)); -+ if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) -+ tIME_string[(sizeof tIME_string) - 1] = '\0'; - -- tIME_string[png_sizeof(tIME_string) - 1] = '\0'; -+ else -+ { -+ strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string); -+ tIME_string[(sizeof tIME_string)-1] = '\0'; -+ } -+ - tIME_chunk_present++; --#endif /* PNG_TIME_RFC1123_SUPPORTED */ -+#endif /* TIME_RFC1123 */ - } - } - #endif -@@ -1417,27 +1511,48 @@ - int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, - &unknowns); - -- if (num_unknowns) -+ if (num_unknowns != 0) - { -- int i; - png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, - num_unknowns); -+#if PNG_LIBPNG_VER < 10600 - /* Copy the locations from the read_info_ptr. The automatically -- * generated locations in write_end_info_ptr are wrong because we -- * haven't written the end_info yet. -+ * generated locations in write_end_info_ptr are wrong prior to 1.6.0 -+ * because they are reset from the write pointer (removed in 1.6.0). - */ -- for (i = 0; i < num_unknowns; i++) -- png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, -- unknowns[i].location); -+ { -+ int i; -+ for (i = 0; i < num_unknowns; i++) -+ png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, -+ unknowns[i].location); -+ } -+#endif - } - } - #endif -+ - #ifdef PNG_WRITE_SUPPORTED -+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -+ /* Normally one would use Z_DEFAULT_STRATEGY for text compression. -+ * This is here just to make pngtest replicate the results from libpng -+ * versions prior to 1.5.4, and to test this new API. -+ */ -+ png_set_text_compression_strategy(write_ptr, Z_FILTERED); -+#endif -+ -+ /* When the unknown vpAg/sTER chunks are written by pngtest the only way to -+ * do it is to write them *before* calling png_write_end. When unknown -+ * chunks are written by libpng, however, they are written just before IEND. -+ * There seems to be no way round this, however vpAg/sTER are not expected -+ * after IDAT. -+ */ -+ write_chunks(write_ptr, after_IDAT); -+ - png_write_end(write_ptr, write_end_info_ptr); - #endif - - #ifdef PNG_EASY_ACCESS_SUPPORTED -- if (verbose) -+ if (verbose != 0) - { - png_uint_32 iwidth, iheight; - iwidth = png_get_image_width(write_ptr, write_info_ptr); -@@ -1466,6 +1581,40 @@ - FCLOSE(fpin); - FCLOSE(fpout); - -+ /* Summarize any warnings or errors and in 'strict' mode fail the test. -+ * Unsupported chunks can result in warnings, in that case ignore the strict -+ * setting, otherwise fail the test on warnings as well as errors. -+ */ -+ if (error_count > 0) -+ { -+ /* We don't really expect to get here because of the setjmp handling -+ * above, but this is safe. -+ */ -+ fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", -+ inname, error_count, warning_count); -+ -+ if (strict != 0) -+ return (1); -+ } -+ -+# ifdef PNG_WRITE_SUPPORTED -+ /* If there we no write support nothing was written! */ -+ else if (unsupported_chunks > 0) -+ { -+ fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", -+ inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); -+ } -+# endif -+ -+ else if (warning_count > 0) -+ { -+ fprintf(STDERR, "\n %s: %d libpng warnings found", -+ inname, warning_count); -+ -+ if (strict != 0) -+ return (1); -+ } -+ - pngtest_debug("Opening files for comparison"); - if ((fpin = fopen(inname, "rb")) == NULL) - { -@@ -1480,61 +1629,84 @@ - return (1); - } - -- for (;;) -+#ifdef PNG_WRITE_SUPPORTED /* else nothing was written */ -+ if (interlace_preserved != 0) /* else the files will be changed */ - { -- png_size_t num_in, num_out; -+ for (;;) -+ { -+ static int wrote_question = 0; -+ png_size_t num_in, num_out; -+ char inbuf[256], outbuf[256]; - -- num_in = fread(inbuf, 1, 1, fpin); -- num_out = fread(outbuf, 1, 1, fpout); -+ num_in = fread(inbuf, 1, sizeof inbuf, fpin); -+ num_out = fread(outbuf, 1, sizeof outbuf, fpout); - -- if (num_in != num_out) -- { -- fprintf(STDERR, "\nFiles %s and %s are of a different size\n", -- inname, outname); -+ if (num_in != num_out) -+ { -+ fprintf(STDERR, "\nFiles %s and %s are of a different size\n", -+ inname, outname); - -- if (wrote_question == 0) -- { -- fprintf(STDERR, -+ if (wrote_question == 0 && unsupported_chunks == 0) -+ { -+ fprintf(STDERR, - " Was %s written with the same maximum IDAT chunk size (%d bytes),", -- inname, PNG_ZBUF_SIZE); -- fprintf(STDERR, -- "\n filtering heuristic (libpng default), compression"); -- fprintf(STDERR, -- " level (zlib default),\n and zlib version (%s)?\n\n", -- ZLIB_VERSION); -- wrote_question = 1; -+ inname, PNG_ZBUF_SIZE); -+ fprintf(STDERR, -+ "\n filtering heuristic (libpng default), compression"); -+ fprintf(STDERR, -+ " level (zlib default),\n and zlib version (%s)?\n\n", -+ ZLIB_VERSION); -+ wrote_question = 1; -+ } -+ -+ FCLOSE(fpin); -+ FCLOSE(fpout); -+ -+ if (strict != 0 && unsupported_chunks == 0) -+ return (1); -+ -+ else -+ return (0); - } - -- FCLOSE(fpin); -- FCLOSE(fpout); -- return (0); -- } -+ if (num_in == 0) -+ break; - -- if (!num_in) -- break; -+ if (memcmp(inbuf, outbuf, num_in)) -+ { -+ fprintf(STDERR, "\nFiles %s and %s are different\n", inname, -+ outname); - -- if (png_memcmp(inbuf, outbuf, num_in)) -- { -- fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); -+ if (wrote_question == 0 && unsupported_chunks == 0) -+ { -+ fprintf(STDERR, -+ " Was %s written with the same maximum IDAT chunk size (%d bytes),", -+ inname, PNG_ZBUF_SIZE); -+ fprintf(STDERR, -+ "\n filtering heuristic (libpng default), compression"); -+ fprintf(STDERR, -+ " level (zlib default),\n and zlib version (%s)?\n\n", -+ ZLIB_VERSION); -+ wrote_question = 1; -+ } - -- if (wrote_question == 0) -- { -- fprintf(STDERR, -- " Was %s written with the same maximum IDAT chunk size (%d bytes),", -- inname, PNG_ZBUF_SIZE); -- fprintf(STDERR, -- "\n filtering heuristic (libpng default), compression"); -- fprintf(STDERR, -- " level (zlib default),\n and zlib version (%s)?\n\n", -- ZLIB_VERSION); -- wrote_question = 1; -+ FCLOSE(fpin); -+ FCLOSE(fpout); -+ -+ /* NOTE: the unsupported_chunks escape is permitted here because -+ * unsupported text chunk compression will result in the compression -+ * mode being changed (to NONE) yet, in the test case, the result -+ * can be exactly the same size! -+ */ -+ if (strict != 0 && unsupported_chunks == 0) -+ return (1); -+ -+ else -+ return (0); - } -- -- FCLOSE(fpin); -- FCLOSE(fpout); -- return (0); - } - } -+#endif /* WRITE */ - - FCLOSE(fpin); - FCLOSE(fpout); -@@ -1614,6 +1786,24 @@ - inname = argv[2]; - } - -+ else if (strcmp(argv[1], "--strict") == 0) -+ { -+ status_dots_requested = 0; -+ verbose = 1; -+ inname = argv[2]; -+ strict++; -+ relaxed = 0; -+ } -+ -+ else if (strcmp(argv[1], "--relaxed") == 0) -+ { -+ status_dots_requested = 0; -+ verbose = 1; -+ inname = argv[2]; -+ strict = 0; -+ relaxed++; -+ } -+ - else - { - inname = argv[1]; -@@ -1621,10 +1811,11 @@ - } - } - -- if (!multiple && argc == 3 + verbose) -+ if (multiple == 0 && argc == 3 + verbose) - outname = argv[2 + verbose]; - -- if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2)) -+ if ((multiple == 0 && argc > 3 + verbose) || -+ (multiple != 0 && argc < 2)) - { - fprintf(STDERR, - "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", -@@ -1636,7 +1827,7 @@ - exit(1); - } - -- if (multiple) -+ if (multiple != 0) - { - int i; - #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG -@@ -1646,6 +1837,9 @@ - { - int kerror; - fprintf(STDERR, "\n Testing %s:", argv[i]); -+#if PNG_DEBUG > 0 -+ fprintf(STDERR, "\n"); -+#endif - kerror = test_one_file(argv[i], outname); - if (kerror == 0) - { -@@ -1660,7 +1854,7 @@ - #endif - #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - for (k = 0; k<256; k++) -- if (filters_used[k]) -+ if (filters_used[k] != 0) - fprintf(STDERR, " Filter %d was used %lu times\n", - k, (unsigned long)filters_used[k]); - #endif -@@ -1669,7 +1863,7 @@ - fprintf(STDERR, " tIME = %s\n", tIME_string); - - tIME_chunk_present = 0; --#endif /* PNG_TIME_RFC1123_SUPPORTED */ -+#endif /* TIME_RFC1123 */ - } - - else -@@ -1691,9 +1885,9 @@ - - while (pinfo != NULL) - { -- fprintf(STDERR, " %lu bytes at %x\n", -+ fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, -- (unsigned int)pinfo->pointer); -+ pinfo->pointer); - pinfo = pinfo->next; - } - } -@@ -1727,7 +1921,12 @@ - status_dots_requested = 0; - - if (i == 0 || verbose == 1 || ierror != 0) -+ { - fprintf(STDERR, "\n Testing %s:", inname); -+#if PNG_DEBUG > 0 -+ fprintf(STDERR, "\n"); -+#endif -+ } - - kerror = test_one_file(inname, outname); - -@@ -1746,21 +1945,26 @@ - #endif - #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - for (k = 0; k<256; k++) -- if (filters_used[k]) -+ if (filters_used[k] != 0) - fprintf(STDERR, " Filter %d was used %lu times\n", - k, (unsigned long)filters_used[k]); - #endif - #ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); --#endif /* PNG_TIME_RFC1123_SUPPORTED */ -+#endif /* TIME_RFC1123 */ - } - } - - else - { - if (verbose == 0 && i != 2) -+ { - fprintf(STDERR, "\n Testing %s:", inname); -+#if PNG_DEBUG > 0 -+ fprintf(STDERR, "\n"); -+#endif -+ } - - fprintf(STDERR, " FAIL\n"); - ierror += kerror; -@@ -1779,8 +1983,8 @@ - - while (pinfo != NULL) - { -- fprintf(STDERR, " %lu bytes at %x\n", -- (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); -+ fprintf(STDERR, " %lu bytes at %p\n", -+ (unsigned long)pinfo->size, pinfo->pointer); - pinfo = pinfo->next; - } - } -@@ -1820,6 +2024,16 @@ - - return (int)(ierror != 0); - } -+#else -+int -+main(void) -+{ -+ fprintf(STDERR, -+ " test ignored because libpng was not built with read support\n"); -+ /* And skip this test */ -+ return PNG_LIBPNG_VER < 10600 ? 0 : 77; -+} -+#endif - - /* Generate a compiler error if there is an old png.h in the search path. */ --typedef png_libpng_version_1_5_4 Your_png_h_is_not_version_1_5_4; -+typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16; ---- ./jdk/src/share/native/sun/awt/libpng/pngtrans.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngtrans.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -46,7 +46,7 @@ - #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) - /* Turn on BGR-to-RGB mapping */ - void PNGAPI --png_set_bgr(png_structp png_ptr) -+png_set_bgr(png_structrp png_ptr) - { - png_debug(1, "in png_set_bgr"); - -@@ -60,7 +60,7 @@ - #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) - /* Turn on 16 bit byte swapping */ - void PNGAPI --png_set_swap(png_structp png_ptr) -+png_set_swap(png_structrp png_ptr) - { - png_debug(1, "in png_set_swap"); - -@@ -75,7 +75,7 @@ - #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) - /* Turn on pixel packing */ - void PNGAPI --png_set_packing(png_structp png_ptr) -+png_set_packing(png_structrp png_ptr) - { - png_debug(1, "in png_set_packing"); - -@@ -85,7 +85,9 @@ - if (png_ptr->bit_depth < 8) - { - png_ptr->transformations |= PNG_PACK; -- png_ptr->usr_bit_depth = 8; -+# ifdef PNG_WRITE_SUPPORTED -+ png_ptr->usr_bit_depth = 8; -+# endif - } - } - #endif -@@ -93,7 +95,7 @@ - #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) - /* Turn on packed pixel swapping */ - void PNGAPI --png_set_packswap(png_structp png_ptr) -+png_set_packswap(png_structrp png_ptr) - { - png_debug(1, "in png_set_packswap"); - -@@ -107,7 +109,7 @@ - - #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - void PNGAPI --png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) -+png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) - { - png_debug(1, "in png_set_shift"); - -@@ -122,11 +124,11 @@ - #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) - int PNGAPI --png_set_interlace_handling(png_structp png_ptr) -+png_set_interlace_handling(png_structrp png_ptr) - { - png_debug(1, "in png_set_interlace handling"); - -- if (png_ptr && png_ptr->interlaced) -+ if (png_ptr != 0 && png_ptr->interlaced != 0) - { - png_ptr->transformations |= PNG_INTERLACE; - return (7); -@@ -143,44 +145,91 @@ - * that don't like bytes as parameters. - */ - void PNGAPI --png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) -+png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) - { - png_debug(1, "in png_set_filler"); - - if (png_ptr == NULL) - return; - -+ /* In libpng 1.6 it is possible to determine whether this is a read or write -+ * operation and therefore to do more checking here for a valid call. -+ */ -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -+ { -+# ifdef PNG_READ_FILLER_SUPPORTED -+ /* On read png_set_filler is always valid, regardless of the base PNG -+ * format, because other transformations can give a format where the -+ * filler code can execute (basically an 8 or 16-bit component RGB or G -+ * format.) -+ * -+ * NOTE: usr_channels is not used by the read code! (This has led to -+ * confusion in the past.) The filler is only used in the read code. -+ */ -+ png_ptr->filler = (png_uint_16)filler; -+# else -+ png_app_error(png_ptr, "png_set_filler not supported on read"); -+ PNG_UNUSED(filler) /* not used in the write case */ -+ return; -+# endif -+ } -+ -+ else /* write */ -+ { -+# ifdef PNG_WRITE_FILLER_SUPPORTED -+ /* On write the usr_channels parameter must be set correctly at the -+ * start to record the number of channels in the app-supplied data. -+ */ -+ switch (png_ptr->color_type) -+ { -+ case PNG_COLOR_TYPE_RGB: -+ png_ptr->usr_channels = 4; -+ break; -+ -+ case PNG_COLOR_TYPE_GRAY: -+ if (png_ptr->bit_depth >= 8) -+ { -+ png_ptr->usr_channels = 2; -+ break; -+ } -+ -+ else -+ { -+ /* There simply isn't any code in libpng to strip out bits -+ * from bytes when the components are less than a byte in -+ * size! -+ */ -+ png_app_error(png_ptr, -+ "png_set_filler is invalid for low bit depth gray output"); -+ return; -+ } -+ -+ default: -+ png_app_error(png_ptr, -+ "png_set_filler: inappropriate color type"); -+ return; -+ } -+# else -+ png_app_error(png_ptr, "png_set_filler not supported on write"); -+ return; -+# endif -+ } -+ -+ /* Here on success - libpng supports the operation, set the transformation -+ * and the flag to say where the filler channel is. -+ */ - png_ptr->transformations |= PNG_FILLER; -- png_ptr->filler = (png_uint_16)filler; - - if (filler_loc == PNG_FILLER_AFTER) - png_ptr->flags |= PNG_FLAG_FILLER_AFTER; - - else - png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; -- -- /* This should probably go in the "do_read_filler" routine. -- * I attempted to do that in libpng-1.0.1a but that caused problems -- * so I restored it in libpng-1.0.2a -- */ -- -- if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) -- { -- png_ptr->usr_channels = 4; -- } -- -- /* Also I added this in libpng-1.0.2a (what happens when we expand -- * a less-than-8-bit grayscale to GA?) */ -- -- if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) -- { -- png_ptr->usr_channels = 2; -- } - } - - /* Added to libpng-1.2.7 */ - void PNGAPI --png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) -+png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) - { - png_debug(1, "in png_set_add_alpha"); - -@@ -188,7 +237,9 @@ - return; - - png_set_filler(png_ptr, filler, filler_loc); -- png_ptr->transformations |= PNG_ADD_ALPHA; -+ /* The above may fail to do anything. */ -+ if ((png_ptr->transformations & PNG_FILLER) != 0) -+ png_ptr->transformations |= PNG_ADD_ALPHA; - } - - #endif -@@ -196,7 +247,7 @@ - #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) - void PNGAPI --png_set_swap_alpha(png_structp png_ptr) -+png_set_swap_alpha(png_structrp png_ptr) - { - png_debug(1, "in png_set_swap_alpha"); - -@@ -210,7 +261,7 @@ - #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) - void PNGAPI --png_set_invert_alpha(png_structp png_ptr) -+png_set_invert_alpha(png_structrp png_ptr) - { - png_debug(1, "in png_set_invert_alpha"); - -@@ -223,7 +274,7 @@ - - #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) - void PNGAPI --png_set_invert_mono(png_structp png_ptr) -+png_set_invert_mono(png_structrp png_ptr) - { - png_debug(1, "in png_set_invert_mono"); - -@@ -304,9 +355,16 @@ - - for (i = 0; i < istop; i++, rp += 2) - { -+#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED -+ /* Feature added to libpng-1.6.11 for testing purposes, not -+ * enabled by default. -+ */ -+ *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp); -+#else - png_byte t = *rp; - *rp = *(rp + 1); - *(rp + 1) = t; -+#endif - } - } - } -@@ -448,7 +506,7 @@ - *rp = table[*rp]; - } - } --#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ -+#endif /* PACKSWAP || WRITE_PACKSWAP */ - - #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -@@ -480,7 +538,7 @@ - { - if (row_info->bit_depth == 8) - { -- if (at_start) /* Skip initial filler */ -+ if (at_start != 0) /* Skip initial filler */ - ++sp; - else /* Skip initial channel and, for sp, the filler */ - sp += 2, ++dp; -@@ -494,7 +552,7 @@ - - else if (row_info->bit_depth == 16) - { -- if (at_start) /* Skip initial filler */ -+ if (at_start != 0) /* Skip initial filler */ - sp += 2; - else /* Skip initial channel and, for sp, the filler */ - sp += 4, dp += 2; -@@ -520,7 +578,7 @@ - { - if (row_info->bit_depth == 8) - { -- if (at_start) /* Skip initial filler */ -+ if (at_start != 0) /* Skip initial filler */ - ++sp; - else /* Skip initial channels and, for sp, the filler */ - sp += 4, dp += 3; -@@ -534,7 +592,7 @@ - - else if (row_info->bit_depth == 16) - { -- if (at_start) /* Skip initial filler */ -+ if (at_start != 0) /* Skip initial filler */ - sp += 2; - else /* Skip initial channels and, for sp, the filler */ - sp += 8, dp += 6; -@@ -575,7 +633,7 @@ - { - png_debug(1, "in png_do_bgr"); - -- if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) -+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) -@@ -645,19 +703,133 @@ - #endif - } - } --#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ -+#endif /* READ_BGR || WRITE_BGR */ -+ -+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ -+ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) -+/* Added at libpng-1.5.10 */ -+void /* PRIVATE */ -+png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) -+{ -+ if (png_ptr->num_palette < (1 << row_info->bit_depth) && -+ png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ -+ { -+ /* Calculations moved outside switch in an attempt to stop different -+ * compiler warnings. 'padding' is in *bits* within the last byte, it is -+ * an 'int' because pixel_depth becomes an 'int' in the expression below, -+ * and this calculation is used because it avoids warnings that other -+ * forms produced on either GCC or MSVC. -+ */ -+ int padding = (-row_info->pixel_depth * row_info->width) & 7; -+ png_bytep rp = png_ptr->row_buf + row_info->rowbytes; -+ -+ switch (row_info->bit_depth) -+ { -+ case 1: -+ { -+ /* in this case, all bytes must be 0 so we don't need -+ * to unpack the pixels except for the rightmost one. -+ */ -+ for (; rp > png_ptr->row_buf; rp--) -+ { -+ if (*rp >> padding != 0) -+ png_ptr->num_palette_max = 1; -+ padding = 0; -+ } -+ -+ break; -+ } -+ -+ case 2: -+ { -+ for (; rp > png_ptr->row_buf; rp--) -+ { -+ int i = ((*rp >> padding) & 0x03); -+ -+ if (i > png_ptr->num_palette_max) -+ png_ptr->num_palette_max = i; -+ -+ i = (((*rp >> padding) >> 2) & 0x03); -+ -+ if (i > png_ptr->num_palette_max) -+ png_ptr->num_palette_max = i; -+ -+ i = (((*rp >> padding) >> 4) & 0x03); -+ -+ if (i > png_ptr->num_palette_max) -+ png_ptr->num_palette_max = i; -+ -+ i = (((*rp >> padding) >> 6) & 0x03); -+ -+ if (i > png_ptr->num_palette_max) -+ png_ptr->num_palette_max = i; -+ -+ padding = 0; -+ } -+ -+ break; -+ } -+ -+ case 4: -+ { -+ for (; rp > png_ptr->row_buf; rp--) -+ { -+ int i = ((*rp >> padding) & 0x0f); -+ -+ if (i > png_ptr->num_palette_max) -+ png_ptr->num_palette_max = i; -+ -+ i = (((*rp >> padding) >> 4) & 0x0f); -+ -+ if (i > png_ptr->num_palette_max) -+ png_ptr->num_palette_max = i; -+ -+ padding = 0; -+ } -+ -+ break; -+ } -+ -+ case 8: -+ { -+ for (; rp > png_ptr->row_buf; rp--) -+ { -+ if (*rp > png_ptr->num_palette_max) -+ png_ptr->num_palette_max = (int) *rp; -+ } -+ -+ break; -+ } -+ -+ default: -+ break; -+ } -+ } -+} -+#endif /* CHECK_FOR_INVALID_INDEX */ - - #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - void PNGAPI --png_set_user_transform_info(png_structp png_ptr, png_voidp -+png_set_user_transform_info(png_structrp png_ptr, png_voidp - user_transform_ptr, int user_transform_depth, int user_transform_channels) - { - png_debug(1, "in png_set_user_transform_info"); - - if (png_ptr == NULL) - return; -+ -+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && -+ (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) -+ { -+ png_app_error(png_ptr, -+ "info change after png_start_read_image or png_read_update_info"); -+ return; -+ } -+#endif -+ - png_ptr->user_transform_ptr = user_transform_ptr; - png_ptr->user_transform_depth = (png_byte)user_transform_depth; - png_ptr->user_transform_channels = (png_byte)user_transform_channels; -@@ -671,20 +843,20 @@ - */ - #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - png_voidp PNGAPI --png_get_user_transform_ptr(png_const_structp png_ptr) -+png_get_user_transform_ptr(png_const_structrp png_ptr) - { - if (png_ptr == NULL) - return (NULL); - -- return ((png_voidp)png_ptr->user_transform_ptr); -+ return png_ptr->user_transform_ptr; - } - #endif - - #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED - png_uint_32 PNGAPI --png_get_current_row_number(png_const_structp png_ptr) -+png_get_current_row_number(png_const_structrp png_ptr) - { -- /* See the comments in png.h - this is the sub-image row when reading and -+ /* See the comments in png.h - this is the sub-image row when reading an - * interlaced image. - */ - if (png_ptr != NULL) -@@ -694,13 +866,12 @@ - } - - png_byte PNGAPI --png_get_current_pass_number(png_const_structp png_ptr) -+png_get_current_pass_number(png_const_structrp png_ptr) - { - if (png_ptr != NULL) - return png_ptr->pass; - return 8; /* invalid */ - } --#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ --#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || -- PNG_WRITE_USER_TRANSFORM_SUPPORTED */ --#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ -+#endif /* USER_TRANSFORM_INFO */ -+#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */ -+#endif /* READ || WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pngwio.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngwio.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.0 [January 6, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -58,11 +58,12 @@ - */ - - void /* PRIVATE */ --png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length) -+png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) - { - /* NOTE: write_data_fn must not change the buffer! */ - if (png_ptr->write_data_fn != NULL ) -- (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length); -+ (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), -+ length); - - else - png_error(png_ptr, "Call to NULL write function"); -@@ -74,7 +75,6 @@ - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ --#ifndef USE_FAR_KEYWORD - void PNGCBAPI - png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) - { -@@ -88,64 +88,6 @@ - if (check != length) - png_error(png_ptr, "Write Error"); - } --#else --/* This is the model-independent version. Since the standard I/O library -- * can't handle far buffers in the medium and small models, we have to copy -- * the data. -- */ -- --#define NEAR_BUF_SIZE 1024 --#define MIN(a,b) (a <= b ? a : b) -- --void PNGCBAPI --png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) --{ -- png_uint_32 check; -- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ -- png_FILE_p io_ptr; -- -- if (png_ptr == NULL) -- return; -- -- /* Check if data really is near. If so, use usual code. */ -- near_data = (png_byte *)CVT_PTR_NOCHECK(data); -- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); -- -- if ((png_bytep)near_data == data) -- { -- check = fwrite(near_data, 1, length, io_ptr); -- } -- -- else -- { -- png_byte buf[NEAR_BUF_SIZE]; -- png_size_t written, remaining, err; -- check = 0; -- remaining = length; -- -- do -- { -- written = MIN(NEAR_BUF_SIZE, remaining); -- png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ -- err = fwrite(buf, 1, written, io_ptr); -- -- if (err != written) -- break; -- -- else -- check += err; -- -- data += written; -- remaining -= written; -- } -- while (remaining != 0); -- } -- -- if (check != length) -- png_error(png_ptr, "Write Error"); --} -- --#endif - #endif - - /* This function is called to output any data pending writing (normally -@@ -154,7 +96,7 @@ - */ - #ifdef PNG_WRITE_FLUSH_SUPPORTED - void /* PRIVATE */ --png_flush(png_structp png_ptr) -+png_flush(png_structrp png_ptr) - { - if (png_ptr->output_flush_fn != NULL) - (*(png_ptr->output_flush_fn))(png_ptr); -@@ -169,7 +111,7 @@ - if (png_ptr == NULL) - return; - -- io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); -+ io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr)); - fflush(io_ptr); - } - # endif -@@ -205,7 +147,7 @@ - * *FILE structure. - */ - void PNGAPI --png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, -+png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) - { - if (png_ptr == NULL) -@@ -235,8 +177,11 @@ - # else - png_ptr->output_flush_fn = output_flush_fn; - # endif --#endif /* PNG_WRITE_FLUSH_SUPPORTED */ -+#else -+ PNG_UNUSED(output_flush_fn) -+#endif /* WRITE_FLUSH */ - -+#ifdef PNG_READ_SUPPORTED - /* It is an error to read while writing a png file */ - if (png_ptr->read_data_fn != NULL) - { -@@ -246,37 +191,6 @@ - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } -+#endif - } -- --#ifdef USE_FAR_KEYWORD --# ifdef _MSC_VER --void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) --{ -- void *near_ptr; -- void FAR *far_ptr; -- FP_OFF(near_ptr) = FP_OFF(ptr); -- far_ptr = (void FAR *)near_ptr; -- -- if (check != 0) -- if (FP_SEG(ptr) != FP_SEG(far_ptr)) -- png_error(png_ptr, "segment lost in conversion"); -- -- return(near_ptr); --} --# else --void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) --{ -- void *near_ptr; -- void FAR *far_ptr; -- near_ptr = (void FAR *)ptr; -- far_ptr = (void FAR *)near_ptr; -- -- if (check != 0) -- if (far_ptr != ptr) -- png_error(png_ptr, "segment lost in conversion"); -- -- return(near_ptr); --} --# endif --#endif --#endif /* PNG_WRITE_SUPPORTED */ -+#endif /* WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pngwrite.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngwrite.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -40,9 +40,65 @@ - */ - - #include "pngpriv.h" -+#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -+# include <errno.h> -+#endif - - #ifdef PNG_WRITE_SUPPORTED - -+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -+/* Write out all the unknown chunks for the current given location */ -+static void -+write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, -+ unsigned int where) -+{ -+ if (info_ptr->unknown_chunks_num != 0) -+ { -+ png_const_unknown_chunkp up; -+ -+ png_debug(5, "writing extra chunks"); -+ -+ for (up = info_ptr->unknown_chunks; -+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; -+ ++up) -+ if ((up->location & where) != 0) -+ { -+ /* If per-chunk unknown chunk handling is enabled use it, otherwise -+ * just write the chunks the application has set. -+ */ -+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+ int keep = png_handle_as_unknown(png_ptr, up->name); -+ -+ /* NOTE: this code is radically different from the read side in the -+ * matter of handling an ancillary unknown chunk. In the read side -+ * the default behavior is to discard it, in the code below the default -+ * behavior is to write it. Critical chunks are, however, only -+ * written if explicitly listed or if the default is set to write all -+ * unknown chunks. -+ * -+ * The default handling is also slightly weird - it is not possible to -+ * stop the writing of all unsafe-to-copy chunks! -+ * -+ * TODO: REVIEW: this would seem to be a bug. -+ */ -+ if (keep != PNG_HANDLE_CHUNK_NEVER && -+ ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || -+ keep == PNG_HANDLE_CHUNK_ALWAYS || -+ (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && -+ png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) -+#endif -+ { -+ /* TODO: review, what is wrong with a zero length unknown chunk? */ -+ if (up->size == 0) -+ png_warning(png_ptr, "Writing zero-length unknown chunk"); -+ -+ png_write_chunk(png_ptr, up->name, up->data, up->size); -+ } -+ } -+ } -+} -+#endif /* WRITE_UNKNOWN_CHUNKS */ -+ - /* Writes all the PNG information. This is the suggested way to use the - * library. If you have a new chunk to add, make a function to write it, - * and put it in the correct location here. If you want the chunk written -@@ -53,21 +109,21 @@ - * them in png_write_end(), and compressing them. - */ - void PNGAPI --png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) -+png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) - { - png_debug(1, "in png_write_info_before_PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) -+ if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) - { - /* Write PNG signature */ - png_write_sig(png_ptr); - - #ifdef PNG_MNG_FEATURES_SUPPORTED -- if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ -- (png_ptr->mng_features_permitted)) -+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ -+ png_ptr->mng_features_permitted != 0) - { - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - png_ptr->mng_features_permitted = 0; -@@ -79,75 +135,88 @@ - info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, - info_ptr->filter_type, - #ifdef PNG_WRITE_INTERLACING_SUPPORTED -- info_ptr->interlace_type); -+ info_ptr->interlace_type - #else -- 0); -+ 0 - #endif -+ ); -+ - /* The rest of these check to see if the valid field has the appropriate - * flag set, and if it does, writes the chunk. -+ * -+ * 1.6.0: COLORSPACE support controls the writing of these chunks too, and -+ * the chunks will be written if the WRITE routine is there and information -+ * is available in the COLORSPACE. (See png_colorspace_sync_info in png.c -+ * for where the valid flags get set.) -+ * -+ * Under certain circumstances the colorspace can be invalidated without -+ * syncing the info_struct 'valid' flags; this happens if libpng detects and -+ * error and calls png_error while the color space is being set, yet the -+ * application continues writing the PNG. So check the 'invalid' flag here -+ * too. - */ --#ifdef PNG_WRITE_gAMA_SUPPORTED -- if (info_ptr->valid & PNG_INFO_gAMA) -- png_write_gAMA_fixed(png_ptr, info_ptr->gamma); --#endif --#ifdef PNG_WRITE_sRGB_SUPPORTED -- if (info_ptr->valid & PNG_INFO_sRGB) -- png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); -+#ifdef PNG_GAMMA_SUPPORTED -+# ifdef PNG_WRITE_gAMA_SUPPORTED -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 && -+ (info_ptr->valid & PNG_INFO_gAMA) != 0) -+ png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); -+# endif - #endif - --#ifdef PNG_WRITE_iCCP_SUPPORTED -- if (info_ptr->valid & PNG_INFO_iCCP) -- png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, -- (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); --#endif -+#ifdef PNG_COLORSPACE_SUPPORTED -+ /* Write only one of sRGB or an ICC profile. If a profile was supplied -+ * and it matches one of the known sRGB ones issue a warning. -+ */ -+# ifdef PNG_WRITE_iCCP_SUPPORTED -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && -+ (info_ptr->valid & PNG_INFO_iCCP) != 0) -+ { -+# ifdef PNG_WRITE_sRGB_SUPPORTED -+ if ((info_ptr->valid & PNG_INFO_sRGB) != 0) -+ png_app_warning(png_ptr, -+ "profile matches sRGB but writing iCCP instead"); -+# endif -+ -+ png_write_iCCP(png_ptr, info_ptr->iccp_name, -+ info_ptr->iccp_profile); -+ } -+# ifdef PNG_WRITE_sRGB_SUPPORTED -+ else -+# endif -+# endif -+ -+# ifdef PNG_WRITE_sRGB_SUPPORTED -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && -+ (info_ptr->valid & PNG_INFO_sRGB) != 0) -+ png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); -+# endif /* WRITE_sRGB */ -+#endif /* COLORSPACE */ -+ - #ifdef PNG_WRITE_sBIT_SUPPORTED -- if (info_ptr->valid & PNG_INFO_sBIT) -+ if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); - #endif --#ifdef PNG_WRITE_cHRM_SUPPORTED -- if (info_ptr->valid & PNG_INFO_cHRM) -- png_write_cHRM_fixed(png_ptr, -- info_ptr->x_white, info_ptr->y_white, -- info_ptr->x_red, info_ptr->y_red, -- info_ptr->x_green, info_ptr->y_green, -- info_ptr->x_blue, info_ptr->y_blue); -+ -+#ifdef PNG_COLORSPACE_SUPPORTED -+# ifdef PNG_WRITE_cHRM_SUPPORTED -+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && -+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && -+ (info_ptr->valid & PNG_INFO_cHRM) != 0) -+ png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); -+# endif - #endif - - #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -- if (info_ptr->unknown_chunks_num) -- { -- png_unknown_chunk *up; -+ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); -+#endif - -- png_debug(5, "writing extra chunks"); -- -- for (up = info_ptr->unknown_chunks; -- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; -- up++) -- { -- int keep = png_handle_as_unknown(png_ptr, up->name); -- -- if (keep != PNG_HANDLE_CHUNK_NEVER && -- up->location && -- !(up->location & PNG_HAVE_PLTE) && -- !(up->location & PNG_HAVE_IDAT) && -- !(up->location & PNG_AFTER_IDAT) && -- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || -- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) -- { -- if (up->size == 0) -- png_warning(png_ptr, "Writing zero-length unknown chunk"); -- -- png_write_chunk(png_ptr, up->name, up->data, up->size); -- } -- } -- } --#endif - png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; - } - } - - void PNGAPI --png_write_info(png_structp png_ptr, png_infop info_ptr) -+png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) - { - #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) - int i; -@@ -160,19 +229,19 @@ - - png_write_info_before_PLTE(png_ptr, info_ptr); - -- if (info_ptr->valid & PNG_INFO_PLTE) -+ if ((info_ptr->valid & PNG_INFO_PLTE) != 0) - png_write_PLTE(png_ptr, info_ptr->palette, - (png_uint_32)info_ptr->num_palette); - -- else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -+ else if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) !=0) - png_error(png_ptr, "Valid palette required for paletted images"); - - #ifdef PNG_WRITE_tRNS_SUPPORTED -- if (info_ptr->valid & PNG_INFO_tRNS) -+ if ((info_ptr->valid & PNG_INFO_tRNS) !=0) - { - #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - /* Invert the alpha channel (in tRNS) */ -- if ((png_ptr->transformations & PNG_INVERT_ALPHA) && -+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 && - info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - int j; -@@ -186,42 +255,42 @@ - } - #endif - #ifdef PNG_WRITE_bKGD_SUPPORTED -- if (info_ptr->valid & PNG_INFO_bKGD) -+ if ((info_ptr->valid & PNG_INFO_bKGD) != 0) - png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); - #endif - - #ifdef PNG_WRITE_hIST_SUPPORTED -- if (info_ptr->valid & PNG_INFO_hIST) -+ if ((info_ptr->valid & PNG_INFO_hIST) != 0) - png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); - #endif - - #ifdef PNG_WRITE_oFFs_SUPPORTED -- if (info_ptr->valid & PNG_INFO_oFFs) -+ if ((info_ptr->valid & PNG_INFO_oFFs) != 0) - png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, - info_ptr->offset_unit_type); - #endif - - #ifdef PNG_WRITE_pCAL_SUPPORTED -- if (info_ptr->valid & PNG_INFO_pCAL) -+ if ((info_ptr->valid & PNG_INFO_pCAL) != 0) - png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, - info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, - info_ptr->pcal_units, info_ptr->pcal_params); - #endif - - #ifdef PNG_WRITE_sCAL_SUPPORTED -- if (info_ptr->valid & PNG_INFO_sCAL) -+ if ((info_ptr->valid & PNG_INFO_sCAL) != 0) - png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, - info_ptr->scal_s_width, info_ptr->scal_s_height); - #endif /* sCAL */ - - #ifdef PNG_WRITE_pHYs_SUPPORTED -- if (info_ptr->valid & PNG_INFO_pHYs) -+ if ((info_ptr->valid & PNG_INFO_pHYs) != 0) - png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, - info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); - #endif /* pHYs */ - - #ifdef PNG_WRITE_tIME_SUPPORTED -- if (info_ptr->valid & PNG_INFO_tIME) -+ if ((info_ptr->valid & PNG_INFO_tIME) != 0) - { - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - png_ptr->mode |= PNG_WROTE_tIME; -@@ -229,7 +298,7 @@ - #endif /* tIME */ - - #ifdef PNG_WRITE_sPLT_SUPPORTED -- if (info_ptr->valid & PNG_INFO_sPLT) -+ if ((info_ptr->valid & PNG_INFO_sPLT) != 0) - for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) - png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); - #endif /* sPLT */ -@@ -251,11 +320,14 @@ - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); -+ /* Mark this chunk as written */ -+ if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) -+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; -+ else -+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - #else -- png_warning(png_ptr, "Unable to write international text"); -+ png_warning(png_ptr, "Unable to write international text"); - #endif -- /* Mark this chunk as written */ -- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - } - - /* If we want a compressed text chunk */ -@@ -264,13 +336,12 @@ - #ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, -- info_ptr->text[i].text, 0, -- info_ptr->text[i].compression); -+ info_ptr->text[i].text, info_ptr->text[i].compression); -+ /* Mark this chunk as written */ -+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - #else - png_warning(png_ptr, "Unable to write compressed text"); - #endif -- /* Mark this chunk as written */ -- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) -@@ -291,29 +362,7 @@ - #endif /* tEXt */ - - #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -- if (info_ptr->unknown_chunks_num) -- { -- png_unknown_chunk *up; -- -- png_debug(5, "writing extra chunks"); -- -- for (up = info_ptr->unknown_chunks; -- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; -- up++) -- { -- int keep = png_handle_as_unknown(png_ptr, up->name); -- if (keep != PNG_HANDLE_CHUNK_NEVER && -- up->location && -- (up->location & PNG_HAVE_PLTE) && -- !(up->location & PNG_HAVE_IDAT) && -- !(up->location & PNG_AFTER_IDAT) && -- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || -- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) -- { -- png_write_chunk(png_ptr, up->name, up->data, up->size); -- } -- } -- } -+ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); - #endif - } - -@@ -323,16 +372,21 @@ - * comments, I suggest writing them here, and compressing them. - */ - void PNGAPI --png_write_end(png_structp png_ptr, png_infop info_ptr) -+png_write_end(png_structrp png_ptr, png_inforp info_ptr) - { - png_debug(1, "in png_write_end"); - - if (png_ptr == NULL) - return; - -- if (!(png_ptr->mode & PNG_HAVE_IDAT)) -+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_error(png_ptr, "No IDATs written into file"); - -+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED -+ if (png_ptr->num_palette_max > png_ptr->num_palette) -+ png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); -+#endif -+ - /* See if user wants us to write information chunks */ - if (info_ptr != NULL) - { -@@ -341,8 +395,8 @@ - #endif - #ifdef PNG_WRITE_tIME_SUPPORTED - /* Check to see if user has supplied a time chunk */ -- if ((info_ptr->valid & PNG_INFO_tIME) && -- !(png_ptr->mode & PNG_WROTE_tIME)) -+ if ((info_ptr->valid & PNG_INFO_tIME) != 0 && -+ (png_ptr->mode & PNG_WROTE_tIME) == 0) - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - - #endif -@@ -363,11 +417,14 @@ - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); -+ /* Mark this chunk as written */ -+ if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) -+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; -+ else -+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - #else - png_warning(png_ptr, "Unable to write international text"); - #endif -- /* Mark this chunk as written */ -- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - } - - else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) -@@ -375,13 +432,12 @@ - #ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, -- info_ptr->text[i].text, 0, -- info_ptr->text[i].compression); -+ info_ptr->text[i].text, info_ptr->text[i].compression); -+ /* Mark this chunk as written */ -+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - #else - png_warning(png_ptr, "Unable to write compressed text"); - #endif -- /* Mark this chunk as written */ -- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) -@@ -390,37 +446,16 @@ - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0); -+ /* Mark this chunk as written */ -+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - #else - png_warning(png_ptr, "Unable to write uncompressed text"); - #endif -- -- /* Mark this chunk as written */ -- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - } - } - #endif - #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -- if (info_ptr->unknown_chunks_num) -- { -- png_unknown_chunk *up; -- -- png_debug(5, "writing extra chunks"); -- -- for (up = info_ptr->unknown_chunks; -- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; -- up++) -- { -- int keep = png_handle_as_unknown(png_ptr, up->name); -- if (keep != PNG_HANDLE_CHUNK_NEVER && -- up->location && -- (up->location & PNG_AFTER_IDAT) && -- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || -- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) -- { -- png_write_chunk(png_ptr, up->name, up->data, up->size); -- } -- } -- } -+ write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); - #endif - } - -@@ -428,6 +463,7 @@ - - /* Write end of PNG file */ - png_write_IEND(png_ptr); -+ - /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, - * and restored again in libpng-1.2.30, may cause some applications that - * do not set png_ptr->output_flush_fn to crash. If your application -@@ -443,9 +479,8 @@ - } - - #ifdef PNG_CONVERT_tIME_SUPPORTED --/* "tm" structure is not supported on WindowsCE */ - void PNGAPI --png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) -+png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) - { - png_debug(1, "in png_convert_from_struct_tm"); - -@@ -474,103 +509,75 @@ - png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) - { --#ifdef PNG_USER_MEM_SUPPORTED -- return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, -- warn_fn, NULL, NULL, NULL)); -+#ifndef PNG_USER_MEM_SUPPORTED -+ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, -+ error_fn, warn_fn, NULL, NULL, NULL); -+#else -+ return png_create_write_struct_2(user_png_ver, error_ptr, error_fn, -+ warn_fn, NULL, NULL, NULL); - } - - /* Alternate initialize png_ptr structure, and allocate any memory needed */ --static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ -- - PNG_FUNCTION(png_structp,PNGAPI - png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) - { --#endif /* PNG_USER_MEM_SUPPORTED */ -- volatile int png_cleanup_needed = 0; --#ifdef PNG_SETJMP_SUPPORTED -- volatile --#endif -- png_structp png_ptr; --#ifdef PNG_SETJMP_SUPPORTED --#ifdef USE_FAR_KEYWORD -- jmp_buf tmp_jmpbuf; --#endif -+ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, -+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -+#endif /* USER_MEM */ -+ if (png_ptr != NULL) -+ { -+ /* Set the zlib control values to defaults; they can be overridden by the -+ * application after the struct has been created. -+ */ -+ png_ptr->zbuffer_size = PNG_ZBUF_SIZE; -+ -+ /* The 'zlib_strategy' setting is irrelevant because png_default_claim in -+ * pngwutil.c defaults it according to whether or not filters will be -+ * used, and ignores this setting. -+ */ -+ png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; -+ png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; -+ png_ptr->zlib_mem_level = 8; -+ png_ptr->zlib_window_bits = 15; -+ png_ptr->zlib_method = 8; -+ -+#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -+ png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; -+ png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; -+ png_ptr->zlib_text_mem_level = 8; -+ png_ptr->zlib_text_window_bits = 15; -+ png_ptr->zlib_text_method = 8; -+#endif /* WRITE_COMPRESSED_TEXT */ -+ -+ /* This is a highly dubious configuration option; by default it is off, -+ * but it may be appropriate for private builds that are testing -+ * extensions not conformant to the current specification, or of -+ * applications that must not fail to write at all costs! -+ */ -+#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED -+ /* In stable builds only warn if an application error can be completely -+ * handled. -+ */ -+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; - #endif - -- png_debug(1, "in png_create_write_struct"); -- --#ifdef PNG_USER_MEM_SUPPORTED -- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, -- (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); --#else -- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); --#endif /* PNG_USER_MEM_SUPPORTED */ -- if (png_ptr == NULL) -- return (NULL); -- -- /* Added at libpng-1.2.6 */ --#ifdef PNG_SET_USER_LIMITS_SUPPORTED -- png_ptr->user_width_max = PNG_USER_WIDTH_MAX; -- png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; -+ /* App warnings are warnings in release (or release candidate) builds but -+ * are errors during development. -+ */ -+#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC -+ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; - #endif - --#ifdef PNG_SETJMP_SUPPORTED --/* Applications that neglect to set up their own setjmp() and then -- encounter a png_error() will longjmp here. Since the jmpbuf is -- then meaningless we abort instead of returning. */ --#ifdef USE_FAR_KEYWORD -- if (setjmp(tmp_jmpbuf)) --#else -- if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ --#endif --#ifdef USE_FAR_KEYWORD -- png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); --#endif -- PNG_ABORT(); --#endif -- --#ifdef PNG_USER_MEM_SUPPORTED -- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); --#endif /* PNG_USER_MEM_SUPPORTED */ -- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); -- -- if (!png_user_version_check(png_ptr, user_png_ver)) -- png_cleanup_needed = 1; -- -- /* Initialize zbuf - compression buffer */ -- png_ptr->zbuf_size = PNG_ZBUF_SIZE; -- -- if (!png_cleanup_needed) -- { -- png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, -- png_ptr->zbuf_size); -- if (png_ptr->zbuf == NULL) -- png_cleanup_needed = 1; -+ /* TODO: delay this, it can be done in png_init_io() (if the app doesn't -+ * do it itself) avoiding setting the default function if it is not -+ * required. -+ */ -+ png_set_write_fn(png_ptr, NULL, NULL, NULL); - } - -- if (png_cleanup_needed) -- { -- /* Clean up PNG structure and deallocate any memory. */ -- png_free(png_ptr, png_ptr->zbuf); -- png_ptr->zbuf = NULL; --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)png_ptr, -- (png_free_ptr)free_fn, (png_voidp)mem_ptr); --#else -- png_destroy_struct((png_voidp)png_ptr); --#endif -- return (NULL); -- } -- -- png_set_write_fn(png_ptr, NULL, NULL, NULL); -- --#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -- png_reset_filter_heuristics(png_ptr); --#endif -- -- return (png_ptr); -+ return png_ptr; - } - - -@@ -580,7 +587,7 @@ - * "write" the image seven times. - */ - void PNGAPI --png_write_rows(png_structp png_ptr, png_bytepp row, -+png_write_rows(png_structrp png_ptr, png_bytepp row, - png_uint_32 num_rows) - { - png_uint_32 i; /* row counter */ -@@ -602,7 +609,7 @@ - * if you are writing an interlaced image. - */ - void PNGAPI --png_write_image(png_structp png_ptr, png_bytepp image) -+png_write_image(png_structrp png_ptr, png_bytepp image) - { - png_uint_32 i; /* row index */ - int pass, num_pass; /* pass variables */ -@@ -632,10 +639,78 @@ - } - } - -+#ifdef PNG_MNG_FEATURES_SUPPORTED -+/* Performs intrapixel differencing */ -+static void -+png_do_write_intrapixel(png_row_infop row_info, png_bytep row) -+{ -+ png_debug(1, "in png_do_write_intrapixel"); -+ -+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) -+ { -+ int bytes_per_pixel; -+ png_uint_32 row_width = row_info->width; -+ if (row_info->bit_depth == 8) -+ { -+ png_bytep rp; -+ png_uint_32 i; -+ -+ if (row_info->color_type == PNG_COLOR_TYPE_RGB) -+ bytes_per_pixel = 3; -+ -+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -+ bytes_per_pixel = 4; -+ -+ else -+ return; -+ -+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -+ { -+ *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); -+ *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); -+ } -+ } -+ -+#ifdef PNG_WRITE_16BIT_SUPPORTED -+ else if (row_info->bit_depth == 16) -+ { -+ png_bytep rp; -+ png_uint_32 i; -+ -+ if (row_info->color_type == PNG_COLOR_TYPE_RGB) -+ bytes_per_pixel = 6; -+ -+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -+ bytes_per_pixel = 8; -+ -+ else -+ return; -+ -+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -+ { -+ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); -+ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); -+ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); -+ png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); -+ png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); -+ *(rp ) = (png_byte)((red >> 8) & 0xff); -+ *(rp + 1) = (png_byte)(red & 0xff); -+ *(rp + 4) = (png_byte)((blue >> 8) & 0xff); -+ *(rp + 5) = (png_byte)(blue & 0xff); -+ } -+ } -+#endif /* WRITE_16BIT */ -+ } -+} -+#endif /* MNG_FEATURES */ -+ - /* Called by user to write a row of image data */ - void PNGAPI --png_write_row(png_structp png_ptr, png_const_bytep row) -+png_write_row(png_structrp png_ptr, png_const_bytep row) - { -+ /* 1.5.6: moved from png_struct to be a local structure: */ -+ png_row_info row_info; -+ - if (png_ptr == NULL) - return; - -@@ -646,44 +721,44 @@ - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Make sure we wrote the header info */ -- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) -+ if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) - png_error(png_ptr, - "png_write_info was never called before png_write_row"); - - /* Check for transforms that have been set but were defined out */ - #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) -- if (png_ptr->transformations & PNG_INVERT_MONO) -+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); - #endif - - #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) -- if (png_ptr->transformations & PNG_FILLER) -+ if ((png_ptr->transformations & PNG_FILLER) != 0) - png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); - #endif - #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - defined(PNG_READ_PACKSWAP_SUPPORTED) -- if (png_ptr->transformations & PNG_PACKSWAP) -+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_warning(png_ptr, - "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); - #endif - - #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) -- if (png_ptr->transformations & PNG_PACK) -+ if ((png_ptr->transformations & PNG_PACK) != 0) - png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); - #endif - - #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) -- if (png_ptr->transformations & PNG_SHIFT) -+ if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); - #endif - - #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) -- if (png_ptr->transformations & PNG_BGR) -+ if ((png_ptr->transformations & PNG_BGR) != 0) - png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); - #endif - - #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) -- if (png_ptr->transformations & PNG_SWAP_BYTES) -+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); - #endif - -@@ -692,12 +767,13 @@ - - #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced and not interested in row, return */ -- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) -+ if (png_ptr->interlaced != 0 && -+ (png_ptr->transformations & PNG_INTERLACE) != 0) - { - switch (png_ptr->pass) - { - case 0: -- if (png_ptr->row_number & 0x07) -+ if ((png_ptr->row_number & 0x07) != 0) - { - png_write_finish_row(png_ptr); - return; -@@ -705,7 +781,7 @@ - break; - - case 1: -- if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) -+ if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5) - { - png_write_finish_row(png_ptr); - return; -@@ -721,7 +797,7 @@ - break; - - case 3: -- if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) -+ if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3) - { - png_write_finish_row(png_ptr); - return; -@@ -737,7 +813,7 @@ - break; - - case 5: -- if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) -+ if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2) - { - png_write_finish_row(png_ptr); - return; -@@ -745,7 +821,7 @@ - break; - - case 6: -- if (!(png_ptr->row_number & 0x01)) -+ if ((png_ptr->row_number & 0x01) == 0) - { - png_write_finish_row(png_ptr); - return; -@@ -759,36 +835,31 @@ - #endif - - /* Set up row info for transformations */ -- png_ptr->row_info.color_type = png_ptr->color_type; -- png_ptr->row_info.width = png_ptr->usr_width; -- png_ptr->row_info.channels = png_ptr->usr_channels; -- png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; -- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * -- png_ptr->row_info.channels); -+ row_info.color_type = png_ptr->color_type; -+ row_info.width = png_ptr->usr_width; -+ row_info.channels = png_ptr->usr_channels; -+ row_info.bit_depth = png_ptr->usr_bit_depth; -+ row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); -+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - -- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, -- png_ptr->row_info.width); -- -- png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); -- png_debug1(3, "row_info->width = %u", png_ptr->row_info.width); -- png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); -- png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth); -- png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth); -- png_debug1(3, "row_info->rowbytes = %lu", -- (unsigned long)png_ptr->row_info.rowbytes); -+ png_debug1(3, "row_info->color_type = %d", row_info.color_type); -+ png_debug1(3, "row_info->width = %u", row_info.width); -+ png_debug1(3, "row_info->channels = %d", row_info.channels); -+ png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); -+ png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); -+ png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); - - /* Copy user's row into buffer, leaving room for filter byte. */ -- png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); -+ memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); - - #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Handle interlacing */ - if (png_ptr->interlaced && png_ptr->pass < 6 && -- (png_ptr->transformations & PNG_INTERLACE)) -+ (png_ptr->transformations & PNG_INTERLACE) != 0) - { -- png_do_write_interlace(&(png_ptr->row_info), -- png_ptr->row_buf + 1, png_ptr->pass); -+ png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); - /* This should always get caught above, but still ... */ -- if (!(png_ptr->row_info.width)) -+ if (row_info.width == 0) - { - png_write_finish_row(png_ptr); - return; -@@ -798,10 +869,17 @@ - - #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - /* Handle other transformations */ -- if (png_ptr->transformations) -- png_do_write_transformations(png_ptr); -+ if (png_ptr->transformations != 0) -+ png_do_write_transformations(png_ptr, &row_info); - #endif - -+ /* At this point the row_info pixel depth must match the 'transformed' depth, -+ * which is also the output depth. -+ */ -+ if (row_info.pixel_depth != png_ptr->pixel_depth || -+ row_info.pixel_depth != png_ptr->transformed_pixel_depth) -+ png_error(png_ptr, "internal write transform logic error"); -+ - #ifdef PNG_MNG_FEATURES_SUPPORTED - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and -@@ -812,16 +890,24 @@ - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ -- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && -+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ -- png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); -+ png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); - } - #endif - -+/* Added at libpng-1.5.10 */ -+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED -+ /* Check for out-of-range palette index */ -+ if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && -+ png_ptr->num_palette_max >= 0) -+ png_do_check_palette_indexes(png_ptr, &row_info); -+#endif -+ - /* Find a filter if necessary, filter the row and write it out. */ -- png_write_find_filter(png_ptr, &(png_ptr->row_info)); -+ png_write_find_filter(png_ptr, &row_info); - - if (png_ptr->write_row_fn != NULL) - (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); -@@ -830,7 +916,7 @@ - #ifdef PNG_WRITE_FLUSH_SUPPORTED - /* Set the automatic flush interval or 0 to turn flushing off */ - void PNGAPI --png_set_flush(png_structp png_ptr, int nrows) -+png_set_flush(png_structrp png_ptr, int nrows) - { - png_debug(1, "in png_set_flush"); - -@@ -842,10 +928,8 @@ - - /* Flush the current output buffers now */ - void PNGAPI --png_write_flush(png_structp png_ptr) -+png_write_flush(png_structrp png_ptr) - { -- int wrote_IDAT; -- - png_debug(1, "in png_write_flush"); - - if (png_ptr == NULL) -@@ -855,146 +939,41 @@ - if (png_ptr->row_number >= png_ptr->num_rows) - return; - -- do -- { -- int ret; -- -- /* Compress the data */ -- ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); -- wrote_IDAT = 0; -- -- /* Check for compression errors */ -- if (ret != Z_OK) -- { -- if (png_ptr->zstream.msg != NULL) -- png_error(png_ptr, png_ptr->zstream.msg); -- -- else -- png_error(png_ptr, "zlib error"); -- } -- -- if (!(png_ptr->zstream.avail_out)) -- { -- /* Write the IDAT and reset the zlib output buffer */ -- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); -- wrote_IDAT = 1; -- } -- } while (wrote_IDAT == 1); -- -- /* If there is any data left to be output, write it into a new IDAT */ -- if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) -- { -- /* Write the IDAT and reset the zlib output buffer */ -- png_write_IDAT(png_ptr, png_ptr->zbuf, -- png_ptr->zbuf_size - png_ptr->zstream.avail_out); -- } -+ png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH); - png_ptr->flush_rows = 0; - png_flush(png_ptr); - } --#endif /* PNG_WRITE_FLUSH_SUPPORTED */ -+#endif /* WRITE_FLUSH */ - --/* Free all memory used by the write */ --void PNGAPI --png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) --{ -- png_structp png_ptr = NULL; -- png_infop info_ptr = NULL; --#ifdef PNG_USER_MEM_SUPPORTED -- png_free_ptr free_fn = NULL; -- png_voidp mem_ptr = NULL; -+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -+static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */ - #endif - -- png_debug(1, "in png_destroy_write_struct"); -- -- if (png_ptr_ptr != NULL) -- { -- png_ptr = *png_ptr_ptr; --#ifdef PNG_USER_MEM_SUPPORTED -- free_fn = png_ptr->free_fn; -- mem_ptr = png_ptr->mem_ptr; --#endif -- } -- --#ifdef PNG_USER_MEM_SUPPORTED -- if (png_ptr != NULL) -- { -- free_fn = png_ptr->free_fn; -- mem_ptr = png_ptr->mem_ptr; -- } --#endif -- -- if (info_ptr_ptr != NULL) -- info_ptr = *info_ptr_ptr; -- -- if (info_ptr != NULL) -- { -- if (png_ptr != NULL) -- { -- png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); -- --#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -- if (png_ptr->num_chunk_list) -- { -- png_free(png_ptr, png_ptr->chunk_list); -- png_ptr->num_chunk_list = 0; -- } --#endif -- } -- --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, -- (png_voidp)mem_ptr); --#else -- png_destroy_struct((png_voidp)info_ptr); --#endif -- *info_ptr_ptr = NULL; -- } -- -- if (png_ptr != NULL) -- { -- png_write_destroy(png_ptr); --#ifdef PNG_USER_MEM_SUPPORTED -- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, -- (png_voidp)mem_ptr); --#else -- png_destroy_struct((png_voidp)png_ptr); --#endif -- *png_ptr_ptr = NULL; -- } --} -- -- --/* Free any memory used in png_ptr struct (old method) */ --void /* PRIVATE */ --png_write_destroy(png_structp png_ptr) -+/* Free any memory used in png_ptr struct without freeing the struct itself. */ -+static void -+png_write_destroy(png_structrp png_ptr) - { --#ifdef PNG_SETJMP_SUPPORTED -- jmp_buf tmp_jmp; /* Save jump buffer */ --#endif -- png_error_ptr error_fn; --#ifdef PNG_WARNINGS_SUPPORTED -- png_error_ptr warning_fn; --#endif -- png_voidp error_ptr; --#ifdef PNG_USER_MEM_SUPPORTED -- png_free_ptr free_fn; --#endif -- - png_debug(1, "in png_write_destroy"); - - /* Free any memory zlib uses */ -- if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) -+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) - deflateEnd(&png_ptr->zstream); - - /* Free our memory. png_free checks NULL for us. */ -- png_free(png_ptr, png_ptr->zbuf); -+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_free(png_ptr, png_ptr->row_buf); -+ png_ptr->row_buf = NULL; - #ifdef PNG_WRITE_FILTER_SUPPORTED - png_free(png_ptr, png_ptr->prev_row); - png_free(png_ptr, png_ptr->sub_row); - png_free(png_ptr, png_ptr->up_row); - png_free(png_ptr, png_ptr->avg_row); - png_free(png_ptr, png_ptr->paeth_row); -+ png_ptr->prev_row = NULL; -+ png_ptr->sub_row = NULL; -+ png_ptr->up_row = NULL; -+ png_ptr->avg_row = NULL; -+ png_ptr->paeth_row = NULL; - #endif - - #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -@@ -1002,41 +981,51 @@ - png_reset_filter_heuristics(png_ptr); - png_free(png_ptr, png_ptr->filter_costs); - png_free(png_ptr, png_ptr->inv_filter_costs); -+ png_ptr->filter_costs = NULL; -+ png_ptr->inv_filter_costs = NULL; - #endif - --#ifdef PNG_SETJMP_SUPPORTED -- /* Reset structure */ -- png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); -+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -+ png_free(png_ptr, png_ptr->chunk_list); -+ png_ptr->chunk_list = NULL; - #endif - -- error_fn = png_ptr->error_fn; --#ifdef PNG_WARNINGS_SUPPORTED -- warning_fn = png_ptr->warning_fn; --#endif -- error_ptr = png_ptr->error_ptr; --#ifdef PNG_USER_MEM_SUPPORTED -- free_fn = png_ptr->free_fn; --#endif -+ /* The error handling and memory handling information is left intact at this -+ * point: the jmp_buf may still have to be freed. See png_destroy_png_struct -+ * for how this happens. -+ */ -+} - -- png_memset(png_ptr, 0, png_sizeof(png_struct)); -+/* Free all memory used by the write. -+ * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for -+ * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free -+ * the passed in info_structs but it would quietly fail to free any of the data -+ * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it -+ * has no png_ptr.) -+ */ -+void PNGAPI -+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) -+{ -+ png_debug(1, "in png_destroy_write_struct"); - -- png_ptr->error_fn = error_fn; --#ifdef PNG_WARNINGS_SUPPORTED -- png_ptr->warning_fn = warning_fn; --#endif -- png_ptr->error_ptr = error_ptr; --#ifdef PNG_USER_MEM_SUPPORTED -- png_ptr->free_fn = free_fn; --#endif -+ if (png_ptr_ptr != NULL) -+ { -+ png_structrp png_ptr = *png_ptr_ptr; - --#ifdef PNG_SETJMP_SUPPORTED -- png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); --#endif -+ if (png_ptr != NULL) /* added in libpng 1.6.0 */ -+ { -+ png_destroy_info_struct(png_ptr, info_ptr_ptr); -+ -+ *png_ptr_ptr = NULL; -+ png_write_destroy(png_ptr); -+ png_destroy_png_struct(png_ptr); -+ } -+ } - } - - /* Allow the application to select one or more row filters to use. */ - void PNGAPI --png_set_filter(png_structp png_ptr, int method, int filters) -+png_set_filter(png_structrp png_ptr, int method, int filters) - { - png_debug(1, "in png_set_filter"); - -@@ -1044,7 +1033,7 @@ - return; - - #ifdef PNG_MNG_FEATURES_SUPPORTED -- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && -+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (method == PNG_INTRAPIXEL_DIFFERENCING)) - method = PNG_FILTER_TYPE_BASE; - -@@ -1056,8 +1045,9 @@ - #ifdef PNG_WRITE_FILTER_SUPPORTED - case 5: - case 6: -- case 7: png_warning(png_ptr, "Unknown row filter for method 0"); --#endif /* PNG_WRITE_FILTER_SUPPORTED */ -+ case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); -+ /* FALL THROUGH */ -+#endif /* WRITE_FILTER */ - case PNG_FILTER_VALUE_NONE: - png_ptr->do_filter = PNG_FILTER_NONE; break; - -@@ -1078,8 +1068,8 @@ - png_ptr->do_filter = (png_byte)filters; break; - #else - default: -- png_warning(png_ptr, "Unknown row filter for method 0"); --#endif /* PNG_WRITE_FILTER_SUPPORTED */ -+ png_app_error(png_ptr, "Unknown row filter for method 0"); -+#endif /* WRITE_FILTER */ - } - - /* If we have allocated the row_buf, this means we have already started -@@ -1094,14 +1084,16 @@ - if (png_ptr->row_buf != NULL) - { - #ifdef PNG_WRITE_FILTER_SUPPORTED -- if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) -+ if ((png_ptr->do_filter & PNG_FILTER_SUB) != 0 && -+ png_ptr->sub_row == NULL) - { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); - png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; - } - -- if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) -+ if ((png_ptr->do_filter & PNG_FILTER_UP) != 0 && -+ png_ptr->up_row == NULL) - { - if (png_ptr->prev_row == NULL) - { -@@ -1118,7 +1110,8 @@ - } - } - -- if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) -+ if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0 && -+ png_ptr->avg_row == NULL) - { - if (png_ptr->prev_row == NULL) - { -@@ -1135,7 +1128,7 @@ - } - } - -- if ((png_ptr->do_filter & PNG_FILTER_PAETH) && -+ if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0 && - png_ptr->paeth_row == NULL) - { - if (png_ptr->prev_row == NULL) -@@ -1153,7 +1146,7 @@ - } - - if (png_ptr->do_filter == PNG_NO_FILTERS) --#endif /* PNG_WRITE_FILTER_SUPPORTED */ -+#endif /* WRITE_FILTER */ - png_ptr->do_filter = PNG_FILTER_NONE; - } - } -@@ -1171,7 +1164,7 @@ - #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ - /* Convenience reset API. */ - static void --png_reset_filter_heuristics(png_structp png_ptr) -+png_reset_filter_heuristics(png_structrp png_ptr) - { - /* Clear out any old values in the 'weights' - this must be done because if - * the app calls set_filter_heuristics multiple times with different -@@ -1204,7 +1197,7 @@ - } - - static int --png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, -+png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method, - int num_weights) - { - if (png_ptr == NULL) -@@ -1224,7 +1217,7 @@ - if (num_weights > 0) - { - png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, -- (png_uint_32)(png_sizeof(png_byte) * num_weights)); -+ (png_uint_32)((sizeof (png_byte)) * num_weights)); - - /* To make sure that the weighting starts out fairly */ - for (i = 0; i < num_weights; i++) -@@ -1233,10 +1226,10 @@ - } - - png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, -- (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); -+ (png_uint_32)((sizeof (png_uint_16)) * num_weights)); - - png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, -- (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); -+ (png_uint_32)((sizeof (png_uint_16)) * num_weights)); - - for (i = 0; i < num_weights; i++) - { -@@ -1254,10 +1247,10 @@ - if (png_ptr->filter_costs == NULL) - { - png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, -- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); -+ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); - - png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, -- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); -+ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); - } - - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) -@@ -1287,7 +1280,7 @@ - /* Provide floating and fixed point APIs */ - #ifdef PNG_FLOATING_POINT_SUPPORTED - void PNGAPI --png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, -+png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, - int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs) - { -@@ -1296,7 +1289,7 @@ - /* The internal API allocates all the arrays and ensures that the elements of - * those arrays are set to the default value. - */ -- if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) -+ if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) - return; - - /* If using the weighted method copy in the weights. */ -@@ -1342,7 +1335,7 @@ - - #ifdef PNG_FIXED_POINT_SUPPORTED - void PNGAPI --png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, -+png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, - int num_weights, png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs) - { -@@ -1351,7 +1344,7 @@ - /* The internal API allocates all the arrays and ensures that the elements of - * those arrays are set to the default value. - */ -- if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) -+ if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) - return; - - /* If using the weighted method copy in the weights. */ -@@ -1405,40 +1398,40 @@ - } - } - #endif /* FIXED_POINT */ --#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ -+#endif /* WRITE_WEIGHTED_FILTER */ - - void PNGAPI --png_set_compression_level(png_structp png_ptr, int level) -+png_set_compression_level(png_structrp png_ptr, int level) - { - png_debug(1, "in png_set_compression_level"); - - if (png_ptr == NULL) - return; - -- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; - png_ptr->zlib_level = level; - } - - void PNGAPI --png_set_compression_mem_level(png_structp png_ptr, int mem_level) -+png_set_compression_mem_level(png_structrp png_ptr, int mem_level) - { - png_debug(1, "in png_set_compression_mem_level"); - - if (png_ptr == NULL) - return; - -- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; - png_ptr->zlib_mem_level = mem_level; - } - - void PNGAPI --png_set_compression_strategy(png_structp png_ptr, int strategy) -+png_set_compression_strategy(png_structrp png_ptr, int strategy) - { - png_debug(1, "in png_set_compression_strategy"); - - if (png_ptr == NULL) - return; - -+ /* The flag setting here prevents the libpng dynamic selection of strategy. -+ */ - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; - png_ptr->zlib_strategy = strategy; - } -@@ -1447,80 +1440,81 @@ - * smaller value of window_bits if it can do so safely. - */ - void PNGAPI --png_set_compression_window_bits(png_structp png_ptr, int window_bits) -+png_set_compression_window_bits(png_structrp png_ptr, int window_bits) - { - if (png_ptr == NULL) - return; - -+ /* Prior to 1.6.0 this would warn but then set the window_bits value, this -+ * meant that negative window bits values could be selected which would cause -+ * libpng to write a non-standard PNG file with raw deflate or gzip -+ * compressed IDAT or ancillary chunks. Such files can be read and there is -+ * no warning on read, so this seems like a very bad idea. -+ */ - if (window_bits > 15) -+ { - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); -+ window_bits = 15; -+ } - - else if (window_bits < 8) -+ { - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); -+ window_bits = 8; -+ } - --#ifndef WBITS_8_OK -- /* Avoid libpng bug with 256-byte windows */ -- if (window_bits == 8) -- { -- png_warning(png_ptr, "Compression window is being reset to 512"); -- window_bits = 9; -- } -- --#endif -- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; - png_ptr->zlib_window_bits = window_bits; - } - - void PNGAPI --png_set_compression_method(png_structp png_ptr, int method) -+png_set_compression_method(png_structrp png_ptr, int method) - { - png_debug(1, "in png_set_compression_method"); - - if (png_ptr == NULL) - return; - -+ /* This would produce an invalid PNG file if it worked, but it doesn't and -+ * deflate will fault it, so it is harmless to just warn here. -+ */ - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - -- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; - png_ptr->zlib_method = method; - } - - /* The following were added to libpng-1.5.4 */ - #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - void PNGAPI --png_set_text_compression_level(png_structp png_ptr, int level) -+png_set_text_compression_level(png_structrp png_ptr, int level) - { - png_debug(1, "in png_set_text_compression_level"); - - if (png_ptr == NULL) - return; - -- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; - png_ptr->zlib_text_level = level; - } - - void PNGAPI --png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) -+png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level) - { - png_debug(1, "in png_set_text_compression_mem_level"); - - if (png_ptr == NULL) - return; - -- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; - png_ptr->zlib_text_mem_level = mem_level; - } - - void PNGAPI --png_set_text_compression_strategy(png_structp png_ptr, int strategy) -+png_set_text_compression_strategy(png_structrp png_ptr, int strategy) - { - png_debug(1, "in png_set_text_compression_strategy"); - - if (png_ptr == NULL) - return; - -- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; - png_ptr->zlib_text_strategy = strategy; - } - -@@ -1528,32 +1522,28 @@ - * smaller value of window_bits if it can do so safely. - */ - void PNGAPI --png_set_text_compression_window_bits(png_structp png_ptr, int window_bits) -+png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) - { - if (png_ptr == NULL) - return; - - if (window_bits > 15) -+ { - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); -+ window_bits = 15; -+ } - - else if (window_bits < 8) -+ { - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); -+ window_bits = 8; -+ } - --#ifndef WBITS_8_OK -- /* Avoid libpng bug with 256-byte windows */ -- if (window_bits == 8) -- { -- png_warning(png_ptr, "Text compression window is being reset to 512"); -- window_bits = 9; -- } -- --#endif -- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; - png_ptr->zlib_text_window_bits = window_bits; - } - - void PNGAPI --png_set_text_compression_method(png_structp png_ptr, int method) -+png_set_text_compression_method(png_structrp png_ptr, int method) - { - png_debug(1, "in png_set_text_compression_method"); - -@@ -1563,14 +1553,13 @@ - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - -- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD; - png_ptr->zlib_text_method = method; - } --#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ -+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ - /* end of API added to libpng-1.5.4 */ - - void PNGAPI --png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) -+png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) - { - if (png_ptr == NULL) - return; -@@ -1580,7 +1569,7 @@ - - #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - void PNGAPI --png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr -+png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - write_user_transform_fn) - { - png_debug(1, "in png_set_write_user_transform_fn"); -@@ -1596,88 +1585,899 @@ - - #ifdef PNG_INFO_IMAGE_SUPPORTED - void PNGAPI --png_write_png(png_structp png_ptr, png_infop info_ptr, -+png_write_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, voidp params) - { - if (png_ptr == NULL || info_ptr == NULL) - return; - -+ if ((info_ptr->valid & PNG_INFO_IDAT) == 0) -+ { -+ png_app_error(png_ptr, "no rows for png_write_image to write"); -+ return; -+ } -+ - /* Write the file header information. */ - png_write_info(png_ptr, info_ptr); - - /* ------ these transformations don't touch the info structure ------- */ - -+ /* Invert monochrome pixels */ -+ if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) - #ifdef PNG_WRITE_INVERT_SUPPORTED -- /* Invert monochrome pixels */ -- if (transforms & PNG_TRANSFORM_INVERT_MONO) - png_set_invert_mono(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); - #endif - --#ifdef PNG_WRITE_SHIFT_SUPPORTED - /* Shift the pixels up to a legal bit depth and fill in - * as appropriate to correctly scale the image. - */ -- if ((transforms & PNG_TRANSFORM_SHIFT) -- && (info_ptr->valid & PNG_INFO_sBIT)) -- png_set_shift(png_ptr, &info_ptr->sig_bit); -+ if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -+#ifdef PNG_WRITE_SHIFT_SUPPORTED -+ if ((info_ptr->valid & PNG_INFO_sBIT) != 0) -+ png_set_shift(png_ptr, &info_ptr->sig_bit); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); - #endif - -+ /* Pack pixels into bytes */ -+ if ((transforms & PNG_TRANSFORM_PACKING) != 0) - #ifdef PNG_WRITE_PACK_SUPPORTED -- /* Pack pixels into bytes */ -- if (transforms & PNG_TRANSFORM_PACKING) -- png_set_packing(png_ptr); -+ png_set_packing(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); - #endif - -+ /* Swap location of alpha bytes from ARGB to RGBA */ -+ if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) - #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -- /* Swap location of alpha bytes from ARGB to RGBA */ -- if (transforms & PNG_TRANSFORM_SWAP_ALPHA) - png_set_swap_alpha(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); - #endif - -+ /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into -+ * RGB, note that the code expects the input color type to be G or RGB; no -+ * alpha channel. -+ */ -+ if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| -+ PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) -+ { - #ifdef PNG_WRITE_FILLER_SUPPORTED -- /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ -- if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) -- png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); -+ if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) -+ { -+ if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) -+ png_app_error(png_ptr, -+ "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); - -- else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) -- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); -+ /* Continue if ignored - this is the pre-1.6.10 behavior */ -+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); -+ } -+ -+ else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) -+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); -+#endif -+ } -+ -+ /* Flip BGR pixels to RGB */ -+ if ((transforms & PNG_TRANSFORM_BGR) != 0) -+#ifdef PNG_WRITE_BGR_SUPPORTED -+ png_set_bgr(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); - #endif - --#ifdef PNG_WRITE_BGR_SUPPORTED -- /* Flip BGR pixels to RGB */ -- if (transforms & PNG_TRANSFORM_BGR) -- png_set_bgr(png_ptr); -+ /* Swap bytes of 16-bit files to most significant byte first */ -+ if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) -+#ifdef PNG_WRITE_SWAP_SUPPORTED -+ png_set_swap(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); - #endif - --#ifdef PNG_WRITE_SWAP_SUPPORTED -- /* Swap bytes of 16-bit files to most significant byte first */ -- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) -- png_set_swap(png_ptr); -+ /* Swap bits of 1, 2, 4 bit packed pixel formats */ -+ if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED -+ png_set_packswap(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); - #endif - --#ifdef PNG_WRITE_PACKSWAP_SUPPORTED -- /* Swap bits of 1, 2, 4 bit packed pixel formats */ -- if (transforms & PNG_TRANSFORM_PACKSWAP) -- png_set_packswap(png_ptr); --#endif -- -+ /* Invert the alpha channel from opacity to transparency */ -+ if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) - #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -- /* Invert the alpha channel from opacity to transparency */ -- if (transforms & PNG_TRANSFORM_INVERT_ALPHA) - png_set_invert_alpha(png_ptr); -+#else -+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); - #endif - - /* ----------------------- end of transformations ------------------- */ - - /* Write the bits */ -- if (info_ptr->valid & PNG_INFO_IDAT) -- png_write_image(png_ptr, info_ptr->row_pointers); -+ png_write_image(png_ptr, info_ptr->row_pointers); - - /* It is REQUIRED to call this to finish writing the rest of the file */ - png_write_end(png_ptr, info_ptr); - -- PNG_UNUSED(transforms) /* Quiet compiler warnings */ - PNG_UNUSED(params) - } - #endif --#endif /* PNG_WRITE_SUPPORTED */ -+ -+ -+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -+#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */ -+/* Initialize the write structure - general purpose utility. */ -+static int -+png_image_write_init(png_imagep image) -+{ -+ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, -+ png_safe_error, png_safe_warning); -+ -+ if (png_ptr != NULL) -+ { -+ png_infop info_ptr = png_create_info_struct(png_ptr); -+ -+ if (info_ptr != NULL) -+ { -+ png_controlp control = png_voidcast(png_controlp, -+ png_malloc_warn(png_ptr, (sizeof *control))); -+ -+ if (control != NULL) -+ { -+ memset(control, 0, (sizeof *control)); -+ -+ control->png_ptr = png_ptr; -+ control->info_ptr = info_ptr; -+ control->for_write = 1; -+ -+ image->opaque = control; -+ return 1; -+ } -+ -+ /* Error clean up */ -+ png_destroy_info_struct(png_ptr, &info_ptr); -+ } -+ -+ png_destroy_write_struct(&png_ptr, NULL); -+ } -+ -+ return png_image_error(image, "png_image_write_: out of memory"); -+} -+ -+/* Arguments to png_image_write_main: */ -+typedef struct -+{ -+ /* Arguments: */ -+ png_imagep image; -+ png_const_voidp buffer; -+ png_int_32 row_stride; -+ png_const_voidp colormap; -+ int convert_to_8bit; -+ /* Local variables: */ -+ png_const_voidp first_row; -+ ptrdiff_t row_bytes; -+ png_voidp local_row; -+} png_image_write_control; -+ -+/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to -+ * do any necessary byte swapping. The component order is defined by the -+ * png_image format value. -+ */ -+static int -+png_write_image_16bit(png_voidp argument) -+{ -+ png_image_write_control *display = png_voidcast(png_image_write_control*, -+ argument); -+ png_imagep image = display->image; -+ png_structrp png_ptr = image->opaque->png_ptr; -+ -+ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, -+ display->first_row); -+ png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); -+ png_uint_16p row_end; -+ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; -+ int aindex = 0; -+ png_uint_32 y = image->height; -+ -+ if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED -+ if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) -+ { -+ aindex = -1; -+ ++input_row; /* To point to the first component */ -+ ++output_row; -+ } -+ -+ else -+# endif -+ aindex = channels; -+ } -+ -+ else -+ png_error(png_ptr, "png_write_image: internal call error"); -+ -+ /* Work out the output row end and count over this, note that the increment -+ * above to 'row' means that row_end can actually be beyond the end of the -+ * row; this is correct. -+ */ -+ row_end = output_row + image->width * (channels+1); -+ -+ while (y-- > 0) -+ { -+ png_const_uint_16p in_ptr = input_row; -+ png_uint_16p out_ptr = output_row; -+ -+ while (out_ptr < row_end) -+ { -+ const png_uint_16 alpha = in_ptr[aindex]; -+ png_uint_32 reciprocal = 0; -+ int c; -+ -+ out_ptr[aindex] = alpha; -+ -+ /* Calculate a reciprocal. The correct calculation is simply -+ * component/alpha*65535 << 15. (I.e. 15 bits of precision); this -+ * allows correct rounding by adding .5 before the shift. 'reciprocal' -+ * is only initialized when required. -+ */ -+ if (alpha > 0 && alpha < 65535) -+ reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; -+ -+ c = channels; -+ do /* always at least one channel */ -+ { -+ png_uint_16 component = *in_ptr++; -+ -+ /* The following gives 65535 for an alpha of 0, which is fine, -+ * otherwise if 0/0 is represented as some other value there is more -+ * likely to be a discontinuity which will probably damage -+ * compression when moving from a fully transparent area to a -+ * nearly transparent one. (The assumption here is that opaque -+ * areas tend not to be 0 intensity.) -+ */ -+ if (component >= alpha) -+ component = 65535; -+ -+ /* component<alpha, so component/alpha is less than one and -+ * component*reciprocal is less than 2^31. -+ */ -+ else if (component > 0 && alpha < 65535) -+ { -+ png_uint_32 calc = component * reciprocal; -+ calc += 16384; /* round to nearest */ -+ component = (png_uint_16)(calc >> 15); -+ } -+ -+ *out_ptr++ = component; -+ } -+ while (--c > 0); -+ -+ /* Skip to next component (skip the intervening alpha channel) */ -+ ++in_ptr; -+ ++out_ptr; -+ } -+ -+ png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); -+ input_row += display->row_bytes/(sizeof (png_uint_16)); -+ } -+ -+ return 1; -+} -+ -+/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel -+ * is present it must be removed from the components, the components are then -+ * written in sRGB encoding. No components are added or removed. -+ * -+ * Calculate an alpha reciprocal to reverse pre-multiplication. As above the -+ * calculation can be done to 15 bits of accuracy; however, the output needs to -+ * be scaled in the range 0..255*65535, so include that scaling here. -+ */ -+#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) -+ -+static png_byte -+png_unpremultiply(png_uint_32 component, png_uint_32 alpha, -+ png_uint_32 reciprocal/*from the above macro*/) -+{ -+ /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 -+ * is represented as some other value there is more likely to be a -+ * discontinuity which will probably damage compression when moving from a -+ * fully transparent area to a nearly transparent one. (The assumption here -+ * is that opaque areas tend not to be 0 intensity.) -+ * -+ * There is a rounding problem here; if alpha is less than 128 it will end up -+ * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the -+ * output change for this too. -+ */ -+ if (component >= alpha || alpha < 128) -+ return 255; -+ -+ /* component<alpha, so component/alpha is less than one and -+ * component*reciprocal is less than 2^31. -+ */ -+ else if (component > 0) -+ { -+ /* The test is that alpha/257 (rounded) is less than 255, the first value -+ * that becomes 255 is 65407. -+ * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, -+ * be exact!) [Could also test reciprocal != 0] -+ */ -+ if (alpha < 65407) -+ { -+ component *= reciprocal; -+ component += 64; /* round to nearest */ -+ component >>= 7; -+ } -+ -+ else -+ component *= 255; -+ -+ /* Convert the component to sRGB. */ -+ return (png_byte)PNG_sRGB_FROM_LINEAR(component); -+ } -+ -+ else -+ return 0; -+} -+ -+static int -+png_write_image_8bit(png_voidp argument) -+{ -+ png_image_write_control *display = png_voidcast(png_image_write_control*, -+ argument); -+ png_imagep image = display->image; -+ png_structrp png_ptr = image->opaque->png_ptr; -+ -+ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, -+ display->first_row); -+ png_bytep output_row = png_voidcast(png_bytep, display->local_row); -+ png_uint_32 y = image->height; -+ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; -+ -+ if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ { -+ png_bytep row_end; -+ int aindex; -+ -+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED -+ if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) -+ { -+ aindex = -1; -+ ++input_row; /* To point to the first component */ -+ ++output_row; -+ } -+ -+ else -+# endif -+ aindex = channels; -+ -+ /* Use row_end in place of a loop counter: */ -+ row_end = output_row + image->width * (channels+1); -+ -+ while (y-- > 0) -+ { -+ png_const_uint_16p in_ptr = input_row; -+ png_bytep out_ptr = output_row; -+ -+ while (out_ptr < row_end) -+ { -+ png_uint_16 alpha = in_ptr[aindex]; -+ png_byte alphabyte = (png_byte)PNG_DIV257(alpha); -+ png_uint_32 reciprocal = 0; -+ int c; -+ -+ /* Scale and write the alpha channel. */ -+ out_ptr[aindex] = alphabyte; -+ -+ if (alphabyte > 0 && alphabyte < 255) -+ reciprocal = UNP_RECIPROCAL(alpha); -+ -+ c = channels; -+ do /* always at least one channel */ -+ *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); -+ while (--c > 0); -+ -+ /* Skip to next component (skip the intervening alpha channel) */ -+ ++in_ptr; -+ ++out_ptr; -+ } /* while out_ptr < row_end */ -+ -+ png_write_row(png_ptr, png_voidcast(png_const_bytep, -+ display->local_row)); -+ input_row += display->row_bytes/(sizeof (png_uint_16)); -+ } /* while y */ -+ } -+ -+ else -+ { -+ /* No alpha channel, so the row_end really is the end of the row and it -+ * is sufficient to loop over the components one by one. -+ */ -+ png_bytep row_end = output_row + image->width * channels; -+ -+ while (y-- > 0) -+ { -+ png_const_uint_16p in_ptr = input_row; -+ png_bytep out_ptr = output_row; -+ -+ while (out_ptr < row_end) -+ { -+ png_uint_32 component = *in_ptr++; -+ -+ component *= 255; -+ *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component); -+ } -+ -+ png_write_row(png_ptr, output_row); -+ input_row += display->row_bytes/(sizeof (png_uint_16)); -+ } -+ } -+ -+ return 1; -+} -+ -+static void -+png_image_set_PLTE(png_image_write_control *display) -+{ -+ const png_imagep image = display->image; -+ const void *cmap = display->colormap; -+ const int entries = image->colormap_entries > 256 ? 256 : -+ (int)image->colormap_entries; -+ -+ /* NOTE: the caller must check for cmap != NULL and entries != 0 */ -+ const png_uint_32 format = image->format; -+ const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); -+ -+# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ -+ defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) -+ const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && -+ (format & PNG_FORMAT_FLAG_ALPHA) != 0; -+# else -+# define afirst 0 -+# endif -+ -+# ifdef PNG_FORMAT_BGR_SUPPORTED -+ const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -+# else -+# define bgr 0 -+# endif -+ -+ int i, num_trans; -+ png_color palette[256]; -+ png_byte tRNS[256]; -+ -+ memset(tRNS, 255, (sizeof tRNS)); -+ memset(palette, 0, (sizeof palette)); -+ -+ for (i=num_trans=0; i<entries; ++i) -+ { -+ /* This gets automatically converted to sRGB with reversal of the -+ * pre-multiplication if the color-map has an alpha channel. -+ */ -+ if ((format & PNG_FORMAT_FLAG_LINEAR) != 0) -+ { -+ png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap); -+ -+ entry += i * channels; -+ -+ if ((channels & 1) != 0) /* no alpha */ -+ { -+ if (channels >= 3) /* RGB */ -+ { -+ palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * -+ entry[(2 ^ bgr)]); -+ palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * -+ entry[1]); -+ palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * -+ entry[bgr]); -+ } -+ -+ else /* Gray */ -+ palette[i].blue = palette[i].red = palette[i].green = -+ (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry); -+ } -+ -+ else /* alpha */ -+ { -+ png_uint_16 alpha = entry[afirst ? 0 : channels-1]; -+ png_byte alphabyte = (png_byte)PNG_DIV257(alpha); -+ png_uint_32 reciprocal = 0; -+ -+ /* Calculate a reciprocal, as in the png_write_image_8bit code above -+ * this is designed to produce a value scaled to 255*65535 when -+ * divided by 128 (i.e. asr 7). -+ */ -+ if (alphabyte > 0 && alphabyte < 255) -+ reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; -+ -+ tRNS[i] = alphabyte; -+ if (alphabyte < 255) -+ num_trans = i+1; -+ -+ if (channels >= 3) /* RGB */ -+ { -+ palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], -+ alpha, reciprocal); -+ palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, -+ reciprocal); -+ palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, -+ reciprocal); -+ } -+ -+ else /* gray */ -+ palette[i].blue = palette[i].red = palette[i].green = -+ png_unpremultiply(entry[afirst], alpha, reciprocal); -+ } -+ } -+ -+ else /* Color-map has sRGB values */ -+ { -+ png_const_bytep entry = png_voidcast(png_const_bytep, cmap); -+ -+ entry += i * channels; -+ -+ switch (channels) -+ { -+ case 4: -+ tRNS[i] = entry[afirst ? 0 : 3]; -+ if (tRNS[i] < 255) -+ num_trans = i+1; -+ /* FALL THROUGH */ -+ case 3: -+ palette[i].blue = entry[afirst + (2 ^ bgr)]; -+ palette[i].green = entry[afirst + 1]; -+ palette[i].red = entry[afirst + bgr]; -+ break; -+ -+ case 2: -+ tRNS[i] = entry[1 ^ afirst]; -+ if (tRNS[i] < 255) -+ num_trans = i+1; -+ /* FALL THROUGH */ -+ case 1: -+ palette[i].blue = palette[i].red = palette[i].green = -+ entry[afirst]; -+ break; -+ -+ default: -+ break; -+ } -+ } -+ } -+ -+# ifdef afirst -+# undef afirst -+# endif -+# ifdef bgr -+# undef bgr -+# endif -+ -+ png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, -+ entries); -+ -+ if (num_trans > 0) -+ png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, -+ num_trans, NULL); -+ -+ image->colormap_entries = entries; -+} -+ -+static int -+png_image_write_main(png_voidp argument) -+{ -+ png_image_write_control *display = png_voidcast(png_image_write_control*, -+ argument); -+ png_imagep image = display->image; -+ png_structrp png_ptr = image->opaque->png_ptr; -+ png_inforp info_ptr = image->opaque->info_ptr; -+ png_uint_32 format = image->format; -+ -+ /* The following four ints are actually booleans */ -+ int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); -+ int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ -+ int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); -+ int write_16bit = linear && !colormap && (display->convert_to_8bit == 0); -+ -+# ifdef PNG_BENIGN_ERRORS_SUPPORTED -+ /* Make sure we error out on any bad situation */ -+ png_set_benign_errors(png_ptr, 0/*error*/); -+# endif -+ -+ /* Default the 'row_stride' parameter if required. */ -+ if (display->row_stride == 0) -+ display->row_stride = PNG_IMAGE_ROW_STRIDE(*image); -+ -+ /* Set the required transforms then write the rows in the correct order. */ -+ if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) -+ { -+ if (display->colormap != NULL && image->colormap_entries > 0) -+ { -+ png_uint_32 entries = image->colormap_entries; -+ -+ png_set_IHDR(png_ptr, info_ptr, image->width, image->height, -+ entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), -+ PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, -+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); -+ -+ png_image_set_PLTE(display); -+ } -+ -+ else -+ png_error(image->opaque->png_ptr, -+ "no color-map for color-mapped image"); -+ } -+ -+ else -+ png_set_IHDR(png_ptr, info_ptr, image->width, image->height, -+ write_16bit ? 16 : 8, -+ ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + -+ ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), -+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); -+ -+ /* Counter-intuitively the data transformations must be called *after* -+ * png_write_info, not before as in the read code, but the 'set' functions -+ * must still be called before. Just set the color space information, never -+ * write an interlaced image. -+ */ -+ -+ if (write_16bit != 0) -+ { -+ /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ -+ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); -+ -+ if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) -+ png_set_cHRM_fixed(png_ptr, info_ptr, -+ /* color x y */ -+ /* white */ 31270, 32900, -+ /* red */ 64000, 33000, -+ /* green */ 30000, 60000, -+ /* blue */ 15000, 6000 -+ ); -+ } -+ -+ else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) -+ png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); -+ -+ /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit -+ * space must still be gamma encoded. -+ */ -+ else -+ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); -+ -+ /* Write the file header. */ -+ png_write_info(png_ptr, info_ptr); -+ -+ /* Now set up the data transformations (*after* the header is written), -+ * remove the handled transformations from the 'format' flags for checking. -+ * -+ * First check for a little endian system if writing 16 bit files. -+ */ -+ if (write_16bit != 0) -+ { -+ PNG_CONST png_uint_16 le = 0x0001; -+ -+ if ((*(png_const_bytep) & le) != 0) -+ png_set_swap(png_ptr); -+ } -+ -+# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED -+ if ((format & PNG_FORMAT_FLAG_BGR) != 0) -+ { -+ if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) -+ png_set_bgr(png_ptr); -+ format &= ~PNG_FORMAT_FLAG_BGR; -+ } -+# endif -+ -+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED -+ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) -+ { -+ if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) -+ png_set_swap_alpha(png_ptr); -+ format &= ~PNG_FORMAT_FLAG_AFIRST; -+ } -+# endif -+ -+ /* If there are 16 or fewer color-map entries we wrote a lower bit depth -+ * above, but the application data is still byte packed. -+ */ -+ if (colormap != 0 && image->colormap_entries <= 16) -+ png_set_packing(png_ptr); -+ -+ /* That should have handled all (both) the transforms. */ -+ if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | -+ PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) -+ png_error(png_ptr, "png_write_image: unsupported transformation"); -+ -+ { -+ png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); -+ ptrdiff_t row_bytes = display->row_stride; -+ -+ if (linear != 0) -+ row_bytes *= (sizeof (png_uint_16)); -+ -+ if (row_bytes < 0) -+ row += (image->height-1) * (-row_bytes); -+ -+ display->first_row = row; -+ display->row_bytes = row_bytes; -+ } -+ -+ /* Apply 'fast' options if the flag is set. */ -+ if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0) -+ { -+ png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS); -+ /* NOTE: determined by experiment using pngstest, this reflects some -+ * balance between the time to write the image once and the time to read -+ * it about 50 times. The speed-up in pngstest was about 10-20% of the -+ * total (user) time on a heavily loaded system. -+ */ -+ png_set_compression_level(png_ptr, 3); -+ } -+ -+ /* Check for the cases that currently require a pre-transform on the row -+ * before it is written. This only applies when the input is 16-bit and -+ * either there is an alpha channel or it is converted to 8-bit. -+ */ -+ if ((linear != 0 && alpha != 0 ) || -+ (colormap == 0 && display->convert_to_8bit != 0)) -+ { -+ png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, -+ png_get_rowbytes(png_ptr, info_ptr))); -+ int result; -+ -+ display->local_row = row; -+ if (write_16bit != 0) -+ result = png_safe_execute(image, png_write_image_16bit, display); -+ else -+ result = png_safe_execute(image, png_write_image_8bit, display); -+ display->local_row = NULL; -+ -+ png_free(png_ptr, row); -+ -+ /* Skip the 'write_end' on error: */ -+ if (result == 0) -+ return 0; -+ } -+ -+ /* Otherwise this is the case where the input is in a format currently -+ * supported by the rest of the libpng write code; call it directly. -+ */ -+ else -+ { -+ png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); -+ ptrdiff_t row_bytes = display->row_bytes; -+ png_uint_32 y = image->height; -+ -+ while (y-- > 0) -+ { -+ png_write_row(png_ptr, row); -+ row += row_bytes; -+ } -+ } -+ -+ png_write_end(png_ptr, info_ptr); -+ return 1; -+} -+ -+int PNGAPI -+png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, -+ const void *buffer, png_int_32 row_stride, const void *colormap) -+{ -+ /* Write the image to the given (FILE*). */ -+ if (image != NULL && image->version == PNG_IMAGE_VERSION) -+ { -+ if (file != NULL) -+ { -+ if (png_image_write_init(image) != 0) -+ { -+ png_image_write_control display; -+ int result; -+ -+ /* This is slightly evil, but png_init_io doesn't do anything other -+ * than this and we haven't changed the standard IO functions so -+ * this saves a 'safe' function. -+ */ -+ image->opaque->png_ptr->io_ptr = file; -+ -+ memset(&display, 0, (sizeof display)); -+ display.image = image; -+ display.buffer = buffer; -+ display.row_stride = row_stride; -+ display.colormap = colormap; -+ display.convert_to_8bit = convert_to_8bit; -+ -+ result = png_safe_execute(image, png_image_write_main, &display); -+ png_image_free(image); -+ return result; -+ } -+ -+ else -+ return 0; -+ } -+ -+ else -+ return png_image_error(image, -+ "png_image_write_to_stdio: invalid argument"); -+ } -+ -+ else if (image != NULL) -+ return png_image_error(image, -+ "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); -+ -+ else -+ return 0; -+} -+ -+int PNGAPI -+png_image_write_to_file(png_imagep image, const char *file_name, -+ int convert_to_8bit, const void *buffer, png_int_32 row_stride, -+ const void *colormap) -+{ -+ /* Write the image to the named file. */ -+ if (image != NULL && image->version == PNG_IMAGE_VERSION) -+ { -+ if (file_name != NULL) -+ { -+ FILE *fp = fopen(file_name, "wb"); -+ -+ if (fp != NULL) -+ { -+ if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, -+ row_stride, colormap) != 0) -+ { -+ int error; /* from fflush/fclose */ -+ -+ /* Make sure the file is flushed correctly. */ -+ if (fflush(fp) == 0 && ferror(fp) == 0) -+ { -+ if (fclose(fp) == 0) -+ return 1; -+ -+ error = errno; /* from fclose */ -+ } -+ -+ else -+ { -+ error = errno; /* from fflush or ferror */ -+ (void)fclose(fp); -+ } -+ -+ (void)remove(file_name); -+ /* The image has already been cleaned up; this is just used to -+ * set the error (because the original write succeeded). -+ */ -+ return png_image_error(image, strerror(error)); -+ } -+ -+ else -+ { -+ /* Clean up: just the opened file. */ -+ (void)fclose(fp); -+ (void)remove(file_name); -+ return 0; -+ } -+ } -+ -+ else -+ return png_image_error(image, strerror(errno)); -+ } -+ -+ else -+ return png_image_error(image, -+ "png_image_write_to_file: invalid argument"); -+ } -+ -+ else if (image != NULL) -+ return png_image_error(image, -+ "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); -+ -+ else -+ return 0; -+} -+#endif /* STDIO */ -+#endif /* SIMPLIFIED_WRITE */ -+#endif /* WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pngwtran.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngwtran.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -42,90 +42,14 @@ - #include "pngpriv.h" - - #ifdef PNG_WRITE_SUPPORTED -- - #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED --/* Transform the data according to the user's wishes. The order of -- * transformations is significant. -- */ --void /* PRIVATE */ --png_do_write_transformations(png_structp png_ptr) --{ -- png_debug(1, "in png_do_write_transformations"); -- -- if (png_ptr == NULL) -- return; -- --#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -- if (png_ptr->transformations & PNG_USER_TRANSFORM) -- if (png_ptr->write_user_transform_fn != NULL) -- (*(png_ptr->write_user_transform_fn)) /* User write transform -- function */ -- (png_ptr, /* png_ptr */ -- &(png_ptr->row_info), /* row_info: */ -- /* png_uint_32 width; width of row */ -- /* png_size_t rowbytes; number of bytes in row */ -- /* png_byte color_type; color type of pixels */ -- /* png_byte bit_depth; bit depth of samples */ -- /* png_byte channels; number of channels (1-4) */ -- /* png_byte pixel_depth; bits per pixel (depth*channels) */ -- png_ptr->row_buf + 1); /* start of pixel data for row */ --#endif -- --#ifdef PNG_WRITE_FILLER_SUPPORTED -- if (png_ptr->transformations & PNG_FILLER) -- png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, -- !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); --#endif -- --#ifdef PNG_WRITE_PACKSWAP_SUPPORTED -- if (png_ptr->transformations & PNG_PACKSWAP) -- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_WRITE_PACK_SUPPORTED -- if (png_ptr->transformations & PNG_PACK) -- png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, -- (png_uint_32)png_ptr->bit_depth); --#endif -- --#ifdef PNG_WRITE_SWAP_SUPPORTED -- if (png_ptr->transformations & PNG_SWAP_BYTES) -- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_WRITE_SHIFT_SUPPORTED -- if (png_ptr->transformations & PNG_SHIFT) -- png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, -- &(png_ptr->shift)); --#endif -- --#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -- if (png_ptr->transformations & PNG_SWAP_ALPHA) -- png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -- if (png_ptr->transformations & PNG_INVERT_ALPHA) -- png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_WRITE_BGR_SUPPORTED -- if (png_ptr->transformations & PNG_BGR) -- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif -- --#ifdef PNG_WRITE_INVERT_SUPPORTED -- if (png_ptr->transformations & PNG_INVERT_MONO) -- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); --#endif --} - - #ifdef PNG_WRITE_PACK_SUPPORTED - /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The - * row_info bit depth should be 8 (one pixel per byte). The channels - * should be 1 (this only happens on grayscale and paletted images). - */ --void /* PRIVATE */ -+static void - png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) - { - png_debug(1, "in png_do_pack"); -@@ -270,7 +194,7 @@ - * would pass 3 as bit_depth, and this routine would translate the - * data to 0 to 15. - */ --void /* PRIVATE */ -+static void - png_do_shift(png_row_infop row_info, png_bytep row, - png_const_color_8p bit_depth) - { -@@ -281,7 +205,7 @@ - int shift_start[4], shift_dec[4]; - int channels = 0; - -- if (row_info->color_type & PNG_COLOR_MASK_COLOR) -+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - shift_start[channels] = row_info->bit_depth - bit_depth->red; - shift_dec[channels] = bit_depth->red; -@@ -303,7 +227,7 @@ - channels++; - } - -- if (row_info->color_type & PNG_COLOR_MASK_ALPHA) -+ if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - shift_start[channels] = row_info->bit_depth - bit_depth->alpha; - shift_dec[channels] = bit_depth->alpha; -@@ -315,7 +239,7 @@ - { - png_bytep bp = row; - png_size_t i; -- png_byte mask; -+ unsigned int mask; - png_size_t row_bytes = row_info->rowbytes; - - if (bit_depth->gray == 1 && row_info->bit_depth == 2) -@@ -329,20 +253,22 @@ - - for (i = 0; i < row_bytes; i++, bp++) - { -- png_uint_16 v; - int j; -+ unsigned int v, out; - - v = *bp; -- *bp = 0; -+ out = 0; - - for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) - { - if (j > 0) -- *bp |= (png_byte)((v << j) & 0xff); -+ out |= v << j; - - else -- *bp |= (png_byte)((v >> (-j)) & mask); -+ out |= (v >> (-j)) & mask; - } -+ -+ *bp = (png_byte)(out & 0xff); - } - } - -@@ -355,21 +281,23 @@ - for (i = 0; i < istop; i++, bp++) - { - -- png_uint_16 v; -+ const unsigned int c = i%channels; - int j; -- int c = (int)(i%channels); -+ unsigned int v, out; - - v = *bp; -- *bp = 0; -+ out = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) -- *bp |= (png_byte)((v << j) & 0xff); -+ out |= v << j; - - else -- *bp |= (png_byte)((v >> (-j)) & 0xff); -+ out |= v >> (-j); - } -+ -+ *bp = (png_byte)(out & 0xff); - } - } - -@@ -381,22 +309,22 @@ - - for (bp = row, i = 0; i < istop; i++) - { -- int c = (int)(i%channels); -- png_uint_16 value, v; -+ const unsigned int c = i%channels; - int j; -+ unsigned int value, v; - -- v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); -+ v = png_get_uint_16(bp); - value = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) -- value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); -+ value |= v << j; - - else -- value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); -+ value |= v >> (-j); - } -- *bp++ = (png_byte)(value >> 8); -+ *bp++ = (png_byte)((value >> 8) & 0xff); - *bp++ = (png_byte)(value & 0xff); - } - } -@@ -405,7 +333,7 @@ - #endif - - #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED --void /* PRIVATE */ -+static void - png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) - { - png_debug(1, "in png_do_write_swap_alpha"); -@@ -453,7 +381,7 @@ - *(dp++) = save[1]; - } - } --#endif /* PNG_WRITE_16BIT_SUPPORTED */ -+#endif /* WRITE_16BIT */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) -@@ -492,14 +420,14 @@ - *(dp++) = save[1]; - } - } --#endif /* PNG_WRITE_16BIT_SUPPORTED */ -+#endif /* WRITE_16BIT */ - } - } - } - #endif - - #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED --void /* PRIVATE */ -+static void - png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) - { - png_debug(1, "in png_do_write_invert_alpha"); -@@ -549,7 +477,7 @@ - *(dp++) = (png_byte)(255 - *(sp++)); - } - } --#endif /* PNG_WRITE_16BIT_SUPPORTED */ -+#endif /* WRITE_16BIT */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) -@@ -587,75 +515,88 @@ - *(dp++) = (png_byte)(255 - *(sp++)); - } - } --#endif /* PNG_WRITE_16BIT_SUPPORTED */ -+#endif /* WRITE_16BIT */ - } - } - } - #endif --#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ - --#ifdef PNG_MNG_FEATURES_SUPPORTED --/* Undoes intrapixel differencing */ -+/* Transform the data according to the user's wishes. The order of -+ * transformations is significant. -+ */ - void /* PRIVATE */ --png_do_write_intrapixel(png_row_infop row_info, png_bytep row) -+png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) - { -- png_debug(1, "in png_do_write_intrapixel"); -+ png_debug(1, "in png_do_write_transformations"); - -- if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) -- { -- int bytes_per_pixel; -- png_uint_32 row_width = row_info->width; -- if (row_info->bit_depth == 8) -- { -- png_bytep rp; -- png_uint_32 i; -+ if (png_ptr == NULL) -+ return; - -- if (row_info->color_type == PNG_COLOR_TYPE_RGB) -- bytes_per_pixel = 3; -+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) -+ if (png_ptr->write_user_transform_fn != NULL) -+ (*(png_ptr->write_user_transform_fn)) /* User write transform -+ function */ -+ (png_ptr, /* png_ptr */ -+ row_info, /* row_info: */ -+ /* png_uint_32 width; width of row */ -+ /* png_size_t rowbytes; number of bytes in row */ -+ /* png_byte color_type; color type of pixels */ -+ /* png_byte bit_depth; bit depth of samples */ -+ /* png_byte channels; number of channels (1-4) */ -+ /* png_byte pixel_depth; bits per pixel (depth*channels) */ -+ png_ptr->row_buf + 1); /* start of pixel data for row */ -+#endif - -- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -- bytes_per_pixel = 4; -+#ifdef PNG_WRITE_FILLER_SUPPORTED -+ if ((png_ptr->transformations & PNG_FILLER) != 0) -+ png_do_strip_channel(row_info, png_ptr->row_buf + 1, -+ !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); -+#endif - -- else -- return; -+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED -+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) -+ png_do_packswap(row_info, png_ptr->row_buf + 1); -+#endif - -- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -- { -- *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); -- *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); -- } -- } -+#ifdef PNG_WRITE_PACK_SUPPORTED -+ if ((png_ptr->transformations & PNG_PACK) != 0) -+ png_do_pack(row_info, png_ptr->row_buf + 1, -+ (png_uint_32)png_ptr->bit_depth); -+#endif - --#ifdef PNG_WRITE_16BIT_SUPPORTED -- else if (row_info->bit_depth == 16) -- { -- png_bytep rp; -- png_uint_32 i; -+#ifdef PNG_WRITE_SWAP_SUPPORTED -+# ifdef PNG_16BIT_SUPPORTED -+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) -+ png_do_swap(row_info, png_ptr->row_buf + 1); -+# endif -+#endif - -- if (row_info->color_type == PNG_COLOR_TYPE_RGB) -- bytes_per_pixel = 6; -+#ifdef PNG_WRITE_SHIFT_SUPPORTED -+ if ((png_ptr->transformations & PNG_SHIFT) != 0) -+ png_do_shift(row_info, png_ptr->row_buf + 1, -+ &(png_ptr->shift)); -+#endif - -- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) -- bytes_per_pixel = 8; -+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -+ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) -+ png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); -+#endif - -- else -- return; -+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) -+ png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); -+#endif - -- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) -- { -- png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); -- png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); -- png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); -- png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); -- png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); -- *(rp ) = (png_byte)((red >> 8) & 0xff); -- *(rp + 1) = (png_byte)(red & 0xff); -- *(rp + 4) = (png_byte)((blue >> 8) & 0xff); -- *(rp + 5) = (png_byte)(blue & 0xff); -- } -- } --#endif /* PNG_WRITE_16BIT_SUPPORTED */ -- } -+#ifdef PNG_WRITE_BGR_SUPPORTED -+ if ((png_ptr->transformations & PNG_BGR) != 0) -+ png_do_bgr(row_info, png_ptr->row_buf + 1); -+#endif -+ -+#ifdef PNG_WRITE_INVERT_SUPPORTED -+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) -+ png_do_invert(row_info, png_ptr->row_buf + 1); -+#endif - } --#endif /* PNG_MNG_FEATURES_SUPPORTED */ --#endif /* PNG_WRITE_SUPPORTED */ -+#endif /* WRITE_TRANSFORMS */ -+#endif /* WRITE */ ---- ./jdk/src/share/native/sun/awt/libpng/pngwutil.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/awt/libpng/pngwutil.c Thu Feb 05 13:00:26 2015 +0100 -@@ -29,8 +29,8 @@ - * However, the following notice accompanied the original version of this - * file and, per its terms, should not be removed: - * -- * Last changed in libpng 1.5.4 [July 7, 2011] -- * Copyright (c) 1998-2011 Glenn Randers-Pehrson -+ * Last changed in libpng 1.6.15 [November 20, 2014] -+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) - * -@@ -57,23 +57,6 @@ - buf[3] = (png_byte)(i & 0xff); - } - --#ifdef PNG_SAVE_INT_32_SUPPORTED --/* The png_save_int_32 function assumes integers are stored in two's -- * complement format. If this isn't the case, then this routine needs to -- * be modified to write data in two's complement format. Note that, -- * the following works correctly even if png_int_32 has more than 32 bits -- * (compare the more complex code required on read for sign extention.) -- */ --void PNGAPI --png_save_int_32(png_bytep buf, png_int_32 i) --{ -- buf[0] = (png_byte)((i >> 24) & 0xff); -- buf[1] = (png_byte)((i >> 16) & 0xff); -- buf[2] = (png_byte)((i >> 8) & 0xff); -- buf[3] = (png_byte)(i & 0xff); --} --#endif -- - /* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. -@@ -93,7 +76,7 @@ - * bytes have already been written. - */ - void PNGAPI --png_write_sig(png_structp png_ptr) -+png_write_sig(png_structrp png_ptr) - { - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - -@@ -110,6 +93,104 @@ - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; - } - -+/* Write the start of a PNG chunk. The type is the chunk type. -+ * The total_length is the sum of the lengths of all the data you will be -+ * passing in png_write_chunk_data(). -+ */ -+static void -+png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, -+ png_uint_32 length) -+{ -+ png_byte buf[8]; -+ -+#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) -+ PNG_CSTRING_FROM_CHUNK(buf, chunk_name); -+ png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); -+#endif -+ -+ if (png_ptr == NULL) -+ return; -+ -+#ifdef PNG_IO_STATE_SUPPORTED -+ /* Inform the I/O callback that the chunk header is being written. -+ * PNG_IO_CHUNK_HDR requires a single I/O call. -+ */ -+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; -+#endif -+ -+ /* Write the length and the chunk name */ -+ png_save_uint_32(buf, length); -+ png_save_uint_32(buf + 4, chunk_name); -+ png_write_data(png_ptr, buf, 8); -+ -+ /* Put the chunk name into png_ptr->chunk_name */ -+ png_ptr->chunk_name = chunk_name; -+ -+ /* Reset the crc and run it over the chunk name */ -+ png_reset_crc(png_ptr); -+ -+ png_calculate_crc(png_ptr, buf + 4, 4); -+ -+#ifdef PNG_IO_STATE_SUPPORTED -+ /* Inform the I/O callback that chunk data will (possibly) be written. -+ * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. -+ */ -+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; -+#endif -+} -+ -+void PNGAPI -+png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, -+ png_uint_32 length) -+{ -+ png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); -+} -+ -+/* Write the data of a PNG chunk started with png_write_chunk_header(). -+ * Note that multiple calls to this function are allowed, and that the -+ * sum of the lengths from these calls *must* add up to the total_length -+ * given to png_write_chunk_header(). -+ */ -+void PNGAPI -+png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, -+ png_size_t length) -+{ -+ /* Write the data, and run the CRC over it */ -+ if (png_ptr == NULL) -+ return; -+ -+ if (data != NULL && length > 0) -+ { -+ png_write_data(png_ptr, data, length); -+ -+ /* Update the CRC after writing the data, -+ * in case the user I/O routine alters it. -+ */ -+ png_calculate_crc(png_ptr, data, length); -+ } -+} -+ -+/* Finish a chunk started with png_write_chunk_header(). */ -+void PNGAPI -+png_write_chunk_end(png_structrp png_ptr) -+{ -+ png_byte buf[4]; -+ -+ if (png_ptr == NULL) return; -+ -+#ifdef PNG_IO_STATE_SUPPORTED -+ /* Inform the I/O callback that the chunk CRC is being written. -+ * PNG_IO_CHUNK_CRC requires a single I/O function call. -+ */ -+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; -+#endif -+ -+ /* Write the crc in a single operation */ -+ png_save_uint_32(buf, png_ptr->crc); -+ -+ png_write_data(png_ptr, buf, (png_size_t)4); -+} -+ - /* Write a PNG chunk all at once. The type is an array of ASCII characters - * representing the chunk name. The array must be at least 4 bytes in - * length, and does not need to be null terminated. To be safe, pass the -@@ -119,569 +200,592 @@ - * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() - * functions instead. - */ --void PNGAPI --png_write_chunk(png_structp png_ptr, png_const_bytep chunk_name, -+static void -+png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, - png_const_bytep data, png_size_t length) - { - if (png_ptr == NULL) - return; - -- png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); -- png_write_chunk_data(png_ptr, data, (png_size_t)length); -+ /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ -+ if (length > PNG_UINT_31_MAX) -+ png_error(png_ptr, "length exceeds PNG maximum"); -+ -+ png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); -+ png_write_chunk_data(png_ptr, data, length); - png_write_chunk_end(png_ptr); - } - --/* Write the start of a PNG chunk. The type is the chunk type. -- * The total_length is the sum of the lengths of all the data you will be -- * passing in png_write_chunk_data(). -+/* This is the API that calls the internal function above. */ -+void PNGAPI -+png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, -+ png_const_bytep data, png_size_t length) -+{ -+ png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, -+ length); -+} -+ -+/* This is used below to find the size of an image to pass to png_deflate_claim, -+ * so it only needs to be accurate if the size is less than 16384 bytes (the -+ * point at which a lower LZ window size can be used.) - */ --void PNGAPI --png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, -- png_uint_32 length) -+static png_alloc_size_t -+png_image_size(png_structrp png_ptr) - { -- png_byte buf[8]; -- -- png_debug2(0, "Writing %s chunk, length = %lu", chunk_name, -- (unsigned long)length); -- -- if (png_ptr == NULL) -- return; -- --#ifdef PNG_IO_STATE_SUPPORTED -- /* Inform the I/O callback that the chunk header is being written. -- * PNG_IO_CHUNK_HDR requires a single I/O call. -+ /* Only return sizes up to the maximum of a png_uint_32; do this by limiting -+ * the width and height used to 15 bits. - */ -- png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; --#endif -- -- /* Write the length and the chunk name */ -- png_save_uint_32(buf, length); -- png_memcpy(buf + 4, chunk_name, 4); -- png_write_data(png_ptr, buf, (png_size_t)8); -- -- /* Put the chunk name into png_ptr->chunk_name */ -- png_memcpy(png_ptr->chunk_name, chunk_name, 4); -- -- /* Reset the crc and run it over the chunk name */ -- png_reset_crc(png_ptr); -- -- png_calculate_crc(png_ptr, chunk_name, 4); -- --#ifdef PNG_IO_STATE_SUPPORTED -- /* Inform the I/O callback that chunk data will (possibly) be written. -- * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. -+ png_uint_32 h = png_ptr->height; -+ -+ if (png_ptr->rowbytes < 32768 && h < 32768) -+ { -+ if (png_ptr->interlaced != 0) -+ { -+ /* Interlacing makes the image larger because of the replication of -+ * both the filter byte and the padding to a byte boundary. -+ */ -+ png_uint_32 w = png_ptr->width; -+ unsigned int pd = png_ptr->pixel_depth; -+ png_alloc_size_t cb_base; -+ int pass; -+ -+ for (cb_base=0, pass=0; pass<=6; ++pass) -+ { -+ png_uint_32 pw = PNG_PASS_COLS(w, pass); -+ -+ if (pw > 0) -+ cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); -+ } -+ -+ return cb_base; -+ } -+ -+ else -+ return (png_ptr->rowbytes+1) * h; -+ } -+ -+ else -+ return 0xffffffffU; -+} -+ -+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -+ /* This is the code to hack the first two bytes of the deflate stream (the -+ * deflate header) to correct the windowBits value to match the actual data -+ * size. Note that the second argument is the *uncompressed* size but the -+ * first argument is the *compressed* data (and it must be deflate -+ * compressed.) - */ -- png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; --#endif --} -- --/* Write the data of a PNG chunk started with png_write_chunk_start(). -- * Note that multiple calls to this function are allowed, and that the -- * sum of the lengths from these calls *must* add up to the total_length -- * given to png_write_chunk_start(). -- */ --void PNGAPI --png_write_chunk_data(png_structp png_ptr, png_const_bytep data, -- png_size_t length) -+static void -+optimize_cmf(png_bytep data, png_alloc_size_t data_size) - { -- /* Write the data, and run the CRC over it */ -- if (png_ptr == NULL) -- return; -- -- if (data != NULL && length > 0) -+ /* Optimize the CMF field in the zlib stream. The resultant zlib stream is -+ * still compliant to the stream specification. -+ */ -+ if (data_size <= 16384) /* else windowBits must be 15 */ - { -- png_write_data(png_ptr, data, length); -- -- /* Update the CRC after writing the data, -- * in case that the user I/O routine alters it. -- */ -- png_calculate_crc(png_ptr, data, length); -+ unsigned int z_cmf = data[0]; /* zlib compression method and flags */ -+ -+ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) -+ { -+ unsigned int z_cinfo; -+ unsigned int half_z_window_size; -+ -+ z_cinfo = z_cmf >> 4; -+ half_z_window_size = 1U << (z_cinfo + 7); -+ -+ if (data_size <= half_z_window_size) /* else no change */ -+ { -+ unsigned int tmp; -+ -+ do -+ { -+ half_z_window_size >>= 1; -+ --z_cinfo; -+ } -+ while (z_cinfo > 0 && data_size <= half_z_window_size); -+ -+ z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); -+ -+ data[0] = (png_byte)z_cmf; -+ tmp = data[1] & 0xe0; -+ tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; -+ data[1] = (png_byte)tmp; -+ } -+ } - } - } -- --/* Finish a chunk started with png_write_chunk_start(). */ --void PNGAPI --png_write_chunk_end(png_structp png_ptr) -+#endif /* WRITE_OPTIMIZE_CMF */ -+ -+/* Initialize the compressor for the appropriate type of compression. */ -+static int -+png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, -+ png_alloc_size_t data_size) - { -- png_byte buf[4]; -- -- if (png_ptr == NULL) return; -- --#ifdef PNG_IO_STATE_SUPPORTED -- /* Inform the I/O callback that the chunk CRC is being written. -- * PNG_IO_CHUNK_CRC requires a single I/O function call. -- */ -- png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; -+ if (png_ptr->zowner != 0) -+ { -+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) -+ char msg[64]; -+ -+ PNG_STRING_FROM_CHUNK(msg, owner); -+ msg[4] = ':'; -+ msg[5] = ' '; -+ PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); -+ /* So the message that results is "<chunk> using zstream"; this is an -+ * internal error, but is very useful for debugging. i18n requirements -+ * are minimal. -+ */ -+ (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); - #endif -- -- /* Write the crc in a single operation */ -- png_save_uint_32(buf, png_ptr->crc); -- -- png_write_data(png_ptr, buf, (png_size_t)4); --} -- --/* Initialize the compressor for the appropriate type of compression. */ --static void --png_zlib_claim(png_structp png_ptr, png_uint_32 state) --{ -- if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE)) -+#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC -+ png_warning(png_ptr, msg); -+ -+ /* Attempt sane error recovery */ -+ if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ -+ { -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); -+ return Z_STREAM_ERROR; -+ } -+ -+ png_ptr->zowner = 0; -+#else -+ png_error(png_ptr, msg); -+#endif -+ } -+ - { -- /* If already initialized for 'state' do not re-init. */ -- if (png_ptr->zlib_state != state) -+ int level = png_ptr->zlib_level; -+ int method = png_ptr->zlib_method; -+ int windowBits = png_ptr->zlib_window_bits; -+ int memLevel = png_ptr->zlib_mem_level; -+ int strategy; /* set below */ -+ int ret; /* zlib return code */ -+ -+ if (owner == png_IDAT) - { -- int ret = Z_OK; -- png_const_charp who = "-"; -- -- /* If actually initialized for another state do a deflateEnd. */ -- if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) -+ if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) -+ strategy = png_ptr->zlib_strategy; -+ -+ else if (png_ptr->do_filter != PNG_FILTER_NONE) -+ strategy = PNG_Z_DEFAULT_STRATEGY; -+ -+ else -+ strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; -+ } -+ -+ else -+ { -+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -+ level = png_ptr->zlib_text_level; -+ method = png_ptr->zlib_text_method; -+ windowBits = png_ptr->zlib_text_window_bits; -+ memLevel = png_ptr->zlib_text_mem_level; -+ strategy = png_ptr->zlib_text_strategy; -+#else -+ /* If customization is not supported the values all come from the -+ * IDAT values except for the strategy, which is fixed to the -+ * default. (This is the pre-1.6.0 behavior too, although it was -+ * implemented in a very different way.) -+ */ -+ strategy = Z_DEFAULT_STRATEGY; -+#endif -+ } -+ -+ /* Adjust 'windowBits' down if larger than 'data_size'; to stop this -+ * happening just pass 32768 as the data_size parameter. Notice that zlib -+ * requires an extra 262 bytes in the window in addition to the data to be -+ * able to see the whole of the data, so if data_size+262 takes us to the -+ * next windowBits size we need to fix up the value later. (Because even -+ * though deflate needs the extra window, inflate does not!) -+ */ -+ if (data_size <= 16384) -+ { -+ /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to -+ * work round a Microsoft Visual C misbehavior which, contrary to C-90, -+ * widens the result of the following shift to 64-bits if (and, -+ * apparently, only if) it is used in a test. -+ */ -+ unsigned int half_window_size = 1U << (windowBits-1); -+ -+ while (data_size + 262 <= half_window_size) - { -- ret = deflateEnd(&png_ptr->zstream); -- who = "end"; -- png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; -- } -- -- /* zlib itself detects an incomplete state on deflateEnd */ -- if (ret == Z_OK) switch (state) -- { --# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -- case PNG_ZLIB_FOR_TEXT: -- ret = deflateInit2(&png_ptr->zstream, -- png_ptr->zlib_text_level, png_ptr->zlib_text_method, -- png_ptr->zlib_text_window_bits, -- png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy); -- who = "text"; -- break; --# endif -- -- case PNG_ZLIB_FOR_IDAT: -- ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, -- png_ptr->zlib_method, png_ptr->zlib_window_bits, -- png_ptr->zlib_mem_level, png_ptr->zlib_strategy); -- who = "IDAT"; -- break; -- -- default: -- png_error(png_ptr, "invalid zlib state"); -- } -- -- if (ret == Z_OK) -- png_ptr->zlib_state = state; -- -- else /* an error in deflateEnd or deflateInit2 */ -- { -- size_t pos = 0; -- char msg[64]; -- -- pos = png_safecat(msg, sizeof msg, pos, -- "zlib failed to initialize compressor ("); -- pos = png_safecat(msg, sizeof msg, pos, who); -- -- switch (ret) -- { -- case Z_VERSION_ERROR: -- pos = png_safecat(msg, sizeof msg, pos, ") version error"); -- break; -- -- case Z_STREAM_ERROR: -- pos = png_safecat(msg, sizeof msg, pos, ") stream error"); -- break; -- -- case Z_MEM_ERROR: -- pos = png_safecat(msg, sizeof msg, pos, ") memory error"); -- break; -- -- default: -- pos = png_safecat(msg, sizeof msg, pos, ") unknown error"); -- break; -- } -- -- png_error(png_ptr, msg); -+ half_window_size >>= 1; -+ --windowBits; - } - } - -- /* Here on success, claim the zstream: */ -- png_ptr->zlib_state |= PNG_ZLIB_IN_USE; -+ /* Check against the previous initialized values, if any. */ -+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 && -+ (png_ptr->zlib_set_level != level || -+ png_ptr->zlib_set_method != method || -+ png_ptr->zlib_set_window_bits != windowBits || -+ png_ptr->zlib_set_mem_level != memLevel || -+ png_ptr->zlib_set_strategy != strategy)) -+ { -+ if (deflateEnd(&png_ptr->zstream) != Z_OK) -+ png_warning(png_ptr, "deflateEnd failed (ignored)"); -+ -+ png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; -+ } -+ -+ /* For safety clear out the input and output pointers (currently zlib -+ * doesn't use them on Init, but it might in the future). -+ */ -+ png_ptr->zstream.next_in = NULL; -+ png_ptr->zstream.avail_in = 0; -+ png_ptr->zstream.next_out = NULL; -+ png_ptr->zstream.avail_out = 0; -+ -+ /* Now initialize if required, setting the new parameters, otherwise just -+ * to a simple reset to the previous parameters. -+ */ -+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) -+ ret = deflateReset(&png_ptr->zstream); -+ -+ else -+ { -+ ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, -+ memLevel, strategy); -+ -+ if (ret == Z_OK) -+ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; -+ } -+ -+ /* The return code is from either deflateReset or deflateInit2; they have -+ * pretty much the same set of error codes. -+ */ -+ if (ret == Z_OK) -+ png_ptr->zowner = owner; -+ -+ else -+ png_zstream_error(png_ptr, ret); -+ -+ return ret; - } -- -- else -- png_error(png_ptr, "zstream already in use (internal error)"); - } - --/* The opposite: release the stream. It is also reset, this API will warn on -- * error but will not fail. -- */ --static void --png_zlib_release(png_structp png_ptr) -+/* Clean up (or trim) a linked list of compression buffers. */ -+void /* PRIVATE */ -+png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) - { -- if (png_ptr->zlib_state & PNG_ZLIB_IN_USE) -+ png_compression_bufferp list = *listp; -+ -+ if (list != NULL) - { -- int ret = deflateReset(&png_ptr->zstream); -- -- png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE; -- -- if (ret != Z_OK) -+ *listp = NULL; -+ -+ do - { -- png_const_charp err; -- PNG_WARNING_PARAMETERS(p) -- -- switch (ret) -- { -- case Z_VERSION_ERROR: -- err = "version"; -- break; -- -- case Z_STREAM_ERROR: -- err = "stream"; -- break; -- -- case Z_MEM_ERROR: -- err = "memory"; -- break; -- -- default: -- err = "unknown"; -- break; -- } -- -- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret); -- png_warning_parameter(p, 2, err); -- -- if (png_ptr->zstream.msg) -- err = png_ptr->zstream.msg; -- else -- err = "[no zlib message]"; -- -- png_warning_parameter(p, 3, err); -- -- png_formatted_warning(png_ptr, p, -- "zlib failed to reset compressor: @1(@2): @3"); -+ png_compression_bufferp next = list->next; -+ -+ png_free(png_ptr, list); -+ list = next; - } -+ while (list != NULL); - } -- -- else -- png_warning(png_ptr, "zstream not in use (internal error)"); - } - - #ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED - /* This pair of functions encapsulates the operation of (a) compressing a - * text string, and (b) issuing it later as a series of chunk data writes. - * The compression_state structure is shared context for these functions -- * set up by the caller in order to make the whole mess thread-safe. -+ * set up by the caller to allow access to the relevant local variables. -+ * -+ * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size -+ * temporary buffers. From 1.6.0 it is retained in png_struct so that it will -+ * be correctly freed in the event of a write error (previous implementations -+ * just leaked memory.) - */ -- - typedef struct - { -- png_const_bytep input; /* The uncompressed input data */ -- png_size_t input_len; /* Its length */ -- int num_output_ptr; /* Number of output pointers used */ -- int max_output_ptr; /* Size of output_ptr */ -- png_bytep *output_ptr; /* Array of pointers to output */ -+ png_const_bytep input; /* The uncompressed input data */ -+ png_alloc_size_t input_len; /* Its length */ -+ png_uint_32 output_len; /* Final compressed length */ -+ png_byte output[1024]; /* First block of output */ - } compression_state; - --/* Compress given text into storage in the png_ptr structure */ --static int /* PRIVATE */ --png_text_compress(png_structp png_ptr, -- png_const_charp text, png_size_t text_len, int compression, -- compression_state *comp) -+static void -+png_text_compress_init(compression_state *comp, png_const_bytep input, -+ png_alloc_size_t input_len) -+{ -+ comp->input = input; -+ comp->input_len = input_len; -+ comp->output_len = 0; -+} -+ -+/* Compress the data in the compression state input */ -+static int -+png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, -+ compression_state *comp, png_uint_32 prefix_len) - { - int ret; - -- comp->num_output_ptr = 0; -- comp->max_output_ptr = 0; -- comp->output_ptr = NULL; -- comp->input = NULL; -- comp->input_len = text_len; -- -- /* We may just want to pass the text right through */ -- if (compression == PNG_TEXT_COMPRESSION_NONE) -+ /* To find the length of the output it is necessary to first compress the -+ * input. The result is buffered rather than using the two-pass algorithm -+ * that is used on the inflate side; deflate is assumed to be slower and a -+ * PNG writer is assumed to have more memory available than a PNG reader. -+ * -+ * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an -+ * upper limit on the output size, but it is always bigger than the input -+ * size so it is likely to be more efficient to use this linked-list -+ * approach. -+ */ -+ ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); -+ -+ if (ret != Z_OK) -+ return ret; -+ -+ /* Set up the compression buffers, we need a loop here to avoid overflowing a -+ * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited -+ * by the output buffer size, so there is no need to check that. Since this -+ * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits -+ * in size. -+ */ - { -- comp->input = (png_const_bytep)text; -- return((int)text_len); -+ png_compression_bufferp *end = &png_ptr->zbuffer_list; -+ png_alloc_size_t input_len = comp->input_len; /* may be zero! */ -+ png_uint_32 output_len; -+ -+ /* zlib updates these for us: */ -+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); -+ png_ptr->zstream.avail_in = 0; /* Set below */ -+ png_ptr->zstream.next_out = comp->output; -+ png_ptr->zstream.avail_out = (sizeof comp->output); -+ -+ output_len = png_ptr->zstream.avail_out; -+ -+ do -+ { -+ uInt avail_in = ZLIB_IO_MAX; -+ -+ if (avail_in > input_len) -+ avail_in = (uInt)input_len; -+ -+ input_len -= avail_in; -+ -+ png_ptr->zstream.avail_in = avail_in; -+ -+ if (png_ptr->zstream.avail_out == 0) -+ { -+ png_compression_buffer *next; -+ -+ /* Chunk data is limited to 2^31 bytes in length, so the prefix -+ * length must be counted here. -+ */ -+ if (output_len + prefix_len > PNG_UINT_31_MAX) -+ { -+ ret = Z_MEM_ERROR; -+ break; -+ } -+ -+ /* Need a new (malloc'ed) buffer, but there may be one present -+ * already. -+ */ -+ next = *end; -+ if (next == NULL) -+ { -+ next = png_voidcast(png_compression_bufferp, png_malloc_base -+ (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); -+ -+ if (next == NULL) -+ { -+ ret = Z_MEM_ERROR; -+ break; -+ } -+ -+ /* Link in this buffer (so that it will be freed later) */ -+ next->next = NULL; -+ *end = next; -+ } -+ -+ png_ptr->zstream.next_out = next->output; -+ png_ptr->zstream.avail_out = png_ptr->zbuffer_size; -+ output_len += png_ptr->zstream.avail_out; -+ -+ /* Move 'end' to the next buffer pointer. */ -+ end = &next->next; -+ } -+ -+ /* Compress the data */ -+ ret = deflate(&png_ptr->zstream, -+ input_len > 0 ? Z_NO_FLUSH : Z_FINISH); -+ -+ /* Claw back input data that was not consumed (because avail_in is -+ * reset above every time round the loop). -+ */ -+ input_len += png_ptr->zstream.avail_in; -+ png_ptr->zstream.avail_in = 0; /* safety */ -+ } -+ while (ret == Z_OK); -+ -+ /* There may be some space left in the last output buffer. This needs to -+ * be subtracted from output_len. -+ */ -+ output_len -= png_ptr->zstream.avail_out; -+ png_ptr->zstream.avail_out = 0; /* safety */ -+ comp->output_len = output_len; -+ -+ /* Now double check the output length, put in a custom message if it is -+ * too long. Otherwise ensure the z_stream::msg pointer is set to -+ * something. -+ */ -+ if (output_len + prefix_len >= PNG_UINT_31_MAX) -+ { -+ png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); -+ ret = Z_MEM_ERROR; -+ } -+ -+ else -+ png_zstream_error(png_ptr, ret); -+ -+ /* Reset zlib for another zTXt/iTXt or image data */ -+ png_ptr->zowner = 0; -+ -+ /* The only success case is Z_STREAM_END, input_len must be 0; if not this -+ * is an internal error. -+ */ -+ if (ret == Z_STREAM_END && input_len == 0) -+ { -+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -+ /* Fix up the deflate header, if required */ -+ optimize_cmf(comp->output, comp->input_len); -+#endif -+ /* But Z_OK is returned, not Z_STREAM_END; this allows the claim -+ * function above to return Z_STREAM_END on an error (though it never -+ * does in the current versions of zlib.) -+ */ -+ return Z_OK; -+ } -+ -+ else -+ return ret; - } -- -- if (compression >= PNG_TEXT_COMPRESSION_LAST) -+} -+ -+/* Ship the compressed text out via chunk writes */ -+static void -+png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) -+{ -+ png_uint_32 output_len = comp->output_len; -+ png_const_bytep output = comp->output; -+ png_uint_32 avail = (sizeof comp->output); -+ png_compression_buffer *next = png_ptr->zbuffer_list; -+ -+ for (;;) -+ { -+ if (avail > output_len) -+ avail = output_len; -+ -+ png_write_chunk_data(png_ptr, output, avail); -+ -+ output_len -= avail; -+ -+ if (output_len == 0 || next == NULL) -+ break; -+ -+ avail = png_ptr->zbuffer_size; -+ output = next->output; -+ next = next->next; -+ } -+ -+ /* This is an internal error; 'next' must have been NULL! */ -+ if (output_len > 0) -+ png_error(png_ptr, "error writing ancillary chunked compressed data"); -+} -+#endif /* WRITE_COMPRESSED_TEXT */ -+ -+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ -+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) -+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, -+ * and if invalid, correct the keyword rather than discarding the entire -+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in -+ * length, forbids leading or trailing whitespace, multiple internal spaces, -+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. -+ * -+ * The 'new_key' buffer must be 80 characters in size (for the keyword plus a -+ * trailing '\0'). If this routine returns 0 then there was no keyword, or a -+ * valid one could not be generated, and the caller must png_error. -+ */ -+static png_uint_32 -+png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) -+{ -+ png_const_charp orig_key = key; -+ png_uint_32 key_len = 0; -+ int bad_character = 0; -+ int space = 1; -+ -+ png_debug(1, "in png_check_keyword"); -+ -+ if (key == NULL) -+ { -+ *new_key = 0; -+ return 0; -+ } -+ -+ while (*key && key_len < 79) -+ { -+ png_byte ch = (png_byte)(0xff & *key++); -+ -+ if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) -+ *new_key++ = ch, ++key_len, space = 0; -+ -+ else if (space == 0) -+ { -+ /* A space or an invalid character when one wasn't seen immediately -+ * before; output just a space. -+ */ -+ *new_key++ = 32, ++key_len, space = 1; -+ -+ /* If the character was not a space then it is invalid. */ -+ if (ch != 32) -+ bad_character = ch; -+ } -+ -+ else if (bad_character == 0) -+ bad_character = ch; /* just skip it, record the first error */ -+ } -+ -+ if (key_len > 0 && space != 0) /* trailing space */ -+ { -+ --key_len, --new_key; -+ if (bad_character == 0) -+ bad_character = 32; -+ } -+ -+ /* Terminate the keyword */ -+ *new_key = 0; -+ -+ if (key_len == 0) -+ return 0; -+ -+#ifdef PNG_WARNINGS_SUPPORTED -+ /* Try to only output one warning per keyword: */ -+ if (*key != 0) /* keyword too long */ -+ png_warning(png_ptr, "keyword truncated"); -+ -+ else if (bad_character != 0) - { - PNG_WARNING_PARAMETERS(p) - -- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, -- compression); -- png_formatted_warning(png_ptr, p, "Unknown compression type @1"); -+ png_warning_parameter(p, 1, orig_key); -+ png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); -+ -+ png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); - } -- -- /* We can't write the chunk until we find out how much data we have, -- * which means we need to run the compressor first and save the -- * output. This shouldn't be a problem, as the vast majority of -- * comments should be reasonable, but we will set up an array of -- * malloc'd pointers to be sure. -- * -- * If we knew the application was well behaved, we could simplify this -- * greatly by assuming we can always malloc an output buffer large -- * enough to hold the compressed text ((1001 * text_len / 1000) + 12) -- * and malloc this directly. The only time this would be a bad idea is -- * if we can't malloc more than 64K and we have 64K of random input -- * data, or if the input string is incredibly large (although this -- * wouldn't cause a failure, just a slowdown due to swapping). -- */ -- png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT); -- -- /* Set up the compression buffers */ -- /* TODO: the following cast hides a potential overflow problem. */ -- png_ptr->zstream.avail_in = (uInt)text_len; -- -- /* NOTE: assume zlib doesn't overwrite the input */ -- png_ptr->zstream.next_in = (Bytef *)text; -- png_ptr->zstream.avail_out = png_ptr->zbuf_size; -- png_ptr->zstream.next_out = png_ptr->zbuf; -- -- /* This is the same compression loop as in png_write_row() */ -- do -- { -- /* Compress the data */ -- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); -- -- if (ret != Z_OK) -- { -- /* Error */ -- if (png_ptr->zstream.msg != NULL) -- png_error(png_ptr, png_ptr->zstream.msg); -- -- else -- png_error(png_ptr, "zlib error"); -- } -- -- /* Check to see if we need more room */ -- if (!(png_ptr->zstream.avail_out)) -- { -- /* Make sure the output array has room */ -- if (comp->num_output_ptr >= comp->max_output_ptr) -- { -- int old_max; -- -- old_max = comp->max_output_ptr; -- comp->max_output_ptr = comp->num_output_ptr + 4; -- if (comp->output_ptr != NULL) -- { -- png_bytepp old_ptr; -- -- old_ptr = comp->output_ptr; -- -- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, -- (png_alloc_size_t) -- (comp->max_output_ptr * png_sizeof(png_charpp))); -- -- png_memcpy(comp->output_ptr, old_ptr, old_max -- * png_sizeof(png_charp)); -- -- png_free(png_ptr, old_ptr); -- } -- else -- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, -- (png_alloc_size_t) -- (comp->max_output_ptr * png_sizeof(png_charp))); -- } -- -- /* Save the data */ -- comp->output_ptr[comp->num_output_ptr] = -- (png_bytep)png_malloc(png_ptr, -- (png_alloc_size_t)png_ptr->zbuf_size); -- -- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, -- png_ptr->zbuf_size); -- -- comp->num_output_ptr++; -- -- /* and reset the buffer */ -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -- png_ptr->zstream.next_out = png_ptr->zbuf; -- } -- /* Continue until we don't have any more to compress */ -- } while (png_ptr->zstream.avail_in); -- -- /* Finish the compression */ -- do -- { -- /* Tell zlib we are finished */ -- ret = deflate(&png_ptr->zstream, Z_FINISH); -- -- if (ret == Z_OK) -- { -- /* Check to see if we need more room */ -- if (!(png_ptr->zstream.avail_out)) -- { -- /* Check to make sure our output array has room */ -- if (comp->num_output_ptr >= comp->max_output_ptr) -- { -- int old_max; -- -- old_max = comp->max_output_ptr; -- comp->max_output_ptr = comp->num_output_ptr + 4; -- if (comp->output_ptr != NULL) -- { -- png_bytepp old_ptr; -- -- old_ptr = comp->output_ptr; -- -- /* This could be optimized to realloc() */ -- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, -- (png_alloc_size_t)(comp->max_output_ptr * -- png_sizeof(png_charp))); -- -- png_memcpy(comp->output_ptr, old_ptr, -- old_max * png_sizeof(png_charp)); -- -- png_free(png_ptr, old_ptr); -- } -- -- else -- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, -- (png_alloc_size_t)(comp->max_output_ptr * -- png_sizeof(png_charp))); -- } -- -- /* Save the data */ -- comp->output_ptr[comp->num_output_ptr] = -- (png_bytep)png_malloc(png_ptr, -- (png_alloc_size_t)png_ptr->zbuf_size); -- -- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, -- png_ptr->zbuf_size); -- -- comp->num_output_ptr++; -- -- /* and reset the buffer pointers */ -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -- png_ptr->zstream.next_out = png_ptr->zbuf; -- } -- } -- else if (ret != Z_STREAM_END) -- { -- /* We got an error */ -- if (png_ptr->zstream.msg != NULL) -- png_error(png_ptr, png_ptr->zstream.msg); -- -- else -- png_error(png_ptr, "zlib error"); -- } -- } while (ret != Z_STREAM_END); -- -- /* Text length is number of buffers plus last buffer */ -- text_len = png_ptr->zbuf_size * comp->num_output_ptr; -- -- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) -- text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; -- -- return((int)text_len); -+#endif /* WARNINGS */ -+ -+ return key_len; - } -- --/* Ship the compressed text out via chunk writes */ --static void /* PRIVATE */ --png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) --{ -- int i; -- -- /* Handle the no-compression case */ -- if (comp->input) -- { -- png_write_chunk_data(png_ptr, comp->input, comp->input_len); -- -- return; -- } -- --#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -- if (comp->input_len >= 2 && comp->input_len < 16384) -- { -- unsigned int z_cmf; /* zlib compression method and flags */ -- -- /* Optimize the CMF field in the zlib stream. This hack of the zlib -- * stream is compliant to the stream specification. -- */ -- -- if (comp->num_output_ptr) -- z_cmf = comp->output_ptr[0][0]; -- else -- z_cmf = png_ptr->zbuf[0]; -- -- if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) -- { -- unsigned int z_cinfo; -- unsigned int half_z_window_size; -- png_size_t uncompressed_text_size = comp->input_len; -- -- z_cinfo = z_cmf >> 4; -- half_z_window_size = 1 << (z_cinfo + 7); -- -- while (uncompressed_text_size <= half_z_window_size && -- half_z_window_size >= 256) -- { -- z_cinfo--; -- half_z_window_size >>= 1; -- } -- -- z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); -- -- if (comp->num_output_ptr) -- { -- -- if (comp->output_ptr[0][0] != z_cmf) -- { -- int tmp; -- -- comp->output_ptr[0][0] = (png_byte)z_cmf; -- tmp = comp->output_ptr[0][1] & 0xe0; -- tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; -- comp->output_ptr[0][1] = (png_byte)tmp; -- } -- } -- else -- { -- int tmp; -- -- png_ptr->zbuf[0] = (png_byte)z_cmf; -- tmp = png_ptr->zbuf[1] & 0xe0; -- tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; -- png_ptr->zbuf[1] = (png_byte)tmp; -- } -- } -- -- else -- png_error(png_ptr, -- "Invalid zlib compression method or flags in non-IDAT chunk"); -- } --#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ -- -- /* Write saved output buffers, if any */ -- for (i = 0; i < comp->num_output_ptr; i++) -- { -- png_write_chunk_data(png_ptr, comp->output_ptr[i], -- (png_size_t)png_ptr->zbuf_size); -- -- png_free(png_ptr, comp->output_ptr[i]); -- } -- -- if (comp->max_output_ptr != 0) -- png_free(png_ptr, comp->output_ptr); -- -- /* Write anything left in zbuf */ -- if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) -- png_write_chunk_data(png_ptr, png_ptr->zbuf, -- (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); -- -- /* Reset zlib for another zTXt/iTXt or image data */ -- png_zlib_release(png_ptr); --} --#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ -+#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */ - - /* Write the IHDR chunk, and update the png_struct with the necessary - * information. Note that the rest of this code depends upon this - * information being correct. - */ - void /* PRIVATE */ --png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, -+png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, - int bit_depth, int color_type, int compression_type, int filter_type, - int interlace_type) - { -- PNG_IHDR; -- - png_byte buf[13]; /* Buffer to store the IHDR info */ - - png_debug(1, "in png_write_IHDR"); -@@ -772,8 +876,8 @@ - */ - if ( - #ifdef PNG_MNG_FEATURES_SUPPORTED -- !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && -- ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && -+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && -+ ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && -@@ -823,14 +927,9 @@ - buf[12] = (png_byte)interlace_type; - - /* Write the chunk */ -- png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); -- -- /* Initialize zlib with PNG info */ -- png_ptr->zstream.zalloc = png_zalloc; -- png_ptr->zstream.zfree = png_zfree; -- png_ptr->zstream.opaque = (voidpf)png_ptr; -- -- if (!(png_ptr->do_filter)) -+ png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); -+ -+ if ((png_ptr->do_filter) == PNG_NO_FILTERS) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - png_ptr->bit_depth < 8) -@@ -840,55 +939,6 @@ - png_ptr->do_filter = PNG_ALL_FILTERS; - } - -- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) -- { -- if (png_ptr->do_filter != PNG_FILTER_NONE) -- png_ptr->zlib_strategy = Z_FILTERED; -- -- else -- png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; -- } -- -- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) -- png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; -- -- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) -- png_ptr->zlib_mem_level = 8; -- -- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) -- png_ptr->zlib_window_bits = 15; -- -- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) -- png_ptr->zlib_method = 8; -- --#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED --#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY)) -- png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; -- -- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL)) -- png_ptr->zlib_text_level = png_ptr->zlib_level; -- -- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL)) -- png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; -- -- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS)) -- png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; -- -- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD)) -- png_ptr->zlib_text_method = png_ptr->zlib_method; --#else -- png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; -- png_ptr->zlib_text_level = png_ptr->zlib_level; -- png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; -- png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; -- png_ptr->zlib_text_method = png_ptr->zlib_method; --#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ --#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ -- -- /* Record that the compressor has not yet been initialized. */ -- png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; -- - png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ - } - -@@ -897,10 +947,9 @@ - * structure. - */ - void /* PRIVATE */ --png_write_PLTE(png_structp png_ptr, png_const_colorp palette, -+png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, - png_uint_32 num_pal) - { -- PNG_PLTE; - png_uint_32 i; - png_const_colorp pal_ptr; - png_byte buf[3]; -@@ -909,7 +958,7 @@ - - if (( - #ifdef PNG_MNG_FEATURES_SUPPORTED -- !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && -+ (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && - #endif - num_pal == 0) || num_pal > 256) - { -@@ -925,7 +974,7 @@ - } - } - -- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) -+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - png_warning(png_ptr, - "Ignoring request to write a PLTE chunk in grayscale PNG"); -@@ -936,7 +985,7 @@ - png_ptr->num_palette = (png_uint_16)num_pal; - png_debug1(3, "num_palette = %d", png_ptr->num_palette); - -- png_write_chunk_start(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); -+ png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); - #ifdef PNG_POINTER_INDEXING_SUPPORTED - - for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) -@@ -966,127 +1015,192 @@ - png_ptr->mode |= PNG_HAVE_PLTE; - } - --/* Write an IDAT chunk */ -+/* This is similar to png_text_compress, above, except that it does not require -+ * all of the data at once and, instead of buffering the compressed result, -+ * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out -+ * because it calls the write interface. As a result it does its own error -+ * reporting and does not return an error code. In the event of error it will -+ * just call png_error. The input data length may exceed 32-bits. The 'flush' -+ * parameter is exactly the same as that to deflate, with the following -+ * meanings: -+ * -+ * Z_NO_FLUSH: normal incremental output of compressed data -+ * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush -+ * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up -+ * -+ * The routine manages the acquire and release of the png_ptr->zstream by -+ * checking and (at the end) clearing png_ptr->zowner; it does some sanity -+ * checks on the 'mode' flags while doing this. -+ */ - void /* PRIVATE */ --png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) -+png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, -+ png_alloc_size_t input_len, int flush) - { -- PNG_IDAT; -- -- png_debug(1, "in png_write_IDAT"); -- -+ if (png_ptr->zowner != png_IDAT) -+ { -+ /* First time. Ensure we have a temporary buffer for compression and -+ * trim the buffer list if it has more than one entry to free memory. -+ * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been -+ * created at this point, but the check here is quick and safe. -+ */ -+ if (png_ptr->zbuffer_list == NULL) -+ { -+ png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, -+ png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); -+ png_ptr->zbuffer_list->next = NULL; -+ } -+ -+ else -+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); -+ -+ /* It is a terminal error if we can't claim the zstream. */ -+ if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) -+ png_error(png_ptr, png_ptr->zstream.msg); -+ -+ /* The output state is maintained in png_ptr->zstream, so it must be -+ * initialized here after the claim. -+ */ -+ png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; -+ png_ptr->zstream.avail_out = png_ptr->zbuffer_size; -+ } -+ -+ /* Now loop reading and writing until all the input is consumed or an error -+ * terminates the operation. The _out values are maintained across calls to -+ * this function, but the input must be reset each time. -+ */ -+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); -+ png_ptr->zstream.avail_in = 0; /* set below */ -+ for (;;) -+ { -+ int ret; -+ -+ /* INPUT: from the row data */ -+ uInt avail = ZLIB_IO_MAX; -+ -+ if (avail > input_len) -+ avail = (uInt)input_len; /* safe because of the check */ -+ -+ png_ptr->zstream.avail_in = avail; -+ input_len -= avail; -+ -+ ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); -+ -+ /* Include as-yet unconsumed input */ -+ input_len += png_ptr->zstream.avail_in; -+ png_ptr->zstream.avail_in = 0; -+ -+ /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note -+ * that these two zstream fields are preserved across the calls, therefore -+ * there is no need to set these up on entry to the loop. -+ */ -+ if (png_ptr->zstream.avail_out == 0) -+ { -+ png_bytep data = png_ptr->zbuffer_list->output; -+ uInt size = png_ptr->zbuffer_size; -+ -+ /* Write an IDAT containing the data then reset the buffer. The -+ * first IDAT may need deflate header optimization. -+ */ - #ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -- if (!(png_ptr->mode & PNG_HAVE_IDAT) && -- png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) -- { -- /* Optimize the CMF field in the zlib stream. This hack of the zlib -- * stream is compliant to the stream specification. -+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && -+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) -+ optimize_cmf(data, png_image_size(png_ptr)); -+#endif -+ -+ png_write_complete_chunk(png_ptr, png_IDAT, data, size); -+ png_ptr->mode |= PNG_HAVE_IDAT; -+ -+ png_ptr->zstream.next_out = data; -+ png_ptr->zstream.avail_out = size; -+ -+ /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with -+ * the same flush parameter until it has finished output, for NO_FLUSH -+ * it doesn't matter. -+ */ -+ if (ret == Z_OK && flush != Z_NO_FLUSH) -+ continue; -+ } -+ -+ /* The order of these checks doesn't matter much; it just affects which -+ * possible error might be detected if multiple things go wrong at once. - */ -- unsigned int z_cmf = data[0]; /* zlib compression method and flags */ -- -- if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) -+ if (ret == Z_OK) /* most likely return code! */ - { -- /* Avoid memory underflows and multiplication overflows. -- * -- * The conditions below are practically always satisfied; -- * however, they still must be checked. -+ /* If all the input has been consumed then just return. If Z_FINISH -+ * was used as the flush parameter something has gone wrong if we get -+ * here. - */ -- if (length >= 2 && -- png_ptr->height < 16384 && png_ptr->width < 16384) -+ if (input_len == 0) - { -- /* Compute the maximum possible length of the datastream */ -- -- /* Number of pixels, plus for each row a filter byte -- * and possibly a padding byte, so increase the maximum -- * size to account for these. -- */ -- unsigned int z_cinfo; -- unsigned int half_z_window_size; -- png_uint_32 uncompressed_idat_size = png_ptr->height * -- ((png_ptr->width * -- png_ptr->channels * png_ptr->bit_depth + 15) >> 3); -- -- /* If it's interlaced, each block of 8 rows is sent as up to -- * 14 rows, i.e., 6 additional rows, each with a filter byte -- * and possibly a padding byte -- */ -- if (png_ptr->interlaced) -- uncompressed_idat_size += ((png_ptr->height + 7)/8) * -- (png_ptr->bit_depth < 8 ? 12 : 6); -- -- z_cinfo = z_cmf >> 4; -- half_z_window_size = 1 << (z_cinfo + 7); -- -- while (uncompressed_idat_size <= half_z_window_size && -- half_z_window_size >= 256) -- { -- z_cinfo--; -- half_z_window_size >>= 1; -- } -- -- z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); -- -- if (data[0] != z_cmf) -- { -- int tmp; -- data[0] = (png_byte)z_cmf; -- tmp = data[1] & 0xe0; -- tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; -- data[1] = (png_byte)tmp; -- } -+ if (flush == Z_FINISH) -+ png_error(png_ptr, "Z_OK on Z_FINISH with output space"); -+ -+ return; - } - } - -+ else if (ret == Z_STREAM_END && flush == Z_FINISH) -+ { -+ /* This is the end of the IDAT data; any pending output must be -+ * flushed. For small PNG files we may still be at the beginning. -+ */ -+ png_bytep data = png_ptr->zbuffer_list->output; -+ uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; -+ -+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && -+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) -+ optimize_cmf(data, png_image_size(png_ptr)); -+#endif -+ -+ png_write_complete_chunk(png_ptr, png_IDAT, data, size); -+ png_ptr->zstream.avail_out = 0; -+ png_ptr->zstream.next_out = NULL; -+ png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; -+ -+ png_ptr->zowner = 0; /* Release the stream */ -+ return; -+ } -+ - else -- png_error(png_ptr, -- "Invalid zlib compression method or flags in IDAT"); -+ { -+ /* This is an error condition. */ -+ png_zstream_error(png_ptr, ret); -+ png_error(png_ptr, png_ptr->zstream.msg); -+ } - } --#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ -- -- png_write_chunk(png_ptr, png_IDAT, data, length); -- png_ptr->mode |= PNG_HAVE_IDAT; -- -- /* Prior to 1.5.4 this code was replicated in every caller (except at the -- * end, where it isn't technically necessary). Since this function has -- * flushed the data we can safely reset the zlib output buffer here. -- */ -- png_ptr->zstream.next_out = png_ptr->zbuf; -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - } - - /* Write an IEND chunk */ - void /* PRIVATE */ --png_write_IEND(png_structp png_ptr) -+png_write_IEND(png_structrp png_ptr) - { -- PNG_IEND; -- - png_debug(1, "in png_write_IEND"); - -- png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); -+ png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); - png_ptr->mode |= PNG_HAVE_IEND; - } - - #ifdef PNG_WRITE_gAMA_SUPPORTED - /* Write a gAMA chunk */ - void /* PRIVATE */ --png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) -+png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) - { -- PNG_gAMA; - png_byte buf[4]; - - png_debug(1, "in png_write_gAMA"); - - /* file_gamma is saved in 1/100,000ths */ - png_save_uint_32(buf, (png_uint_32)file_gamma); -- png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); -+ png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); - } - #endif - - #ifdef PNG_WRITE_sRGB_SUPPORTED - /* Write a sRGB chunk */ - void /* PRIVATE */ --png_write_sRGB(png_structp png_ptr, int srgb_intent) -+png_write_sRGB(png_structrp png_ptr, int srgb_intent) - { -- PNG_sRGB; - png_byte buf[1]; - - png_debug(1, "in png_write_sRGB"); -@@ -1096,104 +1210,79 @@ - "Invalid sRGB rendering intent specified"); - - buf[0]=(png_byte)srgb_intent; -- png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); -+ png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); - } - #endif - - #ifdef PNG_WRITE_iCCP_SUPPORTED - /* Write an iCCP chunk */ - void /* PRIVATE */ --png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, -- png_const_charp profile, int profile_len) -+png_write_iCCP(png_structrp png_ptr, png_const_charp name, -+ png_const_bytep profile) - { -- PNG_iCCP; -- png_size_t name_len; -- png_charp new_name; -+ png_uint_32 name_len; -+ png_uint_32 profile_len; -+ png_byte new_name[81]; /* 1 byte for the compression byte */ - compression_state comp; -- int embedded_profile_len = 0; -+ png_uint_32 temp; - - png_debug(1, "in png_write_iCCP"); - -- comp.num_output_ptr = 0; -- comp.max_output_ptr = 0; -- comp.output_ptr = NULL; -- comp.input = NULL; -- comp.input_len = 0; -- -- if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) -- return; -- -- if (compression_type != PNG_COMPRESSION_TYPE_BASE) -- png_warning(png_ptr, "Unknown compression type in iCCP chunk"); -- -+ /* These are all internal problems: the profile should have been checked -+ * before when it was stored. -+ */ - if (profile == NULL) -- profile_len = 0; -- -- if (profile_len > 3) -- embedded_profile_len = -- ((*( (png_const_bytep)profile ))<<24) | -- ((*( (png_const_bytep)profile + 1))<<16) | -- ((*( (png_const_bytep)profile + 2))<< 8) | -- ((*( (png_const_bytep)profile + 3)) ); -- -- if (embedded_profile_len < 0) -+ png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ -+ -+ profile_len = png_get_uint_32(profile); -+ -+ if (profile_len < 132) -+ png_error(png_ptr, "ICC profile too short"); -+ -+ temp = (png_uint_32) (*(profile+8)); -+ if (temp > 3 && (profile_len & 0x03)) -+ png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); -+ - { -- png_warning(png_ptr, -- "Embedded profile length in iCCP chunk is negative"); -- -- png_free(png_ptr, new_name); -- return; -+ png_uint_32 embedded_profile_len = png_get_uint_32(profile); -+ -+ if (profile_len != embedded_profile_len) -+ png_error(png_ptr, "Profile length does not match profile"); - } - -- if (profile_len < embedded_profile_len) -- { -- png_warning(png_ptr, -- "Embedded profile length too large in iCCP chunk"); -- -- png_free(png_ptr, new_name); -- return; -- } -- -- if (profile_len > embedded_profile_len) -- { -- png_warning(png_ptr, -- "Truncating profile to actual length in iCCP chunk"); -- -- profile_len = embedded_profile_len; -- } -- -- if (profile_len) -- profile_len = png_text_compress(png_ptr, profile, -- (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); -+ name_len = png_check_keyword(png_ptr, name, new_name); -+ -+ if (name_len == 0) -+ png_error(png_ptr, "iCCP: invalid keyword"); -+ -+ new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; - - /* Make sure we include the NULL after the name and the compression type */ -- png_write_chunk_start(png_ptr, png_iCCP, -- (png_uint_32)(name_len + profile_len + 2)); -- -- new_name[name_len + 1] = 0x00; -- -- png_write_chunk_data(png_ptr, (png_bytep)new_name, -- (png_size_t)(name_len + 2)); -- -- if (profile_len) -- { -- comp.input_len = profile_len; -- png_write_compressed_data_out(png_ptr, &comp); -- } -+ ++name_len; -+ -+ png_text_compress_init(&comp, profile, profile_len); -+ -+ /* Allow for keyword terminator and compression byte */ -+ if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) -+ png_error(png_ptr, png_ptr->zstream.msg); -+ -+ png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); -+ -+ png_write_chunk_data(png_ptr, new_name, name_len); -+ -+ png_write_compressed_data_out(png_ptr, &comp); - - png_write_chunk_end(png_ptr); -- png_free(png_ptr, new_name); - } - #endif - - #ifdef PNG_WRITE_sPLT_SUPPORTED - /* Write a sPLT chunk */ - void /* PRIVATE */ --png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) -+png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) - { -- PNG_sPLT; -- png_size_t name_len; -- png_charp new_name; -+ png_uint_32 name_len; -+ png_byte new_name[80]; - png_byte entrybuf[10]; - png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); - png_size_t palette_size = entry_size * spalette->nentries; -@@ -1204,11 +1293,13 @@ - - png_debug(1, "in png_write_sPLT"); - -- if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) -- return; -+ name_len = png_check_keyword(png_ptr, spalette->name, new_name); -+ -+ if (name_len == 0) -+ png_error(png_ptr, "sPLT: invalid keyword"); - - /* Make sure we include the NULL after the name */ -- png_write_chunk_start(png_ptr, png_sPLT, -+ png_write_chunk_header(png_ptr, png_sPLT, - (png_uint_32)(name_len + 2 + palette_size)); - - png_write_chunk_data(png_ptr, (png_bytep)new_name, -@@ -1238,7 +1329,7 @@ - png_save_uint_16(entrybuf + 8, ep->frequency); - } - -- png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); -+ png_write_chunk_data(png_ptr, entrybuf, entry_size); - } - #else - ep=spalette->entries; -@@ -1262,28 +1353,26 @@ - png_save_uint_16(entrybuf + 8, ep[i].frequency); - } - -- png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); -+ png_write_chunk_data(png_ptr, entrybuf, entry_size); - } - #endif - - png_write_chunk_end(png_ptr); -- png_free(png_ptr, new_name); - } - #endif - - #ifdef PNG_WRITE_sBIT_SUPPORTED - /* Write the sBIT chunk */ - void /* PRIVATE */ --png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) -+png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) - { -- PNG_sBIT; - png_byte buf[4]; - png_size_t size; - - png_debug(1, "in png_write_sBIT"); - - /* Make sure we don't depend upon the order of PNG_COLOR_8 */ -- if (color_type & PNG_COLOR_MASK_COLOR) -+ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_byte maxbits; - -@@ -1316,7 +1405,7 @@ - size = 1; - } - -- if (color_type & PNG_COLOR_MASK_ALPHA) -+ if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) - { -@@ -1327,53 +1416,42 @@ - buf[size++] = sbit->alpha; - } - -- png_write_chunk(png_ptr, png_sBIT, buf, size); -+ png_write_complete_chunk(png_ptr, png_sBIT, buf, size); - } - #endif - - #ifdef PNG_WRITE_cHRM_SUPPORTED - /* Write the cHRM chunk */ - void /* PRIVATE */ --png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, -- png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, -- png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, -- png_fixed_point blue_y) -+png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) - { -- PNG_cHRM; - png_byte buf[32]; - - png_debug(1, "in png_write_cHRM"); - - /* Each value is saved in 1/100,000ths */ --#ifdef PNG_CHECK_cHRM_SUPPORTED -- if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, -- green_x, green_y, blue_x, blue_y)) --#endif -- { -- png_save_uint_32(buf, (png_uint_32)white_x); -- png_save_uint_32(buf + 4, (png_uint_32)white_y); -- -- png_save_uint_32(buf + 8, (png_uint_32)red_x); -- png_save_uint_32(buf + 12, (png_uint_32)red_y); -- -- png_save_uint_32(buf + 16, (png_uint_32)green_x); -- png_save_uint_32(buf + 20, (png_uint_32)green_y); -- -- png_save_uint_32(buf + 24, (png_uint_32)blue_x); -- png_save_uint_32(buf + 28, (png_uint_32)blue_y); -- -- png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); -- } -+ png_save_int_32(buf, xy->whitex); -+ png_save_int_32(buf + 4, xy->whitey); -+ -+ png_save_int_32(buf + 8, xy->redx); -+ png_save_int_32(buf + 12, xy->redy); -+ -+ png_save_int_32(buf + 16, xy->greenx); -+ png_save_int_32(buf + 20, xy->greeny); -+ -+ png_save_int_32(buf + 24, xy->bluex); -+ png_save_int_32(buf + 28, xy->bluey); -+ -+ png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); - } - #endif - - #ifdef PNG_WRITE_tRNS_SUPPORTED - /* Write the tRNS chunk */ - void /* PRIVATE */ --png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, -+png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, - png_const_color_16p tran, int num_trans, int color_type) - { -- PNG_tRNS; - png_byte buf[6]; - - png_debug(1, "in png_write_tRNS"); -@@ -1382,12 +1460,14 @@ - { - if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) - { -- png_warning(png_ptr, "Invalid number of transparent colors specified"); -+ png_app_warning(png_ptr, -+ "Invalid number of transparent colors specified"); - return; - } - - /* Write the chunk out as it is */ -- png_write_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); -+ png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, -+ (png_size_t)num_trans); - } - - else if (color_type == PNG_COLOR_TYPE_GRAY) -@@ -1395,14 +1475,14 @@ - /* One 16 bit value */ - if (tran->gray >= (1 << png_ptr->bit_depth)) - { -- png_warning(png_ptr, -+ png_app_warning(png_ptr, - "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, tran->gray); -- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); -+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); - } - - else if (color_type == PNG_COLOR_TYPE_RGB) -@@ -1412,22 +1492,22 @@ - png_save_uint_16(buf + 2, tran->green); - png_save_uint_16(buf + 4, tran->blue); - #ifdef PNG_WRITE_16BIT_SUPPORTED -- if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) -+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) - #else -- if (buf[0] | buf[2] | buf[4]) -+ if ((buf[0] | buf[2] | buf[4]) != 0) - #endif - { -- png_warning(png_ptr, -+ png_app_warning(png_ptr, - "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); - return; - } - -- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); -+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); - } - - else - { -- png_warning(png_ptr, "Can't write tRNS with an alpha channel"); -+ png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); - } - } - #endif -@@ -1435,9 +1515,8 @@ - #ifdef PNG_WRITE_bKGD_SUPPORTED - /* Write the background chunk */ - void /* PRIVATE */ --png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) -+png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) - { -- PNG_bKGD; - png_byte buf[6]; - - png_debug(1, "in png_write_bKGD"); -@@ -1446,8 +1525,8 @@ - { - if ( - #ifdef PNG_MNG_FEATURES_SUPPORTED -- (png_ptr->num_palette || -- (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && -+ (png_ptr->num_palette != 0 || -+ (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && - #endif - back->index >= png_ptr->num_palette) - { -@@ -1456,18 +1535,18 @@ - } - - buf[0] = back->index; -- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); -+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); - } - -- else if (color_type & PNG_COLOR_MASK_COLOR) -+ else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_save_uint_16(buf, back->red); - png_save_uint_16(buf + 2, back->green); - png_save_uint_16(buf + 4, back->blue); - #ifdef PNG_WRITE_16BIT_SUPPORTED -- if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) -+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) - #else -- if (buf[0] | buf[2] | buf[4]) -+ if ((buf[0] | buf[2] | buf[4]) != 0) - #endif - { - png_warning(png_ptr, -@@ -1476,7 +1555,7 @@ - return; - } - -- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); -+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); - } - - else -@@ -1490,7 +1569,7 @@ - } - - png_save_uint_16(buf, back->gray); -- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); -+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); - } - } - #endif -@@ -1498,9 +1577,8 @@ - #ifdef PNG_WRITE_hIST_SUPPORTED - /* Write the histogram */ - void /* PRIVATE */ --png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) -+png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) - { -- PNG_hIST; - int i; - png_byte buf[3]; - -@@ -1515,7 +1593,7 @@ - return; - } - -- png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); -+ png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); - - for (i = 0; i < num_hist; i++) - { -@@ -1527,236 +1605,93 @@ - } - #endif - --#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ -- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) --/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, -- * and if invalid, correct the keyword rather than discarding the entire -- * chunk. The PNG 1.0 specification requires keywords 1-79 characters in -- * length, forbids leading or trailing whitespace, multiple internal spaces, -- * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. -- * -- * The new_key is allocated to hold the corrected keyword and must be freed -- * by the calling routine. This avoids problems with trying to write to -- * static keywords without having to have duplicate copies of the strings. -- */ --png_size_t /* PRIVATE */ --png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key) --{ -- png_size_t key_len; -- png_const_charp ikp; -- png_charp kp, dp; -- int kflag; -- int kwarn=0; -- -- png_debug(1, "in png_check_keyword"); -- -- *new_key = NULL; -- -- if (key == NULL || (key_len = png_strlen(key)) == 0) -- { -- png_warning(png_ptr, "zero length keyword"); -- return ((png_size_t)0); -- } -- -- png_debug1(2, "Keyword to be checked is '%s'", key); -- -- *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); -- -- if (*new_key == NULL) -- { -- png_warning(png_ptr, "Out of memory while procesing keyword"); -- return ((png_size_t)0); -- } -- -- /* Replace non-printing characters with a blank and print a warning */ -- for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) -- { -- if ((png_byte)*ikp < 0x20 || -- ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) -- { -- PNG_WARNING_PARAMETERS(p) -- -- png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x, -- (png_byte)*ikp); -- png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1"); -- *dp = ' '; -- } -- -- else -- { -- *dp = *ikp; -- } -- } -- *dp = '\0'; -- -- /* Remove any trailing white space. */ -- kp = *new_key + key_len - 1; -- if (*kp == ' ') -- { -- png_warning(png_ptr, "trailing spaces removed from keyword"); -- -- while (*kp == ' ') -- { -- *(kp--) = '\0'; -- key_len--; -- } -- } -- -- /* Remove any leading white space. */ -- kp = *new_key; -- if (*kp == ' ') -- { -- png_warning(png_ptr, "leading spaces removed from keyword"); -- -- while (*kp == ' ') -- { -- kp++; -- key_len--; -- } -- } -- -- png_debug1(2, "Checking for multiple internal spaces in '%s'", kp); -- -- /* Remove multiple internal spaces. */ -- for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) -- { -- if (*kp == ' ' && kflag == 0) -- { -- *(dp++) = *kp; -- kflag = 1; -- } -- -- else if (*kp == ' ') -- { -- key_len--; -- kwarn = 1; -- } -- -- else -- { -- *(dp++) = *kp; -- kflag = 0; -- } -- } -- *dp = '\0'; -- if (kwarn) -- png_warning(png_ptr, "extra interior spaces removed from keyword"); -- -- if (key_len == 0) -- { -- png_free(png_ptr, *new_key); -- png_warning(png_ptr, "Zero length keyword"); -- } -- -- if (key_len > 79) -- { -- png_warning(png_ptr, "keyword length must be 1 - 79 characters"); -- (*new_key)[79] = '\0'; -- key_len = 79; -- } -- -- return (key_len); --} --#endif -- - #ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write a tEXt chunk */ - void /* PRIVATE */ --png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, -+png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - png_size_t text_len) - { -- PNG_tEXt; -- png_size_t key_len; -- png_charp new_key; -+ png_uint_32 key_len; -+ png_byte new_key[80]; - - png_debug(1, "in png_write_tEXt"); - -- if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) -- return; -+ key_len = png_check_keyword(png_ptr, key, new_key); -+ -+ if (key_len == 0) -+ png_error(png_ptr, "tEXt: invalid keyword"); - - if (text == NULL || *text == '\0') - text_len = 0; - - else -- text_len = png_strlen(text); -+ text_len = strlen(text); -+ -+ if (text_len > PNG_UINT_31_MAX - (key_len+1)) -+ png_error(png_ptr, "tEXt: text too long"); - - /* Make sure we include the 0 after the key */ -- png_write_chunk_start(png_ptr, png_tEXt, -- (png_uint_32)(key_len + text_len + 1)); -+ png_write_chunk_header(png_ptr, png_tEXt, -+ (png_uint_32)/*checked above*/(key_len + text_len + 1)); - /* - * We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - */ -- png_write_chunk_data(png_ptr, (png_bytep)new_key, -- (png_size_t)(key_len + 1)); -- -- if (text_len) -- png_write_chunk_data(png_ptr, (png_const_bytep)text, -- (png_size_t)text_len); -+ png_write_chunk_data(png_ptr, new_key, key_len + 1); -+ -+ if (text_len != 0) -+ png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); - - png_write_chunk_end(png_ptr); -- png_free(png_ptr, new_key); - } - #endif - - #ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write a compressed text chunk */ - void /* PRIVATE */ --png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, -- png_size_t text_len, int compression) -+png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, -+ int compression) - { -- PNG_zTXt; -- png_size_t key_len; -- png_byte buf; -- png_charp new_key; -+ png_uint_32 key_len; -+ png_byte new_key[81]; - compression_state comp; - - png_debug(1, "in png_write_zTXt"); - -- comp.num_output_ptr = 0; -- comp.max_output_ptr = 0; -- comp.output_ptr = NULL; -- comp.input = NULL; -- comp.input_len = 0; -- -- if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) -+ if (compression == PNG_TEXT_COMPRESSION_NONE) - { -- png_free(png_ptr, new_key); -+ png_write_tEXt(png_ptr, key, text, 0); - return; - } - -- if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) -- { -- png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); -- png_free(png_ptr, new_key); -- return; -- } -- -- text_len = png_strlen(text); -+ if (compression != PNG_TEXT_COMPRESSION_zTXt) -+ png_error(png_ptr, "zTXt: invalid compression type"); -+ -+ key_len = png_check_keyword(png_ptr, key, new_key); -+ -+ if (key_len == 0) -+ png_error(png_ptr, "zTXt: invalid keyword"); -+ -+ /* Add the compression method and 1 for the keyword separator. */ -+ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; -+ ++key_len; - - /* Compute the compressed data; do it now for the length */ -- text_len = png_text_compress(png_ptr, text, text_len, compression, -- &comp); -+ png_text_compress_init(&comp, (png_const_bytep)text, -+ text == NULL ? 0 : strlen(text)); -+ -+ if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) -+ png_error(png_ptr, png_ptr->zstream.msg); - - /* Write start of chunk */ -- png_write_chunk_start(png_ptr, png_zTXt, -- (png_uint_32)(key_len+text_len + 2)); -+ png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); - - /* Write key */ -- png_write_chunk_data(png_ptr, (png_bytep)new_key, -- (png_size_t)(key_len + 1)); -- -- png_free(png_ptr, new_key); -- -- buf = (png_byte)compression; -- -- /* Write compression */ -- png_write_chunk_data(png_ptr, &buf, (png_size_t)1); -+ png_write_chunk_data(png_ptr, new_key, key_len); - - /* Write the compressed data */ -- comp.input_len = text_len; - png_write_compressed_data_out(png_ptr, &comp); - - /* Close the chunk */ -@@ -1767,104 +1702,109 @@ - #ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write an iTXt chunk */ - void /* PRIVATE */ --png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, -+png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, - png_const_charp lang, png_const_charp lang_key, png_const_charp text) - { -- PNG_iTXt; -- png_size_t lang_len, key_len, lang_key_len, text_len; -- png_charp new_lang; -- png_charp new_key = NULL; -- png_byte cbuf[2]; -+ png_uint_32 key_len, prefix_len; -+ png_size_t lang_len, lang_key_len; -+ png_byte new_key[82]; - compression_state comp; - - png_debug(1, "in png_write_iTXt"); - -- comp.num_output_ptr = 0; -- comp.max_output_ptr = 0; -- comp.output_ptr = NULL; -- comp.input = NULL; -- -- if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) -- return; -- -- if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) -+ key_len = png_check_keyword(png_ptr, key, new_key); -+ -+ if (key_len == 0) -+ png_error(png_ptr, "iTXt: invalid keyword"); -+ -+ /* Set the compression flag */ -+ switch (compression) - { -- png_warning(png_ptr, "Empty language field in iTXt chunk"); -- new_lang = NULL; -- lang_len = 0; -+ case PNG_ITXT_COMPRESSION_NONE: -+ case PNG_TEXT_COMPRESSION_NONE: -+ compression = new_key[++key_len] = 0; /* no compression */ -+ break; -+ -+ case PNG_TEXT_COMPRESSION_zTXt: -+ case PNG_ITXT_COMPRESSION_zTXt: -+ compression = new_key[++key_len] = 1; /* compressed */ -+ break; -+ -+ default: -+ png_error(png_ptr, "iTXt: invalid compression"); - } - -- if (lang_key == NULL) -- lang_key_len = 0; -- -- else -- lang_key_len = png_strlen(lang_key); -- -- if (text == NULL) -- text_len = 0; -- -- else -- text_len = png_strlen(text); -- -- /* Compute the compressed data; do it now for the length */ -- text_len = png_text_compress(png_ptr, text, text_len, compression - 2, -- &comp); -- -- -- /* Make sure we include the compression flag, the compression byte, -- * and the NULs after the key, lang, and lang_key parts -- */ -- -- png_write_chunk_start(png_ptr, png_iTXt, (png_uint_32)( -- 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ -- + key_len -- + lang_len -- + lang_key_len -- + text_len)); -+ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; -+ ++key_len; /* for the keywod separator */ - - /* We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of -- * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. -+ * any non-Latin-1 characters except for NEWLINE. ISO PNG, however, -+ * specifies that the text is UTF-8 and this really doesn't require any -+ * checking. -+ * - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. -+ * -+ * TODO: validate the language tag correctly (see the spec.) - */ -- png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); -- -- /* Set the compression flag */ -- if (compression == PNG_ITXT_COMPRESSION_NONE || -- compression == PNG_TEXT_COMPRESSION_NONE) -- cbuf[0] = 0; -- -- else /* compression == PNG_ITXT_COMPRESSION_zTXt */ -- cbuf[0] = 1; -- -- /* Set the compression method */ -- cbuf[1] = 0; -- -- png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); -- -- cbuf[0] = 0; -- png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), -- (png_size_t)(lang_len + 1)); -- -- png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), -- (png_size_t)(lang_key_len + 1)); -- -- png_write_compressed_data_out(png_ptr, &comp); -+ if (lang == NULL) lang = ""; /* empty language is valid */ -+ lang_len = strlen(lang)+1; -+ if (lang_key == NULL) lang_key = ""; /* may be empty */ -+ lang_key_len = strlen(lang_key)+1; -+ if (text == NULL) text = ""; /* may be empty */ -+ -+ prefix_len = key_len; -+ if (lang_len > PNG_UINT_31_MAX-prefix_len) -+ prefix_len = PNG_UINT_31_MAX; -+ else -+ prefix_len = (png_uint_32)(prefix_len + lang_len); -+ -+ if (lang_key_len > PNG_UINT_31_MAX-prefix_len) -+ prefix_len = PNG_UINT_31_MAX; -+ else -+ prefix_len = (png_uint_32)(prefix_len + lang_key_len); -+ -+ png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); -+ -+ if (compression != 0) -+ { -+ if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) -+ png_error(png_ptr, png_ptr->zstream.msg); -+ } -+ -+ else -+ { -+ if (comp.input_len > PNG_UINT_31_MAX-prefix_len) -+ png_error(png_ptr, "iTXt: uncompressed text too long"); -+ -+ /* So the string will fit in a chunk: */ -+ comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; -+ } -+ -+ png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); -+ -+ png_write_chunk_data(png_ptr, new_key, key_len); -+ -+ png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); -+ -+ png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); -+ -+ if (compression != 0) -+ png_write_compressed_data_out(png_ptr, &comp); -+ -+ else -+ png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len); - - png_write_chunk_end(png_ptr); -- -- png_free(png_ptr, new_key); -- png_free(png_ptr, new_lang); - } - #endif - - #ifdef PNG_WRITE_oFFs_SUPPORTED - /* Write the oFFs chunk */ - void /* PRIVATE */ --png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, -+png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, - int unit_type) - { -- PNG_oFFs; - png_byte buf[9]; - - png_debug(1, "in png_write_oFFs"); -@@ -1876,52 +1816,57 @@ - png_save_int_32(buf + 4, y_offset); - buf[8] = (png_byte)unit_type; - -- png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); -+ png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); - } - #endif - #ifdef PNG_WRITE_pCAL_SUPPORTED - /* Write the pCAL chunk (described in the PNG extensions document) */ - void /* PRIVATE */ --png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, -+png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, - png_int_32 X1, int type, int nparams, png_const_charp units, - png_charpp params) - { -- PNG_pCAL; -- png_size_t purpose_len, units_len, total_len; -- png_uint_32p params_len; -+ png_uint_32 purpose_len; -+ png_size_t units_len, total_len; -+ png_size_tp params_len; - png_byte buf[10]; -- png_charp new_purpose; -+ png_byte new_purpose[80]; - int i; - - png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); - - if (type >= PNG_EQUATION_LAST) -- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); -- -- purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; -+ png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); -+ -+ purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); -+ -+ if (purpose_len == 0) -+ png_error(png_ptr, "pCAL: invalid keyword"); -+ -+ ++purpose_len; /* terminator */ -+ - png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); -- units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); -+ units_len = strlen(units) + (nparams == 0 ? 0 : 1); - png_debug1(3, "pCAL units length = %d", (int)units_len); - total_len = purpose_len + units_len + 10; - -- params_len = (png_uint_32p)png_malloc(png_ptr, -- (png_alloc_size_t)(nparams * png_sizeof(png_uint_32))); -+ params_len = (png_size_tp)png_malloc(png_ptr, -+ (png_alloc_size_t)(nparams * (sizeof (png_size_t)))); - - /* Find the length of each parameter, making sure we don't count the - * null terminator for the last parameter. - */ - for (i = 0; i < nparams; i++) - { -- params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); -+ params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); - png_debug2(3, "pCAL parameter %d length = %lu", i, - (unsigned long)params_len[i]); -- total_len += (png_size_t)params_len[i]; -+ total_len += params_len[i]; - } - - png_debug1(3, "pCAL total length = %d", (int)total_len); -- png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); -- png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, -- (png_size_t)purpose_len); -+ png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); -+ png_write_chunk_data(png_ptr, new_purpose, purpose_len); - png_save_int_32(buf, X0); - png_save_int_32(buf + 4, X1); - buf[8] = (png_byte)type; -@@ -1929,12 +1874,9 @@ - png_write_chunk_data(png_ptr, buf, (png_size_t)10); - png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); - -- png_free(png_ptr, new_purpose); -- - for (i = 0; i < nparams; i++) - { -- png_write_chunk_data(png_ptr, (png_const_bytep)params[i], -- (png_size_t)params_len[i]); -+ png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); - } - - png_free(png_ptr, params_len); -@@ -1945,17 +1887,16 @@ - #ifdef PNG_WRITE_sCAL_SUPPORTED - /* Write the sCAL chunk */ - void /* PRIVATE */ --png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, -+png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, - png_const_charp height) - { -- PNG_sCAL; - png_byte buf[64]; - png_size_t wlen, hlen, total_len; - - png_debug(1, "in png_write_sCAL_s"); - -- wlen = png_strlen(width); -- hlen = png_strlen(height); -+ wlen = strlen(width); -+ hlen = strlen(height); - total_len = wlen + hlen + 2; - - if (total_len > 64) -@@ -1965,22 +1906,21 @@ - } - - buf[0] = (png_byte)unit; -- png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ -- png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ -+ memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ -+ memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ - - png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); -- png_write_chunk(png_ptr, png_sCAL, buf, total_len); -+ png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); - } - #endif - - #ifdef PNG_WRITE_pHYs_SUPPORTED - /* Write the pHYs chunk */ - void /* PRIVATE */ --png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, -+png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, - png_uint_32 y_pixels_per_unit, - int unit_type) - { -- PNG_pHYs; - png_byte buf[9]; - - png_debug(1, "in png_write_pHYs"); -@@ -1992,7 +1932,7 @@ - png_save_uint_32(buf + 4, y_pixels_per_unit); - buf[8] = (png_byte)unit_type; - -- png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); -+ png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); - } - #endif - -@@ -2001,9 +1941,8 @@ - * or png_convert_from_time_t(), or fill in the structure yourself. - */ - void /* PRIVATE */ --png_write_tIME(png_structp png_ptr, png_const_timep mod_time) -+png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) - { -- PNG_tIME; - png_byte buf[7]; - - png_debug(1, "in png_write_tIME"); -@@ -2023,40 +1962,44 @@ - buf[5] = mod_time->minute; - buf[6] = mod_time->second; - -- png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); -+ png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); - } - #endif - - /* Initializes the row writing capability of libpng */ - void /* PRIVATE */ --png_write_start_row(png_structp png_ptr) -+png_write_start_row(png_structrp png_ptr) - { - #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ -- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; -+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ -- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ -- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; -+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ -- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - #endif - -- png_size_t buf_size; -+ png_alloc_size_t buf_size; -+ int usr_pixel_depth; - - png_debug(1, "in png_write_start_row"); - -- buf_size = (png_size_t)(PNG_ROWBYTES( -- png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); -+ usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; -+ buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; -+ -+ /* 1.5.6: added to allow checking in the row write code. */ -+ png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; -+ png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; - - /* Set up row buffer */ -- png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, -- (png_alloc_size_t)buf_size); -+ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); - - png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; - -@@ -2070,13 +2013,13 @@ - } - - /* We only need to keep the previous row if we are using one of these. */ -- if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) -+ if ((png_ptr->do_filter & -+ (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) - { - /* Set up previous row buffer */ -- png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, -- (png_alloc_size_t)buf_size); -- -- if (png_ptr->do_filter & PNG_FILTER_UP) -+ png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); -+ -+ if ((png_ptr->do_filter & PNG_FILTER_UP) != 0) - { - png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); -@@ -2084,7 +2027,7 @@ - png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; - } - -- if (png_ptr->do_filter & PNG_FILTER_AVG) -+ if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0) - { - png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); -@@ -2092,7 +2035,7 @@ - png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; - } - -- if (png_ptr->do_filter & PNG_FILTER_PAETH) -+ if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0) - { - png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - png_ptr->rowbytes + 1); -@@ -2100,13 +2043,13 @@ - png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; - } - } --#endif /* PNG_WRITE_FILTER_SUPPORTED */ -+#endif /* WRITE_FILTER */ - - #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, we need to set up width and height of pass */ -- if (png_ptr->interlaced) -+ if (png_ptr->interlaced != 0) - { -- if (!(png_ptr->transformations & PNG_INTERLACE)) -+ if ((png_ptr->transformations & PNG_INTERLACE) == 0) - { - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; -@@ -2128,34 +2071,28 @@ - png_ptr->num_rows = png_ptr->height; - png_ptr->usr_width = png_ptr->width; - } -- -- png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT); -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -- png_ptr->zstream.next_out = png_ptr->zbuf; - } - - /* Internal use only. Called when finished processing a row of data. */ - void /* PRIVATE */ --png_write_finish_row(png_structp png_ptr) -+png_write_finish_row(png_structrp png_ptr) - { - #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ -- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; -+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ -- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ -- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; -+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ -- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - #endif - -- int ret; -- - png_debug(1, "in png_write_finish_row"); - - /* Next row */ -@@ -2167,10 +2104,10 @@ - - #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, go to next pass */ -- if (png_ptr->interlaced) -+ if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; -- if (png_ptr->transformations & PNG_INTERLACE) -+ if ((png_ptr->transformations & PNG_INTERLACE) != 0) - { - png_ptr->pass++; - } -@@ -2195,7 +2132,7 @@ - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - -- if (png_ptr->transformations & PNG_INTERLACE) -+ if ((png_ptr->transformations & PNG_INTERLACE) != 0) - break; - - } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); -@@ -2206,7 +2143,7 @@ - if (png_ptr->pass < 7) - { - if (png_ptr->prev_row != NULL) -- png_memset(png_ptr->prev_row, 0, -+ memset(png_ptr->prev_row, 0, - (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* - png_ptr->usr_bit_depth, png_ptr->width)) + 1); - -@@ -2217,42 +2154,7 @@ - - /* If we get here, we've just written the last row, so we need - to flush the compressor */ -- do -- { -- /* Tell the compressor we are done */ -- ret = deflate(&png_ptr->zstream, Z_FINISH); -- -- /* Check for an error */ -- if (ret == Z_OK) -- { -- /* Check to see if we need more room */ -- if (!(png_ptr->zstream.avail_out)) -- { -- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); -- png_ptr->zstream.next_out = png_ptr->zbuf; -- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; -- } -- } -- -- else if (ret != Z_STREAM_END) -- { -- if (png_ptr->zstream.msg != NULL) -- png_error(png_ptr, png_ptr->zstream.msg); -- -- else -- png_error(png_ptr, "zlib error"); -- } -- } while (ret != Z_STREAM_END); -- -- /* Write any extra space */ -- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) -- { -- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - -- png_ptr->zstream.avail_out); -- } -- -- png_zlib_release(png_ptr); -- png_ptr->zstream.data_type = Z_BINARY; -+ png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); - } - - #ifdef PNG_WRITE_INTERLACING_SUPPORTED -@@ -2269,10 +2171,10 @@ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ -- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; -+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ -- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_write_interlace"); - -@@ -2416,7 +2318,7 @@ - - /* Move the pixel */ - if (dp != sp) -- png_memcpy(dp, sp, pixel_bytes); -+ memcpy(dp, sp, pixel_bytes); - - /* Next pixel */ - dp += pixel_bytes; -@@ -2440,14 +2342,16 @@ - * been specified by the application, and then writes the row out with the - * chosen filter. - */ --static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row); -+static void -+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, -+ png_size_t row_bytes); - - #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) - #define PNG_HISHIFT 10 - #define PNG_LOMASK ((png_uint_32)0xffffL) - #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) - void /* PRIVATE */ --png_write_find_filter(png_structp png_ptr, png_row_infop row_info) -+png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) - { - png_bytep best_row; - #ifdef PNG_WRITE_FILTER_SUPPORTED -@@ -2456,7 +2360,7 @@ - png_byte filter_to_do = png_ptr->do_filter; - png_size_t row_bytes = row_info->rowbytes; - #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -- int num_p_filters = (int)png_ptr->num_prev_filters; -+ int num_p_filters = png_ptr->num_prev_filters; - #endif - - png_debug(1, "in png_write_find_filter"); -@@ -2507,7 +2411,7 @@ - /* We don't need to test the 'no filter' case if this is the only filter - * that has been chosen, as it doesn't actually do anything to the data. - */ -- if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) -+ if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE) - { - png_bytep rp; - png_uint_32 sum = 0; -@@ -2583,7 +2487,7 @@ - best_row = png_ptr->sub_row; - } - -- else if (filter_to_do & PNG_FILTER_SUB) -+ else if ((filter_to_do & PNG_FILTER_SUB) != 0) - { - png_bytep rp, dp, lp; - png_uint_32 sum = 0, lmins = mins; -@@ -2704,7 +2608,7 @@ - best_row = png_ptr->up_row; - } - -- else if (filter_to_do & PNG_FILTER_UP) -+ else if ((filter_to_do & PNG_FILTER_UP) != 0) - { - png_bytep rp, dp, pp; - png_uint_32 sum = 0, lmins = mins; -@@ -2818,7 +2722,7 @@ - best_row = png_ptr->avg_row; - } - -- else if (filter_to_do & PNG_FILTER_AVG) -+ else if ((filter_to_do & PNG_FILTER_AVG) != 0) - { - png_bytep rp, dp, pp, lp; - png_uint_32 sum = 0, lmins = mins; -@@ -2920,7 +2824,7 @@ - } - - /* Paeth filter */ -- if (filter_to_do == PNG_FILTER_PAETH) -+ if ((filter_to_do == PNG_FILTER_PAETH) != 0) - { - png_bytep rp, dp, pp, cp, lp; - png_size_t i; -@@ -2959,7 +2863,7 @@ - best_row = png_ptr->paeth_row; - } - -- else if (filter_to_do & PNG_FILTER_PAETH) -+ else if ((filter_to_do & PNG_FILTER_PAETH) != 0) - { - png_bytep rp, dp, pp, cp, lp; - png_uint_32 sum = 0, lmins = mins; -@@ -3029,7 +2933,7 @@ - pc = (p + pc) < 0 ? -(p + pc) : p + pc; - #endif - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; --#else /* PNG_SLOW_PAETH */ -+#else /* SLOW_PAETH */ - p = a + b - c; - pa = abs(p - a); - pb = abs(p - b); -@@ -3043,7 +2947,7 @@ - - else - p = c; --#endif /* PNG_SLOW_PAETH */ -+#endif /* SLOW_PAETH */ - - v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); - -@@ -3092,10 +2996,10 @@ - best_row = png_ptr->paeth_row; - } - } --#endif /* PNG_WRITE_FILTER_SUPPORTED */ -+#endif /* WRITE_FILTER */ -+ - /* Do the actual writing of the filtered row data from the chosen filter. */ -- -- png_write_filtered_row(png_ptr, best_row); -+ png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); - - #ifdef PNG_WRITE_FILTER_SUPPORTED - #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -@@ -3112,74 +3016,20 @@ - png_ptr->prev_filters[j] = best_row[0]; - } - #endif --#endif /* PNG_WRITE_FILTER_SUPPORTED */ -+#endif /* WRITE_FILTER */ - } - - - /* Do the actual writing of a previously filtered row. */ - static void --png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) -+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, -+ png_size_t full_row_length/*includes filter byte*/) - { -- png_size_t avail; -- - png_debug(1, "in png_write_filtered_row"); - - png_debug1(2, "filter = %d", filtered_row[0]); -- /* Set up the zlib input buffer */ -- -- png_ptr->zstream.next_in = filtered_row; -- png_ptr->zstream.avail_in = 0; -- avail = png_ptr->row_info.rowbytes + 1; -- /* Repeat until we have compressed all the data */ -- do -- { -- int ret; /* Return of zlib */ -- -- /* Record the number of bytes available - zlib supports at least 65535 -- * bytes at one step, depending on the size of the zlib type 'uInt', the -- * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). -- * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. -- * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a -- * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called -- * with smaller chunks of data. -- */ -- if (png_ptr->zstream.avail_in == 0) -- { -- if (avail > ZLIB_IO_MAX) -- { -- png_ptr->zstream.avail_in = ZLIB_IO_MAX; -- avail -= ZLIB_IO_MAX; -- } -- -- else -- { -- /* So this will fit in the available uInt space: */ -- png_ptr->zstream.avail_in = (uInt)avail; -- avail = 0; -- } -- } -- -- /* Compress the data */ -- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); -- -- /* Check for compression errors */ -- if (ret != Z_OK) -- { -- if (png_ptr->zstream.msg != NULL) -- png_error(png_ptr, png_ptr->zstream.msg); -- -- else -- png_error(png_ptr, "zlib error"); -- } -- -- /* See if it is time to write another IDAT */ -- if (!(png_ptr->zstream.avail_out)) -- { -- /* Write the IDAT and reset the zlib output buffer */ -- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); -- } -- /* Repeat until all data has been compressed */ -- } while (avail > 0 || png_ptr->zstream.avail_in > 0); -+ -+ png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); - - /* Swap the current and previous rows */ - if (png_ptr->prev_row != NULL) -@@ -3202,6 +3052,6 @@ - { - png_write_flush(png_ptr); - } --#endif -+#endif /* WRITE_FLUSH */ - } --#endif /* PNG_WRITE_SUPPORTED */ -+#endif /* WRITE */ ---- ./jdk/src/share/native/sun/font/layout/LETableReference.h Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/font/layout/LETableReference.h Thu Feb 05 13:00:26 2015 +0100 -@@ -150,8 +150,8 @@ - if(isEmpty()) { - //err = LE_MISSING_FONT_TABLE_ERROR; - clear(); // it's just empty. Not an error. -- } else if(offset >= fParent->fLength) { -- LE_DEBUG_TR3("offset out of range: (%p) +%d", NULL, offset); -+ } else if(offset >= fParent->fLength || (offset & 0x01)) { -+ LE_DEBUG_TR3("offset out of range or odd alignment: (%p) +%d", NULL, offset); - err = LE_INDEX_OUT_OF_BOUNDS_ERROR; - clear(); - } else { ---- ./jdk/src/share/native/sun/font/layout/LigatureSubstProc.cpp Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/font/layout/LigatureSubstProc.cpp Thu Feb 05 13:00:26 2015 +0100 -@@ -115,7 +115,7 @@ - LE_DEBUG_BAD_FONT("off end of ligature substitution header"); - return newState; // get out! bad font - } -- if(componentGlyph > glyphStorage.getGlyphCount()) { -+ if(componentGlyph >= glyphStorage.getGlyphCount()) { - LE_DEBUG_BAD_FONT("preposterous componentGlyph"); - currGlyph++; - return newState; // get out! bad font ---- ./jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Thu Feb 05 13:00:26 2015 +0100 -@@ -119,7 +119,7 @@ - - offset = action & lafComponentOffsetMask; - if (offset != 0) { -- if(componentGlyph > glyphStorage.getGlyphCount()) { -+ if(componentGlyph >= glyphStorage.getGlyphCount()) { - LE_DEBUG_BAD_FONT("preposterous componentGlyph"); - currGlyph+= dir; - return nextStateIndex; // get out! bad font ---- ./jdk/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Thu Feb 05 13:00:26 2015 +0100 -@@ -58,7 +58,7 @@ - if( LE_FAILURE(success) ) { return 0; } - le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount); - -- LEReferenceTo<Offset> ligatureTableOffsetArray(base, success, ligSetTable->ligatureTableOffsetArray, ligCount); -+ LEReferenceToArrayOf<Offset> ligatureTableOffsetArray(base, success, ligSetTable->ligatureTableOffsetArray, ligCount); - for (le_uint16 lig = 0; LE_SUCCESS(success) && lig < ligCount; lig += 1) { - Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]); - LEReferenceTo<LigatureTable> ligTable(ligSetTable, success, ligTableOffset); ---- ./jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Thu Feb 05 13:00:26 2015 +0100 -@@ -255,6 +255,7 @@ - - if (requiredFeatureIndex != 0xFFFF) { - requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success); -+ if (LE_FAILURE(success)) return; - featureReferences += SWAPW(requiredFeatureTable->lookupCount); - } - -@@ -292,7 +293,7 @@ - } - - featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success); -- -+ if (LE_FAILURE(success)) continue; - if (featureTag == fm.tag) { - count += selectLookups(featureTable, fm.mask, order + count, success); - } -@@ -319,7 +320,7 @@ - #endif - - featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success); -- -+ if (LE_FAILURE(success)) continue; - if (featureTag == fm.tag) { - order += selectLookups(featureTable, fm.mask, order, success); - } ---- ./jdk/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Thu Feb 05 13:00:26 2015 +0100 -@@ -71,7 +71,12 @@ - if (coverageIndex >= 0 && coverageIndex < seqCount) { - Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]); - LEReferenceTo<SequenceTable> sequenceTable(base, success, sequenceTableOffset); -+ if (LE_FAILURE(success)) { -+ return 0; -+ } - le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount); -+ LEReferenceToArrayOf<Offset> -+ substituteArrayRef(base, success, sequenceTable->substituteArray, glyphCount); - - if (glyphCount == 0) { - glyphIterator->setCurrGlyphID(0xFFFF); ---- ./jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -281,9 +281,7 @@ - /* for changing the visible shape of a window to an nonrectangular form */ - void - SplashUpdateShape(Splash * splash) { -- if (!shapeSupported) -- return; -- if (!splash->maskRequired) { -+ if (splash->currentFrame < 0 || !shapeSupported || !splash->maskRequired) { - return; - } - XShapeCombineRectangles(splash->display, splash->window, ShapeClip, 0, 0, -@@ -324,6 +322,10 @@ - - void - SplashRedrawWindow(Splash * splash) { -+ if (splash->currentFrame < 0) { -+ return; -+ } -+ - XImage *ximage; - - // making this method redraw a part of the image does not make ---- ./jdk/test/Makefile Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/Makefile Thu Feb 05 13:00:26 2015 +0100 -@@ -262,8 +262,8 @@ - EXTRA_JTREG_OPTIONS += -concurrency:$(CONCURRENCY) - endif - --# Default JTREG to run (win32 script works for everybody) --JTREG = $(JT_HOME)/win32/bin/jtreg -+# Default JTREG to run -+JTREG = $(JT_HOME)/bin/jtreg - # run in agentvm mode - JTREG_BASIC_OPTIONS += -agentvm - # Only run automatic tests ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ./jdk/test/java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java Thu Feb 05 13:00:26 2015 +0100 -@@ -0,0 +1,162 @@ -+/* -+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+import java.awt.Color; -+import java.awt.Font; -+import java.awt.Graphics2D; -+import java.awt.RenderingHints; -+import java.awt.geom.AffineTransform; -+import java.awt.image.BufferedImage; -+import java.io.File; -+import java.io.IOException; -+ -+import javax.imageio.ImageIO; -+ -+import static java.awt.image.BufferedImage.TYPE_INT_RGB; -+import static java.lang.Math.toRadians; -+ -+/** -+ * @test -+ * @bug 8065373 -+ * @summary Verifies that we get correct direction, when draw rotated string. -+ * @author Sergey Bylokhov -+ * @run main DrawRotatedStringUsingRotatedFont -+ */ -+public final class DrawRotatedStringUsingRotatedFont { -+ -+ private static final int SIZE = 500; -+ private static final String STR = "MMMMMMMMMMMMMMMM"; -+ -+ private static AffineTransform[] txs = { -+ AffineTransform.getRotateInstance(toRadians(00)), -+ AffineTransform.getRotateInstance(toRadians(45)), -+ AffineTransform.getRotateInstance(toRadians(-45)), -+ AffineTransform.getRotateInstance(toRadians(90)), -+ AffineTransform.getRotateInstance(toRadians(-90)), -+ AffineTransform.getRotateInstance(toRadians(135)), -+ AffineTransform.getRotateInstance(toRadians(-135)), -+ AffineTransform.getRotateInstance(toRadians(180)), -+ AffineTransform.getRotateInstance(toRadians(-180)), -+ AffineTransform.getRotateInstance(toRadians(225)), -+ AffineTransform.getRotateInstance(toRadians(-225)), -+ AffineTransform.getRotateInstance(toRadians(270)), -+ AffineTransform.getRotateInstance(toRadians(-270)), -+ AffineTransform.getRotateInstance(toRadians(315)), -+ AffineTransform.getRotateInstance(toRadians(-315)), -+ AffineTransform.getRotateInstance(toRadians(360)), -+ AffineTransform.getRotateInstance(toRadians(-360)) -+ }; -+ -+ public static void main(final String[] args) throws IOException { -+ for (final AffineTransform tx2 : txs) { -+ for (final AffineTransform tx1 : txs) { -+ for (final boolean aa : new boolean[]{true, false}) { -+ final BufferedImage bi1 = createImage(aa, tx1, tx2); -+ final BufferedImage bi2 = createImage(aa, tx2, tx1); -+ compareImage(bi1, bi2); -+ fillTextArea(bi1, tx1, tx2); -+ fillTextArea(bi2, tx2, tx1); -+ checkColors(bi1, bi2); -+ } -+ } -+ } -+ System.out.println("Passed"); -+ } -+ -+ /** -+ * Compares two images. -+ */ -+ private static void compareImage(final BufferedImage bi1, -+ final BufferedImage bi2) -+ throws IOException { -+ for (int i = 0; i < SIZE; ++i) { -+ for (int j = 0; j < SIZE; ++j) { -+ if (bi1.getRGB(i, j) != bi2.getRGB(i, j)) { -+ ImageIO.write(bi1, "png", new File("image1.png")); -+ ImageIO.write(bi2, "png", new File("image2.png")); -+ throw new RuntimeException("Failed: wrong text location"); -+ } -+ } -+ } -+ } -+ -+ /** -+ * Checks an image color. RED and GREEN are allowed only. -+ */ -+ private static void checkColors(final BufferedImage bi1, -+ final BufferedImage bi2) -+ throws IOException { -+ for (int i = 0; i < SIZE; ++i) { -+ for (int j = 0; j < SIZE; ++j) { -+ final int rgb1 = bi1.getRGB(i, j); -+ final int rgb2 = bi2.getRGB(i, j); -+ if (rgb1 != rgb2 || rgb1 != 0xFFFF0000 && rgb1 != 0xFF00FF00) { -+ ImageIO.write(bi1, "png", new File("image1.png")); -+ ImageIO.write(bi2, "png", new File("image2.png")); -+ throw new RuntimeException("Failed: wrong text location"); -+ } -+ } -+ } -+ } -+ -+ /** -+ * Creates an BufferedImage and draws a text, using two transformations, -+ * one for graphics and one for font. -+ */ -+ private static BufferedImage createImage(final boolean aa, -+ final AffineTransform gtx, -+ final AffineTransform ftx) { -+ final BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_RGB); -+ final Graphics2D bg = bi.createGraphics(); -+ bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, -+ aa ? RenderingHints.VALUE_ANTIALIAS_ON -+ : RenderingHints.VALUE_ANTIALIAS_OFF); -+ bg.setColor(Color.RED); -+ bg.fillRect(0, 0, SIZE, SIZE); -+ bg.translate(100, 100); -+ bg.transform(gtx); -+ bg.setColor(Color.BLACK); -+ bg.setFont(bg.getFont().deriveFont(20.0f).deriveFont(ftx)); -+ bg.drawString(STR, 0, 0); -+ bg.dispose(); -+ return bi; -+ } -+ -+ /** -+ * Fills the area of text using green solid color. -+ */ -+ private static void fillTextArea(final BufferedImage bi, -+ final AffineTransform tx1, -+ final AffineTransform tx2) { -+ final Graphics2D bg = bi.createGraphics(); -+ bg.translate(100, 100); -+ bg.transform(tx1); -+ bg.transform(tx2); -+ bg.setColor(Color.GREEN); -+ final Font font = bg.getFont().deriveFont(20.0f); -+ bg.setFont(font); -+ bg.fill(font.getStringBounds(STR, bg.getFontRenderContext())); -+ bg.dispose(); -+ } -+} -+ ---- ./jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Thu Feb 05 13:00:26 2015 +0100 -@@ -36,7 +36,7 @@ - import sun.java2d.SunGraphics2D; - - /** -- * @test -+ * test - * @bug 8043869 - * @author Alexander Scherbatiy - * @summary [macosx] java -splash does not honor 2x hi dpi notation for retina ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ./jdk/test/java/net/Socks/BadProxySelector.java Thu Feb 05 13:00:26 2015 +0100 -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+/* -+ * @test -+ * @bug 7178362 -+ * @run main/othervm BadProxySelector -+ */ -+ -+import java.net.InetSocketAddress; -+import java.net.Proxy; -+import java.net.ProxySelector; -+import java.net.Socket; -+import java.net.SocketAddress; -+import java.net.ServerSocket; -+import java.net.URI; -+import java.util.ArrayList; -+import java.util.List; -+import java.io.*; -+ -+public class BadProxySelector { -+ public static void main(String[] args) throws Exception { -+ ProxySelector.setDefault(new HTTPProxySelector()); -+ try (ServerSocket ss = new ServerSocket(0); -+ Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); -+ Socket s2 = ss.accept()) { -+ } -+ -+ ProxySelector.setDefault(new NullHTTPProxySelector()); -+ try (ServerSocket ss = new ServerSocket(0); -+ Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); -+ Socket s2 = ss.accept()) { -+ } -+ } -+ -+ // always returns bogus HTTP proxies -+ private static class HTTPProxySelector extends ProxySelector { -+ @Override -+ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {} -+ -+ @Override -+ public List<Proxy> select(URI uri) { -+ List<Proxy> proxies = new ArrayList<>(); -+ proxies.add(new Proxy(Proxy.Type.HTTP, -+ new InetSocketAddress("localhost", 0))); -+ proxies.add(new Proxy(Proxy.Type.HTTP, -+ new InetSocketAddress("localhost", 0))); -+ return proxies; -+ } -+ } -+ -+ private static class NullHTTPProxySelector extends ProxySelector { -+ @Override -+ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {} -+ -+ @Override -+ public List<Proxy> select(URI uri) { -+ List<Proxy> proxies = new ArrayList<>(); -+ proxies.add(null); -+ proxies.add(new Proxy(Proxy.Type.HTTP, -+ new InetSocketAddress("localhost", 0))); -+ return proxies; -+ } -+ } -+} ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ./jdk/test/javax/xml/jaxp/transform/8062923/XslSubstringTest.java Thu Feb 05 13:00:26 2015 +0100 -@@ -0,0 +1,104 @@ -+/* -+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+/** -+ * @test -+ * @bug 8062923 8062924 -+ * @run testng XslSubstringTest -+ * @summary Test xsl substring function with negative, Inf and -+ * NaN length and few other use cases -+ */ -+ -+import java.io.StringReader; -+import java.io.StringWriter; -+import javax.xml.transform.Source; -+import javax.xml.transform.Templates; -+import javax.xml.transform.Transformer; -+import javax.xml.transform.TransformerFactory; -+import javax.xml.transform.stream.StreamResult; -+import javax.xml.transform.stream.StreamSource; -+ -+import static org.testng.Assert.assertEquals; -+import org.testng.annotations.Test; -+ -+public class XslSubstringTest { -+ -+ final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test></test>"; -+ final String xslPre = "<xsl:stylesheet version='1.0'" -+ + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" -+ + "<xsl:output method='xml' indent='yes' omit-xml-declaration='yes'/>" -+ + "<xsl:template match='/'><t>"; -+ final String xslPost = "</t></xsl:template></xsl:stylesheet>"; -+ -+ private String testTransform(String xsl) throws Exception { -+ //Prepare sources for transormation -+ Source src = new StreamSource(new StringReader(xml)); -+ Source xslsrc = new StreamSource(new StringReader(xslPre + xsl + xslPost)); -+ //Create factory, template and transformer -+ TransformerFactory tf = TransformerFactory.newInstance(); -+ Templates tmpl = tf.newTemplates(xslsrc); -+ Transformer t = tmpl.newTransformer(); -+ //Prepare output stream -+ StringWriter xmlResultString = new StringWriter(); -+ StreamResult xmlResultStream = new StreamResult(xmlResultString); -+ //Transform -+ t.transform(src, xmlResultStream); -+ return xmlResultString.toString().trim(); -+ } -+ -+ @Test -+ public void test8062923() throws Exception { -+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1)\"/>|"), -+ "<t>||</t>"); -+ } -+ -+ @Test -+ public void test8062924() throws Exception { -+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1 div 0)\"/>|"), -+ "<t>||</t>"); -+ } -+ -+ @Test -+ public void testGeneral1() throws Exception { -+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 1)\"/>|"), -+ "<t>|s|</t>"); -+ } -+ -+ @Test -+ public void testGeneral2() throws Exception { -+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 1 div 0)\"/>|"), -+ "<t>|sdf|</t>"); -+ } -+ -+ @Test -+ public void testGeneral3() throws Exception { -+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, -0 div 0)\"/>|"), -+ "<t>||</t>"); -+ } -+ -+ @Test -+ public void testGeneral4() throws Exception { -+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 0 div 0)\"/>|"), -+ "<t>||</t>"); -+ } -+} ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ./jdk/test/javax/xml/ws/8046817/GenerateEnumSchema.java Thu Feb 05 13:00:26 2015 +0100 -@@ -0,0 +1,134 @@ -+/* -+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+/* -+ * @test -+ * @bug 8046817 -+ * @summary schemagen fails to generate xsd for enum types -+ * @run main/othervm GenerateEnumSchema -+ */ -+import java.io.BufferedReader; -+import java.io.File; -+import java.io.FileNotFoundException; -+import java.io.IOException; -+import java.io.InputStreamReader; -+import java.nio.file.Paths; -+import java.util.Scanner; -+ -+public class GenerateEnumSchema { -+ -+ private static final String SCHEMA_OUTPUT_FILENAME = "schema1.xsd"; -+ private static final File schemaOutputFile = new File(SCHEMA_OUTPUT_FILENAME); -+ -+ public static void main(String[] args) throws Exception, IOException { -+ //Check schema generation for class type -+ runSchemaGen("TestClassType.java"); -+ checkIfSchemaGenerated(); -+ checkSchemaContent("<xs:complexType name=\"testClassType\">"); -+ checkSchemaContent("<xs:element name=\"a\" type=\"xs:int\"/>"); -+ schemaOutputFile.delete(); -+ //Check schema generation for enum type -+ runSchemaGen("TestEnumType.java"); -+ checkIfSchemaGenerated(); -+ checkSchemaContent("<xs:simpleType name=\"testEnumType\">"); -+ checkSchemaContent("<xs:enumeration value=\"ONE\"/>"); -+ checkSchemaContent("<xs:enumeration value=\"TWO\"/>"); -+ checkSchemaContent("<xs:enumeration value=\"THREE\"/>"); -+ schemaOutputFile.delete(); -+ } -+ -+ private static void checkIfSchemaGenerated() { -+ if (!schemaOutputFile.exists()) { -+ throw new RuntimeException("FAIL:" + SCHEMA_OUTPUT_FILENAME + " was not generated by schemagen tool"); -+ } -+ } -+ -+ private static void checkSchemaContent(String exp_token) throws FileNotFoundException { -+ System.out.print("Check if generated schema contains '" + exp_token + "' string: "); -+ try (Scanner scanner = new Scanner(schemaOutputFile)) { -+ if (scanner.findWithinHorizon(exp_token, 0) != null) { -+ System.out.println("OK"); -+ return; -+ } -+ } -+ System.out.println("FAIL"); -+ throw new RuntimeException("The '" + exp_token + "' is not found in generated schema"); -+ -+ } -+ -+ private static String getClassFilePath(String filename) { -+ String testSrc = System.getProperty("test.src"); -+ if (testSrc == null) { -+ testSrc = "."; -+ } -+ return Paths.get(testSrc).resolve(filename).toString(); -+ } -+ -+ private static String getSchemagen() { -+ String javaHome = System.getProperty("java.home"); -+ if (javaHome.endsWith("jre")) { -+ javaHome = new File(javaHome).getParent(); -+ } -+ String schemagen = javaHome + File.separator + "bin" + File.separator + "schemagen"; -+ if (System.getProperty("os.name").startsWith("Windows")) { -+ schemagen = schemagen.concat(".exe"); -+ } -+ return schemagen; -+ } -+ -+ private static void logOutput(Process p) throws IOException { -+ BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); -+ String s = r.readLine(); -+ while (s != null) { -+ System.out.println(s.trim()); -+ s = r.readLine(); -+ } -+ } -+ -+ private static void runSchemaGen(String classFile) { -+ String schemagen = getSchemagen(); -+ -+ try { -+ System.out.println("Call to schemagen: " + schemagen + " " + classFile); -+ String[] schemagen_args = { -+ schemagen, -+ getClassFilePath(classFile) -+ }; -+ -+ ProcessBuilder pb = new ProcessBuilder(schemagen_args); -+ pb.redirectErrorStream(true); -+ Process p = pb.start(); -+ logOutput(p); -+ int result = p.waitFor(); -+ p.destroy(); -+ -+ if (result != 0) { -+ throw new RuntimeException("schemagen failed"); -+ } -+ } catch (IOException | InterruptedException e) { -+ System.err.println("Can't run schemagen tool. Exception:"); -+ e.printStackTrace(System.err); -+ throw new RuntimeException("Error launching schemagen tool"); -+ } -+ } -+} ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ./jdk/test/javax/xml/ws/8046817/TestClassType.java Thu Feb 05 13:00:26 2015 +0100 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+import javax.xml.bind.annotation.XmlType; -+ -+@XmlType -+public class TestClassType { -+ public int a; -+} ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ./jdk/test/javax/xml/ws/8046817/TestEnumType.java Thu Feb 05 13:00:26 2015 +0100 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+ -+import javax.xml.bind.annotation.XmlEnum; -+ -+@XmlEnum(String.class) -+public enum TestEnumType { -+ ONE, TWO, THREE -+} ---- ./jdk/test/sun/security/krb5/ParseConfig.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/security/krb5/ParseConfig.java Thu Feb 05 13:00:26 2015 +0100 -@@ -22,7 +22,7 @@ - */ - /* - * @test -- * @bug 6319046 -+ * @bug 6319046 8055045 - * @compile -XDignore.symbol.file ParseConfig.java - * @run main/othervm ParseConfig - * @summary Problem with parsing krb5.conf -@@ -32,7 +32,8 @@ - - public class ParseConfig { - public static void main(String[] args) throws Exception { -- System.setProperty("java.security.krb5.conf", System.getProperty("test.src", ".") +"/krb5.conf"); -+ System.setProperty("java.security.krb5.conf", -+ System.getProperty("test.src", ".") + "/krb5.conf"); - Config config = Config.getInstance(); - config.listTable(); - -@@ -44,5 +45,11 @@ - expected + "\""); - } - } -+ -+ // JDK-8055045: IOOBE when reading an empty value -+ config.get("empty1", "NOVAL.COM"); -+ config.get("empty2", "NOVAL.COM"); -+ config.get("quote1", "NOVAL.COM"); -+ config.get("quote2", "NOVAL.COM"); - } - } ---- ./jdk/test/sun/security/krb5/krb5.conf Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/security/krb5/krb5.conf Thu Feb 05 13:00:26 2015 +0100 -@@ -27,3 +27,9 @@ - } - } - -+ NOVAL.COM = { -+ empty1 = -+ empty2 =. -+ quote1 = " -+ quote2 = ' -+ } ---- ./jdk/test/sun/security/tools/keytool/ListKeychainStore.sh Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/security/tools/keytool/ListKeychainStore.sh Thu Feb 05 13:00:26 2015 +0100 -@@ -1,5 +1,5 @@ - # --# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. -+# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - # - # This code is free software; you can redistribute it and/or modify it -@@ -22,7 +22,7 @@ - # - - # @test --# @bug 7133495 -+# @bug 7133495 8041740 - # @summary [macosx] KeyChain KeyStore implementation retrieves only one private key entry - - if [ "${TESTJAVA}" = "" ] ; then -@@ -49,8 +49,10 @@ - KEYTOOL="${TESTJAVA}/bin/keytool -storetype KeychainStore -keystore NONE -storepass $PWD" - TEMPORARY_P12="$TESTCLASSES/7133495.p12" - TEMPORARY_KC="$TESTCLASSES/7133495.keychain" -+TEMPORARY_LIST="$TESTCLASSES/7133495.tmp" - CLEANUP_P12="rm -f $TEMPORARY_P12" - CLEANUP_KC="security delete-keychain $TEMPORARY_KC" -+CLEANUP_LIST="rm -f $TEMPORARY_LIST" - - # Count the number of private key entries in the Keychain keystores - -@@ -115,6 +117,15 @@ - fi - echo "Imported keypairs from PKCS12 keystore into the keychain" - -+# Adjust the keychain search order -+ -+echo "\"$TEMPORARY_KC\"" > $TEMPORARY_LIST -+security list-keychains >> $TEMPORARY_LIST -+security list-keychains -s `xargs < ${TEMPORARY_LIST}` -+`$CLEANUP_LIST` -+echo "Temporary keychain search order:" -+security list-keychains -+ - # Recount the number of private key entries in the Keychain keystores - - COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l` ---- ./jdk/test/sun/security/util/HostnameMatcher/TestHostnameChecker.java Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/security/util/HostnameMatcher/TestHostnameChecker.java Thu Feb 05 13:00:26 2015 +0100 -@@ -187,6 +187,9 @@ - in = new FileInputStream(new File(PATH, "cert4.crt")); - X509Certificate cert4 = (X509Certificate)cf.generateCertificate(in); - in.close(); -+ in = new FileInputStream(new File(PATH, "cert5.crt")); -+ X509Certificate cert5 = (X509Certificate)cf.generateCertificate(in); -+ in.close(); - - HostnameChecker checker = HostnameChecker.getInstance( - HostnameChecker.TYPE_TLS); -@@ -202,6 +205,9 @@ - check(checker, "5.6.7.8", cert3, true); - check(checker, "foo.bar.com", cert4, true); - check(checker, "altfoo.bar.com", cert4, true); -+ check(checker, "2001:db8:3c4d:15::1a2f:1a2b", cert5, true); -+ check(checker, "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b", cert5, true); -+ check(checker, "2002:db8:3c4d:15::1a2f:1a2b", cert5, false); - - checker = HostnameChecker.getInstance( - HostnameChecker.TYPE_LDAP); ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ ./jdk/test/sun/security/util/HostnameMatcher/cert5.crt Thu Feb 05 13:00:26 2015 +0100 -@@ -0,0 +1,24 @@ -+-----BEGIN CERTIFICATE----- -+MIIECDCCAvCgAwIBAgIJAJaBmuUlfY8sMA0GCSqGSIb3DQEBBQUAMIGmMQswCQYD -+VQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJU29tZS1DaXR5 -+MSowKAYDVQQKDCFVbmNvbmZpZ3VyZWQgT3BlblNTTCBJbnN0YWxsYXRpb24xEDAO -+BgNVBAsMB3NlY3Rpb24xMDAuBgNVBAMMJzIwMDE6MGRiODozYzRkOjAwMTU6MDAw -+MDowMDAwOjFhMmY6MWEyYjAeFw0xNTAyMTAxODMzMjBaFw0xNTAzMTIxODMzMjBa -+MIGmMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJ -+U29tZS1DaXR5MSowKAYDVQQKDCFVbmNvbmZpZ3VyZWQgT3BlblNTTCBJbnN0YWxs -+YXRpb24xEDAOBgNVBAsMB3NlY3Rpb24xMDAuBgNVBAMMJzIwMDE6MGRiODozYzRk -+OjAwMTU6MDAwMDowMDAwOjFhMmY6MWEyYjCCASIwDQYJKoZIhvcNAQEBBQADggEP -+ADCCAQoCggEBAMcigWxmeF6Dmo3xAw3y/8d3vB8Th4YsmvwXb9DxwNWV+B3vxJgq -+ww6T6VBxrle1bgu/RtZDJwLf5vMhVElxuuE86di2qyurKFbpe29C9xnCxuMlXpje -+X2pNknz4ZzOqD4opmIAFjXZ2Xp1kLt+HJX7ABoz7Uga+IbVfDRPPf2KOqYNpBQkp -+dgI5VOZDQNVNb+8vdXDwyanMQ0TgPXKL4BQIkGB4RM8sgpPMUvB+tEB7zmUtgSco -+2a5M84wIhxv85CmFFoTVSzXsRCDhVAZj0aHRkkmAsMSmzPa4HiPnuVRV740oQjDy -+oMGLndaEs2nxIqckUFHOHcSTf0/wmcvPbIsCAwEAAaM3MDUwCQYDVR0TBAIwADAL -+BgNVHQ8EBAMCBeAwGwYDVR0RBBQwEocQIAENuDxNABUAAAAAGi8aKzANBgkqhkiG -+9w0BAQUFAAOCAQEAtnelRbYPPZRgTd4oxOiPqwc01EE9JgtkFWlooCwVUDChOR2k -+us1qlhKsvbN2Tcsm1Ss3p0Uxk/g1o2/mY8rA/dJ8qiN6jbfjpEi8b2MirP5tQSE0 -+QNXbVGr5FnLbuUmn+82pB0vBSaq7gxehbV6S7dteyQUnb2imltC5wS9PwYb8wWx7 -+IpyXWt0jkYkC8KJEevVYI7qtwpjYhyc1FqwzUiPmdqGz2AFLQ4RgTXJi93SPoyKM -+s65oPV+r6/0qwnslScxVfszHxxFn1Yfsc5Oseare1MnlNzH69PmWs523C/fBvnB2 -+MsHKLPdoN7uSpBLB7j46g5jQG/ceri/cquZKYA== -+-----END CERTIFICATE----- ---- ./jdk/test/sun/util/calendar/zi/tzdata/VERSION Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/VERSION Thu Feb 05 13:00:26 2015 +0100 -@@ -21,4 +21,4 @@ - # or visit www.oracle.com if you need additional information or have any - # questions. - # --tzdata2014j -+tzdata2015a ---- ./jdk/test/sun/util/calendar/zi/tzdata/antarctica Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/antarctica Thu Feb 05 13:00:26 2015 +0100 -@@ -70,8 +70,8 @@ - Rule ChileAQ 2010 only - Apr Sun>=1 3:00u 0 - - Rule ChileAQ 2011 only - May Sun>=2 3:00u 0 - - Rule ChileAQ 2011 only - Aug Sun>=16 4:00u 1:00 S --Rule ChileAQ 2012 max - Apr Sun>=23 3:00u 0 - --Rule ChileAQ 2012 max - Sep Sun>=2 4:00u 1:00 S -+Rule ChileAQ 2012 2015 - Apr Sun>=23 3:00u 0 - -+Rule ChileAQ 2012 2014 - Sep Sun>=2 4:00u 1:00 S - - # Argentina - year-round bases - # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05 -@@ -377,9 +377,10 @@ - # - # Zone NAME GMTOFF RULES FORMAT [UNTIL] - Zone Antarctica/Palmer 0 - zzz 1965 -- -4:00 ArgAQ AR%sT 1969 Oct 5 -+ -4:00 ArgAQ AR%sT 1969 Oct 5 - -3:00 ArgAQ AR%sT 1982 May -- -4:00 ChileAQ CL%sT -+ -4:00 ChileAQ CL%sT 2015 Apr 26 3:00u -+ -3:00 - CLT - # - # - # McMurdo Station, Ross Island, since 1955-12 ---- ./jdk/test/sun/util/calendar/zi/tzdata/asia Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/asia Thu Feb 05 13:00:26 2015 +0100 -@@ -168,10 +168,7 @@ - 4:00 Azer AZ%sT - - # Bahrain --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Bahrain 3:22:20 - LMT 1920 # Manamah -- 4:00 - GST 1972 Jun -- 3:00 - AST -+# See Asia/Qatar. - - # Bangladesh - # From Alexander Krivenyshev (2009-05-13): -@@ -1754,9 +1751,7 @@ - ############################################################################### - - # Kuwait --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Kuwait 3:11:56 - LMT 1950 -- 3:00 - AST -+# See Asia/Riyadh. - - # Laos - # See Asia/Bangkok. -@@ -1977,12 +1972,7 @@ - 5:45 - NPT # Nepal Time - - # Oman -- --# Milne says 3:54:24 was the meridian of the Muscat Tidal Observatory. -- --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Muscat 3:54:24 - LMT 1920 -- 4:00 - GST -+# See Asia/Dubai. - - # Pakistan - -@@ -2476,6 +2466,7 @@ - Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah / Doha - 4:00 - GST 1972 Jun - 3:00 - AST -+Link Asia/Qatar Asia/Bahrain - - # Saudi Arabia - # -@@ -2502,6 +2493,8 @@ - # Zone NAME GMTOFF RULES FORMAT [UNTIL] - Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14 - 3:00 - AST -+Link Asia/Riyadh Asia/Aden # Yemen -+Link Asia/Riyadh Asia/Kuwait - - # Singapore - # taken from Mok Ly Yng (2003-10-30) -@@ -2790,6 +2783,7 @@ - # Zone NAME GMTOFF RULES FORMAT [UNTIL] - Zone Asia/Dubai 3:41:12 - LMT 1920 - 4:00 - GST -+Link Asia/Dubai Asia/Muscat # Oman - - # Uzbekistan - # Byalokoz 1919 says Uzbekistan was 4:27:53. -@@ -2874,10 +2868,4 @@ - 7:00 - ICT - - # Yemen -- --# Milne says 2:59:54 was the meridian of the saluting battery at Aden, --# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia. -- --# Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Asia/Aden 2:59:54 - LMT 1950 -- 3:00 - AST -+# See Asia/Riyadh. ---- ./jdk/test/sun/util/calendar/zi/tzdata/backward Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/backward Thu Feb 05 13:00:26 2015 +0100 -@@ -28,7 +28,7 @@ - # and their old names. Many names changed in late 1993. - - # Link TARGET LINK-NAME --Link Africa/Asmara Africa/Asmera -+Link Africa/Nairobi Africa/Asmera - Link Africa/Abidjan Africa/Timbuktu - Link America/Argentina/Catamarca America/Argentina/ComodRivadavia - Link America/Adak America/Atka ---- ./jdk/test/sun/util/calendar/zi/tzdata/europe Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/europe Thu Feb 05 13:00:26 2015 +0100 -@@ -1430,35 +1430,32 @@ - # might be a reference to the Julian calendar as opposed to Gregorian, or it - # might mean something else (???). - # --# From Paul Eggert (2006-03-22): --# The Iceland Almanak, Shanks & Pottenger, and Whitman disagree on many points. --# We go with the Almanak, except for one claim from Shanks & Pottenger, namely --# that Reykavik was 21W57 from 1837 to 1908, local mean time before that. -+# From Paul Eggert (2014-11-22): -+# The information below is taken from the 1988 Almanak; see -+# http://www.almanak.hi.is/klukkan.html - # - # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S --Rule Iceland 1917 1918 - Feb 19 23:00 1:00 S -+Rule Iceland 1917 1919 - Feb 19 23:00 1:00 S - Rule Iceland 1917 only - Oct 21 1:00 0 - --Rule Iceland 1918 only - Nov 16 1:00 0 - -+Rule Iceland 1918 1919 - Nov 16 1:00 0 - -+Rule Iceland 1921 only - Mar 19 23:00 1:00 S -+Rule Iceland 1921 only - Jun 23 1:00 0 - - Rule Iceland 1939 only - Apr 29 23:00 1:00 S --Rule Iceland 1939 only - Nov 29 2:00 0 - -+Rule Iceland 1939 only - Oct 29 2:00 0 - - Rule Iceland 1940 only - Feb 25 2:00 1:00 S --Rule Iceland 1940 only - Nov 3 2:00 0 - --Rule Iceland 1941 only - Mar 2 1:00s 1:00 S --Rule Iceland 1941 only - Nov 2 1:00s 0 - --Rule Iceland 1942 only - Mar 8 1:00s 1:00 S --Rule Iceland 1942 only - Oct 25 1:00s 0 - -+Rule Iceland 1940 1941 - Nov Sun>=2 1:00s 0 - -+Rule Iceland 1941 1942 - Mar Sun>=2 1:00s 1:00 S - # 1943-1946 - first Sunday in March until first Sunday in winter - Rule Iceland 1943 1946 - Mar Sun>=1 1:00s 1:00 S --Rule Iceland 1943 1948 - Oct Sun>=22 1:00s 0 - -+Rule Iceland 1942 1948 - Oct Sun>=22 1:00s 0 - - # 1947-1967 - first Sunday in April until first Sunday in winter - Rule Iceland 1947 1967 - Apr Sun>=1 1:00s 1:00 S --# 1949 Oct transition delayed by 1 week -+# 1949 and 1967 Oct transitions delayed by 1 week - Rule Iceland 1949 only - Oct 30 1:00s 0 - - Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 - - Rule Iceland 1967 only - Oct 29 1:00s 0 - - # Zone NAME GMTOFF RULES FORMAT [UNTIL] --Zone Atlantic/Reykjavik -1:27:24 - LMT 1837 -- -1:27:48 - RMT 1908 # Reykjavik Mean Time? -+Zone Atlantic/Reykjavik -1:28 - LMT 1908 - -1:00 Iceland IS%sT 1968 Apr 7 1:00s - 0:00 - GMT - ---- ./jdk/test/sun/util/calendar/zi/tzdata/leapseconds Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/leapseconds Thu Feb 05 13:00:26 2015 +0100 -@@ -77,3 +77,7 @@ - Leap 2005 Dec 31 23:59:60 + S - Leap 2008 Dec 31 23:59:60 + S - Leap 2012 Jun 30 23:59:60 + S -+Leap 2015 Jun 30 23:59:60 + S -+ -+# Updated through IERS Bulletin C49 -+# File expires on: 28 December 2015 ---- ./jdk/test/sun/util/calendar/zi/tzdata/northamerica Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/northamerica Thu Feb 05 13:00:26 2015 +0100 -@@ -147,7 +147,7 @@ - Rule US 1918 1919 - Oct lastSun 2:00 0 S - Rule US 1942 only - Feb 9 2:00 1:00 W # War - Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace --Rule US 1945 only - Sep 30 2:00 0 S -+Rule US 1945 only - Sep lastSun 2:00 0 S - Rule US 1967 2006 - Oct lastSun 2:00 0 S - Rule US 1967 1973 - Apr lastSun 2:00 1:00 D - Rule US 1974 only - Jan 6 2:00 1:00 D -@@ -2147,11 +2147,11 @@ - - # Mexico - --# From Paul Eggert (2001-03-05): -+# From Paul Eggert (2014-12-07): - # The Investigation and Analysis Service of the - # Mexican Library of Congress (MLoC) has published a - # history of Mexican local time (in Spanish) --# http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/ -+# http://www.diputados.gob.mx/bibliot/publica/inveyana/polisoc/horver/index.htm - # - # Here are the discrepancies between Shanks & Pottenger (S&P) and the MLoC. - # (In all cases we go with the MLoC.) -@@ -2320,6 +2320,24 @@ - # efecto desde las dos horas del segundo domingo de marzo y concluirá a - # las dos horas del primer domingo de noviembre. - -+# From Steffen Thorsen (2014-12-08), translated by Gwillim Law: -+# The Mexican state of Quintana Roo will likely change to EST in 2015. -+# -+# http://www.unioncancun.mx/articulo/2014/12/04/medio-ambiente/congreso-aprueba-una-hora-mas-de-sol-en-qroo -+# "With this change, the time conflict that has existed between the municipios -+# of Quintana Roo and the municipio of Felipe Carrillo Puerto may come to an -+# end. The latter declared itself in rebellion 15 years ago when a time change -+# was initiated in Mexico, and since then it has refused to change its time -+# zone along with the rest of the country." -+# -+# From Steffen Thorsen (2015-01-14), translated by Gwillim Law: -+# http://sipse.com/novedades/confirman-aplicacion-de-nueva-zona-horaria-para-quintana-roo-132331.html -+# "...the new time zone will come into effect at two o'clock on the first Sunday -+# of February, when we will have to advance the clock one hour from its current -+# time..." -+# -+# Also, the new zone will not use DST. -+ - # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S - Rule Mexico 1939 only - Feb 5 0:00 1:00 D - Rule Mexico 1939 only - Jun 25 0:00 0 S -@@ -2340,7 +2358,8 @@ - Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56 - -6:00 - CST 1981 Dec 23 - -5:00 Mexico E%sT 1998 Aug 2 2:00 -- -6:00 Mexico C%sT -+ -6:00 Mexico C%sT 2015 Feb 1 2:00 -+ -5:00 - EST - # Campeche, Yucatán; represented by Mérida - Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32 - -6:00 - CST 1981 Dec 23 ---- ./jdk/test/sun/util/calendar/zi/tzdata/southamerica Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/southamerica Thu Feb 05 13:00:26 2015 +0100 -@@ -1229,6 +1229,11 @@ - # DST Start: first Saturday of September 2014 (Sun 07 Sep 2014 04:00 UTC) - # http://www.diariooficial.interior.gob.cl//media/2014/02/19/do-20140219.pdf - -+# From Juan Correa (2015-01-28): -+# ... today the Ministry of Energy announced that Chile will drop DST, will keep -+# "summer time" (UTC -3 / UTC -5) all year round.... -+# http://www.minenergia.cl/ministerio/noticias/generales/ministerio-de-energia-anuncia.html -+ - # NOTE: ChileAQ rules for Antarctic bases are stored separately in the - # 'antarctica' file. - -@@ -1270,8 +1275,8 @@ - Rule Chile 2010 only - Apr Sun>=1 3:00u 0 - - Rule Chile 2011 only - May Sun>=2 3:00u 0 - - Rule Chile 2011 only - Aug Sun>=16 4:00u 1:00 S --Rule Chile 2012 max - Apr Sun>=23 3:00u 0 - --Rule Chile 2012 max - Sep Sun>=2 4:00u 1:00 S -+Rule Chile 2012 2015 - Apr Sun>=23 3:00u 0 - -+Rule Chile 2012 2014 - Sep Sun>=2 4:00u 1:00 S - # IATA SSIM anomalies: (1992-02) says 1992-03-14; - # (1996-09) says 1998-03-08. Ignore these. - # Zone NAME GMTOFF RULES FORMAT [UNTIL] -@@ -1282,11 +1287,13 @@ - -4:00 - CLT 1919 Jul 1 # Chile Time - -4:42:46 - SMT 1927 Sep 1 # Santiago Mean Time - -5:00 Chile CL%sT 1947 May 22 # Chile Time -- -4:00 Chile CL%sT -+ -4:00 Chile CL%sT 2015 Apr 26 3:00u -+ -3:00 - CLT - Zone Pacific/Easter -7:17:44 - LMT 1890 - -7:17:28 - EMT 1932 Sep # Easter Mean Time -- -7:00 Chile EAS%sT 1982 Mar 13 21:00 # Easter Time -- -6:00 Chile EAS%sT -+ -7:00 Chile EAS%sT 1982 Mar 13 3:00u # Easter Time -+ -6:00 Chile EAS%sT 2015 Apr 26 3:00u -+ -5:00 - EAST - # - # Salas y Gómez Island is uninhabited. - # Other Chilean locations, including Juan Fernández Is, Desventuradas Is, ---- ./jdk/test/sun/util/calendar/zi/tzdata/zone.tab Mon Feb 02 10:12:21 2015 -0800 -+++ ./jdk/test/sun/util/calendar/zi/tzdata/zone.tab Thu Feb 05 13:00:26 2015 +0100 -@@ -297,7 +297,7 @@ - MV +0410+07330 Indian/Maldives - MW -1547+03500 Africa/Blantyre - MX +1924-09909 America/Mexico_City Central Time - most locations --MX +2105-08646 America/Cancun Central Time - Quintana Roo -+MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo - MX +2058-08937 America/Merida Central Time - Campeche, Yucatan - MX +2540-10019 America/Monterrey Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border - MX +2550-09730 America/Matamoros US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border ---- ./langtools/.hgtags Wed Jan 28 12:08:47 2015 -0800 -+++ ./langtools/.hgtags Tue Mar 17 11:25:42 2015 -0700 -@@ -334,6 +334,8 @@ - 53ca196be1ae098466976c017b166d4ce180c36f jdk8u25-b17 - a4f0c6dd8f97d4dd89baf09463c748abea9b3ed7 jdk8u25-b18 - c4de614efd7affc001715aa5a7040620924ac44a jdk8u25-b31 -+a2a922ccc00f29af625cbecde8e77643c60f147c jdk8u25-b32 -+b72a49d88cc3f5394b69b861455552476341558d jdk8u25-b33 - c4bd223559aad3d152968a09d56241175d82c561 jdk8u31-b00 - 6b5e2c190f3023162a33b798e57a0d78e027c843 jdk8u31-b01 - 8b4ea00b438d7f99ecd6a8345cb018d8a0379620 jdk8u31-b02 -@@ -348,6 +350,8 @@ - e72be544fa9e247fba3c6bb61e291d80e127a461 jdk8u31-b11 - c956b12b30ee21a4fc5df1871fa3b01e84310ebe jdk8u31-b12 - 7a34ec7bb1c831e82ac88da578a028572b676260 jdk8u31-b13 -+b813a76f10911ac8db2c775e52b29f36ab0005f4 jdk8u31-b31 -+8dc0c7e42d90c9f323582b742a7f228bad57b124 jdk8u31-b32 - d231957fe3103e790465fcf058fb8cb33bbc4c4e jdk8u40-b00 - bf89a471779d13a9407f7d1c86f7716258bc4aa6 jdk8u40-b01 - 0b6cc4ea670f5d17b56c088f202869bdbb80a5ce jdk8u40-b02 -@@ -372,3 +376,21 @@ - 9113c7c8d902ec94b28ca0ef4a6466bdba65fcfc jdk8u40-b21 - 79177246b3dbe5296fb53755d8695acdaef59fc8 jdk8u40-b22 - fb294b49373bda0b3afc7f011d64ecefed73b42e jdk8u40-b23 -+c5d4ffa220f3824c2ea5d39dc99d41a9df9e5ae5 jdk8u40-b24 -+991141080b2078e67179ff307a5051e59431762c jdk8u40-b25 -+2904142783dd0a9e12195a84c7dcdb3d8278b1b1 jdk8u40-b26 -+83eca922346e27ec42645e9630c04fbaec5eaf0f jdk8u40-b27 -+dbae37f50c43453f7d6f22d96adc8b5b6cd1e90d jdk8u45-b00 -+244e6dc772877dfae6286530f58e11a210a48a3c jdk8u45-b01 -+401ec76887623a29d3f868f9f9b18b42838d2e92 jdk8u45-b02 -+79d31ae9990e28b99dd64beda6dd247993138431 jdk8u45-b03 -+47292f3c0da7dd197a28765004b588bc3141d189 jdk8u45-b04 -+77d7dd7f35d63f9fe60ed0b7ef32e4e9a8b46c0b jdk8u45-b05 -+22cc48973eae62c63e68c4c4e3f22ff2d89012a8 jdk8u45-b06 -+460238ab73ce27112b3d0d7236366960f9898259 jdk8u45-b07 -+6dd7fd9f027bf037517feae2a571848aa8fbc20f jdk8u45-b08 -+db16aa5c73c99d0050246660ebebb6166002ff57 jdk8u45-b09 -+572895f19937b7aadc8c27c5e83887bf40f5bcff jdk8u45-b10 -+0547ef2be3b303923b30ce78e1ab832725483f4e jdk8u45-b11 -+4f89bbda7b4532b9f6eeee8c41b7a3b38570ae93 jdk8u45-b12 -+5ce022bca792453a7efedaed419a9d763d7a9fc3 jdk8u45-b13 ---- ./langtools/THIRD_PARTY_README Wed Jan 28 12:08:47 2015 -0800 -+++ ./langtools/THIRD_PARTY_README Tue Mar 17 11:25:42 2015 -0700 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - ---- ./nashorn/.hgtags Wed Jan 28 12:08:49 2015 -0800 -+++ ./nashorn/.hgtags Tue Mar 17 11:25:52 2015 -0700 -@@ -322,6 +322,8 @@ - 4b9cc65dd24d398c4f921c0beccfb8caeaaaf584 jdk8u25-b17 - cdbf34dbef404b47805c8c85b11c65c2afaa6674 jdk8u25-b18 - 4f9e65387c21831d0ea5726641a302c2ce73a4cc jdk8u25-b31 -+be20e9a00818df15af12544c21839c3a3d5768d9 jdk8u25-b32 -+a8526abf70a8c98aee5fed64eb727210745a6e5a jdk8u25-b33 - 9b692a6e5f22228f822973d35610d37cb9dd9693 jdk8u31-b00 - 6bf53bb6c969678488b1c073d56dd55df1a0ea17 jdk8u31-b01 - 809bf97d7e70dcb3873fcbc10f12f62580b1c11d jdk8u31-b02 -@@ -336,6 +338,8 @@ - 599bd596fa549d882aa8fc5104c322a75a3af728 jdk8u31-b11 - f36c71a03e4ed467f630cc46d076a5bb4c58b6d5 jdk8u31-b12 - ec36fa3b35eb00f053d624ae837579c6b8e446ac jdk8u31-b13 -+34a64e22b81bd78cf29603a80ff1f4cfc1694df8 jdk8u31-b31 -+d2b5784a3452a4fd9d1ccfefe93ee2d36662842c jdk8u31-b32 - f2925491b61b22ac42f8c30ee9c6723ffa401a4c jdk8u40-b00 - 62468d841b842769d875bd97d10370585c296eb7 jdk8u40-b01 - b476c69c820ac1e05071f4de5abab8e2dff80e87 jdk8u40-b02 -@@ -360,3 +364,21 @@ - dbb663a9d9aa2807ef501c7d20f29415816a1973 jdk8u40-b21 - f9f70a0f60f48fbb95275b6c1110cedf740c6177 jdk8u40-b22 - 6ca090832d30fd0e46214ccc00816490ad75a8ab jdk8u40-b23 -+b2ce5df33715583c898530560d4202853b9ff9bc jdk8u40-b24 -+fb7b6c2b95c5661f15e8e747a63ec6d95d49fe46 jdk8u40-b25 -+b142a2d8e35e54abb08a7ded1dbfb5d7ce534c93 jdk8u40-b26 -+c2dd88e89edc85b1bcb731d3296d0fcec1b78447 jdk8u40-b27 -+05a3614ed5276e5db2a73cce918be04b1a2922fb jdk8u45-b00 -+21ec16eb7e6346c78b4fa67ccd6d2a9c58f0b696 jdk8u45-b01 -+37b3ef9a07323afd2556d6837824db154cccc874 jdk8u45-b02 -+ed3a4177da50d75d6da55ff521bf3f971cfe5214 jdk8u45-b03 -+65f24dedfd29ec02af43f745742647412d90f005 jdk8u45-b04 -+de2ee4c1341fd4eeaba39b81194df0c4274e7c8b jdk8u45-b05 -+cf0097b8987d2d2f480d8a6d2a8f235509bd4421 jdk8u45-b06 -+bb112473c7314146bebb75fb5220b4ec641b0b7a jdk8u45-b07 -+8ab14ee47c8b1558854d3cd71006eceb6c6804d1 jdk8u45-b08 -+397ea4a1bff8adbceaa1a40ff826b3d2d3b09e81 jdk8u45-b09 -+c650c13d2bdf0e869ae86685de6bbb8a4e983ca3 jdk8u45-b10 -+6ae873ddbe195aa966fc348e468c0ecd2702f5e3 jdk8u45-b11 -+9b9fee0f99cd07fba62abaafe705665a5ab89067 jdk8u45-b12 -+6fda38586f73de706ecde311711a587ac49d51d8 jdk8u45-b13 ---- ./nashorn/THIRD_PARTY_README Wed Jan 28 12:08:49 2015 -0800 -+++ ./nashorn/THIRD_PARTY_README Tue Mar 17 11:25:52 2015 -0700 -@@ -1250,7 +1250,7 @@ - - ------------------------------------------------------------------------------- - --%% This notice is provided with respect to libpng 1.5.4, which may be -+%% This notice is provided with respect to libpng 1.6.16, which may be - included with JRE 8, JDK 8, and OpenJDK 8. - - --- begin of LICENSE --- -@@ -1266,8 +1266,8 @@ - - This code is released under the libpng license. - --libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are --Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are -+libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are -+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are - distributed according to the same disclaimer and license as libpng-1.2.5 - with the following individual added to the list of Contributing Authors - -@@ -1364,7 +1364,7 @@ - - Glenn Randers-Pehrson - glennrp at users.sourceforge.net --July 7, 2011 -+December 22, 2014 - - --- end of LICENSE --- - |