aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--java/openjdk8/Makefile10
-rw-r--r--java/openjdk8/files/patch-8u45-b1445638
-rw-r--r--java/openjdk8/files/patch-bsd618
-rw-r--r--java/openjdk8/files/patch-bsd-test468
-rw-r--r--java/openjdk8/files/patch-jdk-make-lib-Awt2dLibraries.gmk2
5 files changed, 46187 insertions, 549 deletions
diff --git a/java/openjdk8/Makefile b/java/openjdk8/Makefile
index 65bbd36aeab1..3b0f337f23ed 100644
--- a/java/openjdk8/Makefile
+++ b/java/openjdk8/Makefile
@@ -2,7 +2,6 @@
PORTNAME= openjdk
PORTVERSION= ${JDK_MAJOR_VERSION}.${JDK_UPDATE_VERSION}.${JDK_BUILD_NUMBER:S/^0//}
-PORTREVISION= 3
CATEGORIES= java devel
MASTER_SITES= http://download.java.net/openjdk/jdk${JDK_MAJOR_VERSION}/promoted/b${DIST_BUILD_NUMBER}/:jdk \
https://adopt-openjdk.ci.cloudbees.com/job/jtreg/${JTREG_JENKINS_BUILD}/artifact/:jtreg \
@@ -26,9 +25,10 @@ LIB_DEPENDS= libasound.so:${PORTSDIR}/audio/alsa-lib \
RUN_DEPENDS= javavm:${PORTSDIR}/java/javavmwrapper \
dejavu>0:${PORTSDIR}/x11-fonts/dejavu
-USES= compiler:features dos2unix gmake iconv pkgconfig shebangfix
-USE_AUTOTOOLS= autoconf
+USES= compiler:features dos2unix gmake iconv pkgconfig \
+ shebangfix
USE_XORG= x11 xext xi xrender xt xtst
+GNU_CONFIGURE= yes
.if !exists(/usr/bin/unzip)
BUILD_DEPENDS+= ${UNZIP_CMD}:${PORTSDIR}/archivers/unzip
@@ -92,8 +92,8 @@ NO_CCACHE= yes
NOPRECIOUSMAKEVARS= yes
JDK_MAJOR_VERSION= 8
-JDK_UPDATE_VERSION= 40
-JDK_BUILD_NUMBER= 25
+JDK_UPDATE_VERSION= 45
+JDK_BUILD_NUMBER= 14
DIST_BUILD_NUMBER= 132
JTREG_VERSION= 4.1
JTREG_BUILD_NUMBER= b08
diff --git a/java/openjdk8/files/patch-8u45-b14 b/java/openjdk8/files/patch-8u45-b14
new file mode 100644
index 000000000000..19470282608c
--- /dev/null
+++ b/java/openjdk8/files/patch-8u45-b14
@@ -0,0 +1,45638 @@
+--- ./.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(&gtest, 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(&gtest, 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, &params))
++ &nparams, &units, &params) != 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 ---
+
diff --git a/java/openjdk8/files/patch-bsd b/java/openjdk8/files/patch-bsd
index d3c863149677..af135e767947 100644
--- a/java/openjdk8/files/patch-bsd
+++ b/java/openjdk8/files/patch-bsd
@@ -1,12 +1,5 @@
---- ./.hgtags Wed Jan 28 12:08:30 2015 -0800
-+++ ./.hgtags Sat Mar 14 10:28:41 2015 -0700
-@@ -374,3 +374,4 @@
- 765a17e75fd622f7b892381e23c9b2c531d416f0 jdk8u40-b21
- b6d03a810a61116268fea08517a9632bd66a7363 jdk8u40-b22
- 5dd2ad6c7911a1e21f15a28f13ffad662378a3be jdk8u40-b23
-+5b37e6757d7c95c9c58b07fb3c9eba234567385a jdk8u40-b24
---- ./common/autoconf/build-performance.m4 Wed Jan 28 12:08:30 2015 -0800
-+++ ./common/autoconf/build-performance.m4 Sat Mar 14 10:28:41 2015 -0700
+--- ./common/autoconf/build-performance.m4 Mon Mar 16 11:19:14 2015 -0700
++++ ./common/autoconf/build-performance.m4 Tue May 05 18:06:47 2015 -0700
@@ -41,6 +41,10 @@
# Looks like a MacOSX system
NUM_CORES=`/usr/sbin/system_profiler -detailLevel full SPHardwareDataType | grep 'Cores' | awk '{print [$]5}'`
@@ -41,8 +34,8 @@
AC_MSG_RESULT([no, disabling ccache])
CCACHE=
else
---- ./common/autoconf/generated-configure.sh Wed Jan 28 12:08:30 2015 -0800
-+++ ./common/autoconf/generated-configure.sh Sat Mar 14 10:28:41 2015 -0700
+--- ./common/autoconf/generated-configure.sh Mon Mar 16 11:19:14 2015 -0700
++++ ./common/autoconf/generated-configure.sh Tue May 05 18:06:47 2015 -0700
@@ -1048,6 +1048,7 @@
with_extra_cflags
with_extra_cxxflags
@@ -241,8 +234,8 @@
elif test "x$OPENJDK_BUILD_OS" = xwindows; then
# Windows, but without cygwin
MEMORY_SIZE=`wmic computersystem get totalphysicalmemory -value | grep = | cut -d "=" -f 2-`
---- ./common/autoconf/libraries.m4 Wed Jan 28 12:08:30 2015 -0800
-+++ ./common/autoconf/libraries.m4 Sat Mar 14 10:28:41 2015 -0700
+--- ./common/autoconf/libraries.m4 Mon Mar 16 11:19:14 2015 -0700
++++ ./common/autoconf/libraries.m4 Tue May 05 18:06:47 2015 -0700
@@ -71,9 +71,9 @@
fi
@@ -297,8 +290,8 @@
+
AC_SUBST(LIBCXX)
])
---- ./common/autoconf/platform.m4 Wed Jan 28 12:08:30 2015 -0800
-+++ ./common/autoconf/platform.m4 Sat Mar 14 10:28:41 2015 -0700
+--- ./common/autoconf/platform.m4 Mon Mar 16 11:19:14 2015 -0700
++++ ./common/autoconf/platform.m4 Tue May 05 18:06:47 2015 -0700
@@ -30,7 +30,7 @@
[
# First argument is the cpu name from the trip/quad
@@ -319,8 +312,8 @@
OPENJDK_TARGET_CPU_OSARCH="i386"
elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
# On all platforms except macosx, we replace x86_64 with amd64.
---- ./common/autoconf/spec.gmk.in Wed Jan 28 12:08:30 2015 -0800
-+++ ./common/autoconf/spec.gmk.in Sat Mar 14 10:28:41 2015 -0700
+--- ./common/autoconf/spec.gmk.in Mon Mar 16 11:19:14 2015 -0700
++++ ./common/autoconf/spec.gmk.in Tue May 05 18:06:47 2015 -0700
@@ -275,7 +275,7 @@
ALSA_LIBS:=@ALSA_LIBS@
ALSA_CFLAGS:=@ALSA_CFLAGS@
@@ -330,8 +323,8 @@
# Source file for cacerts
CACERTS_FILE=@CACERTS_FILE@
---- ./common/autoconf/toolchain.m4 Wed Jan 28 12:08:30 2015 -0800
-+++ ./common/autoconf/toolchain.m4 Sat Mar 14 10:28:41 2015 -0700
+--- ./common/autoconf/toolchain.m4 Mon Mar 16 11:19:14 2015 -0700
++++ ./common/autoconf/toolchain.m4 Tue May 05 18:06:47 2015 -0700
@@ -72,7 +72,7 @@
else
COMPILER_VERSION_TEST=`$COMPILER --version 2>&1 | $HEAD -n 1`
@@ -408,16 +401,16 @@
fi
if test "x$OPENJDK_TARGET_OS" = xlinux; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DLINUX"
---- ./configure Wed Jan 28 12:08:30 2015 -0800
-+++ ./configure Sat Mar 14 10:28:41 2015 -0700
+--- ./configure Mon Mar 16 11:19:14 2015 -0700
++++ ./configure Tue May 05 18:06:47 2015 -0700
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
---- ./make/Main.gmk Wed Jan 28 12:08:30 2015 -0800
-+++ ./make/Main.gmk Sat Mar 14 10:28:41 2015 -0700
+--- ./make/Main.gmk Mon Mar 16 11:19:14 2015 -0700
++++ ./make/Main.gmk Tue May 05 18:06:47 2015 -0700
@@ -58,7 +58,11 @@
# Setup number of jobs to use. -jN is unfortunately not available for us to parse from the command line,
@@ -430,8 +423,8 @@
### Main targets
---- ./make/common/MakeBase.gmk Wed Jan 28 12:08:30 2015 -0800
-+++ ./make/common/MakeBase.gmk Sat Mar 14 10:28:41 2015 -0700
+--- ./make/common/MakeBase.gmk Mon Mar 16 11:19:14 2015 -0700
++++ ./make/common/MakeBase.gmk Tue May 05 18:06:47 2015 -0700
@@ -338,7 +338,7 @@
# (and causing a crash on Cygwin).
# Default shell seems to always be /bin/sh. Must override with bash to get this to work on Solaris.
@@ -452,8 +445,8 @@
endef
# Make directory without forking mkdir if not needed
---- ./make/common/NativeCompilation.gmk Wed Jan 28 12:08:30 2015 -0800
-+++ ./make/common/NativeCompilation.gmk Sat Mar 14 10:28:41 2015 -0700
+--- ./make/common/NativeCompilation.gmk Mon Mar 16 11:19:14 2015 -0700
++++ ./make/common/NativeCompilation.gmk Tue May 05 18:06:47 2015 -0700
@@ -151,9 +151,9 @@
# CC the compiler to use, default is $(CC)
# LDEXE the linker to use for linking executables, default is $(LDEXE)
@@ -467,22 +460,8 @@
ifneq (,$$($1_BIN))
$$(error BIN has been replaced with OBJECT_DIR)
---- ./corba/.hgtags Wed Jan 28 12:08:31 2015 -0800
-+++ ./corba/.hgtags Wed Feb 04 12:14:39 2015 -0800
-@@ -372,3 +372,4 @@
- 9c54cc92c0beb29179abbce272d3f5c8ba4ffd0e jdk8u40-b21
- 4c7421f74674ebefb8e91eba59ab2a2db8c1abd7 jdk8u40-b22
- 62f7faef5ed956cd481cae6216b22fdb4b6e3e46 jdk8u40-b23
-+472aa5bae0e78614e873d56bcc31e7caba49963c jdk8u40-b24
---- ./hotspot/.hgtags Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/.hgtags Sat Mar 14 16:41:08 2015 -0700
-@@ -586,3 +586,4 @@
- 0f0cb4eeab2d871274f4ffdcd6017d2fdfa89238 hs25.40-b25
- 0ee548a1cda08c884eccd563e2d5fdb6ee769b5a jdk8u40-b22
- 0e67683b700174eab71ea205d1cfa4f1cf4523ba jdk8u40-b23
-+fa4e797f61e6dda1a60e06944018213bff2a1b76 jdk8u40-b24
---- ./hotspot/make/bsd/makefiles/build_vm_def.sh Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/build_vm_def.sh Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/build_vm_def.sh Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/build_vm_def.sh Tue May 05 18:06:56 2015 -0700
@@ -1,12 +1,28 @@
#!/bin/sh
@@ -518,8 +497,8 @@
+ if ($3 ~ /^_ZN9Arguments17SharedArchivePathE$/) print "\t" $3 ";"
+ }' | sort -u ;;
+esac
---- ./hotspot/make/bsd/makefiles/debug.make Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/debug.make Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/debug.make Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/debug.make Tue May 05 18:06:56 2015 -0700
@@ -35,7 +35,10 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -532,8 +511,8 @@
VERSION = debug
SYSDEFS += -DASSERT
---- ./hotspot/make/bsd/makefiles/fastdebug.make Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/fastdebug.make Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/fastdebug.make Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/fastdebug.make Tue May 05 18:06:56 2015 -0700
@@ -56,7 +56,10 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -546,8 +525,8 @@
VERSION = fastdebug
SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
---- ./hotspot/make/bsd/makefiles/gcc.make Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/gcc.make Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/gcc.make Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/gcc.make Tue May 05 18:06:56 2015 -0700
@@ -168,6 +168,9 @@
CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
endif
@@ -590,7 +569,7 @@
WARNING_FLAGS += -Wconversion
endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/make/bsd/makefiles/launcher.make Sat Mar 14 16:41:08 2015 -0700
++++ ./hotspot/make/bsd/makefiles/launcher.make Tue May 05 18:06:56 2015 -0700
@@ -0,0 +1,117 @@
+#
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -709,8 +688,8 @@
+ $(QUIETLY) sed -e 's/@@LIBARCH@@/$(LIBARCH)/g' $< > $@
+ $(QUIETLY) chmod +x $@
+
---- ./hotspot/make/bsd/makefiles/mapfile-vers-debug Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/mapfile-vers-debug Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug Tue May 05 18:06:56 2015 -0700
@@ -21,246 +21,254 @@
# questions.
#
@@ -1198,7 +1177,7 @@
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug.macosx Sat Mar 14 16:41:08 2015 -0700
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-debug.macosx Tue May 05 18:06:56 2015 -0700
@@ -0,0 +1,266 @@
+#
+# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
@@ -1466,8 +1445,8 @@
+
+ # INSERT VTABLE SYMBOLS HERE
+
---- ./hotspot/make/bsd/makefiles/mapfile-vers-product Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-product Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/mapfile-vers-product Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-product Tue May 05 18:06:56 2015 -0700
@@ -21,241 +21,249 @@
# questions.
#
@@ -1946,7 +1925,7 @@
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/make/bsd/makefiles/mapfile-vers-product.macosx Sat Mar 14 16:41:08 2015 -0700
++++ ./hotspot/make/bsd/makefiles/mapfile-vers-product.macosx Tue May 05 18:06:56 2015 -0700
@@ -0,0 +1,261 @@
+#
+# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
@@ -2209,8 +2188,8 @@
+
+ # INSERT VTABLE SYMBOLS HERE
+
---- ./hotspot/make/bsd/makefiles/optimized.make Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/optimized.make Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/optimized.make Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/optimized.make Tue May 05 18:06:56 2015 -0700
@@ -38,6 +38,9 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -2222,8 +2201,8 @@
+MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug$(MAPSUFX)
VERSION = optimized
---- ./hotspot/make/bsd/makefiles/product.make Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/product.make Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/product.make Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/product.make Tue May 05 18:06:56 2015 -0700
@@ -38,7 +38,10 @@
# to inhibit the effect of the previous line on CFLAGS.
@@ -2236,8 +2215,8 @@
SYSDEFS += -DPRODUCT
VERSION = optimized
---- ./hotspot/make/bsd/makefiles/rules.make Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/make/bsd/makefiles/rules.make Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/make/bsd/makefiles/rules.make Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/make/bsd/makefiles/rules.make Tue May 05 18:06:56 2015 -0700
@@ -34,7 +34,7 @@
CC_COMPILE = $(CC) $(CXXFLAGS) $(CFLAGS)
CXX_COMPILE = $(CXX) $(CXXFLAGS) $(CFLAGS)
@@ -2247,8 +2226,8 @@
COMPILE.CC = $(CC_COMPILE) -c
GENASM.CC = $(CC_COMPILE) -S
---- ./hotspot/src/cpu/x86/vm/jni_x86.h Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/cpu/x86/vm/jni_x86.h Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/cpu/x86/vm/jni_x86.h Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/cpu/x86/vm/jni_x86.h Tue May 05 18:06:56 2015 -0700
@@ -34,7 +34,7 @@
#ifndef __has_attribute
#define __has_attribute(x) 0
@@ -2258,8 +2237,8 @@
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#else
---- ./hotspot/src/cpu/x86/vm/x86_32.ad Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/cpu/x86/vm/x86_32.ad Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/cpu/x86/vm/x86_32.ad Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/cpu/x86/vm/x86_32.ad Tue May 05 18:06:56 2015 -0700
@@ -1210,6 +1210,7 @@
@@ -2269,7 +2248,7 @@
#ifndef PRODUCT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./hotspot/src/os/bsd/vm/decoder_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
++++ ./hotspot/src/os/bsd/vm/decoder_bsd.cpp Tue May 05 18:06:56 2015 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -2318,8 +2297,8 @@
+ return false;
+}
+#endif
---- ./hotspot/src/os/bsd/vm/jsig.c Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/os/bsd/vm/jsig.c Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/os/bsd/vm/jsig.c Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/os/bsd/vm/jsig.c Tue May 05 18:06:56 2015 -0700
@@ -140,9 +140,8 @@
}
@@ -2332,8 +2311,8 @@
static int call_os_sigaction(int sig, const struct sigaction *act,
struct sigaction *oact) {
---- ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/os/bsd/vm/jvm_bsd.cpp Tue May 05 18:06:56 2015 -0700
@@ -50,6 +50,7 @@
case INTERRUPT_SIGNAL:
case SIGFPE:
@@ -2443,8 +2422,8 @@
+ jio_snprintf(buf, len, "SIG%s", signame);
+ return true;
}
---- ./hotspot/src/os/bsd/vm/jvm_bsd.h Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/os/bsd/vm/jvm_bsd.h Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/os/bsd/vm/jvm_bsd.h Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/os/bsd/vm/jvm_bsd.h Tue May 05 18:06:56 2015 -0700
@@ -112,20 +112,6 @@
#define SHUTDOWN2_SIGNAL SIGINT
#define SHUTDOWN3_SIGNAL SIGTERM
@@ -2466,8 +2445,8 @@
#endif /* JVM_MD_H */
#endif // OS_BSD_VM_JVM_BSD_H
---- ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/os/bsd/vm/osThread_bsd.cpp Tue May 05 18:06:56 2015 -0700
@@ -30,7 +30,7 @@
void OSThread::pd_initialize() {
@@ -2477,8 +2456,8 @@
_thread_id = 0;
#else
_thread_id = NULL;
---- ./hotspot/src/os/bsd/vm/os_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/os/bsd/vm/os_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/os/bsd/vm/os_bsd.cpp Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/os/bsd/vm/os_bsd.cpp Tue May 05 18:06:56 2015 -0700
@@ -103,10 +103,24 @@
# include <sys/ioctl.h>
# include <sys/syscall.h>
@@ -2815,8 +2794,8 @@
{
int flags = ::fcntl(fd, F_GETFD);
if (flags != -1)
---- ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/os/bsd/vm/vmError_bsd.cpp Tue May 05 18:06:56 2015 -0700
@@ -44,7 +44,7 @@
jio_snprintf(p, buflen - len,
"\n\n"
@@ -2835,8 +2814,8 @@
os::current_process_id(), os::current_process_id());
os::fork_and_exec(buf);
---- ./hotspot/src/share/vm/opto/node.cpp Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/share/vm/opto/node.cpp Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/share/vm/opto/node.cpp Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/share/vm/opto/node.cpp Tue May 05 18:06:56 2015 -0700
@@ -286,6 +286,10 @@
#ifdef _MSC_VER // the IDX_INIT hack falls foul of warning C4355
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
@@ -2859,8 +2838,8 @@
//------------------------------clone------------------------------------------
// Clone a Node.
---- ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Tue May 05 18:06:56 2015 -0700
@@ -250,7 +250,7 @@
#endif
@@ -2870,29 +2849,8 @@
#define CAN_USE_NAN_DEFINE 1
#endif
---- ./jaxp/.hgtags Wed Jan 28 12:08:37 2015 -0800
-+++ ./jaxp/.hgtags Wed Feb 04 12:14:41 2015 -0800
-@@ -374,3 +374,4 @@
- 78d90db9de2801eec010ccb9f0db3caf969dfc3b jdk8u40-b21
- 54a13451ce243f2159ed3996e6efcf374a5750ca jdk8u40-b22
- e07fbae1efeac4e50514384caa7d226af7414114 jdk8u40-b23
-+048cebd17f73f23ce2295e360f31c1b6788195aa jdk8u40-b24
---- ./jaxws/.hgtags Wed Jan 28 12:08:39 2015 -0800
-+++ ./jaxws/.hgtags Wed Feb 04 12:14:42 2015 -0800
-@@ -372,3 +372,4 @@
- 16485a38b6bc762b363f4e439047486742fbcfcb jdk8u40-b21
- 6e928fd9152541eddf25694be89eb881434a5c5f jdk8u40-b22
- b6755a463ccf6a79b1e1a43ed7bdb1c5cb1ac17d jdk8u40-b23
-+5fbbfd66643edb81cfa0688825d698dcc5f2eb11 jdk8u40-b24
---- ./jdk/.hgtags Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/.hgtags Sat Mar 14 22:56:25 2015 -0700
-@@ -375,3 +375,4 @@
- 564bca490631e4ed4f7993e6633ed9ee62067624 jdk8u40-b21
- d168113f9841a77b3cee3a6a45fcd85b7351ac90 jdk8u40-b22
- 41fe61722ce96b75dd3a1ba5072473122e21e5a0 jdk8u40-b23
-+9d903721276c8684706db7ecfb6cda568e9f4f69 jdk8u40-b24
---- ./jdk/make/CompileDemos.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/CompileDemos.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/CompileDemos.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/CompileDemos.gmk Tue May 05 18:07:05 2015 -0700
@@ -323,7 +323,7 @@
$(eval $(call SetupJVMTIDemo,hprof, java_crw_demo, \
-I$(JDK_TOPDIR)/src/share/npt -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \
@@ -2902,8 +2860,8 @@
$(eval $(call SetupJVMTIDemo,minst, agent_util java_crw_demo))
$(eval $(call SetupJVMTIDemo,mtrace, agent_util java_crw_demo))
---- ./jdk/make/CompileJavaClasses.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/CompileJavaClasses.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/CompileJavaClasses.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/CompileJavaClasses.gmk Tue May 05 18:07:05 2015 -0700
@@ -130,23 +130,32 @@
sun/nio/fs/LinuxFileStore.java \
sun/nio/fs/LinuxFileSystem.java \
@@ -3004,8 +2962,8 @@
$(CLOSED_SRC_DIRS), \
INCLUDES := $(SECURITY_PKGS), \
EXCLUDES := $(EXCLUDES), \
---- ./jdk/make/CompileLaunchers.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/CompileLaunchers.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/CompileLaunchers.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/CompileLaunchers.gmk Tue May 05 18:07:05 2015 -0700
@@ -49,7 +49,7 @@
ORIGIN_ROOT := /..
endif
@@ -3104,8 +3062,8 @@
BUILD_JSPAWNHELPER := 1
endif
---- ./jdk/make/CopyFiles.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/CopyFiles.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/CopyFiles.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/CopyFiles.gmk Tue May 05 18:07:05 2015 -0700
@@ -29,6 +29,8 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
@@ -3148,8 +3106,8 @@
endif
endif
endif
---- ./jdk/make/Images.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/Images.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/Images.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/Images.gmk Tue May 05 18:07:05 2015 -0700
@@ -234,11 +234,11 @@
endif
@@ -3220,7 +3178,7 @@
################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/data/classlist/classlist.bsd Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/make/data/classlist/classlist.bsd Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,2803 @@
+com/sun/java/swing/SwingUtilities3
+com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI
@@ -6025,8 +5983,8 @@
+sun/util/resources/en/TimeZoneNames_en
+sun/util/spi/CalendarProvider
+# ca392e7ee7285d72
---- ./jdk/make/gendata/GendataFontConfig.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/gendata/GendataFontConfig.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/gendata/GendataFontConfig.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/gendata/GendataFontConfig.gmk Tue May 05 18:07:05 2015 -0700
@@ -73,6 +73,13 @@
GENDATA_FONT_CONFIG_SRC_PREFIX := aix.
endif
@@ -6041,8 +5999,8 @@
###
$(GENDATA_FONT_CONFIG_DST)/%.src: \
---- ./jdk/make/lib/Awt2dLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/lib/Awt2dLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/lib/Awt2dLibraries.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/lib/Awt2dLibraries.gmk Tue May 05 18:07:05 2015 -0700
@@ -309,7 +309,7 @@
debug_trace.c \
debug_util.c
@@ -6143,12 +6101,12 @@
# Solaris still uses OPENWIN_LIB ..
LIBSPLASHSCREEN_LDFLAGS_SUFFIX += -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -lX11 -lXext $(LIBM) -lpthread
+ else ifeq ($(OPENJDK_TARGET_OS), bsd)
-+ LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -liconv -pthread
++ LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -pthread
else # .. all other Unixes can use X_LIBS
LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread
endif
---- ./jdk/make/lib/CoreLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/lib/CoreLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/lib/CoreLibraries.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/lib/CoreLibraries.gmk Tue May 05 18:07:05 2015 -0700
@@ -82,7 +82,7 @@
endif
@@ -6221,8 +6179,8 @@
LDFLAGS_macosx := -liconv, \
LDFLAGS_SUFFIX_windows := -export:nptInitialize -export:nptTerminate, \
LDFLAGS_SUFFIX_solaris := -lc, \
---- ./jdk/make/lib/NetworkingLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/lib/NetworkingLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/lib/NetworkingLibraries.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/lib/NetworkingLibraries.gmk Tue May 05 18:07:05 2015 -0700
@@ -42,7 +42,7 @@
LIBNET_EXCLUDE_FILES += linux_close.c
endif
@@ -6240,8 +6198,8 @@
LDFLAGS_SUFFIX_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib \
delayimp.lib $(WIN_JAVA_LIB) advapi32.lib \
-DELAYLOAD:secur32.dll -DELAYLOAD:iphlpapi.dll, \
---- ./jdk/make/lib/NioLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/lib/NioLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/lib/NioLibraries.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/lib/NioLibraries.gmk Tue May 05 18:07:05 2015 -0700
@@ -77,9 +77,28 @@
UnixNativeDispatcher.c
endif
@@ -6302,8 +6260,8 @@
endif
+ endif
endif
---- ./jdk/make/lib/ServiceabilityLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/lib/ServiceabilityLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/lib/ServiceabilityLibraries.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/lib/ServiceabilityLibraries.gmk Tue May 05 18:07:05 2015 -0700
@@ -34,7 +34,7 @@
ifneq ($(OPENJDK_TARGET_OS), linux)
LIBATTACH_EXCLUDE_FILES += LinuxVirtualMachine.c
@@ -6381,8 +6339,8 @@
ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
LIBHPROF_OPTIMIZATION := LOW
endif
---- ./jdk/make/lib/SoundLibraries.gmk Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/lib/SoundLibraries.gmk Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/lib/SoundLibraries.gmk Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/lib/SoundLibraries.gmk Tue May 05 18:07:05 2015 -0700
@@ -75,6 +75,11 @@
LIBJSOUND_CFLAGS += -DX_PLATFORM=X_AIX
endif # OPENJDK_TARGET_OS aix
@@ -6412,8 +6370,8 @@
LDFLAGS_SUFFIX := $(ALSA_LIBS) -ljava -ljvm, \
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjsoundalsa, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
---- ./jdk/make/mapfiles/launchers/mapfile-x86 Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/mapfiles/launchers/mapfile-x86 Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/mapfiles/launchers/mapfile-x86 Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/mapfiles/launchers/mapfile-x86 Tue May 05 18:07:05 2015 -0700
@@ -33,6 +33,7 @@
environ; # Public symbols and required by Java run time
_environ;
@@ -6422,8 +6380,8 @@
___Argv; # The following are private, but as they are
_start; # exported from ctr1/crtn, the clever hacker
_init; # might know about them. However note, that
---- ./jdk/make/mapfiles/launchers/mapfile-x86_64 Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/mapfiles/launchers/mapfile-x86_64 Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/mapfiles/launchers/mapfile-x86_64 Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/mapfiles/launchers/mapfile-x86_64 Tue May 05 18:07:05 2015 -0700
@@ -33,6 +33,7 @@
environ; # Public symbols and required by Java run time
_environ;
@@ -6433,7 +6391,7 @@
local:
*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/mapfiles/libattach/mapfile-bsd Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/make/mapfiles/libattach/mapfile-bsd Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
@@ -6478,7 +6436,7 @@
+ *;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/mapfiles/libnio/mapfile-bsd Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/make/mapfiles/libnio/mapfile-bsd Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,195 @@
+#
+# Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -6675,8 +6633,8 @@
+ local:
+ *;
+};
---- ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/mapfiles/libunpack/mapfile-vers-unpack200 Tue May 05 18:07:05 2015 -0700
@@ -26,6 +26,9 @@
# Define library interface.
@@ -6688,7 +6646,7 @@
*;
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/netbeans/common/bsd-sources.ent Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/make/netbeans/common/bsd-sources.ent Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
@@ -6736,7 +6694,7 @@
+ <location>${root}/src/bsd/classes</location>
+</source-folder>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/make/netbeans/common/bsd-view.ent Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/make/netbeans/common/bsd-view.ent Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
@@ -6777,8 +6735,8 @@
+ <includes>${includes}</includes>
+ <excludes>${excludes}</excludes>
+</source-folder>
---- ./jdk/make/netbeans/common/java-data-native.ent Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/netbeans/common/java-data-native.ent Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/netbeans/common/java-data-native.ent Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/netbeans/common/java-data-native.ent Tue May 05 18:07:05 2015 -0700
@@ -34,6 +34,7 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
<compilation-unit>
@@ -6787,8 +6745,8 @@
<package-root>${root}/src/macosx/classes</package-root>
<package-root>${root}/src/solaris/classes</package-root>
<package-root>${root}/src/windows/classes</package-root>
---- ./jdk/make/netbeans/common/make.xml Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/netbeans/common/make.xml Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/netbeans/common/make.xml Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/netbeans/common/make.xml Tue May 05 18:07:05 2015 -0700
@@ -32,16 +32,21 @@
-->
@@ -6823,8 +6781,8 @@
<macrodef name="make-run">
<attribute name="target"/>
<attribute name="dir"/>
---- ./jdk/make/netbeans/j2se/nbproject/project.xml Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/netbeans/j2se/nbproject/project.xml Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/netbeans/j2se/nbproject/project.xml Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/netbeans/j2se/nbproject/project.xml Tue May 05 18:07:05 2015 -0700
@@ -34,6 +34,7 @@
<!DOCTYPE project [
<!ENTITY properties SYSTEM "../../common/properties.ent">
@@ -6857,8 +6815,8 @@
&macosx-view;
&unix-view;
&windows-view;
---- ./jdk/make/netbeans/world/nbproject/project.xml Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/make/netbeans/world/nbproject/project.xml Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/make/netbeans/world/nbproject/project.xml Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/make/netbeans/world/nbproject/project.xml Tue May 05 18:07:05 2015 -0700
@@ -34,12 +34,14 @@
<!DOCTYPE project [
<!ENTITY properties SYSTEM "../../common/properties.ent">
@@ -6891,7 +6849,7 @@
&unix-view;
&windows-view;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/java/net/DefaultInterface.java Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/src/bsd/classes/java/net/DefaultInterface.java Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -6991,7 +6949,7 @@
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/DefaultSelectorProvider.java Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/src/bsd/classes/sun/nio/ch/DefaultSelectorProvider.java Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -7042,7 +7000,7 @@
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueArrayWrapper.java Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueArrayWrapper.java Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -7258,7 +7216,7 @@
+ private static native void interrupt(int fd);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorImpl.java Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorImpl.java Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
@@ -7510,7 +7468,7 @@
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorProvider.java Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/src/bsd/classes/sun/nio/ch/KQueueSelectorProvider.java Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -7556,8 +7514,50 @@
+ return new KQueueSelectorImpl(this);
+ }
+}
+--- ./jdk/src/bsd/doc/man/javah.1 Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/bsd/doc/man/javah.1 Tue May 05 18:07:05 2015 -0700
+@@ -110,7 +110,7 @@
+
+ \&.:\fIyour-path\fR
+
+-Example: \f3\&.:/home/avh/classes:/usr/local/java/classes\fR
++Example: \f3\&.:/home/avh/classes:/usr/local/share/java/classes\fR
+
+ \fIWindows\fR:
+
+--- ./jdk/src/bsd/doc/man/rmic.1 Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/bsd/doc/man/rmic.1 Tue May 05 18:07:05 2015 -0700
+@@ -93,7 +93,7 @@
+ .TP
+ -classpath path
+ .br
+-Specifies the path the \f3rmic\fR command uses to look up classes\&. This option overrides the default or the \f3CLASSPATH\fR environment variable when it is set\&. Directories are separated by colons\&. The general format for path is: \f3\&.:<your_path>\fR, for example: \f3\&.:/usr/local/java/classes\fR\&.
++Specifies the path the \f3rmic\fR command uses to look up classes\&. This option overrides the default or the \f3CLASSPATH\fR environment variable when it is set\&. Directories are separated by colons\&. The general format for path is: \f3\&.:<your_path>\fR, for example: \f3\&.:/usr/local/share/java/classes\fR\&.
+ .TP
+ -d \fIdirectory\fR
+ .br
+@@ -207,7 +207,7 @@
+ .SH ENVIRONMENT\ VARIABLES
+ .TP
+ CLASSPATH
+-Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/java/classes\fR\&.
++Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/share/java/classes\fR\&.
+ .SH SEE\ ALSO
+ .TP 0.2i
+ \(bu
+--- ./jdk/src/bsd/doc/man/rmid.1 Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/bsd/doc/man/rmid.1 Tue May 05 18:07:05 2015 -0700
+@@ -301,7 +301,7 @@
+ .SH ENVIRONMENT\ VARIABLES
+ .TP
+ CLASSPATH
+-Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/java/classes\fR\&.
++Used to provide the system a path to user-defined classes\&. Directories are separated by colons, for example: \f3\&.:/usr/local/share/java/classes\fR\&.
+ .SH SEE\ ALSO
+ .TP 0.2i
+ \(bu
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/bsd/native/sun/nio/ch/KQueueArrayWrapper.c Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/src/bsd/native/sun/nio/ch/KQueueArrayWrapper.c Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
@@ -7730,7 +7730,7 @@
+ }
+}
+
---- ./jdk/src/macosx/classes/java/net/DefaultInterface.java Mon Feb 02 10:12:21 2015 -0800
+--- ./jdk/src/macosx/classes/java/net/DefaultInterface.java Tue Mar 17 00:09:12 2015 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
@@ -7830,7 +7830,7 @@
- return (ppp != null) ? ppp : loopback;
- }
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java Mon Feb 02 10:12:21 2015 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java Tue Mar 17 00:09:12 2015 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
@@ -7881,7 +7881,7 @@
- }
-
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Mon Feb 02 10:12:21 2015 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Tue Mar 17 00:09:12 2015 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/*
@@ -8097,7 +8097,7 @@
- long timeout);
- private static native void interrupt(int fd);
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Mon Feb 02 10:12:21 2015 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Tue Mar 17 00:09:12 2015 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-/*
@@ -8349,7 +8349,7 @@
- return this;
- }
-}
---- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Mon Feb 02 10:12:21 2015 -0800
+--- ./jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorProvider.java Tue Mar 17 00:09:12 2015 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
@@ -8396,7 +8396,7 @@
- return new KQueueSelectorImpl(this);
- }
-}
---- ./jdk/src/macosx/native/sun/nio/ch/KQueueArrayWrapper.c Mon Feb 02 10:12:21 2015 -0800
+--- ./jdk/src/macosx/native/sun/nio/ch/KQueueArrayWrapper.c Tue Mar 17 00:09:12 2015 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-/*
@@ -8570,8 +8570,8 @@
- }
-}
-
---- ./jdk/src/share/bin/jli_util.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/bin/jli_util.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/bin/jli_util.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/bin/jli_util.h Tue May 05 18:07:05 2015 -0700
@@ -87,7 +87,7 @@
#define _LARGFILE64_SOURCE
#define JLI_Lseek lseek64
@@ -8581,8 +8581,8 @@
#define JLI_Lseek lseek
#endif
#ifdef _AIX
---- ./jdk/src/share/classes/sun/awt/FontConfiguration.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/awt/FontConfiguration.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/awt/FontConfiguration.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/awt/FontConfiguration.java Tue May 05 18:07:05 2015 -0700
@@ -1146,7 +1146,7 @@
*/
HashMap<String, Boolean> existsMap;
@@ -8592,8 +8592,8 @@
return false;
} else if (existsMap == null) {
existsMap = new HashMap<String, Boolean>();
---- ./jdk/src/share/classes/sun/awt/OSInfo.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/awt/OSInfo.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/awt/OSInfo.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/awt/OSInfo.java Tue May 05 18:07:05 2015 -0700
@@ -39,6 +39,7 @@
WINDOWS,
LINUX,
@@ -8613,8 +8613,8 @@
if (osName.contains("OS X")) {
return MACOSX;
}
---- ./jdk/src/share/classes/sun/font/FontUtilities.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/font/FontUtilities.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/font/FontUtilities.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/font/FontUtilities.java Tue May 05 18:07:05 2015 -0700
@@ -48,6 +48,8 @@
public static boolean isLinux;
@@ -8633,8 +8633,8 @@
isMacOSX = osName.contains("OS X"); // TODO: MacOSX
String t2kStr = System.getProperty("sun.java2d.font.scaler");
---- ./jdk/src/share/classes/sun/font/SunFontManager.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/font/SunFontManager.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/font/SunFontManager.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/font/SunFontManager.java Tue May 05 18:07:05 2015 -0700
@@ -418,7 +418,7 @@
* registerFonts method as on-screen these JRE fonts
* always go through the T2K rasteriser.
@@ -8644,8 +8644,8 @@
/* Linux font configuration uses these fonts */
registerFontDir(jreFontDirName);
}
---- ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Tue May 05 18:07:05 2015 -0700
@@ -1298,7 +1298,7 @@
String osName = AccessController.doPrivileged(
new GetPropertyAction("os.name"));
@@ -8655,8 +8655,8 @@
charset("x-COMPOUND_TEXT", "COMPOUND_TEXT",
new String[] {
"COMPOUND_TEXT", // JDK historical
---- ./jdk/src/share/classes/sun/print/PSPrinterJob.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/print/PSPrinterJob.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/print/PSPrinterJob.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/print/PSPrinterJob.java Tue May 05 18:07:05 2015 -0700
@@ -1587,7 +1587,7 @@
}
@@ -8666,8 +8666,8 @@
execCmd = new String[ncomps];
execCmd[n++] = "/usr/bin/lpr";
if ((pFlags & PRINTER) != 0) {
---- ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java Tue May 05 18:07:05 2015 -0700
@@ -48,6 +48,7 @@
public Boolean run() {
String osname = System.getProperty("os.name");
@@ -8676,8 +8676,8 @@
osname.contains("OS X") ||
osname.startsWith("Linux")) {
return new Boolean(System.getProperty
---- ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Tue May 05 18:07:05 2015 -0700
@@ -90,6 +90,12 @@
"libgssapi_krb5.so",
"libgssapi_krb5.so.2",
@@ -8691,8 +8691,8 @@
} else if (osname.contains("OS X")) {
gssLibs = new String[]{
"libgssapi_krb5.dylib",
---- ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider Tue May 05 18:07:05 2015 -0700
@@ -31,4 +31,5 @@
#[windows]sun.tools.attach.WindowsAttachProvider
#[linux]sun.tools.attach.LinuxAttachProvider
@@ -8700,7 +8700,7 @@
+#[bsd]sun.tools.attach.BsdAttachProvider
#[aix]sun.tools.attach.AixAttachProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ ./jdk/src/share/lib/security/java.security-bsd Sat Mar 14 22:56:25 2015 -0700
++++ ./jdk/src/share/lib/security/java.security-bsd Tue May 05 18:07:05 2015 -0700
@@ -0,0 +1,498 @@
+#
+# This is the "master security properties file".
@@ -9200,8 +9200,8 @@
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
---- ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/com/sun/java/util/jar/pack/zip.cpp Tue May 05 18:07:05 2015 -0700
@@ -62,7 +62,7 @@
#endif // End of ZLIB
@@ -9211,8 +9211,8 @@
#define SWAP_BYTES(a) \
((((a) << 8) & 0xff00) | 0x00ff) & (((a) >> 8) | 0xff00)
#else
---- ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/com/sun/media/sound/DirectAudioDevice.c Tue May 05 18:07:05 2015 -0700
@@ -121,7 +121,7 @@
}
@@ -9240,8 +9240,8 @@
#define MAP_NATIVE2LE16(a) (a)
#define MAP_NATIVE2BE16(a) MAP_SWAP16_impl(a)
#define MAP_NATIVE2LE32(a) (a)
---- ./jdk/src/share/native/com/sun/media/sound/Utilities.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/com/sun/media/sound/Utilities.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/com/sun/media/sound/Utilities.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/com/sun/media/sound/Utilities.c Tue May 05 18:07:05 2015 -0700
@@ -28,7 +28,7 @@
@@ -9251,8 +9251,8 @@
return 0;
#else
return 1;
---- ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/java/lang/fdlibm/include/fdlibm.h Tue May 05 18:07:05 2015 -0700
@@ -40,7 +40,7 @@
#endif
#endif
@@ -9262,8 +9262,8 @@
#define __HI(x) *(1+(int*)&x)
#define __LO(x) *(int*)&x
#define __HIp(x) *(1+(int*)x)
---- ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/image/awt_parseImage.c Tue May 05 18:07:05 2015 -0700
@@ -624,7 +624,7 @@
switch(type) {
case java_awt_image_BufferedImage_TYPE_INT_ARGB:
@@ -9291,8 +9291,8 @@
colorOrder[0] = 2;
colorOrder[1] = 1;
colorOrder[2] = 0;
---- ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Tue May 05 18:07:05 2015 -0700
@@ -1176,7 +1176,7 @@
#define NLUT 8
@@ -9302,8 +9302,8 @@
#define INDEXES { 3, 2, 1, 0, 7, 6, 5, 4 }
#else
#define INDEXES { 0, 1, 2, 3, 4, 5, 6, 7 }
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv2x2_f.c Tue May 05 18:07:05 2015 -0700
@@ -86,7 +86,7 @@
#endif /* MLIB_USE_FTOI_CLAMPING */
@@ -9343,8 +9343,8 @@
#endif /* _NO_LONGLONG */
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16ext.c Tue May 05 18:07:05 2015 -0700
@@ -126,7 +126,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9384,8 +9384,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_16nw.c Tue May 05 18:07:05 2015 -0700
@@ -94,7 +94,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9425,8 +9425,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8ext.c Tue May 05 18:07:05 2015 -0700
@@ -126,7 +126,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9466,8 +9466,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_8nw.c Tue May 05 18:07:05 2015 -0700
@@ -95,7 +95,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9507,8 +9507,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16ext.c Tue May 05 18:07:05 2015 -0700
@@ -126,7 +126,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9548,8 +9548,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageConv_u16nw.c Tue May 05 18:07:05 2015 -0700
@@ -94,7 +94,7 @@
#define D2I(x) CLAMP_S32((x) SAT_OFF)
@@ -9589,8 +9589,8 @@
#endif /* _NO_LONGLONG */
/***************************************************************/
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageCopy_Bit.c Tue May 05 18:07:05 2015 -0700
@@ -95,7 +95,7 @@
dst = dp[0];
if (ld_offset + size < 32) {
@@ -9810,8 +9810,8 @@
}
#else /* _LONGLONG */
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_64.c Tue May 05 18:07:05 2015 -0700
@@ -168,7 +168,7 @@
}
@@ -10092,8 +10092,8 @@
dp[12] = t0;
dp[13] = t1;
dp[14] = t2;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageLookUp_Bit.c Tue May 05 18:07:05 2015 -0700
@@ -88,7 +88,7 @@
} d64_2_f32;
@@ -10245,8 +10245,8 @@
((mlib_u32*)lh)[0] = l; ((mlib_u32*)lh)[1] = l;
((mlib_u32*)lh)[2] = l; ((mlib_u32*)lh)[3] = h;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_ImageUtils.c Tue May 05 18:07:05 2015 -0700
@@ -30,7 +30,7 @@
typedef union {
mlib_d64 db;
@@ -10256,8 +10256,8 @@
mlib_s32 int1, int0;
#else
mlib_s32 int0, int1;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageCopy.c Tue May 05 18:07:05 2015 -0700
@@ -275,11 +275,11 @@
for (i = 0; j <= (b_size - 4); j += 4, i++) {
src0 = src1;
@@ -10356,8 +10356,8 @@
s0 = s1;
dp += SIZE;
sp += SIZE;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_c_ImageLookUp_f.c Tue May 05 18:07:05 2015 -0700
@@ -120,7 +120,7 @@
} \
}
@@ -11590,8 +11590,8 @@
dp[12] = t0;
dp[13] = t1;
dp[14] = t2;
---- ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_image.h Tue May 05 18:07:05 2015 -0700
@@ -27,9 +27,6 @@
#ifndef MLIB_IMAGE_H
#define MLIB_IMAGE_H
@@ -11602,8 +11602,8 @@
#include <mlib_types.h>
#include <mlib_status.h>
#include <mlib_sys.h>
---- ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/awt/medialib/mlib_sys.c Tue May 05 18:07:05 2015 -0700
@@ -29,7 +29,7 @@
#ifdef MACOSX
#include <unistd.h>
@@ -11623,8 +11623,8 @@
#else
return (void *) memalign(8, size);
#endif /* _MSC_VER */
---- ./jdk/src/share/native/sun/font/layout/LEStandalone.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/font/layout/LEStandalone.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/font/layout/LEStandalone.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/font/layout/LEStandalone.h Tue May 05 18:07:05 2015 -0700
@@ -136,7 +136,7 @@
#define U_CAPI extern "C"
@@ -11634,8 +11634,8 @@
#define U_IS_BIG_ENDIAN 0
#endif
#endif
---- ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c Tue May 05 18:07:05 2015 -0700
@@ -182,7 +182,7 @@
return 0L;
}
@@ -11645,8 +11645,8 @@
/* Reversing data packed into int for LE archs */
if (isInIntPacked) {
inFormatter ^= DOSWAP_SH(1);
---- ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/share/native/sun/management/DiagnosticCommandImpl.c Tue May 05 18:07:05 2015 -0700
@@ -27,6 +27,7 @@
#include <jni.h>
#include "management.h"
@@ -11655,8 +11655,8 @@
JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled
(JNIEnv *env, jobject dummy, jboolean enabled) {
---- ./jdk/src/solaris/back/util_md.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/back/util_md.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/back/util_md.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/back/util_md.h Tue May 05 18:07:05 2015 -0700
@@ -51,7 +51,7 @@
/* On little endian machines, convert java big endian numbers. */
@@ -11666,8 +11666,8 @@
#define HOST_TO_JAVA_CHAR(x) (((x & 0xff) << 8) | ((x >> 8) & (0xff)))
#define HOST_TO_JAVA_SHORT(x) (((x & 0xff) << 8) | ((x >> 8) & (0xff)))
---- ./jdk/src/solaris/bin/ergo_i586.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/bin/ergo_i586.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/bin/ergo_i586.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/bin/ergo_i586.c Tue May 05 18:07:05 2015 -0700
@@ -106,7 +106,7 @@
#endif /* __solaris__ */
@@ -11686,8 +11686,8 @@
/*
* Routines shared by solaris-i586 and linux-i586.
---- ./jdk/src/solaris/bin/java_md_solinux.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/bin/java_md_solinux.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/bin/java_md_solinux.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/bin/java_md_solinux.c Tue May 05 18:07:05 2015 -0700
@@ -306,9 +306,9 @@
if (llp == NULL && dmllp == NULL) {
return JNI_FALSE;
@@ -11774,8 +11774,8 @@
}
int
---- ./jdk/src/solaris/bin/java_md_solinux.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/bin/java_md_solinux.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/bin/java_md_solinux.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/bin/java_md_solinux.h Tue May 05 18:07:05 2015 -0700
@@ -26,17 +26,26 @@
#ifndef JAVA_MD_SOLINUX_H
#define JAVA_MD_SOLINUX_H
@@ -11816,8 +11816,8 @@
#else /* !__solaris__, i.e. Linux, AIX,.. */
static const char *system_dir = "/usr/java";
static const char *user_dir = "/java";
---- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/java/lang/UNIXProcess.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/java/lang/UNIXProcess.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/java/lang/UNIXProcess.java Tue May 05 18:07:05 2015 -0700
@@ -82,6 +82,8 @@
LINUX(LaunchMechanism.VFORK, LaunchMechanism.FORK),
@@ -11865,8 +11865,8 @@
case BSD:
case AIX:
// There is a risk that pid will be recycled, causing us to
---- ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/awt/X11FontManager.java Tue May 05 18:07:05 2015 -0700
@@ -236,7 +236,7 @@
if (fontID != null) {
fileName = (String)fontNameMap.get(fontID);
@@ -11894,8 +11894,8 @@
(!mFontConfig.foundOsSpecificFile() ||
!mFontConfig.fontFilesArePresent()) ||
(FontUtilities.isSolaris && !mFontConfig.fontFilesArePresent()))) {
---- ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/awt/fontconfigs/bsd.fontconfig.properties Tue May 05 18:07:05 2015 -0700
@@ -26,134 +26,134 @@
# Version
@@ -12158,8 +12158,8 @@
+filename.NanumGothic_Bold=/usr/local/lib/X11/fonts/nanum-ttf/NanumGothicBold.ttf
+filename.NanumMyeongjo=/usr/local/lib/X11/fonts/nanum-ttf/NanumMyeongjo.ttf
+filename.NanumMyeongjo_Bold=/usr/local/lib/X11/fonts/nanum-ttf/NanumMyeongjoBold.ttf
---- ./jdk/src/solaris/classes/sun/net/PortConfig.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/net/PortConfig.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/net/PortConfig.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/net/PortConfig.java Tue May 05 18:07:05 2015 -0700
@@ -52,7 +52,7 @@
} else if (os.startsWith("SunOS")) {
defaultLower = 32768;
@@ -12169,8 +12169,8 @@
defaultLower = 49152;
defaultUpper = 65535;
} else if (os.startsWith("AIX")) {
---- ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java Tue May 05 18:07:05 2015 -0700
@@ -66,7 +66,7 @@
return createProvider("sun.nio.ch.SolarisAsynchronousChannelProvider");
if (osname.equals("Linux"))
@@ -12180,8 +12180,8 @@
return createProvider("sun.nio.ch.BsdAsynchronousChannelProvider");
if (osname.equals("AIX"))
return createProvider("sun.nio.ch.AixAsynchronousChannelProvider");
---- ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/nio/fs/BsdFileSystemProvider.java Tue May 05 18:07:05 2015 -0700
@@ -25,10 +25,14 @@
package sun.nio.fs;
@@ -12215,8 +12215,8 @@
+ new MagicFileTypeDetector());
+ }
}
---- ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java Tue May 05 18:07:05 2015 -0700
@@ -61,6 +61,8 @@
return createProvider("sun.nio.fs.SolarisFileSystemProvider");
if (osname.equals("Linux"))
@@ -12226,8 +12226,8 @@
if (osname.contains("OS X"))
return createProvider("sun.nio.fs.MacOSXFileSystemProvider");
if (osname.equals("AIX"))
---- ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Tue May 05 18:07:05 2015 -0700
@@ -161,6 +161,7 @@
static boolean isBSD() {
@@ -12251,8 +12251,8 @@
"/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
};
---- ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/classes/sun/tools/attach/BsdVirtualMachine.java Tue May 05 18:07:05 2015 -0700
@@ -273,7 +273,7 @@
try {
b = s.getBytes("UTF-8");
@@ -12262,8 +12262,8 @@
}
BsdVirtualMachine.write(fd, b, 0, b.length);
}
---- ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c Tue May 05 18:07:05 2015 -0700
@@ -140,7 +140,7 @@
(float) ((int) sr->samp_rates[s]),
DAUDIO_PCM, /* encoding - let's only do PCM */
@@ -12273,8 +12273,8 @@
FALSE /* little endian */
#else
(bits[b] > 8)?TRUE:FALSE /* big endian */
---- ./jdk/src/solaris/native/common/jni_util_md.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/common/jni_util_md.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/common/jni_util_md.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/common/jni_util_md.c Tue May 05 18:07:05 2015 -0700
@@ -28,6 +28,7 @@
#include "jni.h"
#include "jni_util.h"
@@ -12283,8 +12283,8 @@
jstring nativeNewStringPlatform(JNIEnv *env, const char *str) {
return NULL;
---- ./jdk/src/solaris/native/java/lang/java_props_md.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/lang/java_props_md.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/lang/java_props_md.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/lang/java_props_md.c Tue May 05 18:07:05 2015 -0700
@@ -151,7 +151,7 @@
lc = setlocale(cat, NULL);
#endif
@@ -12319,8 +12319,8 @@
/* user properties */
{
---- ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/net/Inet4AddressImpl.c Tue May 05 18:07:05 2015 -0700
@@ -36,20 +36,13 @@
#include <stdlib.h>
#include <ctype.h>
@@ -12639,8 +12639,8 @@
#define SET_NONBLOCKING(fd) { \
int flags = fcntl(fd, F_GETFL); \
flags |= O_NONBLOCK; \
---- ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/net/Inet6AddressImpl.c Tue May 05 18:07:05 2015 -0700
@@ -33,7 +33,7 @@
#include <strings.h>
#include <stdlib.h>
@@ -12671,8 +12671,8 @@
/*
* If we're looking up the local machine, attempt to get the address
* from getifaddrs. This ensures we get an IPv6 address for the local
---- ./jdk/src/solaris/native/java/net/NetworkInterface.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/net/NetworkInterface.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/net/NetworkInterface.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/net/NetworkInterface.c Tue May 05 18:07:05 2015 -0700
@@ -67,14 +67,18 @@
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -12694,8 +12694,8 @@
#include "jvm.h"
#include "jni_util.h"
---- ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c Tue May 05 18:07:05 2015 -0700
@@ -2200,7 +2200,7 @@
}
}
@@ -12705,8 +12705,8 @@
if (family == AF_INET6 && index == 0) {
index = getDefaultScopeID(env);
}
---- ./jdk/src/solaris/native/java/net/bsd_close.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/net/bsd_close.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/net/bsd_close.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/net/bsd_close.c Tue May 05 18:07:05 2015 -0700
@@ -316,11 +316,8 @@
}
@@ -12721,8 +12721,8 @@
}
int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
---- ./jdk/src/solaris/native/java/net/net_util_md.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/net/net_util_md.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/net/net_util_md.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/net/net_util_md.c Tue May 05 18:07:05 2015 -0700
@@ -87,7 +87,7 @@
void setDefaultScopeID(JNIEnv *env, struct sockaddr *him)
@@ -12732,8 +12732,8 @@
static jclass ni_class = NULL;
static jfieldID ni_defaultIndexID;
if (ni_class == NULL) {
---- ./jdk/src/solaris/native/java/net/net_util_md.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/net/net_util_md.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/net/net_util_md.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/net/net_util_md.h Tue May 05 18:07:05 2015 -0700
@@ -47,7 +47,7 @@
close subroutine does not return until the select call returns.
...
@@ -12743,8 +12743,8 @@
extern int NET_Timeout(int s, long timeout);
extern int NET_Read(int s, void* buf, size_t len);
extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
---- ./jdk/src/solaris/native/java/util/TimeZone_md.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/java/util/TimeZone_md.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/java/util/TimeZone_md.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/java/util/TimeZone_md.c Tue May 05 18:07:05 2015 -0700
@@ -52,7 +52,11 @@
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
@@ -12829,8 +12829,8 @@
}
#endif
-
---- ./jdk/src/solaris/native/sun/awt/awt_Font.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_Font.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/awt/awt_Font.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/awt/awt_Font.c Tue May 05 18:07:05 2015 -0700
@@ -255,7 +255,7 @@
if (strcmp(style, "regular") == 0) {
altstyle = "roman";
@@ -12840,8 +12840,8 @@
if (!strcmp(family, "lucidasans")) {
family = "lucida";
}
---- ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/awt/awt_GraphicsEnv.c Tue May 05 18:07:05 2015 -0700
@@ -120,7 +120,7 @@
*/
@@ -12926,8 +12926,8 @@
#endif /* HEADLESS */
return point;
}
---- ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/awt/awt_InputMethod.c Tue May 05 18:07:05 2015 -0700
@@ -52,7 +52,7 @@
XIMPreeditDrawCallbackStruct *);
static void PreeditCaretCallback(XIC, XPointer,
@@ -13147,8 +13147,8 @@
AWT_LOCK();
adjustStatusWindow(window);
AWT_UNLOCK();
---- ./jdk/src/solaris/native/sun/awt/awt_Robot.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/awt/awt_Robot.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/awt/awt_Robot.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/awt/awt_Robot.c Tue May 05 18:07:05 2015 -0700
@@ -45,7 +45,7 @@
#include "wsutils.h"
#include "list.h"
@@ -13158,8 +13158,8 @@
#include <sys/socket.h>
#endif
---- ./jdk/src/solaris/native/sun/awt/extutil.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/awt/extutil.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/awt/extutil.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/awt/extutil.h Tue May 05 18:07:05 2015 -0700
@@ -58,7 +58,7 @@
*/
/* $XFree86: xc/include/extensions/extutil.h,v 1.5 2001/01/17 17:53:20 dawes Exp $ */
@@ -13175,8 +13175,8 @@
-#endif /* __linux__ || MACOSX */
+#endif /* __linux__ || _ALLBSD_SOURCE */
---- ./jdk/src/solaris/native/sun/awt/fontpath.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/awt/fontpath.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/awt/fontpath.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/awt/fontpath.c Tue May 05 18:07:05 2015 -0700
@@ -23,9 +23,9 @@
* questions.
*/
@@ -13265,8 +13265,8 @@
&& (strcmp((char*)fontformat, "Type 1") != 0)
#endif
) {
---- ./jdk/src/solaris/native/sun/java2d/j2d_md.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/java2d/j2d_md.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/java2d/j2d_md.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/java2d/j2d_md.h Tue May 05 18:07:05 2015 -0700
@@ -28,11 +28,11 @@
#include <sys/types.h>
@@ -13282,8 +13282,8 @@
typedef unsigned char jubyte;
typedef unsigned short jushort;
---- ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/java2d/loops/mlib_ImageZoom_NN.c Tue May 05 18:07:05 2015 -0700
@@ -63,9 +63,6 @@
* MLIB_EDGE_SRC_PADDED
*/
@@ -13388,8 +13388,8 @@
LOGIC(da[0], dtmp, dtmp1, |);
}
else { /* aligned */
---- ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/java2d/loops/vis_FuncArray.c Tue May 05 18:07:05 2015 -0700
@@ -804,7 +804,7 @@
static int initialized;
static int usevis = JNI_TRUE;
@@ -13399,8 +13399,8 @@
# define ULTRA_CHIP "sparc64"
#else
# define ULTRA_CHIP "sun4u"
---- ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/management/OperatingSystemImpl.c Tue May 05 18:07:05 2015 -0700
@@ -56,6 +56,9 @@
#include <limits.h>
#include <stdlib.h>
@@ -13555,8 +13555,8 @@
return -1;
}
---- ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/nio/ch/sctp/Sctp.h Tue May 05 18:07:05 2015 -0700
@@ -67,7 +67,7 @@
@@ -13605,8 +13605,8 @@
jboolean loadSocketExtensionFuncs(JNIEnv* env);
#endif /* !SUN_NIO_CH_SCTP_H */
---- ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/nio/ch/sctp/SctpNet.c Tue May 05 18:07:05 2015 -0700
@@ -58,6 +58,7 @@
*/
jboolean loadSocketExtensionFuncs
@@ -13623,8 +13623,8 @@
funcsLoaded = JNI_TRUE;
return JNI_TRUE;
---- ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/nio/fs/MagicFileTypeDetector.c Tue May 05 18:07:05 2015 -0700
@@ -31,6 +31,12 @@
#include <dlfcn.h>
#include <string.h>
@@ -13647,8 +13647,8 @@
if (magic_handle == NULL) {
return JNI_FALSE;
}
---- ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/tools/attach/BsdVirtualMachine.c Tue May 05 18:07:05 2015 -0700
@@ -37,7 +37,9 @@
#include <sys/types.h>
#include <sys/socket.h>
@@ -13659,8 +13659,8 @@
#include <sys/un.h>
#include <fcntl.h>
---- ./jdk/src/solaris/native/sun/xawt/XWindow.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/solaris/native/sun/xawt/XWindow.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/solaris/native/sun/xawt/XWindow.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/solaris/native/sun/xawt/XWindow.c Tue May 05 18:07:05 2015 -0700
@@ -886,7 +886,7 @@
{
KeySym originalKeysym = *keysym;
@@ -13670,8 +13670,8 @@
/* The following code on Linux will cause the keypad keys
* not to echo on JTextField when the NumLock is on. The
* keysyms will be 0, because the last parameter 2 is not defined.
---- ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_DirectSound.cpp Tue May 05 18:07:05 2015 -0700
@@ -308,7 +308,7 @@
DAUDIO_PCM,
(bitsArray[bitIndex]==8)?FALSE:TRUE, /* signed */
diff --git a/java/openjdk8/files/patch-bsd-test b/java/openjdk8/files/patch-bsd-test
index b973833664b6..3b0cc2632014 100644
--- a/java/openjdk8/files/patch-bsd-test
+++ b/java/openjdk8/files/patch-bsd-test
@@ -1,5 +1,5 @@
---- ./hotspot/test/compiler/5091921/Test7005594.sh Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/test/compiler/5091921/Test7005594.sh Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/test/compiler/5091921/Test7005594.sh Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/test/compiler/5091921/Test7005594.sh Tue May 05 18:06:56 2015 -0700
@@ -60,6 +60,15 @@
# Windows/MKS
MEM=`"$ROOTDIR/mksnt/sysinf" memory -v | grep "Total Physical Memory: " | sed 's/Total Physical Memory: *//g'`
@@ -16,8 +16,8 @@
else
echo "Unable to determine amount of physical memory on the machine"
fi
---- ./hotspot/test/compiler/6894807/Test6894807.sh Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/test/compiler/6894807/Test6894807.sh Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/test/compiler/6894807/Test6894807.sh Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/test/compiler/6894807/Test6894807.sh Tue May 05 18:06:56 2015 -0700
@@ -21,7 +21,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -27,8 +27,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./hotspot/test/runtime/7110720/Test7110720.sh Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/test/runtime/7110720/Test7110720.sh Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/test/runtime/7110720/Test7110720.sh Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/test/runtime/7110720/Test7110720.sh Tue May 05 18:06:56 2015 -0700
@@ -28,7 +28,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -38,8 +38,8 @@
FS="/"
RM=/bin/rm
CP=/bin/cp
---- ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Tue May 05 18:06:56 2015 -0700
@@ -37,8 +37,8 @@
public static void main(String args[]) throws Throwable {
@@ -51,8 +51,8 @@
return;
}
---- ./hotspot/test/test_env.sh Fri Jan 30 15:14:31 2015 -0800
-+++ ./hotspot/test/test_env.sh Sat Mar 14 16:41:08 2015 -0700
+--- ./hotspot/test/test_env.sh Mon Mar 16 11:19:42 2015 -0700
++++ ./hotspot/test/test_env.sh Tue May 05 18:06:56 2015 -0700
@@ -53,7 +53,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -62,8 +62,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Tue May 05 18:07:05 2015 -0700
@@ -48,7 +48,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -73,8 +73,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/com/sun/corba/cachedSocket/7056731.sh Tue May 05 18:07:05 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -84,8 +84,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/com/sun/jdi/ImmutableResourceTest.sh Tue May 05 18:07:05 2015 -0700
@@ -56,7 +56,7 @@
OS=`uname -s`
@@ -95,8 +95,8 @@
PATHSEP=":"
;;
---- ./jdk/test/com/sun/jdi/JITDebug.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/com/sun/jdi/JITDebug.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/com/sun/jdi/JITDebug.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/com/sun/jdi/JITDebug.sh Tue May 05 18:07:05 2015 -0700
@@ -63,7 +63,7 @@
OS=`uname -s`
export TRANSPORT_METHOD
@@ -106,8 +106,8 @@
PATHSEP=":"
TRANSPORT_METHOD=dt_socket
;;
---- ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/com/sun/jdi/PrivateTransportTest.sh Tue May 05 18:07:05 2015 -0700
@@ -106,7 +106,7 @@
xx=`find ${jreloc}/lib -name libdt_socket.so`
libloc=`dirname ${xx}`
@@ -117,8 +117,8 @@
libloc=${jreloc}/lib
;;
Windows*)
---- ./jdk/test/com/sun/jdi/ShellScaffold.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/com/sun/jdi/ShellScaffold.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/com/sun/jdi/ShellScaffold.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/com/sun/jdi/ShellScaffold.sh Tue May 05 18:07:05 2015 -0700
@@ -295,7 +295,7 @@
psCmd=ps
jstack=jstack.exe
@@ -128,8 +128,8 @@
transport=dt_socket
address=
devnull=/dev/null
---- ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/com/sun/jdi/connect/spi/JdiLoadedByCustomLoader.sh Tue May 05 18:07:05 2015 -0700
@@ -45,7 +45,7 @@
OS=`uname -s`
@@ -139,8 +139,8 @@
PS=":"
;;
Windows* | CYGWIN*)
---- ./jdk/test/java/awt/JAWT/JAWT.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/awt/JAWT/JAWT.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/awt/JAWT/JAWT.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/awt/JAWT/JAWT.sh Tue May 05 18:07:05 2015 -0700
@@ -62,6 +62,23 @@
MAKE="make"
LD_LIBRARY_PATH="."
@@ -174,8 +174,8 @@
exit 0;
;;
* )
---- ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh Tue May 05 18:07:05 2015 -0700
@@ -86,6 +86,14 @@
TMP="/tmp"
;;
@@ -191,8 +191,8 @@
Windows* )
VAR="A different value for Win32"
DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
---- ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Tue May 05 18:07:05 2015 -0700
@@ -59,7 +59,7 @@
# Checking for proper OS
OS=`uname -s`
@@ -202,8 +202,8 @@
FILESEP="/"
;;
---- ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh Tue May 05 18:07:05 2015 -0700
@@ -119,6 +119,14 @@
TMP="/tmp"
;;
@@ -219,8 +219,8 @@
Windows* )
VAR="A different value for Win32"
DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
---- ./jdk/test/java/io/File/GetXSpace.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/io/File/GetXSpace.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/io/File/GetXSpace.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/io/File/GetXSpace.java Tue May 05 18:07:05 2015 -0700
@@ -51,7 +51,7 @@
private static final String dfFormat;
static {
@@ -230,8 +230,8 @@
// FileSystem Total Used Available Use% MountedOn
dfFormat = "([^\\s]+)\\s+(\\d+)\\s+\\d+\\s+(\\d+)\\s+\\d+%\\s+([^\\s]+)";
} else if (name.startsWith("Windows")) {
---- ./jdk/test/java/io/File/GetXSpace.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/io/File/GetXSpace.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/io/File/GetXSpace.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/io/File/GetXSpace.sh Tue May 05 18:07:05 2015 -0700
@@ -26,7 +26,7 @@
# set platform-dependent variable
OS=`uname -s`
@@ -241,8 +241,8 @@
Windows_98 ) return ;;
Windows* ) SID=`sid`; TMP="c:/temp" ;;
* )
---- ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/io/Serializable/evolution/RenamePackage/run.sh Tue May 05 18:07:05 2015 -0700
@@ -45,7 +45,7 @@
# Need to determine the classpath separator and filepath separator based on the
# operating system.
@@ -252,8 +252,8 @@
PS=":" ;;
Windows* | CYGWIN* )
PS=";" ;;
---- ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/io/Serializable/serialver/classpath/run.sh Tue May 05 18:07:05 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -263,8 +263,8 @@
PS=":" ;;
Windows* | CYGWIN* )
PS=";" ;;
---- ./jdk/test/java/io/Serializable/serialver/nested/run.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/io/Serializable/serialver/nested/run.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/io/Serializable/serialver/nested/run.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/io/Serializable/serialver/nested/run.sh Tue May 05 18:07:05 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -274,8 +274,8 @@
PS=":" ;;
Windows* | CYGWIN* )
PS=";" ;;
---- ./jdk/test/java/lang/ClassLoader/Assert.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/ClassLoader/Assert.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/ClassLoader/Assert.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/ClassLoader/Assert.sh Tue May 05 18:07:05 2015 -0700
@@ -25,7 +25,7 @@
OS=`uname -s`
@@ -285,8 +285,8 @@
FS="/"
CHMOD="${FS}bin${FS}chmod"
;;
---- ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh Tue May 05 18:07:05 2015 -0700
@@ -55,7 +55,7 @@
Linux )
FS="/"
@@ -296,8 +296,8 @@
FS="/"
;;
AIX )
---- ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh Tue May 05 18:07:05 2015 -0700
@@ -60,7 +60,7 @@
Linux )
FS="/"
@@ -307,8 +307,8 @@
FS="/"
;;
AIX )
---- ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/ProcessBuilder/DestroyTest.java Tue May 05 18:07:05 2015 -0700
@@ -148,6 +148,9 @@
} else if (osName.startsWith("Linux") == true) {
return new UnixTest(
@@ -319,8 +319,8 @@
} else if (osName.startsWith("Mac OS")) {
return new MacTest(
File.createTempFile("ProcessTrap-", ".sh",null));
---- ./jdk/test/java/lang/ProcessBuilder/Zombies.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/ProcessBuilder/Zombies.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/ProcessBuilder/Zombies.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/ProcessBuilder/Zombies.java Tue May 05 18:07:05 2015 -0700
@@ -34,7 +34,7 @@
static final String os = System.getProperty("os.name");
@@ -330,8 +330,8 @@
"/usr/bin/true" : "/bin/true";
public static void main(String[] args) throws Throwable {
---- ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/StringCoding/CheckEncodings.sh Tue May 05 18:07:05 2015 -0700
@@ -30,7 +30,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -341,8 +341,8 @@
Windows* | CYGWIN* )
echo "Passed"; exit 0 ;;
* ) echo "Unrecognized system!" ; exit 1 ;;
---- ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/annotation/loaderLeak/LoaderLeak.sh Tue May 05 18:07:05 2015 -0700
@@ -48,7 +48,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -352,8 +352,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/java/lang/instrument/MakeJAR2.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/instrument/MakeJAR2.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/instrument/MakeJAR2.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/instrument/MakeJAR2.sh Tue May 05 18:07:05 2015 -0700
@@ -55,7 +55,7 @@
OS=`uname -s`
@@ -363,8 +363,8 @@
PATHSEP=":"
;;
---- ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Tue May 05 18:07:05 2015 -0700
@@ -43,7 +43,7 @@
PS=":"
FS="/"
@@ -374,8 +374,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/management/OperatingSystemMXBean/GetSystemLoadAverage.java Tue May 05 18:07:05 2015 -0700
@@ -79,8 +79,10 @@
System.out.println("Test passed.");
}
@@ -397,8 +397,8 @@
? output.split(" ")
: output.split(",");
double expected = Double.parseDouble(lavg[0]);
---- ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/lang/management/OperatingSystemMXBean/TestSystemLoadAvg.sh Tue May 05 18:07:05 2015 -0700
@@ -61,7 +61,7 @@
while true; do
echo "Run $i: TestSystemLoadAvg"
@@ -408,8 +408,8 @@
runOne GetSystemLoadAverage
;;
* )
---- ./jdk/test/java/net/Authenticator/B4933582.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/Authenticator/B4933582.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/Authenticator/B4933582.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/Authenticator/B4933582.sh Tue May 05 18:07:05 2015 -0700
@@ -26,7 +26,7 @@
OS=`uname -s`
@@ -419,8 +419,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/DatagramSocket/Send12k.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/DatagramSocket/Send12k.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/DatagramSocket/Send12k.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/DatagramSocket/Send12k.java Tue May 05 18:07:05 2015 -0700
@@ -36,9 +36,10 @@
public static void main(String args[]) throws Exception {
@@ -434,8 +434,8 @@
SEND_SIZE = 16 * 576;
} else {
SEND_SIZE = 16 * 1024;
---- ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/DatagramSocket/SendDatagramToBadAddress.java Tue May 05 18:07:05 2015 -0700
@@ -45,6 +45,8 @@
return (true);
if (p.getProperty ("os.name").equals ("Linux"))
@@ -445,8 +445,8 @@
if (p.getProperty ("os.name").startsWith ("Mac OS"))
return (true);
// Check for specific Solaris version from here
---- ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.sh Tue May 05 18:07:05 2015 -0700
@@ -27,11 +27,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -460,8 +460,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/net/Socket/OldSocketImpl.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/Socket/OldSocketImpl.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/Socket/OldSocketImpl.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/Socket/OldSocketImpl.sh Tue May 05 18:07:05 2015 -0700
@@ -28,7 +28,7 @@
OS=`uname -s`
@@ -471,8 +471,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/URL/B5086147.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/URL/B5086147.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/URL/B5086147.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/URL/B5086147.sh Tue May 05 18:07:05 2015 -0700
@@ -26,7 +26,7 @@
OS=`uname -s`
@@ -482,8 +482,8 @@
exit 0
;;
CYGWIN* )
---- ./jdk/test/java/net/URLClassLoader/B5077773.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/URLClassLoader/B5077773.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/URLClassLoader/B5077773.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/URLClassLoader/B5077773.sh Tue May 05 18:07:05 2015 -0700
@@ -34,11 +34,7 @@
OS=`uname -s`
@@ -497,8 +497,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/URLClassLoader/sealing/checksealed.sh Tue May 05 18:07:05 2015 -0700
@@ -27,11 +27,7 @@
OS=`uname -s`
@@ -512,8 +512,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/net/URLConnection/6212146/test.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/net/URLConnection/6212146/test.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/net/URLConnection/6212146/test.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/net/URLConnection/6212146/test.sh Tue May 05 18:07:05 2015 -0700
@@ -33,11 +33,7 @@
OS=`uname -s`
@@ -527,8 +527,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/nio/channels/FileChannel/Transfer.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/nio/channels/FileChannel/Transfer.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/nio/channels/FileChannel/Transfer.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/nio/channels/FileChannel/Transfer.java Tue May 05 18:07:05 2015 -0700
@@ -228,7 +228,7 @@
// Windows and Linux can't handle the really large file sizes for a
// truncate or a positional write required by the test for 4563125
@@ -538,8 +538,8 @@
return;
File source = File.createTempFile("blah", null);
source.deleteOnExit();
---- ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.c Tue May 05 18:07:05 2015 -0700
@@ -17,6 +17,12 @@
#include "Launcher.h"
@@ -562,8 +562,8 @@
_exit(-1);
}
---- ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/nio/charset/coders/CheckSJISMappingProp.sh Tue May 05 18:07:05 2015 -0700
@@ -34,7 +34,7 @@
OS=`uname -s`
@@ -573,8 +573,8 @@
# Skip locale test for Windows
Windows* | CYGWIN* )
echo "Passed"; exit 0 ;;
---- ./jdk/test/java/nio/charset/spi/basic.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/nio/charset/spi/basic.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/nio/charset/spi/basic.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/nio/charset/spi/basic.sh Tue May 05 18:07:05 2015 -0700
@@ -48,7 +48,7 @@
DIR=`pwd`
@@ -584,8 +584,8 @@
Windows* ) CPS=';' ;;
CYGWIN* )
DIR=`/usr/bin/cygpath -a -s -m $DIR`
---- ./jdk/test/java/nio/file/FileSystem/Basic.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/nio/file/FileSystem/Basic.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/nio/file/FileSystem/Basic.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/nio/file/FileSystem/Basic.java Tue May 05 18:07:05 2015 -0700
@@ -76,7 +76,7 @@
checkSupported(fs, "posix", "unix", "owner", "acl", "user");
if (os.equals("Linux"))
@@ -595,8 +595,8 @@
checkSupported(fs, "posix", "unix", "owner");
if (os.equals("Windows"))
checkSupported(fs, "owner", "dos", "acl", "user");
---- ./jdk/test/java/nio/file/Files/CopyAndMove.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/nio/file/Files/CopyAndMove.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/nio/file/Files/CopyAndMove.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/nio/file/Files/CopyAndMove.java Tue May 05 18:07:05 2015 -0700
@@ -651,7 +651,7 @@
// check POSIX attributes are copied
@@ -615,8 +615,8 @@
boolean isDirectory = isDirectory(file, NOFOLLOW_LINKS);
if (isUnix) {
---- ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Tue May 05 18:07:05 2015 -0700
@@ -33,7 +33,7 @@
OS=`uname -s`
@@ -626,8 +626,8 @@
PS=":"
;;
Windows* | CYGWIN* )
---- ./jdk/test/java/rmi/registry/readTest/readTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/rmi/registry/readTest/readTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/rmi/registry/readTest/readTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/rmi/registry/readTest/readTest.sh Tue May 05 18:07:05 2015 -0700
@@ -34,7 +34,7 @@
REGARGS=""
@@ -637,8 +637,8 @@
PS=":"
FS="/"
CHMOD="${FS}bin${FS}chmod"
---- ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/ClassLoaderDeadlock.sh Tue May 05 18:07:05 2015 -0700
@@ -58,7 +58,7 @@
PATHSEP=":"
FILESEP="/"
@@ -648,8 +648,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock.sh Tue May 05 18:07:05 2015 -0700
@@ -42,7 +42,7 @@
PATHSEP=":"
FILESEP="/"
@@ -659,8 +659,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh Tue May 05 18:07:05 2015 -0700
@@ -66,7 +66,7 @@
PATHSEP=";"
FILESEP="/"
@@ -670,8 +670,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/signedfirst/Dyn.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/security/Security/signedfirst/Dyn.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/security/Security/signedfirst/Dyn.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/security/Security/signedfirst/Dyn.sh Tue May 05 18:07:05 2015 -0700
@@ -58,7 +58,7 @@
PATHSEP=":"
FILESEP="/"
@@ -681,8 +681,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/security/Security/signedfirst/Static.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/security/Security/signedfirst/Static.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/security/Security/signedfirst/Static.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/security/Security/signedfirst/Static.sh Tue May 05 18:07:05 2015 -0700
@@ -58,7 +58,7 @@
PATHSEP=":"
FILESEP="/"
@@ -692,8 +692,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/util/Currency/PropertiesTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/util/Currency/PropertiesTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/util/Currency/PropertiesTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/util/Currency/PropertiesTest.sh Tue May 05 18:07:05 2015 -0700
@@ -52,7 +52,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -703,8 +703,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/util/PluggableLocale/ExecTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/util/PluggableLocale/ExecTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/util/PluggableLocale/ExecTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/util/PluggableLocale/ExecTest.sh Tue May 05 18:07:05 2015 -0700
@@ -62,7 +62,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -714,8 +714,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/util/ResourceBundle/Bug6299235Test.sh Tue May 05 18:07:05 2015 -0700
@@ -31,7 +31,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -725,8 +725,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/java/util/ServiceLoader/basic.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/util/ServiceLoader/basic.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/util/ServiceLoader/basic.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/util/ServiceLoader/basic.sh Tue May 05 18:07:05 2015 -0700
@@ -43,9 +43,7 @@
OS=`uname -s`
@@ -738,8 +738,8 @@
SEP=':' ;;
* )
SEP='\;' ;;
---- ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/java/util/prefs/CheckUserPrefsStorage.sh Tue May 05 18:07:05 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -749,8 +749,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Tue May 05 18:07:05 2015 -0700
@@ -56,7 +56,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -760,8 +760,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatTest.sh Tue May 05 18:07:05 2015 -0700
@@ -89,7 +89,7 @@
FILESEP="/"
;;
@@ -771,8 +771,8 @@
VAR="A different value for Linux"
DEFAULT_JDK=/none
#DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
---- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/javax/imageio/metadata/IIOMetadataFormat/runMetadataFormatThreadTest.sh Tue May 05 18:07:05 2015 -0700
@@ -90,7 +90,7 @@
FILESEP="/"
;;
@@ -782,8 +782,8 @@
VAR="A different value for Linux"
DEFAULT_JDK=/none
#DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
---- ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh Tue May 05 18:07:05 2015 -0700
@@ -108,6 +108,14 @@
TMP="/tmp"
;;
@@ -799,8 +799,8 @@
Windows* )
VAR="A different value for Win32"
DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
---- ./jdk/test/javax/script/CommonSetup.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/javax/script/CommonSetup.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/javax/script/CommonSetup.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/javax/script/CommonSetup.sh Tue May 05 18:07:05 2015 -0700
@@ -36,7 +36,7 @@
OS=`uname -s`
@@ -810,8 +810,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/javax/security/auth/Subject/doAs/Test.sh Tue May 05 18:07:05 2015 -0700
@@ -43,7 +43,7 @@
FS="/"
RM="/bin/rm -f"
@@ -821,8 +821,8 @@
PS=":"
FS="/"
RM="/bin/rm -f"
---- ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/lib/security/java.policy/Ext_AllPolicy.sh Tue May 05 18:07:05 2015 -0700
@@ -53,7 +53,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -832,8 +832,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Tue May 05 18:07:05 2015 -0700
@@ -53,8 +53,13 @@
return isOs("linux");
}
@@ -849,8 +849,8 @@
}
public static String getOsName() {
---- ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/awt/dnd/8024061/bug8024061.java Tue May 05 18:07:05 2015 -0700
@@ -107,8 +107,8 @@
public static void main(String[] args) throws AWTException, InvocationTargetException, InterruptedException {
@@ -862,8 +862,8 @@
"skipping!");
return;
}
---- ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh Tue May 05 18:07:05 2015 -0700
@@ -42,7 +42,7 @@
fi
@@ -873,8 +873,8 @@
PATHSEP=":"
FILESEP="/"
DFILESEP=$FILESEP
---- ./jdk/test/sun/net/ftp/MarkResetTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/net/ftp/MarkResetTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/net/ftp/MarkResetTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/net/ftp/MarkResetTest.sh Tue May 05 18:07:05 2015 -0700
@@ -28,7 +28,7 @@
OS=`uname -s`
@@ -884,8 +884,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/net/www/http/HttpClient/RetryPost.sh Tue May 05 18:07:05 2015 -0700
@@ -28,7 +28,7 @@
OS=`uname -s`
@@ -895,8 +895,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/net/www/protocol/jar/B5105410.sh Tue May 05 18:07:05 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -906,8 +906,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/net/www/protocol/jar/jarbug/run.sh Tue May 05 18:07:05 2015 -0700
@@ -31,7 +31,7 @@
OS=`uname -s`
@@ -917,8 +917,8 @@
PS=":"
FS="/"
CHMOD="${FS}bin${FS}chmod"
---- ./jdk/test/sun/nio/ch/SelProvider.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/nio/ch/SelProvider.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/nio/ch/SelProvider.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/nio/ch/SelProvider.java Tue May 05 18:07:05 2015 -0700
@@ -39,7 +39,7 @@
expected = "sun.nio.ch.DevPollSelectorProvider";
} else if ("Linux".equals(osname)) {
@@ -928,8 +928,8 @@
expected = "sun.nio.ch.KQueueSelectorProvider";
} else {
return;
---- ./jdk/test/sun/security/krb5/runNameEquals.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/krb5/runNameEquals.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/krb5/runNameEquals.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/krb5/runNameEquals.sh Tue May 05 18:07:05 2015 -0700
@@ -52,7 +52,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -939,8 +939,8 @@
PATHSEP=":"
FILESEP="/"
NATIVE=true
---- ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Tue May 05 18:07:05 2015 -0700
@@ -49,7 +49,7 @@
OS=`uname -s`
@@ -950,8 +950,8 @@
FS="/"
;;
Windows_* )
---- ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/pkcs11/Provider/ConfigQuotedString.sh Tue May 05 18:07:05 2015 -0700
@@ -66,7 +66,7 @@
CP="${FS}bin${FS}cp"
CHMOD="${FS}bin${FS}chmod"
@@ -961,8 +961,8 @@
FS="/"
PS=":"
CP="${FS}bin${FS}cp"
---- ./jdk/test/sun/security/pkcs11/Provider/Login.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/pkcs11/Provider/Login.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/pkcs11/Provider/Login.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/pkcs11/Provider/Login.sh Tue May 05 18:07:05 2015 -0700
@@ -67,7 +67,7 @@
CP="${FS}bin${FS}cp"
CHMOD="${FS}bin${FS}chmod"
@@ -972,8 +972,8 @@
FS="/"
PS=":"
CP="${FS}bin${FS}cp"
---- ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/provider/KeyStore/DKSTest.sh Tue May 05 18:07:05 2015 -0700
@@ -50,7 +50,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -983,8 +983,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.sh Tue May 05 18:07:05 2015 -0700
@@ -52,7 +52,7 @@
PATHSEP=":"
FILESEP="/"
@@ -994,8 +994,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/provider/PolicyFile/getinstance/getinstance.sh Tue May 05 18:07:05 2015 -0700
@@ -59,7 +59,7 @@
PS=":"
FS="/"
@@ -1005,8 +1005,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/EngineArgs/DebugReportsOneExtraByte.sh Tue May 05 18:07:05 2015 -0700
@@ -33,7 +33,7 @@
OS=`uname -s`
@@ -1016,8 +1016,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
OS=`uname -s`
@@ -1027,8 +1027,8 @@
FILESEP="/"
PATHSEP=":"
;;
---- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.sh Tue May 05 18:07:05 2015 -0700
@@ -32,7 +32,7 @@
HOSTNAME=`uname -n`
OS=`uname -s`
@@ -1038,8 +1038,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Tue May 05 18:07:05 2015 -0700
@@ -32,7 +32,7 @@
HOSTNAME=`uname -n`
OS=`uname -s`
@@ -1049,8 +1049,8 @@
PS=":"
FS="/"
;;
---- ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/jarsigner/AlgOptions.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1060,8 +1060,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/jarsigner/PercentSign.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1071,8 +1071,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/jarsigner/diffend.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/diffend.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/jarsigner/diffend.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/jarsigner/diffend.sh Tue May 05 18:07:05 2015 -0700
@@ -47,6 +47,13 @@
FS="/"
CP="${FS}bin${FS}cp -f"
@@ -1087,8 +1087,8 @@
CYGWIN* )
NULL=/dev/null
PS=";"
---- ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/jarsigner/emptymanifest.sh Tue May 05 18:07:05 2015 -0700
@@ -39,6 +39,11 @@
Windows_* )
FS="\\"
@@ -1101,8 +1101,8 @@
* )
FS="/"
;;
---- ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/jarsigner/oldsig.sh Tue May 05 18:07:05 2015 -0700
@@ -42,7 +42,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1112,8 +1112,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/AltProviderPath.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1123,8 +1123,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/CloneKeyAskPassword.sh Tue May 05 18:07:05 2015 -0700
@@ -55,7 +55,7 @@
PATHSEP=":"
FILESEP="/"
@@ -1134,8 +1134,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/NoExtNPE.sh Tue May 05 18:07:05 2015 -0700
@@ -48,7 +48,7 @@
Linux )
FILESEP="/"
@@ -1145,8 +1145,8 @@
FILESEP="/"
;;
AIX )
---- ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/SecretKeyKS.sh Tue May 05 18:07:05 2015 -0700
@@ -45,7 +45,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1156,8 +1156,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/StandardAlgName.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1167,8 +1167,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1178,8 +1178,8 @@
PATHSEP=":"
FILESEP="/"
;;
---- ./jdk/test/sun/security/tools/keytool/i18n.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/i18n.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/i18n.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/i18n.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1189,8 +1189,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/keytool/printssl.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/printssl.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/printssl.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/printssl.sh Tue May 05 18:07:05 2015 -0700
@@ -40,7 +40,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1200,8 +1200,8 @@
FS="/"
;;
CYGWIN* )
---- ./jdk/test/sun/security/tools/keytool/resource.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/resource.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/resource.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/resource.sh Tue May 05 18:07:05 2015 -0700
@@ -43,7 +43,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1211,8 +1211,8 @@
NULL=/dev/null
FS="/"
;;
---- ./jdk/test/sun/security/tools/keytool/standard.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/keytool/standard.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/keytool/standard.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/keytool/standard.sh Tue May 05 18:07:05 2015 -0700
@@ -45,7 +45,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1222,8 +1222,8 @@
FS="/"
;;
Windows_* )
---- ./jdk/test/sun/security/tools/policytool/Alias.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/policytool/Alias.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/policytool/Alias.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/policytool/Alias.sh Tue May 05 18:07:05 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1233,8 +1233,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/policytool/ChangeUI.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1244,8 +1244,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/policytool/OpenPolicy.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1255,8 +1255,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/SaveAs.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/policytool/SaveAs.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/policytool/SaveAs.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/policytool/SaveAs.sh Tue May 05 18:07:05 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1266,8 +1266,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/policytool/UpdatePermissions.sh Tue May 05 18:07:05 2015 -0700
@@ -47,7 +47,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1277,8 +1277,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/policytool/UsePolicy.sh Tue May 05 18:07:05 2015 -0700
@@ -46,7 +46,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1288,8 +1288,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/security/tools/policytool/i18n.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/security/tools/policytool/i18n.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/security/tools/policytool/i18n.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/security/tools/policytool/i18n.sh Tue May 05 18:07:05 2015 -0700
@@ -49,7 +49,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1299,8 +1299,8 @@
NULL=/dev/null
PS=":"
FS="/"
---- ./jdk/test/sun/tools/common/CommonSetup.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/tools/common/CommonSetup.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/tools/common/CommonSetup.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/tools/common/CommonSetup.sh Tue May 05 18:07:05 2015 -0700
@@ -47,6 +47,7 @@
# isLinux - true if OS is Linux
# isSolaris - true if OS is Solaris
@@ -1328,8 +1328,8 @@
Darwin )
OS="Mac OS X"
isMacos=true
---- ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/tools/jconsole/ResourceCheckTest.sh Tue May 05 18:07:05 2015 -0700
@@ -54,7 +54,7 @@
OS=`uname -s`
@@ -1339,8 +1339,8 @@
PATHSEP=":"
;;
---- ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/sun/tools/native2ascii/resources/ImmutableResourceTest.sh Tue May 05 18:07:05 2015 -0700
@@ -56,7 +56,7 @@
OS=`uname -s`
@@ -1350,8 +1350,8 @@
PATHSEP=":"
;;
---- ./jdk/test/tools/launcher/ExecutionEnvironment.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/tools/launcher/ExecutionEnvironment.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/tools/launcher/ExecutionEnvironment.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/tools/launcher/ExecutionEnvironment.java Tue May 05 18:07:05 2015 -0700
@@ -194,7 +194,7 @@
Map<String, String> env = new HashMap<>();
@@ -1361,8 +1361,8 @@
for (String x : LD_PATH_STRINGS) {
String pairs[] = x.split("=");
env.put(pairs[0], pairs[1]);
---- ./jdk/test/tools/launcher/RunpathTest.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/tools/launcher/RunpathTest.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/tools/launcher/RunpathTest.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/tools/launcher/RunpathTest.java Tue May 05 18:07:05 2015 -0700
@@ -69,7 +69,7 @@
}
@@ -1372,8 +1372,8 @@
RunpathTest rp = new RunpathTest();
rp.testRpath();
}
---- ./jdk/test/tools/launcher/Test7029048.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/tools/launcher/Test7029048.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/tools/launcher/Test7029048.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/tools/launcher/Test7029048.java Tue May 05 18:07:05 2015 -0700
@@ -223,7 +223,7 @@
} else if (isSolaris && passes < 9) {
throw new Exception("Test7029048: FAIL: " +
@@ -1383,8 +1383,8 @@
throw new Exception("Test7029048: FAIL: " +
"all tests did not run, expected " + 6 + " got " + passes);
} else {
---- ./jdk/test/tools/launcher/TestHelper.java Mon Feb 02 10:12:21 2015 -0800
-+++ ./jdk/test/tools/launcher/TestHelper.java Sat Mar 14 22:56:25 2015 -0700
+--- ./jdk/test/tools/launcher/TestHelper.java Tue Mar 17 00:09:12 2015 +0300
++++ ./jdk/test/tools/launcher/TestHelper.java Tue May 05 18:07:05 2015 -0700
@@ -94,6 +94,8 @@
System.getProperty("os.name", "unknown").startsWith("Linux");
static final boolean isAIX =
@@ -1394,8 +1394,8 @@
static final String LIBJVM = isWindows
? "jvm.dll"
: "libjvm" + (isMacOSX ? ".dylib" : ".so");
---- ./langtools/test/Makefile Wed Jan 28 12:08:47 2015 -0800
-+++ ./langtools/test/Makefile Sat Mar 14 10:28:47 2015 -0700
+--- ./langtools/test/Makefile Mon Mar 16 11:21:59 2015 -0700
++++ ./langtools/test/Makefile Tue May 05 18:06:51 2015 -0700
@@ -36,6 +36,14 @@
ARCH=i586
endif
@@ -1411,8 +1411,8 @@
ifeq ($(OSNAME), Darwin)
PLATFORM = bsd
JT_PLATFORM = linux
---- ./langtools/test/tools/javah/ReadOldClass.sh Wed Jan 28 12:08:47 2015 -0800
-+++ ./langtools/test/tools/javah/ReadOldClass.sh Sat Mar 14 10:28:47 2015 -0700
+--- ./langtools/test/tools/javah/ReadOldClass.sh Mon Mar 16 11:21:59 2015 -0700
++++ ./langtools/test/tools/javah/ReadOldClass.sh Tue May 05 18:06:51 2015 -0700
@@ -43,7 +43,7 @@
# set platform-dependent variables
OS=`uname -s`
@@ -1422,8 +1422,8 @@
PS=":"
FS="/"
;;
---- ./nashorn/test/script/jfx.js Wed Jan 28 12:08:49 2015 -0800
-+++ ./nashorn/test/script/jfx.js Sat Mar 14 10:28:56 2015 -0700
+--- ./nashorn/test/script/jfx.js Mon Mar 16 11:22:08 2015 -0700
++++ ./nashorn/test/script/jfx.js Tue May 05 18:06:53 2015 -0700
@@ -93,6 +93,8 @@
f2 = new File(sb.append(fsep + "linux.png").toString());
} else if (OSInfo.getOSType() == OSType.MACOSX) {
diff --git a/java/openjdk8/files/patch-jdk-make-lib-Awt2dLibraries.gmk b/java/openjdk8/files/patch-jdk-make-lib-Awt2dLibraries.gmk
index 679ce886e7ad..569229ba5a28 100644
--- a/java/openjdk8/files/patch-jdk-make-lib-Awt2dLibraries.gmk
+++ b/java/openjdk8/files/patch-jdk-make-lib-Awt2dLibraries.gmk
@@ -21,7 +21,7 @@
# Solaris still uses OPENWIN_LIB ..
LIBSPLASHSCREEN_LDFLAGS_SUFFIX += -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -lX11 -lXext $(LIBM) -lpthread
else ifeq ($(OPENJDK_TARGET_OS), bsd)
-- LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -liconv -pthread
+- LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -pthread
+ LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) %%ICONV_LDFLAGS%% -pthread
else # .. all other Unixes can use X_LIBS
LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread