diff options
author | Greg Lewis <glewis@FreeBSD.org> | 2015-05-06 07:03:53 +0000 |
---|---|---|
committer | Greg Lewis <glewis@FreeBSD.org> | 2015-05-06 07:03:53 +0000 |
commit | 6e15254a686a521b7c5e03e8b4855b7b00073130 (patch) | |
tree | c55895c151f879852bf010826f4dbea42a8767fe | |
parent | b9e4c2bdc64d5f3f7dceca4b8e9881e5c3743ba2 (diff) | |
download | ports-6e15254a686a521b7c5e03e8b4855b7b00073130.tar.gz ports-6e15254a686a521b7c5e03e8b4855b7b00073130.zip |
Notes
-rw-r--r-- | java/openjdk8/Makefile | 10 | ||||
-rw-r--r-- | java/openjdk8/files/patch-8u45-b14 | 45638 | ||||
-rw-r--r-- | java/openjdk8/files/patch-bsd | 618 | ||||
-rw-r--r-- | java/openjdk8/files/patch-bsd-test | 468 | ||||
-rw-r--r-- | java/openjdk8/files/patch-jdk-make-lib-Awt2dLibraries.gmk | 2 |
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(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || ++ png_gamma_significant(gtest) != 0)) ++ { ++ /* Either this is an sRGB image, in which case the calculated gamma ++ * approximation should match, or this is an image with a profile and the ++ * value libpng calculates for the gamma of the profile does not match the ++ * value recorded in the file. The former, sRGB, case is an error, the ++ * latter is just a warning. ++ */ ++ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) ++ { ++ png_chunk_report(png_ptr, "gamma value does not match sRGB", ++ PNG_CHUNK_ERROR); ++ /* Do not overwrite an sRGB value */ ++ return from == 2; ++ } ++ ++ else /* sRGB tag not involved */ ++ { ++ png_chunk_report(png_ptr, "gamma value does not match libpng estimate", ++ PNG_CHUNK_WARNING); ++ return from == 1; ++ } ++ } ++ ++ return 1; ++} ++ ++void /* PRIVATE */ ++png_colorspace_set_gamma(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, png_fixed_point gAMA) ++{ ++ /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't ++ * occur. Since the fixed point representation is asymetrical it is ++ * possible for 1/gamma to overflow the limit of 21474 and this means the ++ * gamma value must be at least 5/100000 and hence at most 20000.0. For ++ * safety the limits here are a little narrower. The values are 0.00016 to ++ * 6250.0, which are truly ridiculous gamma values (and will produce ++ * displays that are all black or all white.) ++ * ++ * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk ++ * handling code, which only required the value to be >0. ++ */ ++ png_const_charp errmsg; ++ ++ if (gAMA < 16 || gAMA > 625000000) ++ errmsg = "gamma value out of range"; ++ ++# ifdef PNG_READ_gAMA_SUPPORTED ++ /* Allow the application to set the gamma value more than once */ ++ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && ++ (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) ++ errmsg = "duplicate"; ++# endif ++ ++ /* Do nothing if the colorspace is already invalid */ ++ else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) ++ return; ++ ++ else ++ { ++ if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, ++ 1/*from gAMA*/) != 0) ++ { ++ /* Store this gamma value. */ ++ colorspace->gamma = gAMA; ++ colorspace->flags |= ++ (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); ++ } ++ ++ /* At present if the check_gamma test fails the gamma of the colorspace is ++ * not updated however the colorspace is not invalidated. This ++ * corresponds to the case where the existing gamma comes from an sRGB ++ * chunk or profile. An error message has already been output. ++ */ ++ return; ++ } ++ ++ /* Error exit - errmsg has been set. */ ++ colorspace->flags |= PNG_COLORSPACE_INVALID; ++ png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); ++} ++ ++void /* PRIVATE */ ++png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) ++{ ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) ++ { ++ /* Everything is invalid */ ++ info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| ++ PNG_INFO_iCCP); ++ ++# ifdef PNG_COLORSPACE_SUPPORTED ++ /* Clean up the iCCP profile now if it won't be used. */ ++ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); ++# else ++ PNG_UNUSED(png_ptr) ++# endif ++ } ++ ++ else ++ { ++# ifdef PNG_COLORSPACE_SUPPORTED ++ /* Leave the INFO_iCCP flag set if the pngset.c code has already set ++ * it; this allows a PNG to contain a profile which matches sRGB and ++ * yet still have that profile retrievable by the application. ++ */ ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) ++ info_ptr->valid |= PNG_INFO_sRGB; ++ ++ else ++ info_ptr->valid &= ~PNG_INFO_sRGB; ++ ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) ++ info_ptr->valid |= PNG_INFO_cHRM; ++ ++ else ++ info_ptr->valid &= ~PNG_INFO_cHRM; ++# endif ++ ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) ++ info_ptr->valid |= PNG_INFO_gAMA; ++ ++ else ++ info_ptr->valid &= ~PNG_INFO_gAMA; ++ } ++} ++ ++#ifdef PNG_READ_SUPPORTED ++void /* PRIVATE */ ++png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) ++{ ++ if (info_ptr == NULL) /* reduce code size; check here not in the caller */ ++ return; ++ ++ info_ptr->colorspace = png_ptr->colorspace; ++ png_colorspace_sync_info(png_ptr, info_ptr); ++} ++#endif ++#endif ++ ++#ifdef PNG_COLORSPACE_SUPPORTED ++/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for ++ * cHRM, as opposed to using chromaticities. These internal APIs return ++ * non-zero on a parameter error. The X, Y and Z values are required to be ++ * positive and less than 1.0. ++ */ ++static int ++png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) ++{ ++ png_int_32 d, dwhite, whiteX, whiteY; ++ ++ d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; ++ if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0) ++ return 1; ++ if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0) ++ return 1; ++ dwhite = d; ++ whiteX = XYZ->red_X; ++ whiteY = XYZ->red_Y; ++ ++ d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; ++ if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0) ++ return 1; ++ if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0) ++ return 1; ++ dwhite += d; ++ whiteX += XYZ->green_X; ++ whiteY += XYZ->green_Y; ++ ++ d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; ++ if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0) ++ return 1; ++ if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0) ++ return 1; ++ dwhite += d; ++ whiteX += XYZ->blue_X; ++ whiteY += XYZ->blue_Y; ++ ++ /* The reference white is simply the sum of the end-point (X,Y,Z) vectors, ++ * thus: ++ */ ++ if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) ++ return 1; ++ if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) ++ return 1; ++ ++ return 0; ++} ++ ++static int ++png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) ++{ ++ png_fixed_point red_inverse, green_inverse, blue_scale; ++ png_fixed_point left, right, denominator; ++ ++ /* Check xy and, implicitly, z. Note that wide gamut color spaces typically ++ * have end points with 0 tristimulus values (these are impossible end ++ * points, but they are used to cover the possible colors.) ++ */ ++ if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; ++ if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; ++ if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; ++ if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; ++ if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; ++ if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; ++ if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; ++ if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1; ++ ++ /* The reverse calculation is more difficult because the original tristimulus ++ * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 ++ * derived values were recorded in the cHRM chunk; ++ * (red,green,blue,white)x(x,y). This loses one degree of freedom and ++ * therefore an arbitrary ninth value has to be introduced to undo the ++ * original transformations. ++ * ++ * Think of the original end-points as points in (X,Y,Z) space. The ++ * chromaticity values (c) have the property: ++ * ++ * C ++ * c = --------- ++ * X + Y + Z ++ * ++ * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the ++ * three chromaticity values (x,y,z) for each end-point obey the ++ * relationship: ++ * ++ * x + y + z = 1 ++ * ++ * This describes the plane in (X,Y,Z) space that intersects each axis at the ++ * value 1.0; call this the chromaticity plane. Thus the chromaticity ++ * calculation has scaled each end-point so that it is on the x+y+z=1 plane ++ * and chromaticity is the intersection of the vector from the origin to the ++ * (X,Y,Z) value with the chromaticity plane. ++ * ++ * To fully invert the chromaticity calculation we would need the three ++ * end-point scale factors, (red-scale, green-scale, blue-scale), but these ++ * were not recorded. Instead we calculated the reference white (X,Y,Z) and ++ * recorded the chromaticity of this. The reference white (X,Y,Z) would have ++ * given all three of the scale factors since: ++ * ++ * color-C = color-c * color-scale ++ * white-C = red-C + green-C + blue-C ++ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale ++ * ++ * But cHRM records only white-x and white-y, so we have lost the white scale ++ * factor: ++ * ++ * white-C = white-c*white-scale ++ * ++ * To handle this the inverse transformation makes an arbitrary assumption ++ * about white-scale: ++ * ++ * Assume: white-Y = 1.0 ++ * Hence: white-scale = 1/white-y ++ * Or: red-Y + green-Y + blue-Y = 1.0 ++ * ++ * Notice the last statement of the assumption gives an equation in three of ++ * the nine values we want to calculate. 8 more equations come from the ++ * above routine as summarised at the top above (the chromaticity ++ * calculation): ++ * ++ * Given: color-x = color-X / (color-X + color-Y + color-Z) ++ * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 ++ * ++ * This is 9 simultaneous equations in the 9 variables "color-C" and can be ++ * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix ++ * determinants, however this is not as bad as it seems because only 28 of ++ * the total of 90 terms in the various matrices are non-zero. Nevertheless ++ * Cramer's rule is notoriously numerically unstable because the determinant ++ * calculation involves the difference of large, but similar, numbers. It is ++ * difficult to be sure that the calculation is stable for real world values ++ * and it is certain that it becomes unstable where the end points are close ++ * together. ++ * ++ * So this code uses the perhaps slightly less optimal but more ++ * understandable and totally obvious approach of calculating color-scale. ++ * ++ * This algorithm depends on the precision in white-scale and that is ++ * (1/white-y), so we can immediately see that as white-y approaches 0 the ++ * accuracy inherent in the cHRM chunk drops off substantially. ++ * ++ * libpng arithmetic: a simple inversion of the above equations ++ * ------------------------------------------------------------ ++ * ++ * white_scale = 1/white-y ++ * white-X = white-x * white-scale ++ * white-Y = 1.0 ++ * white-Z = (1 - white-x - white-y) * white_scale ++ * ++ * white-C = red-C + green-C + blue-C ++ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale ++ * ++ * This gives us three equations in (red-scale,green-scale,blue-scale) where ++ * all the coefficients are now known: ++ * ++ * red-x*red-scale + green-x*green-scale + blue-x*blue-scale ++ * = white-x/white-y ++ * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 ++ * red-z*red-scale + green-z*green-scale + blue-z*blue-scale ++ * = (1 - white-x - white-y)/white-y ++ * ++ * In the last equation color-z is (1 - color-x - color-y) so we can add all ++ * three equations together to get an alternative third: ++ * ++ * red-scale + green-scale + blue-scale = 1/white-y = white-scale ++ * ++ * So now we have a Cramer's rule solution where the determinants are just ++ * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve ++ * multiplication of three coefficients so we can't guarantee to avoid ++ * overflow in the libpng fixed point representation. Using Cramer's rule in ++ * floating point is probably a good choice here, but it's not an option for ++ * fixed point. Instead proceed to simplify the first two equations by ++ * eliminating what is likely to be the largest value, blue-scale: ++ * ++ * blue-scale = white-scale - red-scale - green-scale ++ * ++ * Hence: ++ * ++ * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = ++ * (white-x - blue-x)*white-scale ++ * ++ * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = ++ * 1 - blue-y*white-scale ++ * ++ * And now we can trivially solve for (red-scale,green-scale): ++ * ++ * green-scale = ++ * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale ++ * ----------------------------------------------------------- ++ * green-x - blue-x ++ * ++ * red-scale = ++ * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale ++ * --------------------------------------------------------- ++ * red-y - blue-y ++ * ++ * Hence: ++ * ++ * red-scale = ++ * ( (green-x - blue-x) * (white-y - blue-y) - ++ * (green-y - blue-y) * (white-x - blue-x) ) / white-y ++ * ------------------------------------------------------------------------- ++ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) ++ * ++ * green-scale = ++ * ( (red-y - blue-y) * (white-x - blue-x) - ++ * (red-x - blue-x) * (white-y - blue-y) ) / white-y ++ * ------------------------------------------------------------------------- ++ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) ++ * ++ * Accuracy: ++ * The input values have 5 decimal digits of accuracy. The values are all in ++ * the range 0 < value < 1, so simple products are in the same range but may ++ * need up to 10 decimal digits to preserve the original precision and avoid ++ * underflow. Because we are using a 32-bit signed representation we cannot ++ * match this; the best is a little over 9 decimal digits, less than 10. ++ * ++ * The approach used here is to preserve the maximum precision within the ++ * signed representation. Because the red-scale calculation above uses the ++ * difference between two products of values that must be in the range -1..+1 ++ * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The ++ * factor is irrelevant in the calculation because it is applied to both ++ * numerator and denominator. ++ * ++ * Note that the values of the differences of the products of the ++ * chromaticities in the above equations tend to be small, for example for ++ * the sRGB chromaticities they are: ++ * ++ * red numerator: -0.04751 ++ * green numerator: -0.08788 ++ * denominator: -0.2241 (without white-y multiplication) ++ * ++ * The resultant Y coefficients from the chromaticities of some widely used ++ * color space definitions are (to 15 decimal places): ++ * ++ * sRGB ++ * 0.212639005871510 0.715168678767756 0.072192315360734 ++ * Kodak ProPhoto ++ * 0.288071128229293 0.711843217810102 0.000085653960605 ++ * Adobe RGB ++ * 0.297344975250536 0.627363566255466 0.075291458493998 ++ * Adobe Wide Gamut RGB ++ * 0.258728243040113 0.724682314948566 0.016589442011321 ++ */ ++ /* By the argument, above overflow should be impossible here. The return ++ * value of 2 indicates an internal error to the caller. ++ */ ++ if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0) ++ return 2; ++ if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0) ++ return 2; ++ denominator = left - right; ++ ++ /* Now find the red numerator. */ ++ if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) ++ return 2; ++ if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0) ++ return 2; ++ ++ /* Overflow is possible here and it indicates an extreme set of PNG cHRM ++ * chunk values. This calculation actually returns the reciprocal of the ++ * scale value because this allows us to delay the multiplication of white-y ++ * into the denominator, which tends to produce a small number. ++ */ ++ if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 || ++ red_inverse <= xy->whitey /* r+g+b scales = white scale */) ++ return 1; ++ ++ /* Similarly for green_inverse: */ ++ if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0) ++ return 2; ++ if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) ++ return 2; ++ if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 || ++ green_inverse <= xy->whitey) ++ return 1; ++ ++ /* And the blue scale, the checks above guarantee this can't overflow but it ++ * can still produce 0 for extreme cHRM values. ++ */ ++ blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - ++ png_reciprocal(green_inverse); ++ if (blue_scale <= 0) ++ return 1; ++ ++ ++ /* And fill in the png_XYZ: */ ++ if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, ++ red_inverse) == 0) ++ return 1; ++ ++ if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, ++ green_inverse) == 0) ++ return 1; ++ ++ if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, ++ PNG_FP_1) == 0) ++ return 1; ++ ++ return 0; /*success*/ ++} ++ ++static int ++png_XYZ_normalize(png_XYZ *XYZ) ++{ ++ png_int_32 Y; ++ ++ if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 || ++ XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 || ++ XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0) ++ return 1; ++ ++ /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. ++ * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore ++ * relying on addition of two positive values producing a negative one is not ++ * safe. ++ */ ++ Y = XYZ->red_Y; ++ if (0x7fffffff - Y < XYZ->green_X) ++ return 1; ++ Y += XYZ->green_Y; ++ if (0x7fffffff - Y < XYZ->blue_X) ++ return 1; ++ Y += XYZ->blue_Y; ++ ++ if (Y != PNG_FP_1) ++ { ++ if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0) ++ return 1; ++ ++ if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0) ++ return 1; ++ ++ if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0) ++ return 1; ++ if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int ++png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) ++{ ++ /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ ++ if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || ++ PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || ++ PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || ++ PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || ++ PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || ++ PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || ++ PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || ++ PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) ++ return 0; ++ return 1; ++} ++ ++/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM ++ * chunk chromaticities. Earlier checks used to simply look for the overflow ++ * condition (where the determinant of the matrix to solve for XYZ ends up zero ++ * because the chromaticity values are not all distinct.) Despite this it is ++ * theoretically possible to produce chromaticities that are apparently valid ++ * but that rapidly degrade to invalid, potentially crashing, sets because of ++ * arithmetic inaccuracies when calculations are performed on them. The new ++ * check is to round-trip xy -> XYZ -> xy and then check that the result is ++ * within a small percentage of the original. ++ */ ++static int ++png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) ++{ ++ int result; ++ png_xy xy_test; ++ ++ /* As a side-effect this routine also returns the XYZ endpoints. */ ++ result = png_XYZ_from_xy(XYZ, xy); ++ if (result != 0) ++ return result; ++ ++ result = png_xy_from_XYZ(&xy_test, XYZ); ++ if (result != 0) ++ return result; ++ ++ if (png_colorspace_endpoints_match(xy, &xy_test, ++ 5/*actually, the math is pretty accurate*/) != 0) ++ return 0; ++ ++ /* Too much slip */ ++ return 1; ++} ++ ++/* This is the check going the other way. The XYZ is modified to normalize it ++ * (another side-effect) and the xy chromaticities are returned. ++ */ ++static int ++png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) ++{ ++ int result; ++ png_XYZ XYZtemp; ++ ++ result = png_XYZ_normalize(XYZ); ++ if (result != 0) ++ return result; ++ ++ result = png_xy_from_XYZ(xy, XYZ); ++ if (result != 0) ++ return result; ++ ++ XYZtemp = *XYZ; ++ return png_colorspace_check_xy(&XYZtemp, xy); ++} ++ ++/* Used to check for an endpoint match against sRGB */ ++static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ ++{ ++ /* color x y */ ++ /* red */ 64000, 33000, ++ /* green */ 30000, 60000, ++ /* blue */ 15000, 6000, ++ /* white */ 31270, 32900 ++}; ++ ++static int ++png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, ++ int preferred) ++{ ++ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) ++ return 0; ++ ++ /* The consistency check is performed on the chromaticities; this factors out ++ * variations because of the normalization (or not) of the end point Y ++ * values. ++ */ ++ if (preferred < 2 && ++ (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) ++ { ++ /* The end points must be reasonably close to any we already have. The ++ * following allows an error of up to +/-.001 ++ */ ++ if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, ++ 100) == 0) ++ { ++ colorspace->flags |= PNG_COLORSPACE_INVALID; ++ png_benign_error(png_ptr, "inconsistent chromaticities"); ++ return 0; /* failed */ ++ } ++ ++ /* Only overwrite with preferred values */ ++ if (preferred == 0) ++ return 1; /* ok, but no change */ ++ } ++ ++ colorspace->end_points_xy = *xy; ++ colorspace->end_points_XYZ = *XYZ; ++ colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; ++ ++ /* The end points are normally quoted to two decimal digits, so allow +/-0.01 ++ * on this test. ++ */ ++ if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) ++ colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; ++ ++ else ++ colorspace->flags &= PNG_COLORSPACE_CANCEL( ++ PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); ++ ++ return 2; /* ok and changed */ ++} + + int /* PRIVATE */ +-png_check_cHRM_fixed(png_structp png_ptr, +- png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, +- png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, +- png_fixed_point blue_x, png_fixed_point blue_y) ++png_colorspace_set_chromaticities(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, const png_xy *xy, int preferred) + { +- int ret = 1; +- unsigned long xy_hi,xy_lo,yx_hi,yx_lo; +- +- png_debug(1, "in function png_check_cHRM_fixed"); +- +- if (png_ptr == NULL) ++ /* We must check the end points to ensure they are reasonable - in the past ++ * color management systems have crashed as a result of getting bogus ++ * colorant values, while this isn't the fault of libpng it is the ++ * responsibility of libpng because PNG carries the bomb and libpng is in a ++ * position to protect against it. ++ */ ++ png_XYZ XYZ; ++ ++ switch (png_colorspace_check_xy(&XYZ, xy)) ++ { ++ case 0: /* success */ ++ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, ++ preferred); ++ ++ case 1: ++ /* We can't invert the chromaticities so we can't produce value XYZ ++ * values. Likely as not a color management system will fail too. ++ */ ++ colorspace->flags |= PNG_COLORSPACE_INVALID; ++ png_benign_error(png_ptr, "invalid chromaticities"); ++ break; ++ ++ default: ++ /* libpng is broken; this should be a warning but if it happens we ++ * want error reports so for the moment it is an error. ++ */ ++ colorspace->flags |= PNG_COLORSPACE_INVALID; ++ png_error(png_ptr, "internal error checking chromaticities"); ++ break; ++ } ++ ++ return 0; /* failed */ ++} ++ ++int /* PRIVATE */ ++png_colorspace_set_endpoints(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) ++{ ++ png_XYZ XYZ = *XYZ_in; ++ png_xy xy; ++ ++ switch (png_colorspace_check_XYZ(&xy, &XYZ)) ++ { ++ case 0: ++ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, ++ preferred); ++ ++ case 1: ++ /* End points are invalid. */ ++ colorspace->flags |= PNG_COLORSPACE_INVALID; ++ png_benign_error(png_ptr, "invalid end points"); ++ break; ++ ++ default: ++ colorspace->flags |= PNG_COLORSPACE_INVALID; ++ png_error(png_ptr, "internal error checking chromaticities"); ++ break; ++ } ++ ++ return 0; /* failed */ ++} ++ ++#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) ++/* Error message generation */ ++static char ++png_icc_tag_char(png_uint_32 byte) ++{ ++ byte &= 0xff; ++ if (byte >= 32 && byte <= 126) ++ return (char)byte; ++ else ++ return '?'; ++} ++ ++static void ++png_icc_tag_name(char *name, png_uint_32 tag) ++{ ++ name[0] = '\''; ++ name[1] = png_icc_tag_char(tag >> 24); ++ name[2] = png_icc_tag_char(tag >> 16); ++ name[3] = png_icc_tag_char(tag >> 8); ++ name[4] = png_icc_tag_char(tag ); ++ name[5] = '\''; ++} ++ ++static int ++is_ICC_signature_char(png_alloc_size_t it) ++{ ++ return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || ++ (it >= 97 && it <= 122); ++} ++ ++static int ++is_ICC_signature(png_alloc_size_t it) ++{ ++ return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && ++ is_ICC_signature_char((it >> 16) & 0xff) && ++ is_ICC_signature_char((it >> 8) & 0xff) && ++ is_ICC_signature_char(it & 0xff); ++} ++ ++static int ++png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, ++ png_const_charp name, png_alloc_size_t value, png_const_charp reason) ++{ ++ size_t pos; ++ char message[196]; /* see below for calculation */ ++ ++ if (colorspace != NULL) ++ colorspace->flags |= PNG_COLORSPACE_INVALID; ++ ++ pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ ++ pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ ++ pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ ++ if (is_ICC_signature(value) != 0) ++ { ++ /* So 'value' is at most 4 bytes and the following cast is safe */ ++ png_icc_tag_name(message+pos, (png_uint_32)value); ++ pos += 6; /* total +8; less than the else clause */ ++ message[pos++] = ':'; ++ message[pos++] = ' '; ++ } ++# ifdef PNG_WARNINGS_SUPPORTED ++ else ++ { ++ char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ ++ ++ pos = png_safecat(message, (sizeof message), pos, ++ png_format_number(number, number+(sizeof number), ++ PNG_NUMBER_FORMAT_x, value)); ++ pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ ++ } ++# endif ++ /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ ++ pos = png_safecat(message, (sizeof message), pos, reason); ++ PNG_UNUSED(pos) ++ ++ /* This is recoverable, but make it unconditionally an app_error on write to ++ * avoid writing invalid ICC profiles into PNG files (i.e., we handle them ++ * on read, with a warning, but on write unless the app turns off ++ * application errors the PNG won't be written.) ++ */ ++ png_chunk_report(png_ptr, message, ++ (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); ++ ++ return 0; ++} ++#endif /* sRGB || iCCP */ ++ ++#ifdef PNG_sRGB_SUPPORTED ++int /* PRIVATE */ ++png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, ++ int intent) ++{ ++ /* sRGB sets known gamma, end points and (from the chunk) intent. */ ++ /* IMPORTANT: these are not necessarily the values found in an ICC profile ++ * because ICC profiles store values adapted to a D50 environment; it is ++ * expected that the ICC profile mediaWhitePointTag will be D50; see the ++ * checks and code elsewhere to understand this better. ++ * ++ * These XYZ values, which are accurate to 5dp, produce rgb to gray ++ * coefficients of (6968,23435,2366), which are reduced (because they add up ++ * to 32769 not 32768) to (6968,23434,2366). These are the values that ++ * libpng has traditionally used (and are the best values given the 15bit ++ * algorithm used by the rgb to gray code.) ++ */ ++ static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ ++ { ++ /* color X Y Z */ ++ /* red */ 41239, 21264, 1933, ++ /* green */ 35758, 71517, 11919, ++ /* blue */ 18048, 7219, 95053 ++ }; ++ ++ /* Do nothing if the colorspace is already invalidated. */ ++ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) + return 0; + +- /* (x,y,z) values are first limited to 0..100000 (PNG_FP_1), the white +- * y must also be greater than 0. To test for the upper limit calculate +- * (PNG_FP_1-y) - x must be <= to this for z to be >= 0 (and the expression +- * cannot overflow.) At this point we know x and y are >= 0 and (x+y) is +- * <= PNG_FP_1. The previous test on PNG_MAX_UINT_31 is removed because it +- * pointless (and it produces compiler warnings!) ++ /* Check the intent, then check for existing settings. It is valid for the ++ * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must ++ * be consistent with the correct values. If, however, this function is ++ * called below because an iCCP chunk matches sRGB then it is quite ++ * conceivable that an older app recorded incorrect gAMA and cHRM because of ++ * an incorrect calculation based on the values in the profile - this does ++ * *not* invalidate the profile (though it still produces an error, which can ++ * be ignored.) + */ +- if (white_x < 0 || white_y <= 0 || +- red_x < 0 || red_y < 0 || +- green_x < 0 || green_y < 0 || +- blue_x < 0 || blue_y < 0) ++ if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) ++ return png_icc_profile_error(png_ptr, colorspace, "sRGB", ++ (unsigned)intent, "invalid sRGB rendering intent"); ++ ++ if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && ++ colorspace->rendering_intent != intent) ++ return png_icc_profile_error(png_ptr, colorspace, "sRGB", ++ (unsigned)intent, "inconsistent rendering intents"); ++ ++ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) + { +- png_warning(png_ptr, +- "Ignoring attempt to set negative chromaticity value"); +- ret = 0; ++ png_benign_error(png_ptr, "duplicate sRGB information ignored"); ++ return 0; + } +- /* And (x+y) must be <= PNG_FP_1 (so z is >= 0) */ +- if (white_x > PNG_FP_1 - white_y) ++ ++ /* If the standard sRGB cHRM chunk does not match the one from the PNG file ++ * warn but overwrite the value with the correct one. ++ */ ++ if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && ++ !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, ++ 100)) ++ png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", ++ PNG_CHUNK_ERROR); ++ ++ /* This check is just done for the error reporting - the routine always ++ * returns true when the 'from' argument corresponds to sRGB (2). ++ */ ++ (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, ++ 2/*from sRGB*/); ++ ++ /* intent: bugs in GCC force 'int' to be used as the parameter type. */ ++ colorspace->rendering_intent = (png_uint_16)intent; ++ colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; ++ ++ /* endpoints */ ++ colorspace->end_points_xy = sRGB_xy; ++ colorspace->end_points_XYZ = sRGB_XYZ; ++ colorspace->flags |= ++ (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); ++ ++ /* gamma */ ++ colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; ++ colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; ++ ++ /* Finally record that we have an sRGB profile */ ++ colorspace->flags |= ++ (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); ++ ++ return 1; /* set */ ++} ++#endif /* sRGB */ ++ ++#ifdef PNG_iCCP_SUPPORTED ++/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value ++ * is XYZ(0.9642,1.0,0.8249), which scales to: ++ * ++ * (63189.8112, 65536, 54060.6464) ++ */ ++static const png_byte D50_nCIEXYZ[12] = ++ { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; ++ ++int /* PRIVATE */ ++png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, ++ png_const_charp name, png_uint_32 profile_length) ++{ ++ if (profile_length < 132) ++ return png_icc_profile_error(png_ptr, colorspace, name, profile_length, ++ "too short"); ++ ++ return 1; ++} ++ ++int /* PRIVATE */ ++png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, ++ png_const_charp name, png_uint_32 profile_length, ++ png_const_bytep profile/* first 132 bytes only */, int color_type) ++{ ++ png_uint_32 temp; ++ ++ /* Length check; this cannot be ignored in this code because profile_length ++ * is used later to check the tag table, so even if the profile seems over ++ * long profile_length from the caller must be correct. The caller can fix ++ * this up on read or write by just passing in the profile header length. ++ */ ++ temp = png_get_uint_32(profile); ++ if (temp != profile_length) ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "length does not match profile"); ++ ++ temp = (png_uint_32) (*(profile+8)); ++ if (temp > 3 && (profile_length & 3)) ++ return png_icc_profile_error(png_ptr, colorspace, name, profile_length, ++ "invalid length"); ++ ++ temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ ++ if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ ++ profile_length < 132+12*temp) /* truncated tag table */ ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "tag count too large"); ++ ++ /* The 'intent' must be valid or we can't store it, ICC limits the intent to ++ * 16 bits. ++ */ ++ temp = png_get_uint_32(profile+64); ++ if (temp >= 0xffff) /* The ICC limit */ ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "invalid rendering intent"); ++ ++ /* This is just a warning because the profile may be valid in future ++ * versions. ++ */ ++ if (temp >= PNG_sRGB_INTENT_LAST) ++ (void)png_icc_profile_error(png_ptr, NULL, name, temp, ++ "intent outside defined range"); ++ ++ /* At this point the tag table can't be checked because it hasn't necessarily ++ * been loaded; however, various header fields can be checked. These checks ++ * are for values permitted by the PNG spec in an ICC profile; the PNG spec ++ * restricts the profiles that can be passed in an iCCP chunk (they must be ++ * appropriate to processing PNG data!) ++ */ ++ ++ /* Data checks (could be skipped). These checks must be independent of the ++ * version number; however, the version number doesn't accomodate changes in ++ * the header fields (just the known tags and the interpretation of the ++ * data.) ++ */ ++ temp = png_get_uint_32(profile+36); /* signature 'ascp' */ ++ if (temp != 0x61637370) ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "invalid signature"); ++ ++ /* Currently the PCS illuminant/adopted white point (the computational ++ * white point) are required to be D50, ++ * however the profile contains a record of the illuminant so perhaps ICC ++ * expects to be able to change this in the future (despite the rationale in ++ * the introduction for using a fixed PCS adopted white.) Consequently the ++ * following is just a warning. ++ */ ++ if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) ++ (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, ++ "PCS illuminant is not D50"); ++ ++ /* The PNG spec requires this: ++ * "If the iCCP chunk is present, the image samples conform to the colour ++ * space represented by the embedded ICC profile as defined by the ++ * International Color Consortium [ICC]. The colour space of the ICC profile ++ * shall be an RGB colour space for colour images (PNG colour types 2, 3, and ++ * 6), or a greyscale colour space for greyscale images (PNG colour types 0 ++ * and 4)." ++ * ++ * This checking code ensures the embedded profile (on either read or write) ++ * conforms to the specification requirements. Notice that an ICC 'gray' ++ * color-space profile contains the information to transform the monochrome ++ * data to XYZ or L*a*b (according to which PCS the profile uses) and this ++ * should be used in preference to the standard libpng K channel replication ++ * into R, G and B channels. ++ * ++ * Previously it was suggested that an RGB profile on grayscale data could be ++ * handled. However it it is clear that using an RGB profile in this context ++ * must be an error - there is no specification of what it means. Thus it is ++ * almost certainly more correct to ignore the profile. ++ */ ++ temp = png_get_uint_32(profile+16); /* data colour space field */ ++ switch (temp) + { +- png_warning(png_ptr, "Invalid cHRM white point"); +- ret = 0; ++ case 0x52474220: /* 'RGB ' */ ++ if ((color_type & PNG_COLOR_MASK_COLOR) == 0) ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "RGB color space not permitted on grayscale PNG"); ++ break; ++ ++ case 0x47524159: /* 'GRAY' */ ++ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "Gray color space not permitted on RGB PNG"); ++ break; ++ ++ default: ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "invalid ICC profile color space"); + } + +- if (red_x > PNG_FP_1 - red_y) ++ /* It is up to the application to check that the profile class matches the ++ * application requirements; the spec provides no guidance, but it's pretty ++ * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer ++ * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these ++ * cases. Issue an error for device link or abstract profiles - these don't ++ * contain the records necessary to transform the color-space to anything ++ * other than the target device (and not even that for an abstract profile). ++ * Profiles of these classes may not be embedded in images. ++ */ ++ temp = png_get_uint_32(profile+12); /* profile/device class */ ++ switch (temp) + { +- png_warning(png_ptr, "Invalid cHRM red point"); +- ret = 0; ++ case 0x73636E72: /* 'scnr' */ ++ case 0x6D6E7472: /* 'mntr' */ ++ case 0x70727472: /* 'prtr' */ ++ case 0x73706163: /* 'spac' */ ++ /* All supported */ ++ break; ++ ++ case 0x61627374: /* 'abst' */ ++ /* May not be embedded in an image */ ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "invalid embedded Abstract ICC profile"); ++ ++ case 0x6C696E6B: /* 'link' */ ++ /* DeviceLink profiles cannot be interpreted in a non-device specific ++ * fashion, if an app uses the AToB0Tag in the profile the results are ++ * undefined unless the result is sent to the intended device, ++ * therefore a DeviceLink profile should not be found embedded in a ++ * PNG. ++ */ ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "unexpected DeviceLink ICC profile class"); ++ ++ case 0x6E6D636C: /* 'nmcl' */ ++ /* A NamedColor profile is also device specific, however it doesn't ++ * contain an AToB0 tag that is open to misinterpretation. Almost ++ * certainly it will fail the tests below. ++ */ ++ (void)png_icc_profile_error(png_ptr, NULL, name, temp, ++ "unexpected NamedColor ICC profile class"); ++ break; ++ ++ default: ++ /* To allow for future enhancements to the profile accept unrecognized ++ * profile classes with a warning, these then hit the test below on the ++ * tag content to ensure they are backward compatible with one of the ++ * understood profiles. ++ */ ++ (void)png_icc_profile_error(png_ptr, NULL, name, temp, ++ "unrecognized ICC profile class"); ++ break; + } + +- if (green_x > PNG_FP_1 - green_y) ++ /* For any profile other than a device link one the PCS must be encoded ++ * either in XYZ or Lab. ++ */ ++ temp = png_get_uint_32(profile+20); ++ switch (temp) + { +- png_warning(png_ptr, "Invalid cHRM green point"); +- ret = 0; ++ case 0x58595A20: /* 'XYZ ' */ ++ case 0x4C616220: /* 'Lab ' */ ++ break; ++ ++ default: ++ return png_icc_profile_error(png_ptr, colorspace, name, temp, ++ "unexpected ICC PCS encoding"); + } + +- if (blue_x > PNG_FP_1 - blue_y) ++ return 1; ++} ++ ++int /* PRIVATE */ ++png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, ++ png_const_charp name, png_uint_32 profile_length, ++ png_const_bytep profile /* header plus whole tag table */) ++{ ++ png_uint_32 tag_count = png_get_uint_32(profile+128); ++ png_uint_32 itag; ++ png_const_bytep tag = profile+132; /* The first tag */ ++ ++ /* First scan all the tags in the table and add bits to the icc_info value ++ * (temporarily in 'tags'). ++ */ ++ for (itag=0; itag < tag_count; ++itag, tag += 12) + { +- png_warning(png_ptr, "Invalid cHRM blue point"); +- ret = 0; ++ png_uint_32 tag_id = png_get_uint_32(tag+0); ++ png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ ++ png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ ++ ++ /* The ICC specification does not exclude zero length tags, therefore the ++ * start might actually be anywhere if there is no data, but this would be ++ * a clear abuse of the intent of the standard so the start is checked for ++ * being in range. All defined tag types have an 8 byte header - a 4 byte ++ * type signature then 0. ++ */ ++ if ((tag_start & 3) != 0) ++ { ++ /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is ++ * only a warning here because libpng does not care about the ++ * alignment. ++ */ ++ (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, ++ "ICC profile tag start not a multiple of 4"); ++ } ++ ++ /* This is a hard error; potentially it can cause read outside the ++ * profile. ++ */ ++ if (tag_start > profile_length || tag_length > profile_length - tag_start) ++ return png_icc_profile_error(png_ptr, colorspace, name, tag_id, ++ "ICC profile tag outside profile"); + } + +- png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo); +- png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); +- +- if (xy_hi == yx_hi && xy_lo == yx_lo) ++ return 1; /* success, maybe with warnings */ ++} ++ ++#if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 ++/* Information about the known ICC sRGB profiles */ ++static const struct ++{ ++ png_uint_32 adler, crc, length; ++ png_uint_32 md5[4]; ++ png_byte have_md5; ++ png_byte is_broken; ++ png_uint_16 intent; ++ ++# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) ++# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ ++ { adler, crc, length, md5, broke, intent }, ++ ++} png_sRGB_checks[] = ++{ ++ /* This data comes from contrib/tools/checksum-icc run on downloads of ++ * all four ICC sRGB profiles from www.color.org. ++ */ ++ /* adler32, crc32, MD5[4], intent, date, length, file-name */ ++ PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, ++ PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, ++ "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") ++ ++ /* ICC sRGB v2 perceptual no black-compensation: */ ++ PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, ++ PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, ++ "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") ++ ++ PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, ++ PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, ++ "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") ++ ++ /* ICC sRGB v4 perceptual */ ++ PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, ++ PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, ++ "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") ++ ++ /* The following profiles have no known MD5 checksum. If there is a match ++ * on the (empty) MD5 the other fields are used to attempt a match and ++ * a warning is produced. The first two of these profiles have a 'cprt' tag ++ * which suggests that they were also made by Hewlett Packard. ++ */ ++ PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, ++ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, ++ "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") ++ ++ /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not ++ * match the D50 PCS illuminant in the header (it is in fact the D65 values, ++ * so the white point is recorded as the un-adapted value.) The profiles ++ * below only differ in one byte - the intent - and are basically the same as ++ * the previous profile except for the mediaWhitePointTag error and a missing ++ * chromaticAdaptationTag. ++ */ ++ PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, ++ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, ++ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") ++ ++ PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, ++ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, ++ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") ++}; ++ ++static int ++png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, ++ png_const_bytep profile, uLong adler) ++{ ++ /* The quick check is to verify just the MD5 signature and trust the ++ * rest of the data. Because the profile has already been verified for ++ * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' ++ * field too, so if the profile has been edited with an intent not defined ++ * by sRGB (but maybe defined by a later ICC specification) the read of ++ * the profile will fail at that point. ++ */ ++ ++ png_uint_32 length = 0; ++ png_uint_32 intent = 0x10000; /* invalid */ ++#if PNG_sRGB_PROFILE_CHECKS > 1 ++ uLong crc = 0; /* the value for 0 length data */ ++#endif ++ unsigned int i; ++ ++#ifdef PNG_SET_OPTION_SUPPORTED ++ /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */ ++ if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) == ++ PNG_OPTION_ON) ++ return 0; ++#endif ++ ++ for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) + { +- png_warning(png_ptr, +- "Ignoring attempt to set cHRM RGB triangle with zero area"); +- ret = 0; ++ if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && ++ png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && ++ png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && ++ png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) ++ { ++ /* This may be one of the old HP profiles without an MD5, in that ++ * case we can only use the length and Adler32 (note that these ++ * are not used by default if there is an MD5!) ++ */ ++# if PNG_sRGB_PROFILE_CHECKS == 0 ++ if (png_sRGB_checks[i].have_md5 != 0) ++ return 1+png_sRGB_checks[i].is_broken; ++# endif ++ ++ /* Profile is unsigned or more checks have been configured in. */ ++ if (length == 0) ++ { ++ length = png_get_uint_32(profile); ++ intent = png_get_uint_32(profile+64); ++ } ++ ++ /* Length *and* intent must match */ ++ if (length == png_sRGB_checks[i].length && ++ intent == png_sRGB_checks[i].intent) ++ { ++ /* Now calculate the adler32 if not done already. */ ++ if (adler == 0) ++ { ++ adler = adler32(0, NULL, 0); ++ adler = adler32(adler, profile, length); ++ } ++ ++ if (adler == png_sRGB_checks[i].adler) ++ { ++ /* These basic checks suggest that the data has not been ++ * modified, but if the check level is more than 1 perform ++ * our own crc32 checksum on the data. ++ */ ++# if PNG_sRGB_PROFILE_CHECKS > 1 ++ if (crc == 0) ++ { ++ crc = crc32(0, NULL, 0); ++ crc = crc32(crc, profile, length); ++ } ++ ++ /* So this check must pass for the 'return' below to happen. ++ */ ++ if (crc == png_sRGB_checks[i].crc) ++# endif ++ { ++ if (png_sRGB_checks[i].is_broken != 0) ++ { ++ /* These profiles are known to have bad data that may cause ++ * problems if they are used, therefore attempt to ++ * discourage their use, skip the 'have_md5' warning below, ++ * which is made irrelevant by this error. ++ */ ++ png_chunk_report(png_ptr, "known incorrect sRGB profile", ++ PNG_CHUNK_ERROR); ++ } ++ ++ /* Warn that this being done; this isn't even an error since ++ * the profile is perfectly valid, but it would be nice if ++ * people used the up-to-date ones. ++ */ ++ else if (png_sRGB_checks[i].have_md5 == 0) ++ { ++ png_chunk_report(png_ptr, "out-of-date sRGB profile with" ++ " no signature", ++ PNG_CHUNK_WARNING); ++ } ++ ++ return 1+png_sRGB_checks[i].is_broken; ++ } ++ } ++ ++# if PNG_sRGB_PROFILE_CHECKS > 0 ++ /* The signature matched, but the profile had been changed in some ++ * way. This probably indicates a data error or uninformed hacking. ++ * Fall through to "no match". ++ */ ++ png_chunk_report(png_ptr, "Not recognizing known sRGB profile that" ++ " has been edited", ++ PNG_CHUNK_WARNING); ++ break; ++# endif ++ } ++ } + } + +- return ret; ++ return 0; /* no match */ + } +-# endif /* PNG_CHECK_cHRM_SUPPORTED */ +- ++#endif ++ ++#ifdef PNG_sRGB_SUPPORTED + void /* PRIVATE */ +-png_check_IHDR(png_structp png_ptr, ++png_icc_set_sRGB(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, png_const_bytep profile, uLong adler) ++{ ++ /* Is this profile one of the known ICC sRGB profiles? If it is, just set ++ * the sRGB information. ++ */ ++#if PNG_sRGB_PROFILE_CHECKS >= 0 ++ if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) ++#endif ++ (void)png_colorspace_set_sRGB(png_ptr, colorspace, ++ (int)/*already checked*/png_get_uint_32(profile+64)); ++} ++#endif /* READ_sRGB */ ++ ++int /* PRIVATE */ ++png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, ++ png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, ++ int color_type) ++{ ++ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) ++ return 0; ++ ++ if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && ++ png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, ++ color_type) != 0 && ++ png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, ++ profile) != 0) ++ { ++# ifdef PNG_sRGB_SUPPORTED ++ /* If no sRGB support, don't try storing sRGB information */ ++ png_icc_set_sRGB(png_ptr, colorspace, profile, 0); ++# endif ++ return 1; ++ } ++ ++ /* Failure case */ ++ return 0; ++} ++#endif /* iCCP */ ++ ++#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED ++void /* PRIVATE */ ++png_colorspace_set_rgb_coefficients(png_structrp png_ptr) ++{ ++ /* Set the rgb_to_gray coefficients from the colorspace. */ ++ if (png_ptr->rgb_to_gray_coefficients_set == 0 && ++ (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) ++ { ++ /* png_set_background has not been called, get the coefficients from the Y ++ * values of the colorspace colorants. ++ */ ++ png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; ++ png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; ++ png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; ++ png_fixed_point total = r+g+b; ++ ++ if (total > 0 && ++ r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && ++ g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && ++ b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && ++ r+g+b <= 32769) ++ { ++ /* We allow 0 coefficients here. r+g+b may be 32769 if two or ++ * all of the coefficients were rounded up. Handle this by ++ * reducing the *largest* coefficient by 1; this matches the ++ * approach used for the default coefficients in pngrtran.c ++ */ ++ int add = 0; ++ ++ if (r+g+b > 32768) ++ add = -1; ++ else if (r+g+b < 32768) ++ add = 1; ++ ++ if (add != 0) ++ { ++ if (g >= r && g >= b) ++ g += add; ++ else if (r >= g && r >= b) ++ r += add; ++ else ++ b += add; ++ } ++ ++ /* Check for an internal error. */ ++ if (r+g+b != 32768) ++ png_error(png_ptr, ++ "internal error handling cHRM coefficients"); ++ ++ else ++ { ++ png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; ++ png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; ++ } ++ } ++ ++ /* This is a png_error at present even though it could be ignored - ++ * it should never happen, but it is important that if it does, the ++ * bug is fixed. ++ */ ++ else ++ png_error(png_ptr, "internal error handling cHRM->XYZ"); ++ } ++} ++#endif ++ ++#endif /* COLORSPACE */ ++ ++#ifdef __GNUC__ ++/* This exists solely to work round a warning from GNU C. */ ++static int /* PRIVATE */ ++png_gt(size_t a, size_t b) ++{ ++ return a > b; ++} ++#else ++# define png_gt(a,b) ((a) > (b)) ++#endif ++ ++void /* PRIVATE */ ++png_check_IHDR(png_const_structrp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +@@ -840,53 +2514,68 @@ + png_warning(png_ptr, "Image width is zero in IHDR"); + error = 1; + } ++ else if (width > PNG_UINT_31_MAX) ++ { ++ png_warning(png_ptr, "Invalid image width in IHDR"); ++ error = 1; ++ } ++ ++ else if (png_gt(width, ++ (PNG_SIZE_MAX >> 3) /* 8-byte RGBA pixels */ ++ - 48 /* big_row_buf hack */ ++ - 1 /* filter byte */ ++ - 7*8 /* rounding width to multiple of 8 pix */ ++ - 8)) /* extra max_pixel_depth pad */ ++ { ++ /* The size of the row must be within the limits of this architecture. ++ * Because the read code can perform arbitrary transformations the ++ * maximum size is checked here. Because the code in png_read_start_row ++ * adds extra space "for safety's sake" in several places a conservative ++ * limit is used here. ++ * ++ * NOTE: it would be far better to check the size that is actually used, ++ * but the effect in the real world is minor and the changes are more ++ * extensive, therefore much more dangerous and much more difficult to ++ * write in a way that avoids compiler warnings. ++ */ ++ png_warning(png_ptr, "Image width is too large for this architecture"); ++ error = 1; ++ } ++ else ++ { ++# ifdef PNG_SET_USER_LIMITS_SUPPORTED ++ if (width > png_ptr->user_width_max) ++# else ++ if (width > PNG_USER_WIDTH_MAX) ++# endif ++ { ++ png_warning(png_ptr, "Image width exceeds user limit in IHDR"); ++ error = 1; ++ } ++ } + + if (height == 0) + { + png_warning(png_ptr, "Image height is zero in IHDR"); + error = 1; + } +- +-# ifdef PNG_SET_USER_LIMITS_SUPPORTED +- if (width > png_ptr->user_width_max) +- +-# else +- if (width > PNG_USER_WIDTH_MAX) +-# endif +- { +- png_warning(png_ptr, "Image width exceeds user limit in IHDR"); +- error = 1; +- } +- +-# ifdef PNG_SET_USER_LIMITS_SUPPORTED +- if (height > png_ptr->user_height_max) +-# else +- if (height > PNG_USER_HEIGHT_MAX) +-# endif +- { +- png_warning(png_ptr, "Image height exceeds user limit in IHDR"); +- error = 1; +- } +- +- if (width > PNG_UINT_31_MAX) +- { +- png_warning(png_ptr, "Invalid image width in IHDR"); +- error = 1; +- } +- +- if (height > PNG_UINT_31_MAX) ++ else if (height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image height in IHDR"); + error = 1; + } +- +- if (width > (PNG_UINT_32_MAX +- >> 3) /* 8-byte RGBA pixels */ +- - 48 /* bigrowbuf hack */ +- - 1 /* filter byte */ +- - 7*8 /* rounding of width to multiple of 8 pixels */ +- - 8) /* extra max_pixel_depth pad */ +- png_warning(png_ptr, "Width is too large for libpng to process pixels"); ++ else ++ { ++# ifdef PNG_SET_USER_LIMITS_SUPPORTED ++ if (height > png_ptr->user_height_max) ++# else ++ if (height > PNG_USER_HEIGHT_MAX) ++# endif ++ { ++ png_warning(png_ptr, "Image height exceeds user limit in IHDR"); ++ error = 1; ++ } ++ } + + /* Check other values */ + if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && +@@ -934,13 +2623,13 @@ + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ +- if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && +- png_ptr->mng_features_permitted) ++ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && ++ png_ptr->mng_features_permitted != 0) + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); + + if (filter_type != PNG_FILTER_TYPE_BASE) + { +- if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && ++ if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && + ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || +@@ -950,7 +2639,7 @@ + error = 1; + } + +- if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) ++ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0) + { + png_warning(png_ptr, "Invalid filter method in IHDR"); + error = 1; +@@ -1010,7 +2699,7 @@ + switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) + { + case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: +- if (state & PNG_FP_SAW_ANY) ++ if ((state & PNG_FP_SAW_ANY) != 0) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, type); +@@ -1018,10 +2707,10 @@ + + case PNG_FP_INTEGER + PNG_FP_SAW_DOT: + /* Ok as trailer, ok as lead of fraction. */ +- if (state & PNG_FP_SAW_DOT) /* two dots */ ++ if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ + goto PNG_FP_End; + +- else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ ++ else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ + png_fp_add(state, type); + + else +@@ -1030,7 +2719,7 @@ + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: +- if (state & PNG_FP_SAW_DOT) /* delayed fraction */ ++ if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + + png_fp_add(state, type | PNG_FP_WAS_VALID); +@@ -1068,7 +2757,7 @@ + break; + + case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: +- if (state & PNG_FP_SAW_ANY) ++ if ((state & PNG_FP_SAW_ANY) != 0) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, PNG_FP_SAW_SIGN); +@@ -1111,15 +2800,15 @@ + int state=0; + png_size_t char_index=0; + +- if (png_check_fp_number(string, size, &state, &char_index) && ++ if (png_check_fp_number(string, size, &state, &char_index) != 0 && + (char_index == size || string[char_index] == 0)) + return state /* must be non-zero - see above */; + + return 0; /* i.e. fail */ + } +-#endif /* pCAL or sCAL */ +- +-#ifdef PNG_READ_sCAL_SUPPORTED ++#endif /* pCAL || sCAL */ ++ ++#ifdef PNG_sCAL_SUPPORTED + # ifdef PNG_FLOATING_POINT_SUPPORTED + /* Utility used below - a simple accurate power of ten from an integral + * exponent. +@@ -1151,7 +2840,7 @@ + } + while (power > 0); + +- if (recip) d = 1/d; ++ if (recip != 0) d = 1/d; + } + /* else power is 0 and d is 1 */ + +@@ -1162,7 +2851,7 @@ + * precision. + */ + void /* PRIVATE */ +-png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, ++png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, + double fp, unsigned int precision) + { + /* We use standard functions from math.h, but not printf because +@@ -1365,8 +3054,9 @@ + + if (exp_b10 != (-1)) + { +- if (exp_b10 == 0) *ascii++ = 46, --size; /* counted +- above */ ++ if (exp_b10 == 0) ++ *ascii++ = 46, --size; /* counted above */ ++ + --exp_b10; + } + *ascii++ = (char)(48 + (int)d), ++cdigits; +@@ -1411,18 +3101,30 @@ + size -= cdigits; + + *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ +- if (exp_b10 < 0) ++ ++ /* The following use of an unsigned temporary avoids ambiguities in ++ * the signed arithmetic on exp_b10 and permits GCC at least to do ++ * better optimization. ++ */ + { +- *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ +- exp_b10 = -exp_b10; +- } +- +- cdigits = 0; +- +- while (exp_b10 > 0) +- { +- exponent[cdigits++] = (char)(48 + exp_b10 % 10); +- exp_b10 /= 10; ++ unsigned int uexp_b10; ++ ++ if (exp_b10 < 0) ++ { ++ *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ ++ uexp_b10 = -exp_b10; ++ } ++ ++ else ++ uexp_b10 = exp_b10; ++ ++ cdigits = 0; ++ ++ while (uexp_b10 > 0) ++ { ++ exponent[cdigits++] = (char)(48 + uexp_b10 % 10); ++ uexp_b10 /= 10; ++ } + } + + /* Need another size check here for the exponent digits, so +@@ -1464,8 +3166,8 @@ + /* Function to format a fixed point value in ASCII. + */ + void /* PRIVATE */ +-png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, +- png_fixed_point fp) ++png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, ++ png_size_t size, png_fixed_point fp) + { + /* Require space for 10 decimal digits, a decimal point, a minus sign and a + * trailing \0, 13 characters: +@@ -1480,7 +3182,7 @@ + else + num = fp; + +- if (num <= 0x80000000U) /* else overflowed */ ++ if (num <= 0x80000000) /* else overflowed */ + { + unsigned int ndigits = 0, first = 16 /* flag value */; + char digits[10]; +@@ -1535,21 +3237,30 @@ + #endif /* READ_SCAL */ + + #if defined(PNG_FLOATING_POINT_SUPPORTED) && \ +- !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) ++ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ ++ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ ++ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ ++ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ ++ (defined(PNG_sCAL_SUPPORTED) && \ ++ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) + png_fixed_point +-png_fixed(png_structp png_ptr, double fp, png_const_charp text) ++png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) + { + double r = floor(100000 * fp + .5); + + if (r > 2147483647. || r < -2147483648.) + png_fixed_error(png_ptr, text); + ++# ifndef PNG_ERROR_TEXT_SUPPORTED ++ PNG_UNUSED(text) ++# endif ++ + return (png_fixed_point)r; + } + #endif + +-#if defined(PNG_READ_GAMMA_SUPPORTED) || \ +- defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) ++#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ ++ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) + /* muldiv functions */ + /* This API takes signed arguments and rounds the result to the nearest + * integer (or, for a fixed point number - the standard argument - to +@@ -1653,11 +3364,12 @@ + if (s00 >= (D >> 1)) + ++result; + +- if (negative) ++ if (negative != 0) + result = -result; + + /* Check for overflow. */ +- if ((negative && result <= 0) || (!negative && result >= 0)) ++ if ((negative != 0 && result <= 0) || ++ (negative == 0 && result >= 0)) + { + *res = result; + return 1; +@@ -1676,12 +3388,12 @@ + * result. + */ + png_fixed_point +-png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, ++png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times, + png_int_32 divisor) + { + png_fixed_point result; + +- if (png_muldiv(&result, a, times, divisor)) ++ if (png_muldiv(&result, a, times, divisor) != 0) + return result; + + png_warning(png_ptr, "fixed point overflow ignored"); +@@ -1689,7 +3401,7 @@ + } + #endif + +-#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gammma */ ++#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ + /* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ + png_fixed_point + png_reciprocal(png_fixed_point a) +@@ -1702,34 +3414,48 @@ + #else + png_fixed_point res; + +- if (png_muldiv(&res, 100000, 100000, a)) ++ if (png_muldiv(&res, 100000, 100000, a) != 0) + return res; + #endif + + return 0; /* error/overflow */ + } + ++/* This is the shared test on whether a gamma value is 'significant' - whether ++ * it is worth doing gamma correction. ++ */ ++int /* PRIVATE */ ++png_gamma_significant(png_fixed_point gamma_val) ++{ ++ return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || ++ gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; ++} ++#endif ++ ++#ifdef PNG_READ_GAMMA_SUPPORTED ++#if defined(PNG_16BIT_SUPPORTED) || !defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) + /* A local convenience routine. */ + static png_fixed_point + png_product2(png_fixed_point a, png_fixed_point b) + { + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED ++# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a * 1E-5; + r *= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +-#else ++# else + png_fixed_point res; + +- if (png_muldiv(&res, a, b, 100000)) ++ if (png_muldiv(&res, a, b, 100000) != 0) + return res; +-#endif ++# endif + + return 0; /* overflow */ + } ++#endif /* 16BIT || !FLOATING_ARITHMETIC */ + + /* The inverse of the above. */ + png_fixed_point +@@ -1759,73 +3485,28 @@ + } + #endif /* READ_GAMMA */ + +-#ifdef PNG_CHECK_cHRM_SUPPORTED +-/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, +- * 2010: moved from pngset.c) */ +-/* +- * Multiply two 32-bit numbers, V1 and V2, using 32-bit +- * arithmetic, to produce a 64-bit result in the HI/LO words. +- * +- * A B +- * x C D +- * ------ +- * AD || BD +- * AC || CB || 0 +- * +- * where A and B are the high and low 16-bit words of V1, +- * C and D are the 16-bit words of V2, AD is the product of +- * A and D, and X || Y is (X << 16) + Y. +-*/ +- +-void /* PRIVATE */ +-png_64bit_product (long v1, long v2, unsigned long *hi_product, +- unsigned long *lo_product) +-{ +- int a, b, c, d; +- long lo, hi, x, y; +- +- a = (v1 >> 16) & 0xffff; +- b = v1 & 0xffff; +- c = (v2 >> 16) & 0xffff; +- d = v2 & 0xffff; +- +- lo = b * d; /* BD */ +- x = a * d + c * b; /* AD + CB */ +- y = ((lo >> 16) & 0xffff) + x; +- +- lo = (lo & 0xffff) | ((y & 0xffff) << 16); +- hi = (y >> 16) & 0xffff; +- +- hi += a * c; /* AC */ +- +- *hi_product = (unsigned long)hi; +- *lo_product = (unsigned long)lo; +-} +-#endif /* CHECK_cHRM */ +- + #ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ + #ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* Fixed point gamma. + * ++ * The code to calculate the tables used below can be found in the shell script ++ * contrib/tools/intgamma.sh ++ * + * To calculate gamma this code implements fast log() and exp() calls using only + * fixed point arithmetic. This code has sufficient precision for either 8-bit + * or 16-bit sample values. + * + * The tables used here were calculated using simple 'bc' programs, but C double +- * precision floating point arithmetic would work fine. The programs are given +- * at the head of each table. ++ * precision floating point arithmetic would work fine. + * + * 8-bit log table + * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to + * 255, so it's the base 2 logarithm of a normalized 8-bit floating point + * mantissa. The numbers are 32-bit fractions. + */ +-static png_uint_32 ++static const png_uint_32 + png_8bit_l2[128] = + { +-# if PNG_DO_BC +- for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } +-# endif + 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, + 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, + 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, +@@ -1848,6 +3529,7 @@ + 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, + 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, + 24347096U, 0U ++ + #if 0 + /* The following are the values for 16-bit tables - these work fine for the + * 8-bit conversions but produce very slightly larger errors in the 16-bit +@@ -1869,18 +3551,18 @@ + #endif + }; + +-PNG_STATIC png_int_32 ++static png_int_32 + png_log8bit(unsigned int x) + { + unsigned int lg2 = 0; + /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, + * because the log is actually negate that means adding 1. The final + * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 +- * input), return 7.99998 for the overflow (log 0) case - so the result is ++ * input), return -1 for the overflow (log 0) case, - so the result is + * always at most 19 bits. + */ + if ((x &= 0xff) == 0) +- return 0xffffffff; ++ return -1; + + if ((x & 0xf0) == 0) + lg2 = 4, x <<= 4; +@@ -1925,14 +3607,15 @@ + * Zero (257): 0 + * End (258): 23499 + */ +-PNG_STATIC png_int_32 ++#ifdef PNG_16BIT_SUPPORTED ++static png_int_32 + png_log16bit(png_uint_32 x) + { + unsigned int lg2 = 0; + + /* As above, but now the input has 16 bits. */ + if ((x &= 0xffff) == 0) +- return 0xffffffff; ++ return -1; + + if ((x & 0xff00) == 0) + lg2 = 8, x <<= 8; +@@ -1975,14 +3658,15 @@ + /* Safe, because the result can't have more than 20 bits: */ + return (png_int_32)((lg2 + 2048) >> 12); + } ++#endif /* 16BIT */ + + /* The 'exp()' case must invert the above, taking a 20-bit fixed point + * logarithmic value and returning a 16 or 8-bit number as appropriate. In + * each case only the low 16 bits are relevant - the fraction - since the + * integer bits (the top 4) simply determine a shift. + * +- * The worst case is the 16-bit distinction between 65535 and 65534, this +- * requires perhaps spurious accuracty in the decoding of the logarithm to ++ * The worst case is the 16-bit distinction between 65535 and 65534. This ++ * requires perhaps spurious accuracy in the decoding of the logarithm to + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance + * of getting this accuracy in practice. + * +@@ -1990,12 +3674,9 @@ + * frational part of the logarithm by using an accurate 32-bit value from the + * top four fractional bits then multiplying in the remaining bits. + */ +-static png_uint_32 ++static const png_uint_32 + png_32bit_exp[16] = + { +-# if PNG_DO_BC +- for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } +-# endif + /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ + 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, + 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, +@@ -2003,7 +3684,7 @@ + }; + + /* Adjustment table; provided to explain the numbers in the code below. */ +-#if PNG_DO_BC ++#if 0 + for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} + 11 44937.64284865548751208448 + 10 45180.98734845585101160448 +@@ -2019,7 +3700,7 @@ + 0 45425.85339951654943850496 + #endif + +-PNG_STATIC png_uint_32 ++static png_uint_32 + png_exp(png_fixed_point x) + { + if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ +@@ -2067,13 +3748,13 @@ + return 0; + } + +-PNG_STATIC png_byte ++static png_byte + png_exp8bit(png_fixed_point lg2) + { + /* Get a 32-bit value: */ + png_uint_32 x = png_exp(lg2); + +- /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the ++ /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the + * second, rounding, step can't overflow because of the first, subtraction, + * step. + */ +@@ -2081,7 +3762,8 @@ + return (png_byte)((x + 0x7fffffU) >> 24); + } + +-PNG_STATIC png_uint_16 ++#ifdef PNG_16BIT_SUPPORTED ++static png_uint_16 + png_exp16bit(png_fixed_point lg2) + { + /* Get a 32-bit value: */ +@@ -2091,6 +3773,7 @@ + x -= x >> 16; + return (png_uint_16)((x + 32767U) >> 16); + } ++#endif /* 16BIT */ + #endif /* FLOATING_ARITHMETIC */ + + png_byte +@@ -2099,13 +3782,37 @@ + if (value > 0 && value < 255) + { + # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +- double r = floor(255*pow(value/255.,gamma_val*.00001)+.5); ++ /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly ++ * convert this to a floating point value. This includes values that ++ * would overflow if 'value' were to be converted to 'int'. ++ * ++ * Apparently GCC, however, does an intermediate conversion to (int) ++ * on some (ARM) but not all (x86) platforms, possibly because of ++ * hardware FP limitations. (E.g. if the hardware conversion always ++ * assumes the integer register contains a signed value.) This results ++ * in ANSI-C undefined behavior for large values. ++ * ++ * Other implementations on the same machine might actually be ANSI-C90 ++ * conformant and therefore compile spurious extra code for the large ++ * values. ++ * ++ * We can be reasonably sure that an unsigned to float conversion ++ * won't be faster than an int to float one. Therefore this code ++ * assumes responsibility for the undefined behavior, which it knows ++ * can't happen because of the check above. ++ * ++ * Note the argument to this routine is an (unsigned int) because, on ++ * 16-bit platforms, it is assigned a value which might be out of ++ * range for an (int); that would result in undefined behavior in the ++ * caller if the *argument* ('value') were to be declared (int). ++ */ ++ double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5); + return (png_byte)r; + # else + png_int_32 lg2 = png_log8bit(value); + png_fixed_point res; + +- if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) ++ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) + return png_exp8bit(res); + + /* Overflow. */ +@@ -2116,19 +3823,26 @@ + return (png_byte)value; + } + ++#ifdef PNG_16BIT_SUPPORTED + png_uint_16 + png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) + { + if (value > 0 && value < 65535) + { + # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +- double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5); ++ /* The same (unsigned int)->(double) constraints apply here as above, ++ * however in this case the (unsigned int) to (int) conversion can ++ * overflow on an ANSI-C90 compliant system so the cast needs to ensure ++ * that this is not possible. ++ */ ++ double r = floor(65535*pow((png_int_32)value/65535., ++ gamma_val*.00001)+.5); + return (png_uint_16)r; + # else + png_int_32 lg2 = png_log16bit(value); + png_fixed_point res; + +- if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) ++ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) + return png_exp16bit(res); + + /* Overflow. */ +@@ -2138,6 +3852,7 @@ + + return (png_uint_16)value; + } ++#endif /* 16BIT */ + + /* This does the right thing based on the bit_depth field of the + * png_struct, interpreting values as 8-bit or 16-bit. While the result +@@ -2145,26 +3860,22 @@ + * 8-bit (as are the arguments.) + */ + png_uint_16 /* PRIVATE */ +-png_gamma_correct(png_structp png_ptr, unsigned int value, ++png_gamma_correct(png_structrp png_ptr, unsigned int value, + png_fixed_point gamma_val) + { + if (png_ptr->bit_depth == 8) + return png_gamma_8bit_correct(value, gamma_val); + ++#ifdef PNG_16BIT_SUPPORTED + else + return png_gamma_16bit_correct(value, gamma_val); ++#else ++ /* should not reach this */ ++ return 0; ++#endif /* 16BIT */ + } + +-/* This is the shared test on whether a gamma value is 'significant' - whether +- * it is worth doing gamma correction. +- */ +-int /* PRIVATE */ +-png_gamma_significant(png_fixed_point gamma_val) +-{ +- return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || +- gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; +-} +- ++#ifdef PNG_16BIT_SUPPORTED + /* Internal function to build a single 16-bit table - the table consists of + * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount + * to shift the input values right (or 16-number_of_signifiant_bits). +@@ -2174,27 +3885,33 @@ + * should be somewhere that will be cleaned. + */ + static void +-png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, ++png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + { + /* Various values derived from 'shift': */ + PNG_CONST unsigned int num = 1U << (8U - shift); ++#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED ++ /* CSE the division and work round wacky GCC warnings (see the comments ++ * in png_gamma_8bit_correct for where these come from.) ++ */ ++ PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1); ++#endif + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); + unsigned int i; + + png_uint_16pp table = *ptable = +- (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); ++ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); + + for (i = 0; i < num; i++) + { + png_uint_16p sub_table = table[i] = +- (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); ++ (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); + + /* The 'threshold' test is repeated here because it can arise for one of + * the 16-bit tables even if the others don't hit it. + */ +- if (png_gamma_significant(gamma_val)) ++ if (png_gamma_significant(gamma_val) != 0) + { + /* The old code would overflow at the end and this would cause the + * 'pow' function to return a result >1, resulting in an +@@ -2210,10 +3927,13 @@ + png_uint_32 ig = (j << (8-shift)) + i; + # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* Inline the 'max' scaling operation: */ +- double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); ++ /* See png_gamma_8bit_correct for why the cast to (int) is ++ * required here. ++ */ ++ double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5); + sub_table[j] = (png_uint_16)d; + # else +- if (shift) ++ if (shift != 0) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); +@@ -2229,7 +3949,7 @@ + { + png_uint_32 ig = (j << (8-shift)) + i; + +- if (shift) ++ if (shift != 0) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = (png_uint_16)ig; +@@ -2242,7 +3962,7 @@ + * required. + */ + static void +-png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, ++png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + { + PNG_CONST unsigned int num = 1U << (8U - shift); +@@ -2251,15 +3971,15 @@ + png_uint_32 last; + + png_uint_16pp table = *ptable = +- (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); ++ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); + + /* 'num' is the number of tables and also the number of low bits of low + * bits of the input 16-bit value used to select a table. Each table is +- * itself index by the high 8 bits of the value. ++ * itself indexed by the high 8 bits of the value. + */ + for (i = 0; i < num; i++) + table[i] = (png_uint_16p)png_malloc(png_ptr, +- 256 * png_sizeof(png_uint_16)); ++ 256 * (sizeof (png_uint_16))); + + /* 'gamma_val' is set to the reciprocal of the value calculated above, so + * pow(out,g) is an *input* value. 'last' is the last input value set. +@@ -2303,23 +4023,84 @@ + last++; + } + } ++#endif /* 16BIT */ + + /* Build a single 8-bit table: same as the 16-bit case but much simpler (and + * typically much faster). Note that libpng currently does no sBIT processing +- * (apparently contrary to the spec) so a 256 entry table is always generated. ++ * (apparently contrary to the spec) so a 256-entry table is always generated. + */ + static void +-png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, ++png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, + PNG_CONST png_fixed_point gamma_val) + { + unsigned int i; + png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); + +- if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++) +- table[i] = png_gamma_8bit_correct(i, gamma_val); +- +- else for (i=0; i<256; ++i) +- table[i] = (png_byte)i; ++ if (png_gamma_significant(gamma_val) != 0) ++ for (i=0; i<256; i++) ++ table[i] = png_gamma_8bit_correct(i, gamma_val); ++ ++ else ++ for (i=0; i<256; ++i) ++ table[i] = (png_byte)i; ++} ++ ++/* Used from png_read_destroy and below to release the memory used by the gamma ++ * tables. ++ */ ++void /* PRIVATE */ ++png_destroy_gamma_table(png_structrp png_ptr) ++{ ++ png_free(png_ptr, png_ptr->gamma_table); ++ png_ptr->gamma_table = NULL; ++ ++#ifdef PNG_16BIT_SUPPORTED ++ if (png_ptr->gamma_16_table != NULL) ++ { ++ int i; ++ int istop = (1 << (8 - png_ptr->gamma_shift)); ++ for (i = 0; i < istop; i++) ++ { ++ png_free(png_ptr, png_ptr->gamma_16_table[i]); ++ } ++ png_free(png_ptr, png_ptr->gamma_16_table); ++ png_ptr->gamma_16_table = NULL; ++ } ++#endif /* 16BIT */ ++ ++#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ ++ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ ++ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) ++ png_free(png_ptr, png_ptr->gamma_from_1); ++ png_ptr->gamma_from_1 = NULL; ++ png_free(png_ptr, png_ptr->gamma_to_1); ++ png_ptr->gamma_to_1 = NULL; ++ ++#ifdef PNG_16BIT_SUPPORTED ++ if (png_ptr->gamma_16_from_1 != NULL) ++ { ++ int i; ++ int istop = (1 << (8 - png_ptr->gamma_shift)); ++ for (i = 0; i < istop; i++) ++ { ++ png_free(png_ptr, png_ptr->gamma_16_from_1[i]); ++ } ++ png_free(png_ptr, png_ptr->gamma_16_from_1); ++ png_ptr->gamma_16_from_1 = NULL; ++ } ++ if (png_ptr->gamma_16_to_1 != NULL) ++ { ++ int i; ++ int istop = (1 << (8 - png_ptr->gamma_shift)); ++ for (i = 0; i < istop; i++) ++ { ++ png_free(png_ptr, png_ptr->gamma_16_to_1[i]); ++ } ++ png_free(png_ptr, png_ptr->gamma_16_to_1); ++ png_ptr->gamma_16_to_1 = NULL; ++ } ++#endif /* 16BIT */ ++#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } + + /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit +@@ -2328,35 +4109,48 @@ + * we don't need to allocate > 64K chunks for a full 16-bit table. + */ + void /* PRIVATE */ +-png_build_gamma_table(png_structp png_ptr, int bit_depth) ++png_build_gamma_table(png_structrp png_ptr, int bit_depth) + { + png_debug(1, "in png_build_gamma_table"); + ++ /* Remove any existing table; this copes with multiple calls to ++ * png_read_update_info. The warning is because building the gamma tables ++ * multiple times is a performance hit - it's harmless but the ability to call ++ * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible ++ * to warn if the app introduces such a hit. ++ */ ++ if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) ++ { ++ png_warning(png_ptr, "gamma table being rebuilt"); ++ png_destroy_gamma_table(png_ptr); ++ } ++ + if (bit_depth <= 8) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, +- png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, ++ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma) : PNG_FP_1); + + #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +- if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) ++ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, +- png_reciprocal(png_ptr->gamma)); ++ png_reciprocal(png_ptr->colorspace.gamma)); + + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : +- png_ptr->gamma/* Probably doing rgb_to_gray */); ++ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + } + #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } ++#ifdef PNG_16BIT_SUPPORTED + else + { + png_byte shift, sig_bit; + +- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) ++ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + sig_bit = png_ptr->sig_bit.red; + +@@ -2376,7 +4170,7 @@ + * Where 'iv' is the input color value and 'ov' is the output value - + * pow(iv, gamma). + * +- * Thus the gamma table consists of up to 256 256 entry tables. The table ++ * Thus the gamma table consists of up to 256 256-entry tables. The table + * is selected by the (8-gamma_shift) most significant of the low 8 bits of + * the color value then indexed by the upper 8 bits: + * +@@ -2393,7 +4187,7 @@ + else + shift = 0; /* keep all 16 bits */ + +- if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) ++ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) + { + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively + * the significant bits in the *input* when the output will +@@ -2408,32 +4202,28 @@ + + png_ptr->gamma_shift = shift; + +-#ifdef PNG_16BIT_SUPPORTED + /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now + * PNG_COMPOSE). This effectively smashed the background calculation for + * 16-bit output because the 8-bit table assumes the result will be reduced + * to 8 bits. + */ +- if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) +-#endif ++ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, +- png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, ++ png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +-#ifdef PNG_16BIT_SUPPORTED + else + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, +- png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, ++ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma) : PNG_FP_1); +-#endif + + #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +- if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) ++ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) + { + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, +- png_reciprocal(png_ptr->gamma)); ++ png_reciprocal(png_ptr->colorspace.gamma)); + + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, so it can't be. +@@ -2441,10 +4231,291 @@ + */ + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : +- png_ptr->gamma/* Probably doing rgb_to_gray */); ++ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); + } + #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + } ++#endif /* 16BIT */ + } + #endif /* READ_GAMMA */ +-#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ ++ ++/* HARDWARE OR SOFTWARE OPTION SUPPORT */ ++#ifdef PNG_SET_OPTION_SUPPORTED ++int PNGAPI ++png_set_option(png_structrp png_ptr, int option, int onoff) ++{ ++ if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && ++ (option & 1) == 0) ++ { ++ int mask = 3 << option; ++ int setting = (2 + (onoff != 0)) << option; ++ int current = png_ptr->options; ++ ++ png_ptr->options = (png_byte)((current & ~mask) | setting); ++ ++ return (current & mask) >> option; ++ } ++ ++ return PNG_OPTION_INVALID; ++} ++#endif ++ ++/* sRGB support */ ++#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ ++ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) ++/* sRGB conversion tables; these are machine generated with the code in ++ * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the ++ * specification (see the article at http://en.wikipedia.org/wiki/SRGB) ++ * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. ++ * The sRGB to linear table is exact (to the nearest 16 bit linear fraction). ++ * The inverse (linear to sRGB) table has accuracies as follows: ++ * ++ * For all possible (255*65535+1) input values: ++ * ++ * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact ++ * ++ * For the input values corresponding to the 65536 16-bit values: ++ * ++ * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact ++ * ++ * In all cases the inexact readings are only off by one. ++ */ ++ ++#ifdef PNG_SIMPLIFIED_READ_SUPPORTED ++/* The convert-to-sRGB table is only currently required for read. */ ++const png_uint_16 png_sRGB_table[256] = ++{ ++ 0,20,40,60,80,99,119,139, ++ 159,179,199,219,241,264,288,313, ++ 340,367,396,427,458,491,526,562, ++ 599,637,677,718,761,805,851,898, ++ 947,997,1048,1101,1156,1212,1270,1330, ++ 1391,1453,1517,1583,1651,1720,1790,1863, ++ 1937,2013,2090,2170,2250,2333,2418,2504, ++ 2592,2681,2773,2866,2961,3058,3157,3258, ++ 3360,3464,3570,3678,3788,3900,4014,4129, ++ 4247,4366,4488,4611,4736,4864,4993,5124, ++ 5257,5392,5530,5669,5810,5953,6099,6246, ++ 6395,6547,6700,6856,7014,7174,7335,7500, ++ 7666,7834,8004,8177,8352,8528,8708,8889, ++ 9072,9258,9445,9635,9828,10022,10219,10417, ++ 10619,10822,11028,11235,11446,11658,11873,12090, ++ 12309,12530,12754,12980,13209,13440,13673,13909, ++ 14146,14387,14629,14874,15122,15371,15623,15878, ++ 16135,16394,16656,16920,17187,17456,17727,18001, ++ 18277,18556,18837,19121,19407,19696,19987,20281, ++ 20577,20876,21177,21481,21787,22096,22407,22721, ++ 23038,23357,23678,24002,24329,24658,24990,25325, ++ 25662,26001,26344,26688,27036,27386,27739,28094, ++ 28452,28813,29176,29542,29911,30282,30656,31033, ++ 31412,31794,32179,32567,32957,33350,33745,34143, ++ 34544,34948,35355,35764,36176,36591,37008,37429, ++ 37852,38278,38706,39138,39572,40009,40449,40891, ++ 41337,41785,42236,42690,43147,43606,44069,44534, ++ 45002,45473,45947,46423,46903,47385,47871,48359, ++ 48850,49344,49841,50341,50844,51349,51858,52369, ++ 52884,53401,53921,54445,54971,55500,56032,56567, ++ 57105,57646,58190,58737,59287,59840,60396,60955, ++ 61517,62082,62650,63221,63795,64372,64952,65535 ++}; ++#endif /* SIMPLIFIED_READ */ ++ ++/* The base/delta tables are required for both read and write (but currently ++ * only the simplified versions.) ++ */ ++const png_uint_16 png_sRGB_base[512] = ++{ ++ 128,1782,3383,4644,5675,6564,7357,8074, ++ 8732,9346,9921,10463,10977,11466,11935,12384, ++ 12816,13233,13634,14024,14402,14769,15125,15473, ++ 15812,16142,16466,16781,17090,17393,17690,17981, ++ 18266,18546,18822,19093,19359,19621,19879,20133, ++ 20383,20630,20873,21113,21349,21583,21813,22041, ++ 22265,22487,22707,22923,23138,23350,23559,23767, ++ 23972,24175,24376,24575,24772,24967,25160,25352, ++ 25542,25730,25916,26101,26284,26465,26645,26823, ++ 27000,27176,27350,27523,27695,27865,28034,28201, ++ 28368,28533,28697,28860,29021,29182,29341,29500, ++ 29657,29813,29969,30123,30276,30429,30580,30730, ++ 30880,31028,31176,31323,31469,31614,31758,31902, ++ 32045,32186,32327,32468,32607,32746,32884,33021, ++ 33158,33294,33429,33564,33697,33831,33963,34095, ++ 34226,34357,34486,34616,34744,34873,35000,35127, ++ 35253,35379,35504,35629,35753,35876,35999,36122, ++ 36244,36365,36486,36606,36726,36845,36964,37083, ++ 37201,37318,37435,37551,37668,37783,37898,38013, ++ 38127,38241,38354,38467,38580,38692,38803,38915, ++ 39026,39136,39246,39356,39465,39574,39682,39790, ++ 39898,40005,40112,40219,40325,40431,40537,40642, ++ 40747,40851,40955,41059,41163,41266,41369,41471, ++ 41573,41675,41777,41878,41979,42079,42179,42279, ++ 42379,42478,42577,42676,42775,42873,42971,43068, ++ 43165,43262,43359,43456,43552,43648,43743,43839, ++ 43934,44028,44123,44217,44311,44405,44499,44592, ++ 44685,44778,44870,44962,45054,45146,45238,45329, ++ 45420,45511,45601,45692,45782,45872,45961,46051, ++ 46140,46229,46318,46406,46494,46583,46670,46758, ++ 46846,46933,47020,47107,47193,47280,47366,47452, ++ 47538,47623,47709,47794,47879,47964,48048,48133, ++ 48217,48301,48385,48468,48552,48635,48718,48801, ++ 48884,48966,49048,49131,49213,49294,49376,49458, ++ 49539,49620,49701,49782,49862,49943,50023,50103, ++ 50183,50263,50342,50422,50501,50580,50659,50738, ++ 50816,50895,50973,51051,51129,51207,51285,51362, ++ 51439,51517,51594,51671,51747,51824,51900,51977, ++ 52053,52129,52205,52280,52356,52432,52507,52582, ++ 52657,52732,52807,52881,52956,53030,53104,53178, ++ 53252,53326,53400,53473,53546,53620,53693,53766, ++ 53839,53911,53984,54056,54129,54201,54273,54345, ++ 54417,54489,54560,54632,54703,54774,54845,54916, ++ 54987,55058,55129,55199,55269,55340,55410,55480, ++ 55550,55620,55689,55759,55828,55898,55967,56036, ++ 56105,56174,56243,56311,56380,56448,56517,56585, ++ 56653,56721,56789,56857,56924,56992,57059,57127, ++ 57194,57261,57328,57395,57462,57529,57595,57662, ++ 57728,57795,57861,57927,57993,58059,58125,58191, ++ 58256,58322,58387,58453,58518,58583,58648,58713, ++ 58778,58843,58908,58972,59037,59101,59165,59230, ++ 59294,59358,59422,59486,59549,59613,59677,59740, ++ 59804,59867,59930,59993,60056,60119,60182,60245, ++ 60308,60370,60433,60495,60558,60620,60682,60744, ++ 60806,60868,60930,60992,61054,61115,61177,61238, ++ 61300,61361,61422,61483,61544,61605,61666,61727, ++ 61788,61848,61909,61969,62030,62090,62150,62211, ++ 62271,62331,62391,62450,62510,62570,62630,62689, ++ 62749,62808,62867,62927,62986,63045,63104,63163, ++ 63222,63281,63340,63398,63457,63515,63574,63632, ++ 63691,63749,63807,63865,63923,63981,64039,64097, ++ 64155,64212,64270,64328,64385,64443,64500,64557, ++ 64614,64672,64729,64786,64843,64900,64956,65013, ++ 65070,65126,65183,65239,65296,65352,65409,65465 ++}; ++ ++const png_byte png_sRGB_delta[512] = ++{ ++ 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, ++ 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, ++ 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, ++ 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, ++ 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, ++ 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, ++ 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, ++ 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, ++ 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, ++ 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, ++ 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, ++ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, ++ 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, ++ 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, ++ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, ++ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, ++ 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, ++ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, ++ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, ++ 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ++ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ++ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ++ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ++ 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 ++}; ++#endif /* SIMPLIFIED READ/WRITE sRGB support */ ++ ++/* SIMPLIFIED READ/WRITE SUPPORT */ ++#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ ++ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) ++static int ++png_image_free_function(png_voidp argument) ++{ ++ png_imagep image = png_voidcast(png_imagep, argument); ++ png_controlp cp = image->opaque; ++ png_control c; ++ ++ /* Double check that we have a png_ptr - it should be impossible to get here ++ * without one. ++ */ ++ if (cp->png_ptr == NULL) ++ return 0; ++ ++ /* First free any data held in the control structure. */ ++# ifdef PNG_STDIO_SUPPORTED ++ if (cp->owned_file != 0) ++ { ++ FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); ++ cp->owned_file = 0; ++ ++ /* Ignore errors here. */ ++ if (fp != NULL) ++ { ++ cp->png_ptr->io_ptr = NULL; ++ (void)fclose(fp); ++ } ++ } ++# endif ++ ++ /* Copy the control structure so that the original, allocated, version can be ++ * safely freed. Notice that a png_error here stops the remainder of the ++ * cleanup, but this is probably fine because that would indicate bad memory ++ * problems anyway. ++ */ ++ c = *cp; ++ image->opaque = &c; ++ png_free(c.png_ptr, cp); ++ ++ /* Then the structures, calling the correct API. */ ++ if (c.for_write != 0) ++ { ++# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED ++ png_destroy_write_struct(&c.png_ptr, &c.info_ptr); ++# else ++ png_error(c.png_ptr, "simplified write not supported"); ++# endif ++ } ++ else ++ { ++# ifdef PNG_SIMPLIFIED_READ_SUPPORTED ++ png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); ++# else ++ png_error(c.png_ptr, "simplified read not supported"); ++# endif ++ } ++ ++ /* Success. */ ++ return 1; ++} ++ ++void PNGAPI ++png_image_free(png_imagep image) ++{ ++ /* Safely call the real function, but only if doing so is safe at this point ++ * (if not inside an error handling context). Otherwise assume ++ * png_safe_execute will call this API after the return. ++ */ ++ if (image != NULL && image->opaque != NULL && ++ image->opaque->error_buf == NULL) ++ { ++ /* Ignore errors here: */ ++ (void)png_safe_execute(image, png_image_free_function, image); ++ image->opaque = NULL; ++ } ++} ++ ++int /* PRIVATE */ ++png_image_error(png_imagep image, png_const_charp error_message) ++{ ++ /* Utility to log an error. */ ++ png_safecat(image->message, (sizeof image->message), 0, error_message); ++ image->warning_or_error |= PNG_IMAGE_ERROR; ++ png_image_free(image); ++ return 0; ++} ++ ++#endif /* SIMPLIFIED READ/WRITE */ ++#endif /* READ || WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/png.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/png.h Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * libpng version 1.5.4 - July 7, 2011 +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * libpng version 1.6.16, December 22, 2014 ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -39,7 +39,7 @@ + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger +- * libpng versions 0.97, January 1998, through 1.5.4 - July 7, 2011: Glenn ++ * libpng versions 0.97, January 1998, through 1.6.16, December 22, 2014: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: +@@ -185,6 +185,61 @@ + * 1.5.4beta01-08 15 10504 15.so.15.4[.0] + * 1.5.4rc01 15 10504 15.so.15.4[.0] + * 1.5.4 15 10504 15.so.15.4[.0] ++ * 1.5.5beta01-08 15 10505 15.so.15.5[.0] ++ * 1.5.5rc01 15 10505 15.so.15.5[.0] ++ * 1.5.5 15 10505 15.so.15.5[.0] ++ * 1.5.6beta01-07 15 10506 15.so.15.6[.0] ++ * 1.5.6rc01-03 15 10506 15.so.15.6[.0] ++ * 1.5.6 15 10506 15.so.15.6[.0] ++ * 1.5.7beta01-05 15 10507 15.so.15.7[.0] ++ * 1.5.7rc01-03 15 10507 15.so.15.7[.0] ++ * 1.5.7 15 10507 15.so.15.7[.0] ++ * 1.6.0beta01-40 16 10600 16.so.16.0[.0] ++ * 1.6.0rc01-08 16 10600 16.so.16.0[.0] ++ * 1.6.0 16 10600 16.so.16.0[.0] ++ * 1.6.1beta01-09 16 10601 16.so.16.1[.0] ++ * 1.6.1rc01 16 10601 16.so.16.1[.0] ++ * 1.6.1 16 10601 16.so.16.1[.0] ++ * 1.6.2beta01 16 10602 16.so.16.2[.0] ++ * 1.6.2rc01-06 16 10602 16.so.16.2[.0] ++ * 1.6.2 16 10602 16.so.16.2[.0] ++ * 1.6.3beta01-11 16 10603 16.so.16.3[.0] ++ * 1.6.3rc01 16 10603 16.so.16.3[.0] ++ * 1.6.3 16 10603 16.so.16.3[.0] ++ * 1.6.4beta01-02 16 10604 16.so.16.4[.0] ++ * 1.6.4rc01 16 10604 16.so.16.4[.0] ++ * 1.6.4 16 10604 16.so.16.4[.0] ++ * 1.6.5 16 10605 16.so.16.5[.0] ++ * 1.6.6 16 10606 16.so.16.6[.0] ++ * 1.6.7beta01-04 16 10607 16.so.16.7[.0] ++ * 1.6.7rc01-03 16 10607 16.so.16.7[.0] ++ * 1.6.7 16 10607 16.so.16.7[.0] ++ * 1.6.8beta01-02 16 10608 16.so.16.8[.0] ++ * 1.6.8rc01-02 16 10608 16.so.16.8[.0] ++ * 1.6.8 16 10608 16.so.16.8[.0] ++ * 1.6.9beta01-04 16 10609 16.so.16.9[.0] ++ * 1.6.9rc01-02 16 10609 16.so.16.9[.0] ++ * 1.6.9 16 10609 16.so.16.9[.0] ++ * 1.6.10beta01-03 16 10610 16.so.16.10[.0] ++ * 1.6.10rc01-03 16 10610 16.so.16.10[.0] ++ * 1.6.10 16 10610 16.so.16.10[.0] ++ * 1.6.11beta01-06 16 10611 16.so.16.11[.0] ++ * 1.6.11rc01-02 16 10611 16.so.16.11[.0] ++ * 1.6.11 16 10611 16.so.16.11[.0] ++ * 1.6.12rc01-03 16 10612 16.so.16.12[.0] ++ * 1.6.12 16 10612 16.so.16.12[.0] ++ * 1.6.13beta01-04 16 10613 16.so.16.13[.0] ++ * 1.6.13rc01-02 16 10613 16.so.16.13[.0] ++ * 1.6.13 16 10613 16.so.16.13[.0] ++ * 1.6.14beta01-07 16 10614 16.so.16.14[.0] ++ * 1.6.14rc01-02 16 10614 16.so.16.14[.0] ++ * 1.6.14 16 10614 16.so.16.14[.0] ++ * 1.6.15beta01-08 16 10615 16.so.16.15[.0] ++ * 1.6.15rc01-03 16 10615 16.so.16.15[.0] ++ * 1.6.15 16 10615 16.so.16.15[.0] ++ * 1.6.16beta01-03 16 10616 16.so.16.16[.0] ++ * 1.6.16rc01-02 16 10616 16.so.16.16[.0] ++ * 1.6.16 16 10616 16.so.16.16[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be +@@ -194,7 +249,7 @@ + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public +- * release number plus "betaNN" or "rcN". ++ * release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled +@@ -216,8 +271,8 @@ + * + * This code is released under the libpng license. + * +- * libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are +- * Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are ++ * libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are ++ * Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.2.5 + * with the following individual added to the list of Contributing Authors: + * +@@ -328,28 +383,30 @@ + * Y2K compliance in libpng: + * ========================= + * +- * July 7, 2011 ++ * December 22, 2014 + * + * Since the PNG Development group is an ad-hoc body, we can't make + * an official declaration. + * + * This is your unofficial assurance that libpng from version 0.71 and +- * upward through 1.5.4 are Y2K compliant. It is my belief that ++ * upward through 1.6.16 are Y2K compliant. It is my belief that + * earlier versions were also Y2K compliant. + * + * Libpng only has two year fields. One is a 2-byte unsigned integer +- * that will hold years up to 65535. The other holds the date in text +- * format, and will hold years up to 9999. ++ * that will hold years up to 65535. The other, which is deprecated, ++ * holds the date in text format, and will hold years up to 9999. + * + * The integer is + * "png_uint_16 year" in png_time_struct. + * + * The string is +- * "png_char time_buffer" in png_struct ++ * "char time_buffer[29]" in png_struct. This is no longer used ++ * in libpng-1.6.x and will be removed from libpng-1.7.0. + * + * There are seven time-related functions: +- * png.c: png_convert_to_rfc_1123() in png.c +- * (formerly png_convert_to_rfc_1152() in error) ++ * png.c: png_convert_to_rfc_1123_buffer() in png.c ++ * (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and ++ * png_convert_to_rfc_1152() in error prior to libpng-0.98) + * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c + * png_convert_from_time_t() in pngwrite.c + * png_get_tIME() in pngget.c +@@ -360,8 +417,8 @@ + * All handle dates properly in a Y2K environment. The + * png_convert_from_time_t() function calls gmtime() to convert from system + * clock time, which returns (year - 1900), which we properly convert to +- * the full 4-digit year. There is a possibility that applications using +- * libpng are not passing 4-digit years into the png_convert_to_rfc_1123() ++ * the full 4-digit year. There is a possibility that libpng applications ++ * are not passing 4-digit years into the png_convert_to_rfc_1123_buffer() + * function, or that they are incorrectly passing only a 2-digit year + * instead of "year - 1900" into the png_convert_from_struct_tm() function, + * but this is not under our control. The libpng documentation has always +@@ -385,21 +442,27 @@ + /* This is not the place to learn how to use libpng. The file libpng-manual.txt + * describes how to use libpng, and the file example.c summarizes it + * with some code on which to build. This file is useful for looking +- * at the actual function definitions and structure components. ++ * at the actual function definitions and structure components. If that ++ * file has been stripped from your copy of libpng, you can find it at ++ * <http://www.libpng.org/pub/png/libpng-manual.txt> ++ * ++ * If you just need to read a PNG file and don't want to read the documentation ++ * skip to the end of this file and read the section entitled 'simplified API'. + */ + + /* Version information for png.h - this should match the version in png.c */ +-#define PNG_LIBPNG_VER_STRING "1.5.4" ++#define PNG_LIBPNG_VER_STRING "1.6.16" + #define PNG_HEADER_VERSION_STRING \ +- " libpng version 1.5.4 - July 7, 2011\n" +- +-#define PNG_LIBPNG_VER_SONUM 15 +-#define PNG_LIBPNG_VER_DLLNUM 15 ++ " libpng version 1.6.16 - December 22, 2014\n" ++ ++#define PNG_LIBPNG_VER_SONUM 16 ++#define PNG_LIBPNG_VER_DLLNUM 16 + + /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ + #define PNG_LIBPNG_VER_MAJOR 1 +-#define PNG_LIBPNG_VER_MINOR 5 +-#define PNG_LIBPNG_VER_RELEASE 4 ++#define PNG_LIBPNG_VER_MINOR 6 ++#define PNG_LIBPNG_VER_RELEASE 16 ++ + /* This should match the numeric part of the final component of + * PNG_LIBPNG_VER_STRING, omitting any leading zero: + */ +@@ -421,7 +484,7 @@ + #define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_PRIVATE */ + +-#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA ++#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE + + /* Careful here. At one time, Guy wanted to use 082, but that would be octal. + * We must not include leading zeros. +@@ -429,7 +492,7 @@ + * version 1.0.0 was mis-numbered 100 instead of 10000). From + * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release + */ +-#define PNG_LIBPNG_VER 10504 /* 1.5.4 */ ++#define PNG_LIBPNG_VER 10616 /* 1.6.16 */ + + /* Library configuration: these options cannot be changed after + * the library has been built. +@@ -442,25 +505,7 @@ + #endif + + #ifndef PNG_VERSION_INFO_ONLY +-# ifndef PNG_BUILDING_SYMBOL_TABLE +- /* +- * Standard header files (not needed for the version info or while +- * building symbol table -- see scripts/pnglibconf.dfa) +- */ +-# ifdef PNG_SETJMP_SUPPORTED +-# include <setjmp.h> +-# endif +- +- /* Need the time information for converting tIME chunks, it +- * defines struct tm: +- */ +-# ifdef PNG_CONVERT_tIME_SUPPORTED +- /* "time.h" functions are not supported on all operating systems */ +-# include <time.h> +-# endif +-# endif +- +-/* Machine specific configuration. */ ++ /* Machine specific configuration. */ + # include "pngconf.h" + #endif + +@@ -509,6 +554,7 @@ + * 2. Type definitions (base types are defined in pngconf.h), structure + * definitions. + * 3. Exported library functions. ++ * 4. Simplified API. + * + * The library source code has additional files (principally pngpriv.h) that + * allow configuration of the library. +@@ -551,7 +597,48 @@ + /* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +-typedef char* png_libpng_version_1_5_4; ++typedef char* png_libpng_version_1_6_16; ++ ++/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. ++ * ++ * png_struct is the cache of information used while reading or writing a single ++ * PNG file. One of these is always required, although the simplified API ++ * (below) hides the creation and destruction of it. ++ */ ++typedef struct png_struct_def png_struct; ++typedef const png_struct * png_const_structp; ++typedef png_struct * png_structp; ++typedef png_struct * * png_structpp; ++ ++/* png_info contains information read from or to be written to a PNG file. One ++ * or more of these must exist while reading or creating a PNG file. The ++ * information is not used by libpng during read but is used to control what ++ * gets written when a PNG file is created. "png_get_" function calls read ++ * information during read and "png_set_" functions calls write information ++ * when creating a PNG. ++ * been moved into a separate header file that is not accessible to ++ * applications. Read libpng-manual.txt or libpng.3 for more info. ++ */ ++typedef struct png_info_def png_info; ++typedef png_info * png_infop; ++typedef const png_info * png_const_infop; ++typedef png_info * * png_infopp; ++ ++/* Types with names ending 'p' are pointer types. The corresponding types with ++ * names ending 'rp' are identical pointer types except that the pointer is ++ * marked 'restrict', which means that it is the only pointer to the object ++ * passed to the function. Applications should not use the 'restrict' types; ++ * it is always valid to pass 'p' to a pointer with a function argument of the ++ * corresponding 'rp' type. Different compilers have different rules with ++ * regard to type matching in the presence of 'restrict'. For backward ++ * compatibility libpng callbacks never have 'restrict' in their parameters and, ++ * consequentially, writing portable application code is extremely difficult if ++ * an attempt is made to use 'restrict'. ++ */ ++typedef png_struct * PNG_RESTRICT png_structrp; ++typedef const png_struct * PNG_RESTRICT png_const_structrp; ++typedef png_info * PNG_RESTRICT png_inforp; ++typedef const png_info * PNG_RESTRICT png_const_inforp; + + /* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to +@@ -563,9 +650,9 @@ + png_byte green; + png_byte blue; + } png_color; +-typedef png_color FAR * png_colorp; +-typedef PNG_CONST png_color FAR * png_const_colorp; +-typedef png_color FAR * FAR * png_colorpp; ++typedef png_color * png_colorp; ++typedef const png_color * png_const_colorp; ++typedef png_color * * png_colorpp; + + typedef struct png_color_16_struct + { +@@ -575,9 +662,9 @@ + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ + } png_color_16; +-typedef png_color_16 FAR * png_color_16p; +-typedef PNG_CONST png_color_16 FAR * png_const_color_16p; +-typedef png_color_16 FAR * FAR * png_color_16pp; ++typedef png_color_16 * png_color_16p; ++typedef const png_color_16 * png_const_color_16p; ++typedef png_color_16 * * png_color_16pp; + + typedef struct png_color_8_struct + { +@@ -587,9 +674,9 @@ + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ + } png_color_8; +-typedef png_color_8 FAR * png_color_8p; +-typedef PNG_CONST png_color_8 FAR * png_const_color_8p; +-typedef png_color_8 FAR * FAR * png_color_8pp; ++typedef png_color_8 * png_color_8p; ++typedef const png_color_8 * png_const_color_8p; ++typedef png_color_8 * * png_color_8pp; + + /* + * The following two structures are used for the in-core representation +@@ -603,9 +690,9 @@ + png_uint_16 alpha; + png_uint_16 frequency; + } png_sPLT_entry; +-typedef png_sPLT_entry FAR * png_sPLT_entryp; +-typedef PNG_CONST png_sPLT_entry FAR * png_const_sPLT_entryp; +-typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; ++typedef png_sPLT_entry * png_sPLT_entryp; ++typedef const png_sPLT_entry * png_const_sPLT_entryp; ++typedef png_sPLT_entry * * png_sPLT_entrypp; + + /* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member +@@ -619,18 +706,27 @@ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ + } png_sPLT_t; +-typedef png_sPLT_t FAR * png_sPLT_tp; +-typedef PNG_CONST png_sPLT_t FAR * png_const_sPLT_tp; +-typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; ++typedef png_sPLT_t * png_sPLT_tp; ++typedef const png_sPLT_t * png_const_sPLT_tp; ++typedef png_sPLT_t * * png_sPLT_tpp; + + #ifdef PNG_TEXT_SUPPORTED + /* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field +- * points to a regular zero-terminated C string. The "text", "lang", and +- * "lang_key" fields can be regular C strings, empty strings, or NULL pointers. ++ * points to a regular zero-terminated C string. The "text" fields can be a ++ * regular C string, an empty string, or a NULL pointer. + * However, the structure returned by png_get_text() will always contain +- * regular zero-terminated C strings (possibly empty), never NULL pointers, +- * so they can be safely used in printf() and other string-handling functions. ++ * the "text" field as a regular zero-terminated C string (possibly ++ * empty), never a NULL pointer, so it can be safely used in printf() and ++ * other string-handling functions. Note that the "itxt_length", "lang", and ++ * "lang_key" members of the structure only exist when the library is built ++ * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by ++ * default without iTXt support. Also note that when iTXt *is* supported, ++ * the "lang" and "lang_key" fields contain NULL pointers when the ++ * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or ++ * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the ++ * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" ++ * which is always 0 or 1, or its "compression method" which is always 0. + */ + typedef struct png_text_struct + { +@@ -649,9 +745,9 @@ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ + } png_text; +-typedef png_text FAR * png_textp; +-typedef PNG_CONST png_text FAR * png_const_textp; +-typedef png_text FAR * FAR * png_textpp; ++typedef png_text * png_textp; ++typedef const png_text * png_const_textp; ++typedef png_text * * png_textpp; + #endif + + /* Supported compression types for text in PNG files (tEXt, and zTXt). +@@ -679,49 +775,45 @@ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ + } png_time; +-typedef png_time FAR * png_timep; +-typedef PNG_CONST png_time FAR * png_const_timep; +-typedef png_time FAR * FAR * png_timepp; +- +-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ +- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) ++typedef png_time * png_timep; ++typedef const png_time * png_const_timep; ++typedef png_time * * png_timepp; ++ ++#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ ++ defined(PNG_USER_CHUNKS_SUPPORTED) + /* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. ++ * ++ * The data in the structure is set by libpng on read and used on write. + */ + typedef struct png_unknown_chunk_t + { +- png_byte name[5]; +- png_byte *data; ++ png_byte name[5]; /* Textual chunk name with '\0' terminator */ ++ png_byte *data; /* Data, should not be modified on read! */ + png_size_t size; + +- /* libpng-using applications should NOT directly modify this byte. */ ++ /* On write 'location' must be set using the flag values listed below. ++ * Notice that on read it is set by libpng however the values stored have ++ * more bits set than are listed below. Always treat the value as a ++ * bitmask. On write set only one bit - setting multiple bits may cause the ++ * chunk to be written in multiple places. ++ */ + png_byte location; /* mode of operation at read time */ + } +- +- + png_unknown_chunk; +-typedef png_unknown_chunk FAR * png_unknown_chunkp; +-typedef PNG_CONST png_unknown_chunk FAR * png_const_unknown_chunkp; +-typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; ++ ++typedef png_unknown_chunk * png_unknown_chunkp; ++typedef const png_unknown_chunk * png_const_unknown_chunkp; ++typedef png_unknown_chunk * * png_unknown_chunkpp; + #endif + +-/* Values for the unknown chunk location byte */ +- ++/* Flag values for the unknown chunk location byte. */ + #define PNG_HAVE_IHDR 0x01 + #define PNG_HAVE_PLTE 0x02 + #define PNG_AFTER_IDAT 0x08 + +-/* The complete definition of png_info has, as of libpng-1.5.0, +- * been moved into a separate header file that is not accessible to +- * applications. Read libpng-manual.txt or libpng.3 for more info. +- */ +-typedef struct png_info_def png_info; +-typedef png_info FAR * png_infop; +-typedef PNG_CONST png_info FAR * png_const_infop; +-typedef png_info FAR * FAR * png_infopp; +- + /* Maximum positive integer used in PNG is (2^31)-1 */ + #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) + #define PNG_UINT_32_MAX ((png_uint_32)(-1)) +@@ -821,7 +913,7 @@ + #define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ + #define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ + #define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +-#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ ++#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */ + + /* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using +@@ -837,16 +929,8 @@ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ + } png_row_info; + +-typedef png_row_info FAR * png_row_infop; +-typedef png_row_info FAR * FAR * png_row_infopp; +- +-/* The complete definition of png_struct has, as of libpng-1.5.0, +- * been moved into a separate header file that is not accessible to +- * applications. Read libpng-manual.txt or libpng.3 for more info. +- */ +-typedef struct png_struct_def png_struct; +-typedef PNG_CONST png_struct FAR * png_const_structp; +-typedef png_struct FAR * png_structp; ++typedef png_row_info * png_row_infop; ++typedef png_row_info * * png_row_infopp; + + /* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her +@@ -893,7 +977,8 @@ + png_unknown_chunkp)); + #endif + #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +-typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); ++/* not used anywhere */ ++/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ + #endif + + #ifdef PNG_SETJMP_SUPPORTED +@@ -949,8 +1034,6 @@ + png_alloc_size_t)); + typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); + +-typedef png_struct FAR * FAR * png_structpp; +- + /* Section 3: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.txt for the +@@ -986,7 +1069,7 @@ + /* Tell lib we have already handled the first <num_bytes> magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +-PNG_EXPORT(2, void, png_set_sig_bytes, (png_structp png_ptr, int num_bytes)); ++PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); + + /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG +@@ -1014,9 +1097,9 @@ + PNG_ALLOCATED); + + PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, +- (png_const_structp png_ptr)); +- +-PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structp png_ptr, ++ (png_const_structrp png_ptr)); ++ ++PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, + png_size_t size)); + + /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp +@@ -1030,10 +1113,10 @@ + * allocated by the library - the call will return NULL on a mismatch + * indicating an ABI mismatch. + */ +-PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, ++PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, + png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); + # define png_jmpbuf(png_ptr) \ +- (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) ++ (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) + #else + # define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) +@@ -1043,12 +1126,12 @@ + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +-PNG_EXPORTA(9, void, png_longjmp, (png_structp png_ptr, int val), ++PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), + PNG_NORETURN); + + #ifdef PNG_READ_SUPPORTED + /* Reset the compression stream */ +-PNG_EXPORT(10, int, png_reset_zstream, (png_structp png_ptr)); ++PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); + #endif + + /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +@@ -1066,91 +1149,107 @@ + #endif + + /* Write the PNG file signature. */ +-PNG_EXPORT(13, void, png_write_sig, (png_structp png_ptr)); ++PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); + + /* Write a PNG chunk - size, type, (optional) data, CRC. */ +-PNG_EXPORT(14, void, png_write_chunk, (png_structp png_ptr, png_const_bytep ++PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, png_size_t length)); + + /* Write the start of a PNG chunk - length and chunk name. */ +-PNG_EXPORT(15, void, png_write_chunk_start, (png_structp png_ptr, ++PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); + + /* Write the data of a PNG chunk started with png_write_chunk_start(). */ +-PNG_EXPORT(16, void, png_write_chunk_data, (png_structp png_ptr, ++PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, + png_const_bytep data, png_size_t length)); + + /* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +-PNG_EXPORT(17, void, png_write_chunk_end, (png_structp png_ptr)); ++PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); + + /* Allocate and initialize the info structure */ +-PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_structp png_ptr), ++PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), + PNG_ALLOCATED); + +-PNG_EXPORT(19, void, png_info_init_3, (png_infopp info_ptr, +- png_size_t png_info_struct_size)); ++/* DEPRECATED: this function allowed init structures to be created using the ++ * default allocation method (typically malloc). Use is deprecated in 1.6.0 and ++ * the API will be removed in the future. ++ */ ++PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, ++ png_size_t png_info_struct_size), PNG_DEPRECATED); + + /* Writes all the PNG information before the image. */ + PNG_EXPORT(20, void, png_write_info_before_PLTE, +- (png_structp png_ptr, png_infop info_ptr)); ++ (png_structrp png_ptr, png_const_inforp info_ptr)); + PNG_EXPORT(21, void, png_write_info, +- (png_structp png_ptr, png_infop info_ptr)); ++ (png_structrp png_ptr, png_const_inforp info_ptr)); + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read the information before the actual image data. */ + PNG_EXPORT(22, void, png_read_info, +- (png_structp png_ptr, png_infop info_ptr)); ++ (png_structrp png_ptr, png_inforp info_ptr)); + #endif + + #ifdef PNG_TIME_RFC1123_SUPPORTED +-PNG_EXPORT(23, png_const_charp, png_convert_to_rfc1123, +- (png_structp png_ptr, ++ /* Convert to a US string format: there is no localization support in this ++ * routine. The original implementation used a 29 character buffer in ++ * png_struct, this will be removed in future versions. ++ */ ++#if PNG_LIBPNG_VER < 10700 ++/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ ++PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, ++ png_const_timep ptime),PNG_DEPRECATED); ++#endif ++PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], + png_const_timep ptime)); + #endif + + #ifdef PNG_CONVERT_tIME_SUPPORTED + /* Convert from a struct tm to png_time */ + PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, +- PNG_CONST struct tm FAR * ttime)); ++ const struct tm * ttime)); + + /* Convert from time_t to png_time. Uses gmtime() */ +-PNG_EXPORT(25, void, png_convert_from_time_t, +- (png_timep ptime, time_t ttime)); +-#endif /* PNG_CONVERT_tIME_SUPPORTED */ ++PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime)); ++#endif /* CONVERT_tIME */ + + #ifdef PNG_READ_EXPAND_SUPPORTED + /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +-PNG_EXPORT(26, void, png_set_expand, (png_structp png_ptr)); +-PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structp png_ptr)); +-PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structp png_ptr)); +-PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structp png_ptr)); ++PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); ++PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); ++PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); ++PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); + #endif + + #ifdef PNG_READ_EXPAND_16_SUPPORTED + /* Expand to 16-bit channels, forces conversion of palette to RGB and expansion + * of a tRNS chunk if present. + */ +-PNG_EXPORT(221, void, png_set_expand_16, (png_structp png_ptr)); ++PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) + /* Use blue, green, red order for pixels. */ +-PNG_EXPORT(30, void, png_set_bgr, (png_structp png_ptr)); ++PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); + #endif + + #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* Expand the grayscale to 24-bit RGB if necessary. */ +-PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structp png_ptr)); ++PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); + #endif + + #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Reduce RGB to grayscale. */ +-PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structp png_ptr, +- int error_action, double red, double green)); +-PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structp png_ptr, +- int error_action, png_fixed_point red, png_fixed_point green)); +- +-PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structp ++#define PNG_ERROR_ACTION_NONE 1 ++#define PNG_ERROR_ACTION_WARN 2 ++#define PNG_ERROR_ACTION_ERROR 3 ++#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ ++ ++PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, ++ int error_action, double red, double green)) ++PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, ++ int error_action, png_fixed_point red, png_fixed_point green)) ++ ++PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp + png_ptr)); + #endif + +@@ -1160,9 +1259,9 @@ + #endif + + #ifdef PNG_READ_ALPHA_MODE_SUPPORTED +-/* How the alpha channel is interpreted - this affects how the color channels of +- * a PNG file are returned when an alpha channel, or tRNS chunk in a palette +- * file, is present. ++/* How the alpha channel is interpreted - this affects how the color channels ++ * of a PNG file are returned to the calling application when an alpha channel, ++ * or a tRNS chunk in a palette file, is present. + * + * This has no effect on the way pixels are written into a PNG output + * datastream. The color samples in a PNG datastream are never premultiplied +@@ -1170,33 +1269,19 @@ + * + * The default is to return data according to the PNG specification: the alpha + * channel is a linear measure of the contribution of the pixel to the +- * corresponding composited pixel. The gamma encoded color channels must be +- * scaled according to the contribution and to do this it is necessary to undo ++ * corresponding composited pixel, and the color channels are unassociated ++ * (not premultiplied). The gamma encoded color channels must be scaled ++ * according to the contribution and to do this it is necessary to undo + * the encoding, scale the color values, perform the composition and reencode + * the values. This is the 'PNG' mode. + * + * The alternative is to 'associate' the alpha with the color information by +- * storing color channel values that have been scaled by the alpha. The +- * advantage is that the color channels can be resampled (the image can be +- * scaled) in this form. The disadvantage is that normal practice is to store +- * linear, not (gamma) encoded, values and this requires 16-bit channels for +- * still images rather than the 8-bit channels that are just about sufficient if +- * gamma encoding is used. In addition all non-transparent pixel values, +- * including completely opaque ones, must be gamma encoded to produce the final +- * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the +- * latter being the two common names for associated alpha color channels.) ++ * storing color channel values that have been scaled by the alpha. ++ * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes ++ * (the latter being the two common names for associated alpha color channels). + * +- * Since it is not necessary to perform arithmetic on opaque color values so +- * long as they are not to be resampled and are in the final color space it is +- * possible to optimize the handling of alpha by storing the opaque pixels in +- * the PNG format (adjusted for the output color space) while storing partially +- * opaque pixels in the standard, linear, format. The accuracy required for +- * standard alpha composition is relatively low, because the pixels are +- * isolated, therefore typically the accuracy loss in storing 8-bit linear +- * values is acceptable. (This is not true if the alpha channel is used to +- * simulate transparency over large areas - use 16 bits or the PNG mode in +- * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is +- * treated as opaque only if the alpha value is equal to the maximum value. ++ * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha ++ * value is equal to the maximum value. + * + * The final choice is to gamma encode the alpha channel as well. This is + * broken because, in practice, no implementation that uses this choice +@@ -1215,76 +1300,15 @@ + #define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ + #define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +-PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structp png_ptr, int mode, +- double output_gamma)); +-PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structp png_ptr, +- int mode, png_fixed_point output_gamma)); ++PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, ++ double output_gamma)) ++PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, ++ int mode, png_fixed_point output_gamma)) + #endif + +-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) ++#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* The output_gamma value is a screen gamma in libpng terminology: it expresses +- * how to decode the output values, not how they are encoded. The values used +- * correspond to the normal numbers used to describe the overall gamma of a +- * computer display system; for example 2.2 for an sRGB conformant system. The +- * values are scaled by 100000 in the _fixed version of the API (so 220000 for +- * sRGB.) +- * +- * The inverse of the value is always used to provide a default for the PNG file +- * encoding if it has no gAMA chunk and if png_set_gamma() has not been called +- * to override the PNG gamma information. +- * +- * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode +- * opaque pixels however pixels with lower alpha values are not encoded, +- * regardless of the output gamma setting. +- * +- * When the standard Porter Duff handling is requested with mode 1 the output +- * encoding is set to be linear and the output_gamma value is only relevant +- * as a default for input data that has no gamma information. The linear output +- * encoding will be overridden if png_set_gamma() is called - the results may be +- * highly unexpected! +- * +- * The following numbers are derived from the sRGB standard and the research +- * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of +- * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing +- * correction required to take account of any differences in the color +- * environment of the original scene and the intended display environment; the +- * value expresses how to *decode* the image for display, not how the original +- * data was *encoded*. +- * +- * sRGB provides a peg for the PNG standard by defining a viewing environment. +- * sRGB itself, and earlier TV standards, actually use a more complex transform +- * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is +- * limited to simple power laws.) By saying that an image for direct display on +- * an sRGB conformant system should be stored with a gAMA chunk value of 45455 +- * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification +- * makes it possible to derive values for other display systems and +- * environments. +- * +- * The Mac value is deduced from the sRGB based on an assumption that the actual +- * extra viewing correction used in early Mac display systems was implemented as +- * a power 1.45 lookup table. +- * +- * Any system where a programmable lookup table is used or where the behavior of +- * the final display device characteristics can be changed requires system +- * specific code to obtain the current characteristic. However this can be +- * difficult and most PNG gamma correction only requires an approximate value. +- * +- * By default, if png_set_alpha_mode() is not called, libpng assumes that all +- * values are unencoded, linear, values and that the output device also has a +- * linear characteristic. This is only very rarely correct - it is invariably +- * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the +- * default if you don't know what the right answer is! +- * +- * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS +- * 10.6) which used a correction table to implement a somewhat lower gamma on an +- * otherwise sRGB system. +- * +- * Both these values are reserved (not simple gamma values) in order to allow +- * more precise correction internally in the future. +- * +- * NOTE: the following values can be passed to either the fixed or floating +- * point APIs, but the floating point API will also accept floating point +- * values. ++ * how to decode the output values, not how they are encoded. + */ + #define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ + #define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ +@@ -1351,7 +1375,7 @@ + * + * When the default gamma of PNG files doesn't match the output gamma. + * If you have PNG files with no gamma information png_set_alpha_mode allows +- * you to provide a default gamma, but it also sets the output gamma to the ++ * you to provide a default gamma, but it also sets the ouput gamma to the + * matching value. If you know your PNG files have a gamma that doesn't + * match the output you can take advantage of the fact that + * png_set_alpha_mode always sets the output gamma but only sets the PNG +@@ -1369,51 +1393,50 @@ + */ + + #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +-PNG_EXPORT(36, void, png_set_strip_alpha, (png_structp png_ptr)); ++PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +-PNG_EXPORT(37, void, png_set_swap_alpha, (png_structp png_ptr)); ++PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +-PNG_EXPORT(38, void, png_set_invert_alpha, (png_structp png_ptr)); ++PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) + /* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +-PNG_EXPORT(39, void, png_set_filler, (png_structp png_ptr, png_uint_32 filler, ++PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, + int flags)); + /* The values of the PNG_FILLER_ defines should NOT be changed */ + # define PNG_FILLER_BEFORE 0 + # define PNG_FILLER_AFTER 1 + /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +-PNG_EXPORT(40, void, png_set_add_alpha, +- (png_structp png_ptr, png_uint_32 filler, +- int flags)); +-#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ ++PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, ++ png_uint_32 filler, int flags)); ++#endif /* READ_FILLER || WRITE_FILLER */ + + #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) + /* Swap bytes in 16-bit depth files. */ +-PNG_EXPORT(41, void, png_set_swap, (png_structp png_ptr)); ++PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) + /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +-PNG_EXPORT(42, void, png_set_packing, (png_structp png_ptr)); ++PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) + /* Swap packing order of pixels in bytes. */ +-PNG_EXPORT(43, void, png_set_packswap, (png_structp png_ptr)); ++PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + /* Converts files to legal bit depths. */ +-PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_color_8p ++PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p + true_bits)); + #endif + +@@ -1425,12 +1448,12 @@ + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. + */ +-PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr)); ++PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); + #endif + + #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) + /* Invert monochrome files */ +-PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr)); ++PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); + #endif + + #ifdef PNG_READ_BACKGROUND_SUPPORTED +@@ -1439,12 +1462,12 @@ + * read. Doing so will result in unexpected behavior and possible warnings or + * errors if the PNG file contains a bKGD chunk. + */ +-PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr, ++PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, +- int need_expand, double background_gamma)); +-PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr, ++ int need_expand, double background_gamma)) ++PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, +- int need_expand, png_fixed_point background_gamma)); ++ int need_expand, png_fixed_point background_gamma)) + #endif + #ifdef PNG_READ_BACKGROUND_SUPPORTED + # define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +@@ -1455,23 +1478,22 @@ + + #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + /* Scale a 16-bit depth file down to 8-bit, accurately. */ +-PNG_EXPORT(229, void, png_set_scale_16, (png_structp png_ptr)); ++PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); + #endif + + #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + #define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */ + /* Strip the second byte of information from a 16-bit depth file. */ +-PNG_EXPORT(48, void, png_set_strip_16, (png_structp png_ptr)); ++PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); + #endif + + #ifdef PNG_READ_QUANTIZE_SUPPORTED + /* Turn on quantizing, and reduce the palette to the number of colors + * available. + */ +-PNG_EXPORT(49, void, png_set_quantize, +- (png_structp png_ptr, png_colorp palette, +- int num_palette, int maximum_colors, png_const_uint_16p histogram, +- int full_quantize)); ++PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, ++ png_colorp palette, int num_palette, int maximum_colors, ++ png_const_uint_16p histogram, int full_quantize)); + #endif + + #ifdef PNG_READ_GAMMA_SUPPORTED +@@ -1491,71 +1513,69 @@ + * API (floating point or fixed.) Notice, however, that the 'file_gamma' value + * is the inverse of a 'screen gamma' value. + */ +-PNG_FP_EXPORT(50, void, png_set_gamma, +- (png_structp png_ptr, double screen_gamma, +- double override_file_gamma)); +-PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structp png_ptr, +- png_fixed_point screen_gamma, png_fixed_point override_file_gamma)); ++PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, ++ double screen_gamma, double override_file_gamma)) ++PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, ++ png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) + #endif + + #ifdef PNG_WRITE_FLUSH_SUPPORTED + /* Set how many lines between output flushes - 0 for no flushing */ +-PNG_EXPORT(51, void, png_set_flush, (png_structp png_ptr, int nrows)); ++PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows)); + /* Flush the current PNG output buffer */ +-PNG_EXPORT(52, void, png_write_flush, (png_structp png_ptr)); ++PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); + #endif + + /* Optional update palette with requested transformations */ +-PNG_EXPORT(53, void, png_start_read_image, (png_structp png_ptr)); ++PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); + + /* Optional call to update the users info structure */ +-PNG_EXPORT(54, void, png_read_update_info, +- (png_structp png_ptr, png_infop info_ptr)); ++PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, ++ png_inforp info_ptr)); + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read one or more rows of image data. */ +-PNG_EXPORT(55, void, png_read_rows, (png_structp png_ptr, png_bytepp row, ++PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); + #endif + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read a row of data. */ +-PNG_EXPORT(56, void, png_read_row, (png_structp png_ptr, png_bytep row, ++PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, + png_bytep display_row)); + #endif + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read the whole image into memory at once. */ +-PNG_EXPORT(57, void, png_read_image, (png_structp png_ptr, png_bytepp image)); ++PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); + #endif + + /* Write a row of image data */ +-PNG_EXPORT(58, void, png_write_row, +- (png_structp png_ptr, png_const_bytep row)); ++PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, ++ png_const_bytep row)); + + /* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +-PNG_EXPORT(59, void, png_write_rows, (png_structp png_ptr, png_bytepp row, ++PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, + png_uint_32 num_rows)); + + /* Write the image data */ +-PNG_EXPORT(60, void, png_write_image, +- (png_structp png_ptr, png_bytepp image)); ++PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); + + /* Write the end of the PNG file. */ +-PNG_EXPORT(61, void, png_write_end, +- (png_structp png_ptr, png_infop info_ptr)); ++PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, ++ png_inforp info_ptr)); + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read the end of the PNG file. */ +-PNG_EXPORT(62, void, png_read_end, (png_structp png_ptr, png_infop info_ptr)); ++PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); + #endif + + /* Free any memory associated with the png_info_struct */ +-PNG_EXPORT(63, void, png_destroy_info_struct, (png_structp png_ptr, ++PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, + png_infopp info_ptr_ptr)); + + /* Free any memory associated with the png_struct and the png_info_structs */ +@@ -1567,8 +1587,8 @@ + png_infopp info_ptr_ptr)); + + /* Set the libpng method of handling chunk CRC errors */ +-PNG_EXPORT(66, void, png_set_crc_action, +- (png_structp png_ptr, int crit_action, int ancil_action)); ++PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, ++ int ancil_action)); + + /* Values for png_set_crc_action() say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained +@@ -1597,8 +1617,8 @@ + /* Set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +-PNG_EXPORT(67, void, png_set_filter, +- (png_structp png_ptr, int method, int filters)); ++PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, ++ int filters)); + + /* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types +@@ -1653,14 +1673,14 @@ + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +-PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structp png_ptr, ++PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, + int heuristic_method, int num_weights, png_const_doublep filter_weights, +- png_const_doublep filter_costs)); ++ png_const_doublep filter_costs)) + PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, +- (png_structp png_ptr, +- int heuristic_method, int num_weights, png_const_fixed_point_p +- filter_weights, png_const_fixed_point_p filter_costs)); +-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ ++ (png_structrp png_ptr, int heuristic_method, int num_weights, ++ png_const_fixed_point_p filter_weights, ++ png_const_fixed_point_p filter_costs)) ++#endif /* WRITE_WEIGHTED_FILTER */ + + /* Heuristic used for row filter selection. These defines should NOT be + * changed. +@@ -1678,45 +1698,45 @@ + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +-PNG_EXPORT(69, void, png_set_compression_level, +- (png_structp png_ptr, int level)); +- +-PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structp png_ptr, ++PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr, ++ int level)); ++ ++PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +-PNG_EXPORT(71, void, png_set_compression_strategy, (png_structp png_ptr, ++PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr, + int strategy)); + + /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +-PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structp png_ptr, ++PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr, + int window_bits)); + +-PNG_EXPORT(73, void, png_set_compression_method, (png_structp png_ptr, ++PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr, + int method)); + #endif + + #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + /* Also set zlib parameters for compressing non-IDAT chunks */ +-PNG_EXPORT(222, void, png_set_text_compression_level, +- (png_structp png_ptr, int level)); +- +-PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structp png_ptr, ++PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr, ++ int level)); ++ ++PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, + int mem_level)); + +-PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structp png_ptr, ++PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, + int strategy)); + + /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +-PNG_EXPORT(225, void, png_set_text_compression_window_bits, (png_structp +- png_ptr, int window_bits)); +- +-PNG_EXPORT(226, void, png_set_text_compression_method, (png_structp png_ptr, ++PNG_EXPORT(225, void, png_set_text_compression_window_bits, ++ (png_structrp png_ptr, int window_bits)); ++ ++PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, + int method)); +-#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ ++#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ + + /* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, +@@ -1729,7 +1749,7 @@ + + #ifdef PNG_STDIO_SUPPORTED + /* Initialize the input/output for the PNG file to the default functions. */ +-PNG_EXPORT(74, void, png_init_io, (png_structp png_ptr, png_FILE_p fp)); ++PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); + #endif + + /* Replace the (error and abort), and warning functions with user +@@ -1740,12 +1760,11 @@ + * default function will be used. + */ + +-PNG_EXPORT(75, void, png_set_error_fn, +- (png_structp png_ptr, png_voidp error_ptr, +- png_error_ptr error_fn, png_error_ptr warning_fn)); ++PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, ++ png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + + /* Return the user pointer associated with the error functions */ +-PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structp png_ptr)); ++PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); + + /* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. +@@ -1757,47 +1776,47 @@ + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +-PNG_EXPORT(77, void, png_set_write_fn, (png_structp png_ptr, png_voidp io_ptr, ++PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + + /* Replace the default data input function with a user supplied one. */ +-PNG_EXPORT(78, void, png_set_read_fn, (png_structp png_ptr, png_voidp io_ptr, ++PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn)); + + /* Return the user pointer associated with the I/O functions */ +-PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_structp png_ptr)); +- +-PNG_EXPORT(80, void, png_set_read_status_fn, (png_structp png_ptr, ++PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); ++ ++PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, + png_read_status_ptr read_row_fn)); + +-PNG_EXPORT(81, void, png_set_write_status_fn, (png_structp png_ptr, ++PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, + png_write_status_ptr write_row_fn)); + + #ifdef PNG_USER_MEM_SUPPORTED + /* Replace the default memory allocation functions with user supplied one(s). */ +-PNG_EXPORT(82, void, png_set_mem_fn, (png_structp png_ptr, png_voidp mem_ptr, ++PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); + /* Return the user pointer associated with the memory functions */ +-PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structp png_ptr)); ++PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); + #endif + + #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +-PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structp png_ptr, ++PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr read_user_transform_fn)); + #endif + + #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +-PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structp png_ptr, ++PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, + png_user_transform_ptr write_user_transform_fn)); + #endif + + #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +-PNG_EXPORT(86, void, png_set_user_transform_info, (png_structp png_ptr, ++PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, + png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); + /* Return the user pointer associated with the user transform functions */ + PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + #endif + + #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +@@ -1812,31 +1831,53 @@ + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +-PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structp)); +-PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structp)); ++PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); ++PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); + #endif + ++#ifdef PNG_READ_USER_CHUNKS_SUPPORTED ++/* This callback is called only for *unknown* chunks. If ++ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known ++ * chunks to be treated as unknown, however in this case the callback must do ++ * any processing required by the chunk (e.g. by calling the appropriate ++ * png_set_ APIs.) ++ * ++ * There is no write support - on write, by default, all the chunks in the ++ * 'unknown' list are written in the specified position. ++ * ++ * The integer return from the callback function is interpreted thus: ++ * ++ * negative: An error occured, png_chunk_error will be called. ++ * zero: The chunk was not handled, the chunk will be saved. A critical ++ * chunk will cause an error at this point unless it is to be saved. ++ * positive: The chunk was handled, libpng will ignore/discard it. ++ * ++ * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about ++ * how this behavior will change in libpng 1.7 ++ */ ++PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, ++ png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); ++#endif ++ + #ifdef PNG_USER_CHUNKS_SUPPORTED +-PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structp png_ptr, +- png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +-PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structp png_ptr)); ++PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); + #endif + + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED + /* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +-PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structp png_ptr, ++PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, + png_voidp progressive_ptr, png_progressive_info_ptr info_fn, + png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); + + /* Returns the user pointer associated with the push read functions */ +-PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, (png_const_structp png_ptr)); ++PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, ++ (png_const_structrp png_ptr)); + + /* Function to be called when data becomes available */ +-PNG_EXPORT(92, void, png_process_data, +- (png_structp png_ptr, png_infop info_ptr, +- png_bytep buffer, png_size_t buffer_size)); ++PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, ++ png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size)); + + /* A function which may be called *only* within png_process_data to stop the + * processing of any more data. The function returns the number of bytes +@@ -1845,7 +1886,7 @@ + * 'save' is set to true the routine will first save all the pending data and + * will always return 0. + */ +-PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structp, int save)); ++PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save)); + + /* A function which may be called *only* outside (after) a call to + * png_process_data. It returns the number of bytes of data to skip in the +@@ -1853,40 +1894,43 @@ + * application must skip than number of bytes of input data and pass the + * following data to the next call to png_process_data. + */ +-PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp)); ++PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); + + /* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. + */ +-PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr, ++PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, + png_bytep old_row, png_const_bytep new_row)); +-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ +- +-PNG_EXPORTA(94, png_voidp, png_malloc, +- (png_structp png_ptr, png_alloc_size_t size), +- PNG_ALLOCATED); ++#endif /* PROGRESSIVE_READ */ ++ ++PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, ++ png_alloc_size_t size), PNG_ALLOCATED); + /* Added at libpng version 1.4.0 */ +-PNG_EXPORTA(95, png_voidp, png_calloc, +- (png_structp png_ptr, png_alloc_size_t size), +- PNG_ALLOCATED); ++PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, ++ png_alloc_size_t size), PNG_ALLOCATED); + + /* Added at libpng version 1.2.4 */ +-PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_structp png_ptr, ++PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); + + /* Frees a pointer allocated by png_malloc() */ +-PNG_EXPORT(97, void, png_free, (png_structp png_ptr, png_voidp ptr)); ++PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); + + /* Free data that was allocated internally */ +-PNG_EXPORT(98, void, png_free_data, +- (png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); ++PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 free_me, int num)); + + /* Reassign responsibility for freeing existing data, whether allocated +- * by libpng or by the application */ +-PNG_EXPORT(99, void, png_data_freer, +- (png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); ++ * by libpng or by the application; this works on the png_info structure passed ++ * in, it does not change the state for other png_info structures. ++ * ++ * It is unlikely that this function works correctly as of 1.6.0 and using it ++ * may result either in memory leaks or double free of allocated data. ++ */ ++PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, ++ png_inforp info_ptr, int freer, png_uint_32 mask)); + + /* Assignments for png_data_freer */ + #define PNG_DESTROY_WILL_FREE_DATA 1 +@@ -1899,8 +1943,10 @@ + #define PNG_FREE_ROWS 0x0040 + #define PNG_FREE_PCAL 0x0080 + #define PNG_FREE_SCAL 0x0100 +-#define PNG_FREE_UNKN 0x0200 +-#define PNG_FREE_LIST 0x0400 ++#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED ++# define PNG_FREE_UNKN 0x0200 ++#endif ++/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */ + #define PNG_FREE_PLTE 0x1000 + #define PNG_FREE_TRNS 0x2000 + #define PNG_FREE_TEXT 0x4000 +@@ -1908,50 +1954,55 @@ + #define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + + #ifdef PNG_USER_MEM_SUPPORTED +-PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_structp png_ptr, +- png_alloc_size_t size), PNG_ALLOCATED); +-PNG_EXPORT(101, void, png_free_default, (png_structp png_ptr, png_voidp ptr)); ++PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, ++ png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); ++PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, ++ png_voidp ptr), PNG_DEPRECATED); + #endif + + #ifdef PNG_ERROR_TEXT_SUPPORTED + /* Fatal error in PNG image of libpng - can't continue */ +-PNG_EXPORTA(102, void, png_error, +- (png_structp png_ptr, png_const_charp error_message), +- PNG_NORETURN); ++PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, ++ png_const_charp error_message), PNG_NORETURN); + + /* The same, but the chunk name is prepended to the error string. */ +-PNG_EXPORTA(103, void, png_chunk_error, (png_structp png_ptr, ++PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, + png_const_charp error_message), PNG_NORETURN); + + #else + /* Fatal error in PNG image of libpng - can't continue */ +-PNG_EXPORTA(104, void, png_err, (png_structp png_ptr), PNG_NORETURN); ++PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); ++# define png_error(s1,s2) png_err(s1) ++# define png_chunk_error(s1,s2) png_err(s1) + #endif + + #ifdef PNG_WARNINGS_SUPPORTED + /* Non-fatal error in libpng. Can continue, but may have a problem. */ +-PNG_EXPORT(105, void, png_warning, (png_structp png_ptr, ++PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); + + /* Non-fatal error in libpng, chunk name is prepended to message. */ +-PNG_EXPORT(106, void, png_chunk_warning, (png_structp png_ptr, ++PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, + png_const_charp warning_message)); ++#else ++# define png_warning(s1,s2) ((void)(s1)) ++# define png_chunk_warning(s1,s2) ((void)(s1)) + #endif + + #ifdef PNG_BENIGN_ERRORS_SUPPORTED + /* Benign error in libpng. Can continue, but may have a problem. + * User can choose whether to handle as a fatal error or as a warning. */ +-# undef png_benign_error +-PNG_EXPORT(107, void, png_benign_error, (png_structp png_ptr, ++PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); + +-/* Same, chunk name is prepended to message. */ +-# undef png_chunk_benign_error +-PNG_EXPORT(108, void, png_chunk_benign_error, (png_structp png_ptr, ++#ifdef PNG_READ_SUPPORTED ++/* Same, chunk name is prepended to message (only during read) */ ++PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, + png_const_charp warning_message)); ++#endif + + PNG_EXPORT(109, void, png_set_benign_errors, +- (png_structp png_ptr, int allowed)); ++ (png_structrp png_ptr, int allowed)); + #else + # ifdef PNG_ALLOW_BENIGN_ERRORS + # define png_benign_error png_warning +@@ -1975,268 +2026,274 @@ + * png_info_struct. + */ + /* Returns "flag" if chunk data is valid in info_ptr. */ +-PNG_EXPORT(110, png_uint_32, png_get_valid, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_uint_32 flag)); ++PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, png_uint_32 flag)); + + /* Returns number of bytes needed to hold a transformed row. */ +-PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + #ifdef PNG_INFO_IMAGE_SUPPORTED + /* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +-PNG_EXPORT(112, png_bytepp, png_get_rows, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); ++ + /* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +-PNG_EXPORT(113, void, png_set_rows, (png_structp png_ptr, +- png_infop info_ptr, png_bytepp row_pointers)); ++PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_bytepp row_pointers)); + #endif + + /* Returns number of color channels in image. */ +-PNG_EXPORT(114, png_byte, png_get_channels, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + #ifdef PNG_EASY_ACCESS_SUPPORTED + /* Returns image width in pixels. */ +-PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + /* Returns image height in pixels. */ +-PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + /* Returns image bit_depth. */ +-PNG_EXPORT(117, png_byte, png_get_bit_depth, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + /* Returns image color_type. */ +-PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + /* Returns image filter_type. */ +-PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + /* Returns image interlace_type. */ +-PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + /* Returns image compression_type. */ +-PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); + + /* Returns image resolution in pixels per meter, from pHYs chunk data. */ + PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + + /* Returns pixel aspect ratio, computed from pHYs chunk data. */ + PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)) + PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)) + + /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ + PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, +- (png_const_structp png_ptr, png_const_infop info_ptr)); +- +-#endif /* PNG_EASY_ACCESS_SUPPORTED */ +- ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); ++ ++#endif /* EASY_ACCESS */ ++ ++#ifdef PNG_READ_SUPPORTED + /* Returns pointer to signature string read from PNG header */ +-PNG_EXPORT(130, png_const_bytep, png_get_signature, +- (png_const_structp png_ptr, png_infop info_ptr)); ++PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)); ++#endif + + #ifdef PNG_bKGD_SUPPORTED +-PNG_EXPORT(131, png_uint_32, png_get_bKGD, +- (png_const_structp png_ptr, png_infop info_ptr, +- png_color_16p *background)); ++PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_color_16p *background)); + #endif + + #ifdef PNG_bKGD_SUPPORTED +-PNG_EXPORT(132, void, png_set_bKGD, (png_structp png_ptr, png_infop info_ptr, +- png_const_color_16p background)); ++PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_color_16p background)); + #endif + + #ifdef PNG_cHRM_SUPPORTED +-PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structp png_ptr, +- png_const_infop info_ptr, double *white_x, double *white_y, double *red_x, ++PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, +- double *blue_y)); +-#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */ ++ double *blue_y)) ++PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, ++ double *green_X, double *green_Y, double *green_Z, double *blue_X, ++ double *blue_Y, double *blue_Z)) + PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, +- (png_const_structp png_ptr, +- png_const_infop info_ptr, png_fixed_point *int_white_x, +- png_fixed_point *int_white_y, png_fixed_point *int_red_x, +- png_fixed_point *int_red_y, png_fixed_point *int_green_x, +- png_fixed_point *int_green_y, png_fixed_point *int_blue_x, +- png_fixed_point *int_blue_y)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr, ++ png_fixed_point *int_white_x, png_fixed_point *int_white_y, ++ png_fixed_point *int_red_x, png_fixed_point *int_red_y, ++ png_fixed_point *int_green_x, png_fixed_point *int_green_y, ++ png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) ++PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, ++ (png_const_structrp png_ptr, png_const_inforp info_ptr, ++ png_fixed_point *int_red_X, png_fixed_point *int_red_Y, ++ png_fixed_point *int_red_Z, png_fixed_point *int_green_X, ++ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, ++ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, ++ png_fixed_point *int_blue_Z)) + #endif +-#endif + + #ifdef PNG_cHRM_SUPPORTED +-PNG_FP_EXPORT(135, void, png_set_cHRM, +- (png_structp png_ptr, png_infop info_ptr, ++PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, ++ png_inforp info_ptr, + double white_x, double white_y, double red_x, double red_y, double green_x, +- double green_y, double blue_x, double blue_y)); +-PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr, +- png_infop info_ptr, png_fixed_point int_white_x, ++ double green_y, double blue_x, double blue_y)) ++PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, ++ png_inforp info_ptr, double red_X, double red_Y, double red_Z, ++ double green_X, double green_Y, double green_Z, double blue_X, ++ double blue_Y, double blue_Z)) ++PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_fixed_point int_white_x, + png_fixed_point int_white_y, png_fixed_point int_red_x, + png_fixed_point int_red_y, png_fixed_point int_green_x, + png_fixed_point int_green_y, png_fixed_point int_blue_x, +- png_fixed_point int_blue_y)); ++ png_fixed_point int_blue_y)) ++PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, ++ png_fixed_point int_red_Z, png_fixed_point int_green_X, ++ png_fixed_point int_green_Y, png_fixed_point int_green_Z, ++ png_fixed_point int_blue_X, png_fixed_point int_blue_Y, ++ png_fixed_point int_blue_Z)) + #endif + + #ifdef PNG_gAMA_SUPPORTED +-PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- double *file_gamma)); ++PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, double *file_gamma)) + PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_fixed_point *int_file_gamma)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr, ++ png_fixed_point *int_file_gamma)) + #endif + + #ifdef PNG_gAMA_SUPPORTED +-PNG_FP_EXPORT(139, void, png_set_gAMA, (png_structp png_ptr, +- png_infop info_ptr, double file_gamma)); +-PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_structp png_ptr, +- png_infop info_ptr, png_fixed_point int_file_gamma)); ++PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, ++ png_inforp info_ptr, double file_gamma)) ++PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_fixed_point int_file_gamma)) + #endif + + #ifdef PNG_hIST_SUPPORTED +-PNG_EXPORT(141, png_uint_32, png_get_hIST, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_uint_16p *hist)); ++PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_uint_16p *hist)); + #endif + + #ifdef PNG_hIST_SUPPORTED +-PNG_EXPORT(142, void, png_set_hIST, (png_structp png_ptr, +- png_infop info_ptr, png_const_uint_16p hist)); ++PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_uint_16p hist)); + #endif + +-PNG_EXPORT(143, png_uint_32, png_get_IHDR, +- (png_structp png_ptr, png_infop info_ptr, +- png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, +- int *interlace_method, int *compression_method, int *filter_method)); +- +-PNG_EXPORT(144, void, png_set_IHDR, +- (png_structp png_ptr, png_infop info_ptr, +- png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, +- int interlace_method, int compression_method, int filter_method)); ++PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, ++ int *bit_depth, int *color_type, int *interlace_method, ++ int *compression_method, int *filter_method)); ++ ++PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, ++ int color_type, int interlace_method, int compression_method, ++ int filter_method)); + + #ifdef PNG_oFFs_SUPPORTED +-PNG_EXPORT(145, png_uint_32, png_get_oFFs, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); ++PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, ++ int *unit_type)); + #endif + + #ifdef PNG_oFFs_SUPPORTED +-PNG_EXPORT(146, void, png_set_oFFs, +- (png_structp png_ptr, png_infop info_ptr, +- png_int_32 offset_x, png_int_32 offset_y, int unit_type)); ++PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, ++ int unit_type)); + #endif + + #ifdef PNG_pCAL_SUPPORTED +-PNG_EXPORT(147, png_uint_32, png_get_pCAL, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, +- int *nparams, +- png_charp *units, png_charpp *params)); ++PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, ++ png_int_32 *X1, int *type, int *nparams, png_charp *units, ++ png_charpp *params)); + #endif + + #ifdef PNG_pCAL_SUPPORTED +-PNG_EXPORT(148, void, png_set_pCAL, (png_structp png_ptr, +- png_infop info_ptr, +- png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, +- int nparams, png_const_charp units, png_charpp params)); ++PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, ++ int type, int nparams, png_const_charp units, png_charpp params)); + #endif + + #ifdef PNG_pHYs_SUPPORTED +-PNG_EXPORT(149, png_uint_32, png_get_pHYs, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); ++PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, ++ int *unit_type)); + #endif + + #ifdef PNG_pHYs_SUPPORTED +-PNG_EXPORT(150, void, png_set_pHYs, +- (png_structp png_ptr, png_infop info_ptr, +- png_uint_32 res_x, png_uint_32 res_y, int unit_type)); ++PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); + #endif + +-PNG_EXPORT(151, png_uint_32, png_get_PLTE, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_colorp *palette, int *num_palette)); +- +-PNG_EXPORT(152, void, png_set_PLTE, +- (png_structp png_ptr, png_infop info_ptr, +- png_const_colorp palette, int num_palette)); ++PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_colorp *palette, int *num_palette)); ++ ++PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, ++ png_inforp info_ptr, png_const_colorp palette, int num_palette)); + + #ifdef PNG_sBIT_SUPPORTED +-PNG_EXPORT(153, png_uint_32, png_get_sBIT, +- (png_const_structp png_ptr, png_infop info_ptr, +- png_color_8p *sig_bit)); ++PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_color_8p *sig_bit)); + #endif + + #ifdef PNG_sBIT_SUPPORTED +-PNG_EXPORT(154, void, png_set_sBIT, +- (png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit)); ++PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_color_8p sig_bit)); + #endif + + #ifdef PNG_sRGB_SUPPORTED +-PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structp png_ptr, +- png_const_infop info_ptr, int *file_srgb_intent)); ++PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, int *file_srgb_intent)); + #endif + + #ifdef PNG_sRGB_SUPPORTED +-PNG_EXPORT(156, void, png_set_sRGB, +- (png_structp png_ptr, png_infop info_ptr, int srgb_intent)); +-PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_structp png_ptr, +- png_infop info_ptr, int srgb_intent)); ++PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, ++ png_inforp info_ptr, int srgb_intent)); ++PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, ++ png_inforp info_ptr, int srgb_intent)); + #endif + + #ifdef PNG_iCCP_SUPPORTED +-PNG_EXPORT(158, png_uint_32, png_get_iCCP, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_charpp name, int *compression_type, png_bytepp profile, +- png_uint_32 *proflen)); ++PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_charpp name, int *compression_type, ++ png_bytepp profile, png_uint_32 *proflen)); + #endif + + #ifdef PNG_iCCP_SUPPORTED +-PNG_EXPORT(159, void, png_set_iCCP, +- (png_structp png_ptr, png_infop info_ptr, +- png_const_charp name, int compression_type, png_const_bytep profile, +- png_uint_32 proflen)); ++PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_charp name, int compression_type, ++ png_const_bytep profile, png_uint_32 proflen)); + #endif + + #ifdef PNG_sPLT_SUPPORTED +-PNG_EXPORT(160, png_uint_32, png_get_sPLT, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_sPLT_tpp entries)); ++PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_sPLT_tpp entries)); + #endif + + #ifdef PNG_sPLT_SUPPORTED +-PNG_EXPORT(161, void, png_set_sPLT, +- (png_structp png_ptr, png_infop info_ptr, +- png_const_sPLT_tp entries, int nentries)); ++PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); + #endif + + #ifdef PNG_TEXT_SUPPORTED + /* png_get_text also returns the number of text chunks in *num_text */ +-PNG_EXPORT(162, png_uint_32, png_get_text, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- png_textp *text_ptr, int *num_text)); ++PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_textp *text_ptr, int *num_text)); + #endif + + /* Note while png_set_text() will accept a structure whose text, +@@ -2247,116 +2304,220 @@ + */ + + #ifdef PNG_TEXT_SUPPORTED +-PNG_EXPORT(163, void, png_set_text, +- (png_structp png_ptr, png_infop info_ptr, +- png_const_textp text_ptr, int num_text)); ++PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_textp text_ptr, int num_text)); + #endif + + #ifdef PNG_tIME_SUPPORTED +-PNG_EXPORT(164, png_uint_32, png_get_tIME, +- (png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); ++PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_timep *mod_time)); + #endif + + #ifdef PNG_tIME_SUPPORTED +-PNG_EXPORT(165, void, png_set_tIME, +- (png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)); ++PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_timep mod_time)); + #endif + + #ifdef PNG_tRNS_SUPPORTED +-PNG_EXPORT(166, png_uint_32, png_get_tRNS, +- (png_const_structp png_ptr, png_infop info_ptr, +- png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)); ++PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, ++ png_color_16p *trans_color)); + #endif + + #ifdef PNG_tRNS_SUPPORTED +-PNG_EXPORT(167, void, png_set_tRNS, +- (png_structp png_ptr, png_infop info_ptr, +- png_const_bytep trans_alpha, int num_trans, ++PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, ++ png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); + #endif + + #ifdef PNG_sCAL_SUPPORTED +-PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- int *unit, double *width, double *height)); +-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED ++PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, int *unit, double *width, double *height)) ++#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ ++ defined(PNG_FLOATING_POINT_SUPPORTED) + /* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ + PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, +- (png_structp png_ptr, png_const_infop info_ptr, int *unit, +- png_fixed_point *width, +- png_fixed_point *height)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, ++ png_fixed_point *width, png_fixed_point *height)) + #endif + PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, +- (png_const_structp png_ptr, png_const_infop info_ptr, +- int *unit, png_charpp swidth, png_charpp sheight)); +- +-PNG_FP_EXPORT(170, void, png_set_sCAL, +- (png_structp png_ptr, png_infop info_ptr, +- int unit, double width, double height)); +-PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_structp png_ptr, +- png_infop info_ptr, int unit, png_fixed_point width, +- png_fixed_point height)); +-PNG_EXPORT(171, void, png_set_sCAL_s, +- (png_structp png_ptr, png_infop info_ptr, +- int unit, png_const_charp swidth, png_const_charp sheight)); +-#endif /* PNG_sCAL_SUPPORTED */ +- +-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +-/* Provide a list of chunks and how they are to be handled, if the built-in +- handling or default unknown chunk handling is not desired. Any chunks not +- listed will be handled in the default manner. The IHDR and IEND chunks +- must not be listed. +- keep = 0: follow default behaviour +- = 1: do not keep +- = 2: keep only if safe-to-copy +- = 3: keep even if unsafe-to-copy +-*/ +-PNG_EXPORT(172, void, png_set_keep_unknown_chunks, +- (png_structp png_ptr, int keep, +- png_const_bytep chunk_list, int num_chunks)); +-PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, ++ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, ++ png_charpp swidth, png_charpp sheight)); ++ ++PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, ++ png_inforp info_ptr, int unit, double width, double height)) ++PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, ++ png_inforp info_ptr, int unit, png_fixed_point width, ++ png_fixed_point height)) ++PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, ++ png_inforp info_ptr, int unit, ++ png_const_charp swidth, png_const_charp sheight)); ++#endif /* sCAL */ ++ ++#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++/* Provide the default handling for all unknown chunks or, optionally, for ++ * specific unknown chunks. ++ * ++ * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was ++ * ignored and the default was used, the per-chunk setting only had an effect on ++ * write. If you wish to have chunk-specific handling on read in code that must ++ * work on earlier versions you must use a user chunk callback to specify the ++ * desired handling (keep or discard.) ++ * ++ * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The ++ * parameter is interpreted as follows: ++ * ++ * READ: ++ * PNG_HANDLE_CHUNK_AS_DEFAULT: ++ * Known chunks: do normal libpng processing, do not keep the chunk (but ++ * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) ++ * Unknown chunks: for a specific chunk use the global default, when used ++ * as the default discard the chunk data. ++ * PNG_HANDLE_CHUNK_NEVER: ++ * Discard the chunk data. ++ * PNG_HANDLE_CHUNK_IF_SAFE: ++ * Keep the chunk data if the chunk is not critical else raise a chunk ++ * error. ++ * PNG_HANDLE_CHUNK_ALWAYS: ++ * Keep the chunk data. ++ * ++ * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, ++ * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent ++ * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks ++ * it simply resets the behavior to the libpng default. ++ * ++ * INTERACTION WTIH USER CHUNK CALLBACKS: ++ * The per-chunk handling is always used when there is a png_user_chunk_ptr ++ * callback and the callback returns 0; the chunk is then always stored *unless* ++ * it is critical and the per-chunk setting is other than ALWAYS. Notice that ++ * the global default is *not* used in this case. (In effect the per-chunk ++ * value is incremented to at least IF_SAFE.) ++ * ++ * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and ++ * per-chunk defaults will be honored. If you want to preserve the current ++ * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE ++ * as the default - if you don't do this libpng 1.6 will issue a warning. ++ * ++ * If you want unhandled unknown chunks to be discarded in libpng 1.6 and ++ * earlier simply return '1' (handled). ++ * ++ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: ++ * If this is *not* set known chunks will always be handled by libpng and ++ * will never be stored in the unknown chunk list. Known chunks listed to ++ * png_set_keep_unknown_chunks will have no effect. If it is set then known ++ * chunks listed with a keep other than AS_DEFAULT will *never* be processed ++ * by libpng, in addition critical chunks must either be processed by the ++ * callback or saved. ++ * ++ * The IHDR and IEND chunks must not be listed. Because this turns off the ++ * default handling for chunks that would otherwise be recognized the ++ * behavior of libpng transformations may well become incorrect! ++ * ++ * WRITE: ++ * When writing chunks the options only apply to the chunks specified by ++ * png_set_unknown_chunks (below), libpng will *always* write known chunks ++ * required by png_set_ calls and will always write the core critical chunks ++ * (as required for PLTE). ++ * ++ * Each chunk in the png_set_unknown_chunks list is looked up in the ++ * png_set_keep_unknown_chunks list to find the keep setting, this is then ++ * interpreted as follows: ++ * ++ * PNG_HANDLE_CHUNK_AS_DEFAULT: ++ * Write safe-to-copy chunks and write other chunks if the global ++ * default is set to _ALWAYS, otherwise don't write this chunk. ++ * PNG_HANDLE_CHUNK_NEVER: ++ * Do not write the chunk. ++ * PNG_HANDLE_CHUNK_IF_SAFE: ++ * Write the chunk if it is safe-to-copy, otherwise do not write it. ++ * PNG_HANDLE_CHUNK_ALWAYS: ++ * Write the chunk. ++ * ++ * Note that the default behavior is effectively the opposite of the read case - ++ * in read unknown chunks are not stored by default, in write they are written ++ * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different ++ * - on write the safe-to-copy bit is checked, on read the critical bit is ++ * checked and on read if the chunk is critical an error will be raised. ++ * ++ * num_chunks: ++ * =========== ++ * If num_chunks is positive, then the "keep" parameter specifies the manner ++ * for handling only those chunks appearing in the chunk_list array, ++ * otherwise the chunk list array is ignored. ++ * ++ * If num_chunks is 0 the "keep" parameter specifies the default behavior for ++ * unknown chunks, as described above. ++ * ++ * If num_chunks is negative, then the "keep" parameter specifies the manner ++ * for handling all unknown chunks plus all chunks recognized by libpng ++ * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to ++ * be processed by libpng. ++ */ ++PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, ++ int keep, png_const_bytep chunk_list, int num_chunks)); ++ ++/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; ++ * the result is therefore true (non-zero) if special handling is required, ++ * false for the default handling. ++ */ ++PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, + png_const_bytep chunk_name)); + #endif +-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +-PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structp png_ptr, +- png_infop info_ptr, png_const_unknown_chunkp unknowns, ++ ++#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED ++PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_unknown_chunkp unknowns, + int num_unknowns)); ++ /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added ++ * unknowns to the location currently stored in the png_struct. This is ++ * invariably the wrong value on write. To fix this call the following API ++ * for each chunk in the list with the correct location. If you know your ++ * code won't be compiled on earlier versions you can rely on ++ * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing ++ * the correct thing. ++ */ ++ + PNG_EXPORT(175, void, png_set_unknown_chunk_location, +- (png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +-PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structp png_ptr, +- png_const_infop info_ptr, png_unknown_chunkpp entries)); ++ (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); ++ ++PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, ++ png_inforp info_ptr, png_unknown_chunkpp entries)); + #endif + + /* Png_free_data() will turn off the "valid" flag for anything it frees. + * If you need to turn it off for a chunk that your application has freed, + * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); + */ +-PNG_EXPORT(177, void, png_set_invalid, +- (png_structp png_ptr, png_infop info_ptr, int mask)); ++PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, ++ png_inforp info_ptr, int mask)); + + #ifdef PNG_INFO_IMAGE_SUPPORTED + /* The "params" pointer is currently not used and is for future expansion. */ +-PNG_EXPORT(178, void, png_read_png, (png_structp png_ptr, png_infop info_ptr, +- int transforms, png_voidp params)); +-PNG_EXPORT(179, void, png_write_png, (png_structp png_ptr, png_infop info_ptr, ++#ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); + #endif ++#ifdef PNG_WRITE_SUPPORTED ++PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, ++ int transforms, png_voidp params)); ++#endif ++#endif + + PNG_EXPORT(180, png_const_charp, png_get_copyright, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + PNG_EXPORT(181, png_const_charp, png_get_header_ver, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + PNG_EXPORT(182, png_const_charp, png_get_header_version, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + + #ifdef PNG_MNG_FEATURES_SUPPORTED +-PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structp png_ptr, ++PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, + png_uint_32 mng_features_permitted)); + #endif + +@@ -2365,75 +2526,77 @@ + #define PNG_HANDLE_CHUNK_NEVER 1 + #define PNG_HANDLE_CHUNK_IF_SAFE 2 + #define PNG_HANDLE_CHUNK_ALWAYS 3 ++#define PNG_HANDLE_CHUNK_LAST 4 + + /* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. + */ + #ifdef PNG_ERROR_NUMBERS_SUPPORTED +-PNG_EXPORT(185, void, png_set_strip_error_numbers, +- (png_structp png_ptr, ++PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, + png_uint_32 strip_mode)); + #endif + + /* Added in libpng-1.2.6 */ + #ifdef PNG_SET_USER_LIMITS_SUPPORTED +-PNG_EXPORT(186, void, png_set_user_limits, (png_structp png_ptr, ++PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); + PNG_EXPORT(187, png_uint_32, png_get_user_width_max, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + PNG_EXPORT(188, png_uint_32, png_get_user_height_max, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + /* Added in libpng-1.4.0 */ +-PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structp png_ptr, ++PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, + png_uint_32 user_chunk_cache_max)); + PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + /* Added in libpng-1.4.1 */ +-PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structp png_ptr, ++PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, + png_alloc_size_t user_chunk_cache_max)); + PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + #endif + + #if defined(PNG_INCH_CONVERSIONS_SUPPORTED) + PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + + PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + + PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)); + + PNG_FP_EXPORT(196, float, png_get_x_offset_inches, +- (png_const_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)) + #ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ + PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, +- (png_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)) + #endif + +-PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structp png_ptr, +- png_const_infop info_ptr)); ++PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr)) + #ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ + PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, +- (png_structp png_ptr, png_const_infop info_ptr)); ++ (png_const_structrp png_ptr, png_const_inforp info_ptr)) + #endif + + # ifdef PNG_pHYs_SUPPORTED +-PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structp png_ptr, +- png_const_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, ++PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, ++ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +-# endif /* PNG_pHYs_SUPPORTED */ +-#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ ++# endif /* pHYs */ ++#endif /* INCH_CONVERSIONS */ + + /* Added in libpng-1.4.0 */ + #ifdef PNG_IO_STATE_SUPPORTED +-PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_structp png_ptr)); +- +-PNG_EXPORTA(200, png_const_bytep, png_get_io_chunk_name, +- (png_structp png_ptr), PNG_DEPRECATED); ++PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); ++ ++/* Removed from libpng 1.6; use png_get_io_chunk_type. */ ++PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), ++ PNG_DEPRECATED) ++ + PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, +- (png_const_structp png_ptr)); ++ (png_const_structrp png_ptr)); + + /* The flags returned by png_get_io_state() are the following: */ + # define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +@@ -2445,7 +2608,7 @@ + # define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ + # define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ + # define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +-#endif /* ?PNG_IO_STATE_SUPPORTED */ ++#endif /* IO_STATE */ + + /* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle +@@ -2457,8 +2620,16 @@ + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +-#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) +-#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) ++#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) ++#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) ++ ++/* A macro to return the offset between pixels in the output row for a pair of ++ * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that ++ * follows. Note that ROW_OFFSET is the offset from one row to the next whereas ++ * COL_OFFSET is from one column to the next, within a row. ++ */ ++#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) ++#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) + + /* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or +@@ -2481,10 +2652,10 @@ + * necessary to find the row in the output image given a row in an interlaced + * image, so two more macros: + */ +-#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ +- (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) +-#define PNG_COL_FROM_PASS_COL(xIn, pass) \ +- (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) ++#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ ++ (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) ++#define PNG_COL_FROM_PASS_COL(x_in, pass) \ ++ (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) + + /* Two macros which return a boolean (0 or 1) saying whether the given row + * or column is in a particular pass. These use a common utility macro that +@@ -2493,8 +2664,8 @@ + * the tile. + */ + #define PNG_PASS_MASK(pass,off) ( \ +- ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \ +- ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) ++ ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \ ++ ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) + + #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +@@ -2520,14 +2691,14 @@ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ + * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 \ +- - (png_uint_16)(alpha)) + (png_uint_16)128); \ ++ - (png_uint_16)(alpha)) + 128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + + # define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ + * (png_uint_32)(alpha) \ +- + (png_uint_32)(bg)*(png_uint_32)(65535L \ +- - (png_uint_32)(alpha)) + (png_uint_32)32768L); \ ++ + (png_uint_32)(bg)*(65535 \ ++ - (png_uint_32)(alpha)) + 32768); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + + #else /* Standard method using integer division */ +@@ -2535,13 +2706,13 @@ + # define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ +- (png_uint_16)127) / 255) ++ 127) / 255) + + # define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ +- (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ +- (png_uint_32)32767) / (png_uint_32)65535L) +-#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ ++ (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ ++ 32767) / 65535) ++#endif /* READ_COMPOSITE_NODIV */ + + #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED + PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); +@@ -2549,7 +2720,7 @@ + PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); + #endif + +-PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_structp png_ptr, ++PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, + png_const_bytep buf)); + /* No png_get_int_16 -- may be added if there's a real need for it. */ + +@@ -2575,7 +2746,7 @@ + * The png_get_int_32() routine assumes we are using two's complement + * format for negative values, which is almost certainly true. + */ +-# define png_get_uint_32(buf) \ ++# define PNG_get_uint_32(buf) \ + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ +@@ -2584,27 +2755,550 @@ + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ +-# define png_get_uint_16(buf) \ ++# define PNG_get_uint_16(buf) \ + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) + +-# define png_get_int_32(buf) \ ++# define PNG_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ + : (png_int_32)png_get_uint_32(buf))) ++ ++ /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, ++ * but defining a macro name prefixed with PNG_PREFIX. ++ */ ++# ifndef PNG_PREFIX ++# define png_get_uint_32(buf) PNG_get_uint_32(buf) ++# define png_get_uint_16(buf) PNG_get_uint_16(buf) ++# define png_get_int_32(buf) PNG_get_int_32(buf) ++# endif ++#else ++# ifdef PNG_PREFIX ++ /* No macros; revert to the (redefined) function */ ++# define PNG_get_uint_32 (png_get_uint_32) ++# define PNG_get_uint_16 (png_get_uint_16) ++# define PNG_get_int_32 (png_get_int_32) ++# endif + #endif + +-/* Maintainer: Put new public prototypes here ^, in libpng.3, and project +- * defs ++#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ ++ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) ++/******************************************************************************* ++ * SIMPLIFIED API ++ ******************************************************************************* ++ * ++ * Please read the documentation in libpng-manual.txt (TODO: write said ++ * documentation) if you don't understand what follows. ++ * ++ * The simplified API hides the details of both libpng and the PNG file format ++ * itself. It allows PNG files to be read into a very limited number of ++ * in-memory bitmap formats or to be written from the same formats. If these ++ * formats do not accomodate your needs then you can, and should, use the more ++ * sophisticated APIs above - these support a wide variety of in-memory formats ++ * and a wide variety of sophisticated transformations to those formats as well ++ * as a wide variety of APIs to manipulate ancillary information. ++ * ++ * To read a PNG file using the simplified API: ++ * ++ * 1) Declare a 'png_image' structure (see below) on the stack and set the ++ * version field to PNG_IMAGE_VERSION. ++ * 2) Call the appropriate png_image_begin_read... function. ++ * 3) Set the png_image 'format' member to the required sample format. ++ * 4) Allocate a buffer for the image and, if required, the color-map. ++ * 5) Call png_image_finish_read to read the image and, if required, the ++ * color-map into your buffers. ++ * ++ * There are no restrictions on the format of the PNG input itself; all valid ++ * color types, bit depths, and interlace methods are acceptable, and the ++ * input image is transformed as necessary to the requested in-memory format ++ * during the png_image_finish_read() step. The only caveat is that if you ++ * request a color-mapped image from a PNG that is full-color or makes ++ * complex use of an alpha channel the transformation is extremely lossy and the ++ * result may look terrible. ++ * ++ * To write a PNG file using the simplified API: ++ * ++ * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. ++ * 2) Initialize the members of the structure that describe the image, setting ++ * the 'format' member to the format of the image samples. ++ * 3) Call the appropriate png_image_write... function with a pointer to the ++ * image and, if necessary, the color-map to write the PNG data. ++ * ++ * png_image is a structure that describes the in-memory format of an image ++ * when it is being read or defines the in-memory format of an image that you ++ * need to write: + */ ++#define PNG_IMAGE_VERSION 1 ++ ++typedef struct png_control *png_controlp; ++typedef struct ++{ ++ png_controlp opaque; /* Initialize to NULL, free with png_image_free */ ++ png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ ++ png_uint_32 width; /* Image width in pixels (columns) */ ++ png_uint_32 height; /* Image height in pixels (rows) */ ++ png_uint_32 format; /* Image format as defined below */ ++ png_uint_32 flags; /* A bit mask containing informational flags */ ++ png_uint_32 colormap_entries; ++ /* Number of entries in the color-map */ ++ ++ /* In the event of an error or warning the following field will be set to a ++ * non-zero value and the 'message' field will contain a '\0' terminated ++ * string with the libpng error or warning message. If both warnings and ++ * an error were encountered, only the error is recorded. If there ++ * are multiple warnings, only the first one is recorded. ++ * ++ * The upper 30 bits of this value are reserved, the low two bits contain ++ * a value as follows: ++ */ ++# define PNG_IMAGE_WARNING 1 ++# define PNG_IMAGE_ERROR 2 ++ /* ++ * The result is a two-bit code such that a value more than 1 indicates ++ * a failure in the API just called: ++ * ++ * 0 - no warning or error ++ * 1 - warning ++ * 2 - error ++ * 3 - error preceded by warning ++ */ ++# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) ++ ++ png_uint_32 warning_or_error; ++ ++ char message[64]; ++} png_image, *png_imagep; ++ ++/* The samples of the image have one to four channels whose components have ++ * original values in the range 0 to 1.0: ++ * ++ * 1: A single gray or luminance channel (G). ++ * 2: A gray/luminance channel and an alpha channel (GA). ++ * 3: Three red, green, blue color channels (RGB). ++ * 4: Three color channels and an alpha channel (RGBA). ++ * ++ * The components are encoded in one of two ways: ++ * ++ * a) As a small integer, value 0..255, contained in a single byte. For the ++ * alpha channel the original value is simply value/255. For the color or ++ * luminance channels the value is encoded according to the sRGB specification ++ * and matches the 8-bit format expected by typical display devices. ++ * ++ * The color/gray channels are not scaled (pre-multiplied) by the alpha ++ * channel and are suitable for passing to color management software. ++ * ++ * b) As a value in the range 0..65535, contained in a 2-byte integer. All ++ * channels can be converted to the original value by dividing by 65535; all ++ * channels are linear. Color channels use the RGB encoding (RGB end-points) of ++ * the sRGB specification. This encoding is identified by the ++ * PNG_FORMAT_FLAG_LINEAR flag below. ++ * ++ * When the simplified API needs to convert between sRGB and linear colorspaces, ++ * the actual sRGB transfer curve defined in the sRGB specification (see the ++ * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 ++ * approximation used elsewhere in libpng. ++ * ++ * When an alpha channel is present it is expected to denote pixel coverage ++ * of the color or luminance channels and is returned as an associated alpha ++ * channel: the color/gray channels are scaled (pre-multiplied) by the alpha ++ * value. ++ * ++ * The samples are either contained directly in the image data, between 1 and 8 ++ * bytes per pixel according to the encoding, or are held in a color-map indexed ++ * by bytes in the image data. In the case of a color-map the color-map entries ++ * are individual samples, encoded as above, and the image data has one byte per ++ * pixel to select the relevant sample from the color-map. ++ */ ++ ++/* PNG_FORMAT_* ++ * ++ * #defines to be used in png_image::format. Each #define identifies a ++ * particular layout of sample data and, if present, alpha values. There are ++ * separate defines for each of the two component encodings. ++ * ++ * A format is built up using single bit flag values. All combinations are ++ * valid. Formats can be built up from the flag values or you can use one of ++ * the predefined values below. When testing formats always use the FORMAT_FLAG ++ * macros to test for individual features - future versions of the library may ++ * add new flags. ++ * ++ * When reading or writing color-mapped images the format should be set to the ++ * format of the entries in the color-map then png_image_{read,write}_colormap ++ * called to read or write the color-map and set the format correctly for the ++ * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! ++ * ++ * NOTE: libpng can be built with particular features disabled, if you see ++ * compiler errors because the definition of one of the following flags has been ++ * compiled out it is because libpng does not have the required support. It is ++ * possible, however, for the libpng configuration to enable the format on just ++ * read or just write; in that case you may see an error at run time. You can ++ * guard against this by checking for the definition of the appropriate ++ * "_SUPPORTED" macro, one of: ++ * ++ * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED ++ */ ++#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ ++#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ ++#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */ ++#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ ++ ++#ifdef PNG_FORMAT_BGR_SUPPORTED ++# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ ++#endif ++ ++#ifdef PNG_FORMAT_AFIRST_SUPPORTED ++# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ ++#endif ++ ++/* Commonly used formats have predefined macros. ++ * ++ * First the single byte (sRGB) formats: ++ */ ++#define PNG_FORMAT_GRAY 0 ++#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA ++#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) ++#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR ++#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) ++#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) ++#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) ++#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) ++#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) ++ ++/* Then the linear 2-byte formats. When naming these "Y" is used to ++ * indicate a luminance (gray) channel. ++ */ ++#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR ++#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) ++#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) ++#define PNG_FORMAT_LINEAR_RGB_ALPHA \ ++ (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) ++ ++/* With color-mapped formats the image data is one byte for each pixel, the byte ++ * is an index into the color-map which is formatted as above. To obtain a ++ * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP ++ * to one of the above definitions, or you can use one of the definitions below. ++ */ ++#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) ++#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) ++#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) ++#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) ++#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) ++#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) ++ ++/* PNG_IMAGE macros ++ * ++ * These are convenience macros to derive information from a png_image ++ * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the ++ * actual image sample values - either the entries in the color-map or the ++ * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values ++ * for the pixels and will always return 1 for color-mapped formats. The ++ * remaining macros return information about the rows in the image and the ++ * complete image. ++ * ++ * NOTE: All the macros that take a png_image::format parameter are compile time ++ * constants if the format parameter is, itself, a constant. Therefore these ++ * macros can be used in array declarations and case labels where required. ++ * Similarly the macros are also pre-processor constants (sizeof is not used) so ++ * they can be used in #if tests. ++ * ++ * First the information about the samples. ++ */ ++#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ ++ (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) ++ /* Return the total number of channels in a given format: 1..4 */ ++ ++#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ ++ ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) ++ /* Return the size in bytes of a single component of a pixel or color-map ++ * entry (as appropriate) in the image: 1 or 2. ++ */ ++ ++#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ ++ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) ++ /* This is the size of the sample data for one sample. If the image is ++ * color-mapped it is the size of one color-map entry (and image pixels are ++ * one byte in size), otherwise it is the size of one image pixel. ++ */ ++ ++#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ ++ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) ++ /* The maximum size of the color-map required by the format expressed in a ++ * count of components. This can be used to compile-time allocate a ++ * color-map: ++ * ++ * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; ++ * ++ * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; ++ * ++ * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the ++ * information from one of the png_image_begin_read_ APIs and dynamically ++ * allocate the required memory. ++ */ ++ ++/* Corresponding information about the pixels */ ++#define PNG_IMAGE_PIXEL_(test,fmt)\ ++ (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) ++ ++#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ ++ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) ++ /* The number of separate channels (components) in a pixel; 1 for a ++ * color-mapped image. ++ */ ++ ++#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ ++ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) ++ /* The size, in bytes, of each component in a pixel; 1 for a color-mapped ++ * image. ++ */ ++ ++#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) ++ /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ ++ ++/* Information about the whole row, or whole image */ ++#define PNG_IMAGE_ROW_STRIDE(image)\ ++ (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) ++ /* Return the total number of components in a single row of the image; this ++ * is the minimum 'row stride', the minimum count of components between each ++ * row. For a color-mapped image this is the minimum number of bytes in a ++ * row. ++ */ ++ ++#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ ++ (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) ++ /* Return the size, in bytes, of an image buffer given a png_image and a row ++ * stride - the number of components to leave space for in each row. ++ */ ++ ++#define PNG_IMAGE_SIZE(image)\ ++ PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) ++ /* Return the size, in bytes, of the image in memory given just a png_image; ++ * the row stride is the minimum stride required for the image. ++ */ ++ ++#define PNG_IMAGE_COLORMAP_SIZE(image)\ ++ (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) ++ /* Return the size, in bytes, of the color-map of this image. If the image ++ * format is not a color-map format this will return a size sufficient for ++ * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if ++ * you don't want to allocate a color-map in this case. ++ */ ++ ++/* PNG_IMAGE_FLAG_* ++ * ++ * Flags containing additional information about the image are held in the ++ * 'flags' field of png_image. ++ */ ++#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 ++ /* This indicates the the RGB values of the in-memory bitmap do not ++ * correspond to the red, green and blue end-points defined by sRGB. ++ */ ++ ++#define PNG_IMAGE_FLAG_FAST 0x02 ++ /* On write emphasise speed over compression; the resultant PNG file will be ++ * larger but will be produced significantly faster, particular for large ++ * images. Do not use this option for images which will be distributed, only ++ * used it when producing intermediate files that will be read back in ++ * repeatedly. For a typical 24-bit image the option will double the read ++ * speed at the cost of increasing the image size by 25%, however for many ++ * more compressible images the PNG file can be 10 times larger with only a ++ * slight speed gain. ++ */ ++ ++#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 ++ /* On read if the image is a 16-bit per component image and there is no gAMA ++ * or sRGB chunk assume that the components are sRGB encoded. Notice that ++ * images output by the simplified API always have gamma information; setting ++ * this flag only affects the interpretation of 16-bit images from an ++ * external source. It is recommended that the application expose this flag ++ * to the user; the user can normally easily recognize the difference between ++ * linear and sRGB encoding. This flag has no effect on write - the data ++ * passed to the write APIs must have the correct encoding (as defined ++ * above.) ++ * ++ * If the flag is not set (the default) input 16-bit per component data is ++ * assumed to be linear. ++ * ++ * NOTE: the flag can only be set after the png_image_begin_read_ call, ++ * because that call initializes the 'flags' field. ++ */ ++ ++#ifdef PNG_SIMPLIFIED_READ_SUPPORTED ++/* READ APIs ++ * --------- ++ * ++ * The png_image passed to the read APIs must have been initialized by setting ++ * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) ++ */ ++#ifdef PNG_STDIO_SUPPORTED ++PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, ++ const char *file_name)); ++ /* The named file is opened for read and the image header is filled in ++ * from the PNG header in the file. ++ */ ++ ++PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, ++ FILE* file)); ++ /* The PNG header is read from the stdio FILE object. */ ++#endif /* STDIO */ ++ ++PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, ++ png_const_voidp memory, png_size_t size)); ++ /* The PNG header is read from the given memory buffer. */ ++ ++PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, ++ png_const_colorp background, void *buffer, png_int_32 row_stride, ++ void *colormap)); ++ /* Finish reading the image into the supplied buffer and clean up the ++ * png_image structure. ++ * ++ * row_stride is the step, in byte or 2-byte units as appropriate, ++ * between adjacent rows. A positive stride indicates that the top-most row ++ * is first in the buffer - the normal top-down arrangement. A negative ++ * stride indicates that the bottom-most row is first in the buffer. ++ * ++ * background need only be supplied if an alpha channel must be removed from ++ * a png_byte format and the removal is to be done by compositing on a solid ++ * color; otherwise it may be NULL and any composition will be done directly ++ * onto the buffer. The value is an sRGB color to use for the background, ++ * for grayscale output the green channel is used. ++ * ++ * background must be supplied when an alpha channel must be removed from a ++ * single byte color-mapped output format, in other words if: ++ * ++ * 1) The original format from png_image_begin_read_from_* had ++ * PNG_FORMAT_FLAG_ALPHA set. ++ * 2) The format set by the application does not. ++ * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and ++ * PNG_FORMAT_FLAG_LINEAR *not* set. ++ * ++ * For linear output removing the alpha channel is always done by compositing ++ * on black and background is ignored. ++ * ++ * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must ++ * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. ++ * image->colormap_entries will be updated to the actual number of entries ++ * written to the colormap; this may be less than the original value. ++ */ ++ ++PNG_EXPORT(238, void, png_image_free, (png_imagep image)); ++ /* Free any data allocated by libpng in image->opaque, setting the pointer to ++ * NULL. May be called at any time after the structure is initialized. ++ */ ++#endif /* SIMPLIFIED_READ */ ++ ++#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED ++#ifdef PNG_STDIO_SUPPORTED ++/* WRITE APIS ++ * ---------- ++ * For write you must initialize a png_image structure to describe the image to ++ * be written. To do this use memset to set the whole structure to 0 then ++ * initialize fields describing your image. ++ * ++ * version: must be set to PNG_IMAGE_VERSION ++ * opaque: must be initialized to NULL ++ * width: image width in pixels ++ * height: image height in rows ++ * format: the format of the data (image and color-map) you wish to write ++ * flags: set to 0 unless one of the defined flags applies; set ++ * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB ++ * values do not correspond to the colors in sRGB. ++ * colormap_entries: set to the number of entries in the color-map (0 to 256) ++ */ ++PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, ++ const char *file, int convert_to_8bit, const void *buffer, ++ png_int_32 row_stride, const void *colormap)); ++ /* Write the image to the named file. */ ++ ++PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, ++ int convert_to_8_bit, const void *buffer, png_int_32 row_stride, ++ const void *colormap)); ++ /* Write the image to the given (FILE*). */ ++ ++/* With both write APIs if image is in one of the linear formats with 16-bit ++ * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG ++ * gamma encoded according to the sRGB specification, otherwise a 16-bit linear ++ * encoded PNG file is written. ++ * ++ * With color-mapped data formats the colormap parameter point to a color-map ++ * with at least image->colormap_entries encoded in the specified format. If ++ * the format is linear the written PNG color-map will be converted to sRGB ++ * regardless of the convert_to_8_bit flag. ++ * ++ * With all APIs row_stride is handled as in the read APIs - it is the spacing ++ * from one row to the next in component sized units (1 or 2 bytes) and if ++ * negative indicates a bottom-up row layout in the buffer. ++ * ++ * Note that the write API does not support interlacing or sub-8-bit pixels. ++ */ ++#endif /* STDIO */ ++#endif /* SIMPLIFIED_WRITE */ ++/******************************************************************************* ++ * END OF SIMPLIFIED API ++ ******************************************************************************/ ++#endif /* SIMPLIFIED_{READ|WRITE} */ ++ ++#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED ++PNG_EXPORT(242, void, png_set_check_for_invalid_index, ++ (png_structrp png_ptr, int allowed)); ++# ifdef PNG_GET_PALETTE_MAX_SUPPORTED ++PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, ++ png_const_infop info_ptr)); ++# endif ++#endif /* CHECK_FOR_INVALID_INDEX */ ++ ++/******************************************************************************* ++ * IMPLEMENTATION OPTIONS ++ ******************************************************************************* ++ * ++ * Support for arbitrary implementation-specific optimizations. The API allows ++ * particular options to be turned on or off. 'Option' is the number of the ++ * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given ++ * by the PNG_OPTION_ defines below. ++ * ++ * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, ++ * are detected at run time, however sometimes it may be impossible ++ * to do this in user mode, in which case it is necessary to discover ++ * the capabilities in an OS specific way. Such capabilities are ++ * listed here when libpng has support for them and must be turned ++ * ON by the application if present. ++ * ++ * SOFTWARE: sometimes software optimizations actually result in performance ++ * decrease on some architectures or systems, or with some sets of ++ * PNG images. 'Software' options allow such optimizations to be ++ * selected at run time. ++ */ ++#ifdef PNG_SET_OPTION_SUPPORTED ++#ifdef PNG_ARM_NEON_API_SUPPORTED ++# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ ++#endif ++#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ ++#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ ++#define PNG_OPTION_NEXT 6 /* Next option - numbers must be even */ ++ ++/* Return values: NOTE: there are four values and 'off' is *not* zero */ ++#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ ++#define PNG_OPTION_INVALID 1 /* Option number out of range */ ++#define PNG_OPTION_OFF 2 ++#define PNG_OPTION_ON 3 ++ ++PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, ++ int onoff)); ++#endif /* SET_OPTION */ ++ ++/******************************************************************************* ++ * END OF HARDWARE AND SOFTWARE OPTIONS ++ ******************************************************************************/ ++ ++/* Maintainer: Put new public prototypes here ^, in libpng.3, in project ++ * defs, and in scripts/symbols.def. ++ */ + + /* The last ordinal number (this is the *last* one already used; the next +- * one to use is one more than this.) Maintainer, remember to add an entry to +- * scripts/symbols.def as well. ++ * one to use is one more than this.) + */ + #ifdef PNG_EXPORT_LAST_ORDINAL +- PNG_EXPORT_LAST_ORDINAL(229); ++ PNG_EXPORT_LAST_ORDINAL(244); + #endif + + #ifdef __cplusplus +--- ./jdk/src/share/native/sun/awt/libpng/pngconf.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngconf.h Thu Feb 05 13:00:26 2015 +0100 +@@ -29,9 +29,9 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * libpng version 1.5.4 - July 7, 2011 ++ * libpng version 1.6.16,December 22, 2014 + * +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -50,37 +50,73 @@ + #ifndef PNGCONF_H + #define PNGCONF_H + +-#ifndef PNG_BUILDING_SYMBOL_TABLE +-/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C +- * definition file for machine specific limits, this may impact the +- * correctness of the definitons below (see uses of INT_MAX). +- */ +-# ifndef PNG_NO_LIMITS_H +-# include <limits.h> ++/* To do: Do all of this in scripts/pnglibconf.dfa */ ++#ifdef PNG_SAFE_LIMITS_SUPPORTED ++# ifdef PNG_USER_WIDTH_MAX ++# undef PNG_USER_WIDTH_MAX ++# define PNG_USER_WIDTH_MAX 1000000L + # endif +- +-/* For the memory copy APIs (i.e. the standard definitions of these), +- * because this file defines png_memcpy and so on the base APIs must +- * be defined here. +- */ +-# ifdef BSD +-# include <strings.h> +-# else +-# include <string.h> ++# ifdef PNG_USER_HEIGHT_MAX ++# undef PNG_USER_HEIGHT_MAX ++# define PNG_USER_HEIGHT_MAX 1000000L + # endif +- +-/* For png_FILE_p - this provides the standard definition of a +- * FILE +- */ +-# ifdef PNG_STDIO_SUPPORTED +-# include <stdio.h> ++# ifdef PNG_USER_CHUNK_MALLOC_MAX ++# undef PNG_USER_CHUNK_MALLOC_MAX ++# define PNG_USER_CHUNK_MALLOC_MAX 4000000L ++# endif ++# ifdef PNG_USER_CHUNK_CACHE_MAX ++# undef PNG_USER_CHUNK_CACHE_MAX ++# define PNG_USER_CHUNK_CACHE_MAX 128 + # endif + #endif + ++#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ ++ ++/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C ++ * compiler for correct compilation. The following header files are required by ++ * the standard. If your compiler doesn't provide these header files, or they ++ * do not match the standard, you will need to provide/improve them. ++ */ ++#include <limits.h> ++#include <stddef.h> ++ ++/* Library header files. These header files are all defined by ISOC90; libpng ++ * expects conformant implementations, however, an ISOC90 conformant system need ++ * not provide these header files if the functionality cannot be implemented. ++ * In this case it will be necessary to disable the relevant parts of libpng in ++ * the build of pnglibconf.h. ++ * ++ * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not ++ * include this unnecessary header file. ++ */ ++ ++#ifdef PNG_STDIO_SUPPORTED ++ /* Required for the definition of FILE: */ ++# include <stdio.h> ++#endif ++ ++#ifdef PNG_SETJMP_SUPPORTED ++ /* Required for the definition of jmp_buf and the declaration of longjmp: */ ++# include <setjmp.h> ++#endif ++ ++#ifdef PNG_CONVERT_tIME_SUPPORTED ++ /* Required for struct tm: */ ++# include <time.h> ++#endif ++ ++#endif /* PNG_BUILDING_SYMBOL_TABLE */ ++ ++/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using ++ * PNG_NO_CONST; this is no longer supported except for data declarations which ++ * apparently still cause problems in 2011 on some compilers. ++ */ ++#define PNG_CONST const /* backward compatibility only */ ++ + /* This controls optimization of the reading of 16 and 32 bit values + * from PNG files. It can be set on a per-app-file basis - it +- * just changes whether a macro is used to the function is called. +- * The library builder sets the default, if read functions are not ++ * just changes whether a macro is used when the function is called. ++ * The library builder sets the default; if read functions are not + * built into the library the macro implementation is forced on. + */ + #ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +@@ -100,28 +136,13 @@ + * may be changed on a per-file basis when compiling against libpng. + */ + +-/* The PNGARG macro protects us against machines that don't have function +- * prototypes (ie K&R style headers). If your compiler does not handle +- * function prototypes, define this macro and use the included ansi2knr. +- * I've always been able to use _NO_PROTO as the indicator, but you may +- * need to drag the empty declaration out in front of here, or change the +- * ifdef to suit your own needs. ++/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect ++ * against legacy (pre ISOC90) compilers that did not understand function ++ * prototypes. It is not required for modern C compilers. + */ + #ifndef PNGARG +- +-# ifdef OF /* zlib prototype munger */ +-# define PNGARG(arglist) OF(arglist) +-# else +- +-# ifdef _NO_PROTO +-# define PNGARG(arglist) () +-# else +-# define PNGARG(arglist) arglist +-# endif /* _NO_PROTO */ +- +-# endif /* OF */ +- +-#endif /* PNGARG */ ++# define PNGARG(arglist) arglist ++#endif + + /* Function calling conventions. + * ============================= +@@ -192,7 +213,9 @@ + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to +- * make a symbol exported from the DLL. ++ * make a symbol exported from the DLL. Not used in the ++ * public header files; see pngpriv.h for how it is used ++ * in the libpng build. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when +@@ -203,18 +226,16 @@ + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL +- * import processing is possible. On Windows/x86 systems it also sets ++ * import processing is possible. On Windows systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +-#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ +- defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\ +- ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\ +- defined(_M_X64) || defined(_M_IA64) ) +- /* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes +- * builds under Cygwin or MinGW. Also includes Watcom builds but these need +- * special treatment because they are not compatible with GCC or Visual C +- * because of different calling conventions. ++#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ ++ defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ++ /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or ++ * MinGW on any architecture currently supported by Windows. Also includes ++ * Watcom builds but these need special treatment because they are not ++ * compatible with GCC or Visual C because of different calling conventions. + */ + # if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not +@@ -225,9 +246,12 @@ + # define PNGCAPI __watcall + # endif + +-# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) ++# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) + # define PNGCAPI __cdecl + # if PNG_API_RULE == 1 ++ /* If this line results in an error __stdcall is not understood and ++ * PNG_API_RULE should not have been set to '1'. ++ */ + # define PNGAPI __stdcall + # endif + # else +@@ -242,10 +266,11 @@ + # define PNGAPI _stdcall + # endif + # endif /* compiler/api */ ++ + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + + # if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) +- ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed ++# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" + # endif + + # if (defined(_MSC_VER) && _MSC_VER < 800) ||\ +@@ -265,7 +290,7 @@ + # endif + # endif /* compiler */ + +-#else /* !Windows/x86 */ ++#else /* !Windows */ + # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) + # define PNGAPI _System + # else /* !Windows/x86 && !OS/2 */ +@@ -286,25 +311,14 @@ + # define PNGAPI PNGCAPI + #endif + +-/* The default for PNG_IMPEXP depends on whether the library is +- * being built or used. ++/* PNG_IMPEXP may be set on the compilation system command line or (if not set) ++ * then in an internal header file when building the library, otherwise (when ++ * using the library) it is set here. + */ + #ifndef PNG_IMPEXP +-# ifdef PNGLIB_BUILD +- /* Building the library */ +-# if (defined(DLL_EXPORT)/*from libtool*/ ||\ +- defined(_WINDLL) || defined(_DLL) || defined(__DLL__) ||\ +- defined(_USRDLL) ||\ +- defined(PNG_BUILD_DLL)) && defined(PNG_DLL_EXPORT) +- /* Building a DLL. */ +-# define PNG_IMPEXP PNG_DLL_EXPORT +-# endif /* DLL */ +-# else +- /* Using the library */ +-# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) +- /* This forces use of a DLL, disallowing static linking */ +-# define PNG_IMPEXP PNG_DLL_IMPORT +-# endif ++# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) ++ /* This forces use of a DLL, disallowing static linking */ ++# define PNG_IMPEXP PNG_DLL_IMPORT + # endif + + # ifndef PNG_IMPEXP +@@ -370,26 +384,48 @@ + + #ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used +- * so that where compiler support is available incorrect use of API ++ * so that where compiler support is available, incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng +- * version 1.2.41. ++ * version 1.2.41. Disabling these removes the warnings but may also produce ++ * less efficient code. + */ +-# if defined(__GNUC__) ++# if defined(__clang__) && defined(__has_attribute) ++ /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ ++# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) ++# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) ++# endif ++# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) ++# define PNG_NORETURN __attribute__((__noreturn__)) ++# endif ++# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) ++# define PNG_ALLOCATED __attribute__((__malloc__)) ++# endif ++# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) ++# define PNG_DEPRECATED __attribute__((__deprecated__)) ++# endif ++# if !defined(PNG_PRIVATE) ++# ifdef __has_extension ++# if __has_extension(attribute_unavailable_with_message) ++# define PNG_PRIVATE __attribute__((__unavailable__(\ ++ "This function is not exported by libpng."))) ++# endif ++# endif ++# endif ++# ifndef PNG_RESTRICT ++# define PNG_RESTRICT __restrict ++# endif ++ ++# elif defined(__GNUC__) + # ifndef PNG_USE_RESULT + # define PNG_USE_RESULT __attribute__((__warn_unused_result__)) + # endif + # ifndef PNG_NORETURN + # define PNG_NORETURN __attribute__((__noreturn__)) + # endif +-# ifndef PNG_ALLOCATED +-# define PNG_ALLOCATED __attribute__((__malloc__)) +-# endif +- +- /* This specifically protects structure members that should only be +- * accessed from within the library, therefore should be empty during +- * a library build. +- */ +-# ifndef PNGLIB_BUILD ++# if __GNUC__ >= 3 ++# ifndef PNG_ALLOCATED ++# define PNG_ALLOCATED __attribute__((__malloc__)) ++# endif + # ifndef PNG_DEPRECATED + # define PNG_DEPRECATED __attribute__((__deprecated__)) + # endif +@@ -402,10 +438,14 @@ + __attribute__((__deprecated__)) + # endif + # endif +-# endif /* PNGLIB_BUILD */ +-# endif /* __GNUC__ */ ++# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) ++# ifndef PNG_RESTRICT ++# define PNG_RESTRICT __restrict ++# endif ++# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ ++# endif /* __GNUC__ >= 3 */ + +-# if defined(_MSC_VER) && (_MSC_VER >= 1300) ++# elif defined(_MSC_VER) && (_MSC_VER >= 1300) + # ifndef PNG_USE_RESULT + # define PNG_USE_RESULT /* not supported */ + # endif +@@ -417,20 +457,23 @@ + # define PNG_ALLOCATED __declspec(restrict) + # endif + # endif ++# ifndef PNG_DEPRECATED ++# define PNG_DEPRECATED __declspec(deprecated) ++# endif ++# ifndef PNG_PRIVATE ++# define PNG_PRIVATE __declspec(deprecated) ++# endif ++# ifndef PNG_RESTRICT ++# if (_MSC_VER >= 1400) ++# define PNG_RESTRICT __restrict ++# endif ++# endif + +- /* This specifically protects structure members that should only be +- * accessed from within the library, therefore should be empty during +- * a library build. +- */ +-# ifndef PNGLIB_BUILD +-# ifndef PNG_DEPRECATED +-# define PNG_DEPRECATED __declspec(deprecated) +-# endif +-# ifndef PNG_PRIVATE +-# define PNG_PRIVATE __declspec(deprecated) +-# endif +-# endif /* PNGLIB_BUILD */ +-# endif /* _MSC_VER */ ++# elif defined(__WATCOMC__) ++# ifndef PNG_RESTRICT ++# define PNG_RESTRICT __restrict ++# endif ++# endif + #endif /* PNG_PEDANTIC_WARNINGS */ + + #ifndef PNG_DEPRECATED +@@ -448,10 +491,14 @@ + #ifndef PNG_PRIVATE + # define PNG_PRIVATE /* This is a private libpng function */ + #endif ++#ifndef PNG_RESTRICT ++# define PNG_RESTRICT /* The C99 "restrict" feature */ ++#endif ++ + #ifndef PNG_FP_EXPORT /* A floating point API. */ + # ifdef PNG_FLOATING_POINT_SUPPORTED + # define PNG_FP_EXPORT(ordinal, type, name, args)\ +- PNG_EXPORT(ordinal, type, name, args) ++ PNG_EXPORT(ordinal, type, name, args); + # else /* No floating point APIs */ + # define PNG_FP_EXPORT(ordinal, type, name, args) + # endif +@@ -459,189 +506,167 @@ + #ifndef PNG_FIXED_EXPORT /* A fixed point API. */ + # ifdef PNG_FIXED_POINT_SUPPORTED + # define PNG_FIXED_EXPORT(ordinal, type, name, args)\ +- PNG_EXPORT(ordinal, type, name, args) ++ PNG_EXPORT(ordinal, type, name, args); + # else /* No fixed point APIs */ + # define PNG_FIXED_EXPORT(ordinal, type, name, args) + # endif + #endif + +-/* The following uses const char * instead of char * for error +- * and warning message functions, so some compilers won't complain. +- * If you do not want to use const, define PNG_NO_CONST here. ++#ifndef PNG_BUILDING_SYMBOL_TABLE ++/* Some typedefs to get us started. These should be safe on most of the common ++ * platforms. + * +- * This should not change how the APIs are called, so it can be done +- * on a per-file basis in the application. ++ * png_uint_32 and png_int_32 may, currently, be larger than required to hold a ++ * 32-bit value however this is not normally advisable. ++ * ++ * png_uint_16 and png_int_16 should always be two bytes in size - this is ++ * verified at library build time. ++ * ++ * png_byte must always be one byte in size. ++ * ++ * The checks below use constants from limits.h, as defined by the ISOC90 ++ * standard. + */ +-#ifndef PNG_CONST +-# ifndef PNG_NO_CONST +-# define PNG_CONST const +-# else +-# define PNG_CONST ++#if CHAR_BIT == 8 && UCHAR_MAX == 255 ++ typedef unsigned char png_byte; ++#else ++# error "libpng requires 8 bit bytes" ++#endif ++ ++#if INT_MIN == -32768 && INT_MAX == 32767 ++ typedef int png_int_16; ++#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 ++ typedef short png_int_16; ++#else ++# error "libpng requires a signed 16 bit type" ++#endif ++ ++#if UINT_MAX == 65535 ++ typedef unsigned int png_uint_16; ++#elif USHRT_MAX == 65535 ++ typedef unsigned short png_uint_16; ++#else ++# error "libpng requires an unsigned 16 bit type" ++#endif ++ ++#if INT_MIN < -2147483646 && INT_MAX > 2147483646 ++ typedef int png_int_32; ++#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 ++ typedef long int png_int_32; ++#else ++# error "libpng requires a signed 32 bit (or more) type" ++#endif ++ ++#if UINT_MAX > 4294967294 ++ typedef unsigned int png_uint_32; ++#elif ULONG_MAX > 4294967294 ++ typedef unsigned long int png_uint_32; ++#else ++# error "libpng requires an unsigned 32 bit (or more) type" ++#endif ++ ++/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, ++ * requires an ISOC90 compiler and relies on consistent behavior of sizeof. ++ */ ++typedef size_t png_size_t; ++typedef ptrdiff_t png_ptrdiff_t; ++ ++/* libpng needs to know the maximum value of 'size_t' and this controls the ++ * definition of png_alloc_size_t, below. This maximum value of size_t limits ++ * but does not control the maximum allocations the library makes - there is ++ * direct application control of this through png_set_user_limits(). ++ */ ++#ifndef PNG_SMALL_SIZE_T ++ /* Compiler specific tests for systems where size_t is known to be less than ++ * 32 bits (some of these systems may no longer work because of the lack of ++ * 'far' support; see above.) ++ */ ++# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ ++ (defined(_MSC_VER) && defined(MAXSEG_64K)) ++# define PNG_SMALL_SIZE_T + # endif + #endif + +-/* Some typedefs to get us started. These should be safe on most of the +- * common platforms. The typedefs should be at least as large as the +- * numbers suggest (a png_uint_32 must be at least 32 bits long), but they +- * don't have to be exactly that size. Some compilers dislike passing +- * unsigned shorts as function parameters, so you may be better off using +- * unsigned int for png_uint_16. ++/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no ++ * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to ++ * png_alloc_size_t are not necessary; in fact, it is recommended not to use ++ * them at all so that the compiler can complain when something turns out to be ++ * problematic. ++ * ++ * Casts in the other direction (from png_alloc_size_t to png_size_t or ++ * png_uint_32) should be explicitly applied; however, we do not expect to ++ * encounter practical situations that require such conversions. ++ * ++ * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than ++ * 4294967295 - i.e. less than the maximum value of png_uint_32. ++ */ ++#ifdef PNG_SMALL_SIZE_T ++ typedef png_uint_32 png_alloc_size_t; ++#else ++ typedef png_size_t png_alloc_size_t; ++#endif ++ ++/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler ++ * implementations of Intel CPU specific support of user-mode segmented address ++ * spaces, where 16-bit pointers address more than 65536 bytes of memory using ++ * separate 'segment' registers. The implementation requires two different ++ * types of pointer (only one of which includes the segment value.) ++ * ++ * If required this support is available in version 1.2 of libpng and may be ++ * available in versions through 1.5, although the correctness of the code has ++ * not been verified recently. + */ + +-#if defined(INT_MAX) && (INT_MAX > 0x7ffffffeL) +-typedef unsigned int png_uint_32; +-typedef int png_int_32; +-#else +-typedef unsigned long png_uint_32; +-typedef long png_int_32; +-#endif +-typedef unsigned short png_uint_16; +-typedef short png_int_16; +-typedef unsigned char png_byte; +- +-#ifdef PNG_NO_SIZE_T +-typedef unsigned int png_size_t; +-#else +-typedef size_t png_size_t; +-#endif +-#define png_sizeof(x) (sizeof (x)) +- +-/* The following is needed for medium model support. It cannot be in the +- * pngpriv.h header. Needs modification for other compilers besides +- * MSC. Model independent support declares all arrays and pointers to be +- * large using the far keyword. The zlib version used must also support +- * model independent data. As of version zlib 1.0.4, the necessary changes +- * have been made in zlib. The USE_FAR_KEYWORD define triggers other +- * changes that are needed. (Tim Wegner) +- */ +- +-/* Separate compiler dependencies (problem here is that zlib.h always +- * defines FAR. (SJT) +- */ +-#ifdef __BORLANDC__ +-# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +-# define LDATA 1 +-# else +-# define LDATA 0 +-# endif +- /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +-# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +-# define PNG_MAX_MALLOC_64K /* only used in build */ +-# if (LDATA != 1) +-# ifndef FAR +-# define FAR __far +-# endif +-# define USE_FAR_KEYWORD +-# endif /* LDATA != 1 */ +- /* Possibly useful for moving data out of default segment. +- * Uncomment it if you want. Could also define FARDATA as +- * const if your compiler supports it. (SJT) +-# define FARDATA FAR +- */ +-# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +-#endif /* __BORLANDC__ */ +- +- +-/* Suggest testing for specific compiler first before testing for +- * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, +- * making reliance oncertain keywords suspect. (SJT) +- */ +- +-/* MSC Medium model */ +-#ifdef FAR +-# ifdef M_I86MM +-# define USE_FAR_KEYWORD +-# define FARDATA FAR +-# include <dos.h> +-# endif +-#endif +- +-/* SJT: default case */ +-#ifndef FAR +-# define FAR +-#endif +- +-/* At this point FAR is always defined */ +-#ifndef FARDATA +-# define FARDATA +-#endif +- +-/* Typedef for floating-point numbers that are converted +- * to fixed-point with a multiple of 100,000, e.g., gamma ++/* Typedef for floating-point numbers that are converted to fixed-point with a ++ * multiple of 100,000, e.g., gamma + */ + typedef png_int_32 png_fixed_point; + + /* Add typedefs for pointers */ +-typedef void FAR * png_voidp; +-typedef PNG_CONST void FAR * png_const_voidp; +-typedef png_byte FAR * png_bytep; +-typedef PNG_CONST png_byte FAR * png_const_bytep; +-typedef png_uint_32 FAR * png_uint_32p; +-typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p; +-typedef png_int_32 FAR * png_int_32p; +-typedef PNG_CONST png_int_32 FAR * png_const_int_32p; +-typedef png_uint_16 FAR * png_uint_16p; +-typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p; +-typedef png_int_16 FAR * png_int_16p; +-typedef PNG_CONST png_int_16 FAR * png_const_int_16p; +-typedef char FAR * png_charp; +-typedef PNG_CONST char FAR * png_const_charp; +-typedef png_fixed_point FAR * png_fixed_point_p; +-typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p; +-typedef png_size_t FAR * png_size_tp; +-typedef PNG_CONST png_size_t FAR * png_const_size_tp; ++typedef void * png_voidp; ++typedef const void * png_const_voidp; ++typedef png_byte * png_bytep; ++typedef const png_byte * png_const_bytep; ++typedef png_uint_32 * png_uint_32p; ++typedef const png_uint_32 * png_const_uint_32p; ++typedef png_int_32 * png_int_32p; ++typedef const png_int_32 * png_const_int_32p; ++typedef png_uint_16 * png_uint_16p; ++typedef const png_uint_16 * png_const_uint_16p; ++typedef png_int_16 * png_int_16p; ++typedef const png_int_16 * png_const_int_16p; ++typedef char * png_charp; ++typedef const char * png_const_charp; ++typedef png_fixed_point * png_fixed_point_p; ++typedef const png_fixed_point * png_const_fixed_point_p; ++typedef png_size_t * png_size_tp; ++typedef const png_size_t * png_const_size_tp; + + #ifdef PNG_STDIO_SUPPORTED + typedef FILE * png_FILE_p; + #endif + + #ifdef PNG_FLOATING_POINT_SUPPORTED +-typedef double FAR * png_doublep; +-typedef PNG_CONST double FAR * png_const_doublep; ++typedef double * png_doublep; ++typedef const double * png_const_doublep; + #endif + + /* Pointers to pointers; i.e. arrays */ +-typedef png_byte FAR * FAR * png_bytepp; +-typedef png_uint_32 FAR * FAR * png_uint_32pp; +-typedef png_int_32 FAR * FAR * png_int_32pp; +-typedef png_uint_16 FAR * FAR * png_uint_16pp; +-typedef png_int_16 FAR * FAR * png_int_16pp; +-typedef PNG_CONST char FAR * FAR * png_const_charpp; +-typedef char FAR * FAR * png_charpp; +-typedef png_fixed_point FAR * FAR * png_fixed_point_pp; ++typedef png_byte * * png_bytepp; ++typedef png_uint_32 * * png_uint_32pp; ++typedef png_int_32 * * png_int_32pp; ++typedef png_uint_16 * * png_uint_16pp; ++typedef png_int_16 * * png_int_16pp; ++typedef const char * * png_const_charpp; ++typedef char * * png_charpp; ++typedef png_fixed_point * * png_fixed_point_pp; + #ifdef PNG_FLOATING_POINT_SUPPORTED +-typedef double FAR * FAR * png_doublepp; ++typedef double * * png_doublepp; + #endif + + /* Pointers to pointers to pointers; i.e., pointer to array */ +-typedef char FAR * FAR * FAR * png_charppp; ++typedef char * * * png_charppp; + +-/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, +- * and no smaller than png_uint_32. Casts from png_size_t or png_uint_32 +- * to png_alloc_size_t are not necessary; in fact, it is recommended +- * not to use them at all so that the compiler can complain when something +- * turns out to be problematic. +- * Casts in the other direction (from png_alloc_size_t to png_size_t or +- * png_uint_32) should be explicitly applied; however, we do not expect +- * to encounter practical situations that require such conversions. +- */ +-#if defined(__TURBOC__) && !defined(__FLAT__) +- typedef unsigned long png_alloc_size_t; +-#else +-# if defined(_MSC_VER) && defined(MAXSEG_64K) +- typedef unsigned long png_alloc_size_t; +-# else +- /* This is an attempt to detect an old Windows system where (int) is +- * actually 16 bits, in that case png_malloc must have an argument with a +- * bigger size to accommodate the requirements of the library. +- */ +-# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) && \ +- (!defined(INT_MAX) || INT_MAX <= 0x7ffffffeL) +- typedef DWORD png_alloc_size_t; +-# else +- typedef png_size_t png_alloc_size_t; +-# endif +-# endif +-#endif ++#endif /* PNG_BUILDING_SYMBOL_TABLE */ + + #endif /* PNGCONF_H */ +--- ./jdk/src/share/native/sun/awt/libpng/pngdebug.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngdebug.h Thu Feb 05 13:00:26 2015 +0100 +@@ -29,11 +29,11 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +- * Last changed in libpng 1.5.0 [January 6, 2011] ++ * Last changed in libpng 1.6.8 [December 19, 2013] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer +@@ -53,7 +53,7 @@ + * (actually ((void)0)). + * + * level: level of detail of message, starting at 0. A level 'n' +- * message is preceded by 'n' tab characters (not implemented ++ * message is preceded by 'n' 3-space indentations (not implemented + * on Microsoft compilers unless PNG_DEBUG_FILE is also + * defined, to allow debug DLL compilation with no standard IO). + * message: a printf(3) style text string. A trailing '\n' is added +@@ -105,32 +105,29 @@ + # endif /* PNG_DEBUG_FILE */ + + # if (PNG_DEBUG > 1) +-/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on +- * non-ISO compilers +- */ + # ifdef __STDC__ + # ifndef png_debug + # define png_debug(l,m) \ + do { \ + int num_tabs=l; \ +- fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ +- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ ++ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ ++ (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \ + } while (0) + # endif + # ifndef png_debug1 + # define png_debug1(l,m,p1) \ + do { \ + int num_tabs=l; \ +- fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ +- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ ++ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ ++ (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \ + } while (0) + # endif + # ifndef png_debug2 + # define png_debug2(l,m,p1,p2) \ + do { \ + int num_tabs=l; \ +- fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ +- (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ ++ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ ++ (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\ + } while (0) + # endif + # else /* __STDC __ */ +--- ./jdk/src/share/native/sun/awt/libpng/pngerror.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngerror.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -48,14 +48,14 @@ + + #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +-static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr, ++static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr, + png_const_charp error_message)),PNG_NORETURN); + + #ifdef PNG_WARNINGS_SUPPORTED + static void /* PRIVATE */ +-png_default_warning PNGARG((png_structp png_ptr, ++png_default_warning PNGARG((png_const_structrp png_ptr, + png_const_charp warning_message)); +-#endif /* PNG_WARNINGS_SUPPORTED */ ++#endif /* WARNINGS */ + + /* This function is called whenever there is a fatal error. This function + * should not be changed. If there is a need to handle errors differently, +@@ -64,14 +64,15 @@ + */ + #ifdef PNG_ERROR_TEXT_SUPPORTED + PNG_FUNCTION(void,PNGAPI +-png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN) ++png_error,(png_const_structrp png_ptr, png_const_charp error_message), ++ PNG_NORETURN) + { + #ifdef PNG_ERROR_NUMBERS_SUPPORTED + char msg[16]; + if (png_ptr != NULL) + { +- if (png_ptr->flags& +- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) ++ if ((png_ptr->flags & ++ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0 + { + if (*error_message == PNG_LITERAL_SHARP) + { +@@ -81,7 +82,7 @@ + if (error_message[offset] == ' ') + break; + +- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) ++ if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) + { + int i; + for (i = 0; i < offset - 1; i++) +@@ -96,7 +97,7 @@ + + else + { +- if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) ++ if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) + { + msg[0] = '0'; + msg[1] = '\0'; +@@ -107,7 +108,8 @@ + } + #endif + if (png_ptr != NULL && png_ptr->error_fn != NULL) +- (*(png_ptr->error_fn))(png_ptr, error_message); ++ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ++ error_message); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ +@@ -115,7 +117,7 @@ + } + #else + PNG_FUNCTION(void,PNGAPI +-png_err,(png_structp png_ptr),PNG_NORETURN) ++png_err,(png_const_structrp png_ptr),PNG_NORETURN) + { + /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed + * erroneously as '\0', instead of the empty string "". This was +@@ -123,13 +125,13 @@ + * will crash in this case. + */ + if (png_ptr != NULL && png_ptr->error_fn != NULL) +- (*(png_ptr->error_fn))(png_ptr, ""); ++ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ""); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, ""); + } +-#endif /* PNG_ERROR_TEXT_SUPPORTED */ ++#endif /* ERROR_TEXT */ + + /* Utility to safely appends strings to a buffer. This never errors out so + * error checking is not required in the caller. +@@ -178,7 +180,7 @@ + case PNG_NUMBER_FORMAT_fixed: + /* Needs five digits (the fraction) */ + mincount = 5; +- if (output || number % 10 != 0) ++ if (output != 0 || number % 10 != 0) + { + *--end = digits[number % 10]; + output = 1; +@@ -189,7 +191,7 @@ + case PNG_NUMBER_FORMAT_02u: + /* Expects at least 2 digits. */ + mincount = 2; +- /* fall through */ ++ /* FALL THROUGH */ + + case PNG_NUMBER_FORMAT_u: + *--end = digits[number % 10]; +@@ -199,7 +201,7 @@ + case PNG_NUMBER_FORMAT_02x: + /* This format expects at least two digits */ + mincount = 2; +- /* fall through */ ++ /* FALL THROUGH */ + + case PNG_NUMBER_FORMAT_x: + *--end = digits[number & 0xf]; +@@ -215,13 +217,13 @@ + ++count; + + /* Float a fixed number here: */ +- if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start) ++ if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start)) + { + /* End of the fraction, but maybe nothing was output? In that case + * drop the decimal point. If the number is a true zero handle that + * here. + */ +- if (output) ++ if (output != 0) + *--end = '.'; + else if (number == 0) /* and !output */ + *--end = '0'; +@@ -239,14 +241,14 @@ + * png_set_error_fn() to replace the warning function at run-time. + */ + void PNGAPI +-png_warning(png_structp png_ptr, png_const_charp warning_message) ++png_warning(png_const_structrp png_ptr, png_const_charp warning_message) + { + int offset = 0; + if (png_ptr != NULL) + { + #ifdef PNG_ERROR_NUMBERS_SUPPORTED +- if (png_ptr->flags& +- (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) ++ if ((png_ptr->flags & ++ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) + #endif + { + if (*warning_message == PNG_LITERAL_SHARP) +@@ -258,7 +260,8 @@ + } + } + if (png_ptr != NULL && png_ptr->warning_fn != NULL) +- (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); ++ (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), ++ warning_message + offset); + else + png_default_warning(png_ptr, warning_message + offset); + } +@@ -306,38 +309,43 @@ + } + + void +-png_formatted_warning(png_structp png_ptr, png_warning_parameters p, ++png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, + png_const_charp message) + { +- /* The internal buffer is just 128 bytes - enough for all our messages, +- * overflow doesn't happen because this code checks! ++ /* The internal buffer is just 192 bytes - enough for all our messages, ++ * overflow doesn't happen because this code checks! If someone figures ++ * out how to send us a message longer than 192 bytes, all that will ++ * happen is that the message will be truncated appropriately. + */ +- size_t i; +- char msg[128]; ++ size_t i = 0; /* Index in the msg[] buffer: */ ++ char msg[192]; + +- for (i=0; i<(sizeof msg)-1 && *message != '\0'; ++i) ++ /* Each iteration through the following loop writes at most one character ++ * to msg[i++] then returns here to validate that there is still space for ++ * the trailing '\0'. It may (in the case of a parameter) read more than ++ * one character from message[]; it must check for '\0' and continue to the ++ * test if it finds the end of string. ++ */ ++ while (i<(sizeof msg)-1 && *message != '\0') + { +- if (*message == '@') ++ /* '@' at end of string is now just printed (previously it was skipped); ++ * it is an error in the calling code to terminate the string with @. ++ */ ++ if (p != NULL && *message == '@' && message[1] != '\0') + { +- int parameter = -1; +- switch (*++message) +- { +- case '1': +- parameter = 0; +- break; ++ int parameter_char = *++message; /* Consume the '@' */ ++ static const char valid_parameters[] = "123456789"; ++ int parameter = 0; + +- case '2': +- parameter = 1; +- break; ++ /* Search for the parameter digit, the index in the string is the ++ * parameter to use. ++ */ ++ while (valid_parameters[parameter] != parameter_char && ++ valid_parameters[parameter] != '\0') ++ ++parameter; + +- case '\0': +- continue; /* To break out of the for loop above. */ +- +- default: +- break; +- } +- +- if (parameter >= 0 && parameter < PNG_WARNING_PARAMETER_COUNT) ++ /* If the parameter digit is out of range it will just get printed. */ ++ if (parameter < PNG_WARNING_PARAMETER_COUNT) + { + /* Append this parameter */ + png_const_charp parm = p[parameter]; +@@ -347,47 +355,101 @@ + * that parm[] has been initialized, so there is no guarantee of a + * trailing '\0': + */ +- for (; i<(sizeof msg)-1 && parm != '\0' && parm < pend; ++i) +- msg[i] = *parm++; ++ while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) ++ msg[i++] = *parm++; + ++ /* Consume the parameter digit too: */ + ++message; + continue; + } + + /* else not a parameter and there is a character after the @ sign; just +- * copy that. ++ * copy that. This is known not to be '\0' because of the test above. + */ + } + + /* At this point *message can't be '\0', even in the bad parameter case + * above where there is a lone '@' at the end of the message string. + */ +- msg[i] = *message++; ++ msg[i++] = *message++; + } + + /* i is always less than (sizeof msg), so: */ + msg[i] = '\0'; + +- /* And this is the formatted message: */ ++ /* And this is the formatted message. It may be larger than ++ * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these ++ * are not (currently) formatted. ++ */ + png_warning(png_ptr, msg); + } +-#endif /* PNG_WARNINGS_SUPPORTED */ ++#endif /* WARNINGS */ + + #ifdef PNG_BENIGN_ERRORS_SUPPORTED + void PNGAPI +-png_benign_error(png_structp png_ptr, png_const_charp error_message) ++png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) + { +- if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) ++ if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) ++ { ++# ifdef PNG_READ_SUPPORTED ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && ++ png_ptr->chunk_name != 0) ++ png_chunk_warning(png_ptr, error_message); ++ else ++# endif ++ png_warning(png_ptr, error_message); ++ } ++ ++ else ++ { ++# ifdef PNG_READ_SUPPORTED ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && ++ png_ptr->chunk_name != 0) ++ png_chunk_error(png_ptr, error_message); ++ else ++# endif ++ png_error(png_ptr, error_message); ++ } ++ ++# ifndef PNG_ERROR_TEXT_SUPPORTED ++ PNG_UNUSED(error_message) ++# endif ++} ++ ++void /* PRIVATE */ ++png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) ++{ ++ if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); ++ ++# ifndef PNG_ERROR_TEXT_SUPPORTED ++ PNG_UNUSED(error_message) ++# endif + } +-#endif + ++void /* PRIVATE */ ++png_app_error(png_const_structrp png_ptr, png_const_charp error_message) ++{ ++ if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) ++ png_warning(png_ptr, error_message); ++ else ++ png_error(png_ptr, error_message); ++ ++# ifndef PNG_ERROR_TEXT_SUPPORTED ++ PNG_UNUSED(error_message) ++# endif ++} ++#endif /* BENIGN_ERRORS */ ++ ++#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */ ++#if defined(PNG_WARNINGS_SUPPORTED) || \ ++ (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)) + /* These utilities are used internally to build an error message that relates + * to the current chunk. The chunk name comes from png_ptr->chunk_name, +- * this is used to prefix the message. The message is limited in length +- * to 63 bytes, the name characters are output as hex digits wrapped in [] ++ * which is used to prefix the message. The message is limited in length ++ * to 63 bytes. The name characters are output as hex digits wrapped in [] + * if the character is invalid. + */ + #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) +@@ -396,18 +458,19 @@ + 'A', 'B', 'C', 'D', 'E', 'F' + }; + +-#define PNG_MAX_ERROR_TEXT 64 +-#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) + static void /* PRIVATE */ +-png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp ++png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp + error_message) + { +- int iout = 0, iin = 0; ++ png_uint_32 chunk_name = png_ptr->chunk_name; ++ int iout = 0, ishift = 24; + +- while (iin < 4) ++ while (ishift >= 0) + { +- int c = png_ptr->chunk_name[iin++]; +- if (isnonalpha(c)) ++ int c = (int)(chunk_name >> ishift) & 0xff; ++ ++ ishift -= 8; ++ if (isnonalpha(c) != 0) + { + buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; + buffer[iout++] = png_digit[(c & 0xf0) >> 4]; +@@ -417,7 +480,7 @@ + + else + { +- buffer[iout++] = (png_byte)c; ++ buffer[iout++] = (char)c; + } + } + +@@ -426,10 +489,11 @@ + + else + { ++ int iin = 0; ++ + buffer[iout++] = ':'; + buffer[iout++] = ' '; + +- iin = 0; + while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') + buffer[iout++] = error_message[iin++]; + +@@ -437,11 +501,11 @@ + buffer[iout] = '\0'; + } + } +-#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */ ++#endif /* WARNINGS || ERROR_TEXT */ + + #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) + PNG_FUNCTION(void,PNGAPI +-png_chunk_error,(png_structp png_ptr, png_const_charp error_message), ++png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN) + { + char msg[18+PNG_MAX_ERROR_TEXT]; +@@ -454,11 +518,11 @@ + png_error(png_ptr, msg); + } + } +-#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */ ++#endif /* READ && ERROR_TEXT */ + + #ifdef PNG_WARNINGS_SUPPORTED + void PNGAPI +-png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) ++png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message) + { + char msg[18+PNG_MAX_ERROR_TEXT]; + if (png_ptr == NULL) +@@ -470,38 +534,83 @@ + png_warning(png_ptr, msg); + } + } +-#endif /* PNG_WARNINGS_SUPPORTED */ ++#endif /* WARNINGS */ + + #ifdef PNG_READ_SUPPORTED + #ifdef PNG_BENIGN_ERRORS_SUPPORTED + void PNGAPI +-png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) ++png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp ++ error_message) + { +- if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) ++ if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) + png_chunk_warning(png_ptr, error_message); + + else + png_chunk_error(png_ptr, error_message); ++ ++# ifndef PNG_ERROR_TEXT_SUPPORTED ++ PNG_UNUSED(error_message) ++# endif + } + #endif +-#endif /* PNG_READ_SUPPORTED */ ++#endif /* READ */ ++ ++void /* PRIVATE */ ++png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error) ++{ ++# ifndef PNG_WARNINGS_SUPPORTED ++ PNG_UNUSED(message) ++# endif ++ ++ /* This is always supported, but for just read or just write it ++ * unconditionally does the right thing. ++ */ ++# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) ++# endif ++ ++# ifdef PNG_READ_SUPPORTED ++ { ++ if (error < PNG_CHUNK_ERROR) ++ png_chunk_warning(png_ptr, message); ++ ++ else ++ png_chunk_benign_error(png_ptr, message); ++ } ++# endif ++ ++# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) ++ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) ++# endif ++ ++# ifdef PNG_WRITE_SUPPORTED ++ { ++ if (error < PNG_CHUNK_WRITE_ERROR) ++ png_app_warning(png_ptr, message); ++ ++ else ++ png_app_error(png_ptr, message); ++ } ++# endif ++} + + #ifdef PNG_ERROR_TEXT_SUPPORTED + #ifdef PNG_FLOATING_POINT_SUPPORTED + PNG_FUNCTION(void, +-png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN) ++png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) + { + # define fixed_message "fixed point overflow in " + # define fixed_message_ln ((sizeof fixed_message)-1) + int iin; + char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; +- png_memcpy(msg, fixed_message, fixed_message_ln); ++ memcpy(msg, fixed_message, fixed_message_ln); + iin = 0; +- if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) +- { +- msg[fixed_message_ln + iin] = name[iin]; +- ++iin; +- } ++ if (name != NULL) ++ while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) ++ { ++ msg[fixed_message_ln + iin] = name[iin]; ++ ++iin; ++ } + msg[fixed_message_ln + iin] = 0; + png_error(png_ptr, msg); + } +@@ -513,14 +622,111 @@ + * otherwise it is necessary for png_default_error to be overridden. + */ + jmp_buf* PNGAPI +-png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, ++png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, + size_t jmp_buf_size) + { +- if (png_ptr == NULL || jmp_buf_size != png_sizeof(jmp_buf)) ++ /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value ++ * and it must not change after that. Libpng doesn't care how big the ++ * buffer is, just that it doesn't change. ++ * ++ * If the buffer size is no *larger* than the size of jmp_buf when libpng is ++ * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0 ++ * semantics that this call will not fail. If the size is larger, however, ++ * the buffer is allocated and this may fail, causing the function to return ++ * NULL. ++ */ ++ if (png_ptr == NULL) + return NULL; + ++ if (png_ptr->jmp_buf_ptr == NULL) ++ { ++ png_ptr->jmp_buf_size = 0; /* not allocated */ ++ ++ if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local)) ++ png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; ++ ++ else ++ { ++ png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, ++ png_malloc_warn(png_ptr, jmp_buf_size)); ++ ++ if (png_ptr->jmp_buf_ptr == NULL) ++ return NULL; /* new NULL return on OOM */ ++ ++ png_ptr->jmp_buf_size = jmp_buf_size; ++ } ++ } ++ ++ else /* Already allocated: check the size */ ++ { ++ size_t size = png_ptr->jmp_buf_size; ++ ++ if (size == 0) ++ { ++ size = (sizeof png_ptr->jmp_buf_local); ++ if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local) ++ { ++ /* This is an internal error in libpng: somehow we have been left ++ * with a stack allocated jmp_buf when the application regained ++ * control. It's always possible to fix this up, but for the moment ++ * this is a png_error because that makes it easy to detect. ++ */ ++ png_error(png_ptr, "Libpng jmp_buf still allocated"); ++ /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */ ++ } ++ } ++ ++ if (size != jmp_buf_size) ++ { ++ png_warning(png_ptr, "Application jmp_buf size changed"); ++ return NULL; /* caller will probably crash: no choice here */ ++ } ++ } ++ ++ /* Finally fill in the function, now we have a satisfactory buffer. It is ++ * valid to change the function on every call. ++ */ + png_ptr->longjmp_fn = longjmp_fn; +- return &png_ptr->longjmp_buffer; ++ return png_ptr->jmp_buf_ptr; ++} ++ ++void /* PRIVATE */ ++png_free_jmpbuf(png_structrp png_ptr) ++{ ++ if (png_ptr != NULL) ++ { ++ jmp_buf *jb = png_ptr->jmp_buf_ptr; ++ ++ /* A size of 0 is used to indicate a local, stack, allocation of the ++ * pointer; used here and in png.c ++ */ ++ if (jb != NULL && png_ptr->jmp_buf_size > 0) ++ { ++ ++ /* This stuff is so that a failure to free the error control structure ++ * does not leave libpng in a state with no valid error handling: the ++ * free always succeeds, if there is an error it gets ignored. ++ */ ++ if (jb != &png_ptr->jmp_buf_local) ++ { ++ /* Make an internal, libpng, jmp_buf to return here */ ++ jmp_buf free_jmp_buf; ++ ++ if (!setjmp(free_jmp_buf)) ++ { ++ png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */ ++ png_ptr->jmp_buf_size = 0; /* stack allocation */ ++ png_ptr->longjmp_fn = longjmp; ++ png_free(png_ptr, jb); /* Return to setjmp on error */ ++ } ++ } ++ } ++ ++ /* *Always* cancel everything out: */ ++ png_ptr->jmp_buf_size = 0; ++ png_ptr->jmp_buf_ptr = NULL; ++ png_ptr->longjmp_fn = 0; ++ } + } + #endif + +@@ -530,7 +736,7 @@ + * error function pointer in png_set_error_fn(). + */ + static PNG_FUNCTION(void /* PRIVATE */, +-png_default_error,(png_structp png_ptr, png_const_charp error_message), ++png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN) + { + #ifdef PNG_CONSOLE_IO_SUPPORTED +@@ -577,24 +783,23 @@ + } + + PNG_FUNCTION(void,PNGAPI +-png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN) ++png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN) + { + #ifdef PNG_SETJMP_SUPPORTED +- if (png_ptr && png_ptr->longjmp_fn) +- { +-# ifdef USE_FAR_KEYWORD +- { +- jmp_buf tmp_jmpbuf; +- png_memcpy(tmp_jmpbuf, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); +- png_ptr->longjmp_fn(tmp_jmpbuf, val); +- } ++ if (png_ptr != NULL && png_ptr->longjmp_fn != NULL && ++ png_ptr->jmp_buf_ptr != NULL) ++ png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(val) ++#endif + +-# else +- png_ptr->longjmp_fn(png_ptr->longjmp_buffer, val); +-# endif +- } +-#endif +- /* Here if not setjmp support or if png_ptr is null. */ ++ /* If control reaches this point, png_longjmp() must not return. The only ++ * choice is to terminate the whole process (or maybe the thread); to do ++ * this the ANSI-C abort() function is used unless a different method is ++ * implemented by overriding the default configuration setting for ++ * PNG_ABORT(). ++ */ + PNG_ABORT(); + } + +@@ -605,7 +810,7 @@ + * not used, but it is passed in case it may be useful. + */ + static void /* PRIVATE */ +-png_default_warning(png_structp png_ptr, png_const_charp warning_message) ++png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) + { + #ifdef PNG_CONSOLE_IO_SUPPORTED + # ifdef PNG_ERROR_NUMBERS_SUPPORTED +@@ -647,15 +852,15 @@ + #endif + PNG_UNUSED(png_ptr) /* Make compiler happy */ + } +-#endif /* PNG_WARNINGS_SUPPORTED */ ++#endif /* WARNINGS */ + + /* This function is called when the application wants to use another method + * of handling errors and warnings. Note that the error function MUST NOT + * return to the calling routine or serious problems will occur. The return +- * method used in the default routine calls longjmp(png_ptr->longjmp_buffer, 1) ++ * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1) + */ + void PNGAPI +-png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, ++png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warning_fn) + { + if (png_ptr == NULL) +@@ -676,7 +881,7 @@ + * pointer before png_write_destroy and png_read_destroy are called. + */ + png_voidp PNGAPI +-png_get_error_ptr(png_const_structp png_ptr) ++png_get_error_ptr(png_const_structrp png_ptr) + { + if (png_ptr == NULL) + return NULL; +@@ -687,7 +892,7 @@ + + #ifdef PNG_ERROR_NUMBERS_SUPPORTED + void PNGAPI +-png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) ++png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) + { + if (png_ptr != NULL) + { +@@ -697,4 +902,90 @@ + } + } + #endif +-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ ++ ++#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ ++ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) ++ /* Currently the above both depend on SETJMP_SUPPORTED, however it would be ++ * possible to implement without setjmp support just so long as there is some ++ * way to handle the error return here: ++ */ ++PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI ++png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), ++ PNG_NORETURN) ++{ ++ const png_const_structrp png_ptr = png_nonconst_ptr; ++ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); ++ ++ /* An error is always logged here, overwriting anything (typically a warning) ++ * that is already there: ++ */ ++ if (image != NULL) ++ { ++ png_safecat(image->message, (sizeof image->message), 0, error_message); ++ image->warning_or_error |= PNG_IMAGE_ERROR; ++ ++ /* Retrieve the jmp_buf from within the png_control, making this work for ++ * C++ compilation too is pretty tricky: C++ wants a pointer to the first ++ * element of a jmp_buf, but C doesn't tell us the type of that. ++ */ ++ if (image->opaque != NULL && image->opaque->error_buf != NULL) ++ longjmp(png_control_jmp_buf(image->opaque), 1); ++ ++ /* Missing longjmp buffer, the following is to help debugging: */ ++ { ++ size_t pos = png_safecat(image->message, (sizeof image->message), 0, ++ "bad longjmp: "); ++ png_safecat(image->message, (sizeof image->message), pos, ++ error_message); ++ } ++ } ++ ++ /* Here on an internal programming error. */ ++ abort(); ++} ++ ++#ifdef PNG_WARNINGS_SUPPORTED ++void /* PRIVATE */ PNGCBAPI ++png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) ++{ ++ const png_const_structrp png_ptr = png_nonconst_ptr; ++ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); ++ ++ /* A warning is only logged if there is no prior warning or error. */ ++ if (image->warning_or_error == 0) ++ { ++ png_safecat(image->message, (sizeof image->message), 0, warning_message); ++ image->warning_or_error |= PNG_IMAGE_WARNING; ++ } ++} ++#endif ++ ++int /* PRIVATE */ ++png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) ++{ ++ volatile png_imagep image = image_in; ++ volatile int result; ++ volatile png_voidp saved_error_buf; ++ jmp_buf safe_jmpbuf; ++ ++ /* Safely execute function(arg) with png_error returning to this function. */ ++ saved_error_buf = image->opaque->error_buf; ++ result = setjmp(safe_jmpbuf) == 0; ++ ++ if (result != 0) ++ { ++ ++ image->opaque->error_buf = safe_jmpbuf; ++ result = function(arg); ++ } ++ ++ image->opaque->error_buf = saved_error_buf; ++ ++ /* And do the cleanup prior to any failure return. */ ++ if (result == 0) ++ png_image_free(image); ++ ++ return result; ++} ++#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ ++#endif /* READ || WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pngget.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngget.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.1 [February 3, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -45,7 +45,7 @@ + #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + + png_uint_32 PNGAPI +-png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 flag) + { + if (png_ptr != NULL && info_ptr != NULL) +@@ -55,7 +55,7 @@ + } + + png_size_t PNGAPI +-png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->rowbytes); +@@ -65,7 +65,7 @@ + + #ifdef PNG_INFO_IMAGE_SUPPORTED + png_bytepp PNGAPI +-png_get_rows(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->row_pointers); +@@ -77,7 +77,7 @@ + #ifdef PNG_EASY_ACCESS_SUPPORTED + /* Easy access to info, added in libpng-0.99 */ + png_uint_32 PNGAPI +-png_get_image_width(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->width; +@@ -86,7 +86,7 @@ + } + + png_uint_32 PNGAPI +-png_get_image_height(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->height; +@@ -95,7 +95,7 @@ + } + + png_byte PNGAPI +-png_get_bit_depth(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->bit_depth; +@@ -104,7 +104,7 @@ + } + + png_byte PNGAPI +-png_get_color_type(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->color_type; +@@ -113,7 +113,7 @@ + } + + png_byte PNGAPI +-png_get_filter_type(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->filter_type; +@@ -122,7 +122,7 @@ + } + + png_byte PNGAPI +-png_get_interlace_type(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->interlace_type; +@@ -131,7 +131,7 @@ + } + + png_byte PNGAPI +-png_get_compression_type(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->compression_type; +@@ -140,10 +140,12 @@ + } + + png_uint_32 PNGAPI +-png_get_x_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp ++ info_ptr) + { + #ifdef PNG_pHYs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + png_debug1(1, "in %s retrieval function", + "png_get_x_pixels_per_meter"); +@@ -151,16 +153,21 @@ + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->x_pixels_per_unit); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return (0); + } + + png_uint_32 PNGAPI +-png_get_y_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp ++ info_ptr) + { + #ifdef PNG_pHYs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + png_debug1(1, "in %s retrieval function", + "png_get_y_pixels_per_meter"); +@@ -168,16 +175,20 @@ + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->y_pixels_per_unit); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return (0); + } + + png_uint_32 PNGAPI +-png_get_pixels_per_meter(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + #ifdef PNG_pHYs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); + +@@ -185,6 +196,9 @@ + info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) + return (info_ptr->x_pixels_per_unit); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return (0); +@@ -192,10 +206,12 @@ + + #ifdef PNG_FLOATING_POINT_SUPPORTED + float PNGAPI +-png_get_pixel_aspect_ratio(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp ++ info_ptr) + { + #ifdef PNG_READ_pHYs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); + +@@ -203,6 +219,9 @@ + return ((float)((float)info_ptr->y_pixels_per_unit + /(float)info_ptr->x_pixels_per_unit)); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return ((float)0.0); +@@ -211,14 +230,15 @@ + + #ifdef PNG_FIXED_POINT_SUPPORTED + png_fixed_point PNGAPI +-png_get_pixel_aspect_ratio_fixed(png_const_structp png_ptr, +- png_const_infop info_ptr) ++png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, ++ png_const_inforp info_ptr) + { + #ifdef PNG_READ_pHYs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) +- && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 +- && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX +- && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_pHYs) != 0 && ++ info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && ++ info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX && ++ info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) + { + png_fixed_point res; + +@@ -228,9 +248,12 @@ + * range of 0..2^31-1; otherwise the cast might overflow. + */ + if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, +- (png_int_32)info_ptr->x_pixels_per_unit)) ++ (png_int_32)info_ptr->x_pixels_per_unit) != 0) + return res; + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return 0; +@@ -238,64 +261,80 @@ + #endif + + png_int_32 PNGAPI +-png_get_x_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + #ifdef PNG_oFFs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->x_offset); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return (0); + } + + png_int_32 PNGAPI +-png_get_y_offset_microns(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + #ifdef PNG_oFFs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->y_offset); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return (0); + } + + png_int_32 PNGAPI +-png_get_x_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + #ifdef PNG_oFFs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->x_offset); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return (0); + } + + png_int_32 PNGAPI +-png_get_y_offset_pixels(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + #ifdef PNG_oFFs_SUPPORTED +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); + + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->y_offset); + } ++#else ++ PNG_UNUSED(png_ptr) ++ PNG_UNUSED(info_ptr) + #endif + + return (0); +@@ -326,7 +365,7 @@ + */ + png_fixed_point result; + if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, +- 5000)) ++ 5000) != 0) + return result; + + /* Overflow. */ +@@ -335,26 +374,26 @@ + } + + png_uint_32 PNGAPI +-png_get_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); + } + + png_uint_32 PNGAPI +-png_get_x_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); + } + + png_uint_32 PNGAPI +-png_get_y_pixels_per_inch(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); + } + + #ifdef PNG_FIXED_POINT_SUPPORTED + static png_fixed_point +-png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns) ++png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) + { + /* Convert from metres * 1,000,000 to inches * 100,000, meters to + * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. +@@ -365,8 +404,8 @@ + } + + png_fixed_point PNGAPI +-png_get_x_offset_inches_fixed(png_structp png_ptr, +- png_const_infop info_ptr) ++png_get_x_offset_inches_fixed(png_const_structrp png_ptr, ++ png_const_inforp info_ptr) + { + return png_fixed_inches_from_microns(png_ptr, + png_get_x_offset_microns(png_ptr, info_ptr)); +@@ -375,8 +414,8 @@ + + #ifdef PNG_FIXED_POINT_SUPPORTED + png_fixed_point PNGAPI +-png_get_y_offset_inches_fixed(png_structp png_ptr, +- png_const_infop info_ptr) ++png_get_y_offset_inches_fixed(png_const_structrp png_ptr, ++ png_const_inforp info_ptr) + { + return png_fixed_inches_from_microns(png_ptr, + png_get_y_offset_microns(png_ptr, info_ptr)); +@@ -385,7 +424,7 @@ + + #ifdef PNG_FLOATING_POINT_SUPPORTED + float PNGAPI +-png_get_x_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + /* To avoid the overflow do the conversion directly in floating + * point. +@@ -396,7 +435,7 @@ + + #ifdef PNG_FLOATING_POINT_SUPPORTED + float PNGAPI +-png_get_y_offset_inches(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + /* To avoid the overflow do the conversion directly in floating + * point. +@@ -407,12 +446,13 @@ + + #ifdef PNG_pHYs_SUPPORTED + png_uint_32 PNGAPI +-png_get_pHYs_dpi(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) + { + png_uint_32 retval = 0; + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + png_debug1(1, "in %s retrieval function", "pHYs"); + +@@ -443,15 +483,16 @@ + + return (retval); + } +-#endif /* PNG_pHYs_SUPPORTED */ +-#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ ++#endif /* pHYs */ ++#endif /* INCH_CONVERSIONS */ + + /* png_get_channels really belongs in here, too, but it's been around longer */ + +-#endif /* PNG_EASY_ACCESS_SUPPORTED */ ++#endif /* EASY_ACCESS */ ++ + + png_byte PNGAPI +-png_get_channels(png_const_structp png_ptr, png_const_infop info_ptr) ++png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->channels); +@@ -459,22 +500,25 @@ + return (0); + } + ++#ifdef PNG_READ_SUPPORTED + png_const_bytep PNGAPI +-png_get_signature(png_const_structp png_ptr, png_infop info_ptr) ++png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) + { + if (png_ptr != NULL && info_ptr != NULL) + return(info_ptr->signature); + + return (NULL); + } ++#endif + + #ifdef PNG_bKGD_SUPPORTED + png_uint_32 PNGAPI +-png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr, ++png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, + png_color_16p *background) + { +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) +- && background != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_bKGD) != 0 && ++ background != NULL) + { + png_debug1(1, "in %s retrieval function", "bKGD"); + +@@ -487,32 +531,95 @@ + #endif + + #ifdef PNG_cHRM_SUPPORTED ++/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the ++ * same time to correct the rgb grayscale coefficient defaults obtained from the ++ * cHRM chunk in 1.5.4 ++ */ + # ifdef PNG_FLOATING_POINT_SUPPORTED + png_uint_32 PNGAPI +-png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *white_x, double *white_y, double *red_x, double *red_y, + double *green_x, double *green_y, double *blue_x, double *blue_y) + { +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) ++ /* Quiet API change: this code used to only return the end points if a cHRM ++ * chunk was present, but the end points can also come from iCCP or sRGB ++ * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and ++ * the png_set_ APIs merely check that set end points are mutually ++ * consistent. ++ */ ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + { + png_debug1(1, "in %s retrieval function", "cHRM"); + + if (white_x != NULL) +- *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X"); ++ *white_x = png_float(png_ptr, ++ info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); + if (white_y != NULL) +- *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y"); ++ *white_y = png_float(png_ptr, ++ info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); + if (red_x != NULL) +- *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X"); ++ *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, ++ "cHRM red X"); + if (red_y != NULL) +- *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y"); ++ *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, ++ "cHRM red Y"); + if (green_x != NULL) +- *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X"); ++ *green_x = png_float(png_ptr, ++ info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); + if (green_y != NULL) +- *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y"); ++ *green_y = png_float(png_ptr, ++ info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); + if (blue_x != NULL) +- *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X"); ++ *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, ++ "cHRM blue X"); + if (blue_y != NULL) +- *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y"); ++ *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, ++ "cHRM blue Y"); ++ return (PNG_INFO_cHRM); ++ } ++ ++ return (0); ++} ++ ++png_uint_32 PNGAPI ++png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, ++ double *red_X, double *red_Y, double *red_Z, double *green_X, ++ double *green_Y, double *green_Z, double *blue_X, double *blue_Y, ++ double *blue_Z) ++{ ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) ++ { ++ png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); ++ ++ if (red_X != NULL) ++ *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, ++ "cHRM red X"); ++ if (red_Y != NULL) ++ *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, ++ "cHRM red Y"); ++ if (red_Z != NULL) ++ *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, ++ "cHRM red Z"); ++ if (green_X != NULL) ++ *green_X = png_float(png_ptr, ++ info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); ++ if (green_Y != NULL) ++ *green_Y = png_float(png_ptr, ++ info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); ++ if (green_Z != NULL) ++ *green_Z = png_float(png_ptr, ++ info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); ++ if (blue_X != NULL) ++ *blue_X = png_float(png_ptr, ++ info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); ++ if (blue_Y != NULL) ++ *blue_Y = png_float(png_ptr, ++ info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); ++ if (blue_Z != NULL) ++ *blue_Z = png_float(png_ptr, ++ info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); + return (PNG_INFO_cHRM); + } + +@@ -522,31 +629,69 @@ + + # ifdef PNG_FIXED_POINT_SUPPORTED + png_uint_32 PNGAPI +-png_get_cHRM_fixed(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, ++ png_fixed_point *int_red_X, png_fixed_point *int_red_Y, ++ png_fixed_point *int_red_Z, png_fixed_point *int_green_X, ++ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, ++ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, ++ png_fixed_point *int_blue_Z) ++{ ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) ++ { ++ png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); ++ ++ if (int_red_X != NULL) ++ *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; ++ if (int_red_Y != NULL) ++ *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; ++ if (int_red_Z != NULL) ++ *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; ++ if (int_green_X != NULL) ++ *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; ++ if (int_green_Y != NULL) ++ *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; ++ if (int_green_Z != NULL) ++ *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; ++ if (int_blue_X != NULL) ++ *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; ++ if (int_blue_Y != NULL) ++ *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; ++ if (int_blue_Z != NULL) ++ *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; ++ return (PNG_INFO_cHRM); ++ } ++ ++ return (0); ++} ++ ++png_uint_32 PNGAPI ++png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, + png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, + png_fixed_point *blue_x, png_fixed_point *blue_y) + { + png_debug1(1, "in %s retrieval function", "cHRM"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) + { + if (white_x != NULL) +- *white_x = info_ptr->x_white; ++ *white_x = info_ptr->colorspace.end_points_xy.whitex; + if (white_y != NULL) +- *white_y = info_ptr->y_white; ++ *white_y = info_ptr->colorspace.end_points_xy.whitey; + if (red_x != NULL) +- *red_x = info_ptr->x_red; ++ *red_x = info_ptr->colorspace.end_points_xy.redx; + if (red_y != NULL) +- *red_y = info_ptr->y_red; ++ *red_y = info_ptr->colorspace.end_points_xy.redy; + if (green_x != NULL) +- *green_x = info_ptr->x_green; ++ *green_x = info_ptr->colorspace.end_points_xy.greenx; + if (green_y != NULL) +- *green_y = info_ptr->y_green; ++ *green_y = info_ptr->colorspace.end_points_xy.greeny; + if (blue_x != NULL) +- *blue_x = info_ptr->x_blue; ++ *blue_x = info_ptr->colorspace.end_points_xy.bluex; + if (blue_y != NULL) +- *blue_y = info_ptr->y_blue; ++ *blue_y = info_ptr->colorspace.end_points_xy.bluey; + return (PNG_INFO_cHRM); + } + +@@ -556,49 +701,57 @@ + #endif + + #ifdef PNG_gAMA_SUPPORTED +-png_uint_32 PNGFAPI +-png_get_gAMA_fixed(png_const_structp png_ptr, png_const_infop info_ptr, ++# ifdef PNG_FIXED_POINT_SUPPORTED ++png_uint_32 PNGAPI ++png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *file_gamma) + { + png_debug1(1, "in %s retrieval function", "gAMA"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) +- && file_gamma != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && ++ file_gamma != NULL) + { +- *file_gamma = info_ptr->gamma; ++ *file_gamma = info_ptr->colorspace.gamma; + return (PNG_INFO_gAMA); + } + + return (0); + } ++# endif ++ + # ifdef PNG_FLOATING_POINT_SUPPORTED + png_uint_32 PNGAPI +-png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *file_gamma) + { +- png_fixed_point igamma; +- png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma); ++ png_debug1(1, "in %s retrieval function", "gAMA(float)"); + +- if (ok) +- *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA"); ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && ++ file_gamma != NULL) ++ { ++ *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, ++ "png_get_gAMA"); ++ return (PNG_INFO_gAMA); ++ } + +- return ok; ++ return (0); + } +- + # endif + #endif + + #ifdef PNG_sRGB_SUPPORTED + png_uint_32 PNGAPI +-png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *file_srgb_intent) + { + png_debug1(1, "in %s retrieval function", "sRGB"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) +- && file_srgb_intent != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) + { +- *file_srgb_intent = (int)info_ptr->srgb_intent; ++ *file_srgb_intent = info_ptr->colorspace.rendering_intent; + return (PNG_INFO_sRGB); + } + +@@ -608,22 +761,24 @@ + + #ifdef PNG_iCCP_SUPPORTED + png_uint_32 PNGAPI +-png_get_iCCP(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, + png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen) + { + png_debug1(1, "in %s retrieval function", "iCCP"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) +- && name != NULL && profile != NULL && proflen != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_iCCP) != 0 && ++ name != NULL && compression_type != NULL && profile != NULL && ++ proflen != NULL) + { + *name = info_ptr->iccp_name; + *profile = info_ptr->iccp_profile; +- /* Compression_type is a dummy so the API won't have to change +- * if we introduce multiple compression types later. ++ *proflen = png_get_uint_32(info_ptr->iccp_profile); ++ /* This is somewhat irrelevant since the profile data returned has ++ * actually been uncompressed. + */ +- *proflen = (int)info_ptr->iccp_proflen; +- *compression_type = (int)info_ptr->iccp_compression; ++ *compression_type = PNG_COMPRESSION_TYPE_BASE; + return (PNG_INFO_iCCP); + } + +@@ -632,14 +787,14 @@ + #endif + + #ifdef PNG_sPLT_SUPPORTED +-png_uint_32 PNGAPI +-png_get_sPLT(png_const_structp png_ptr, png_const_infop info_ptr, ++int PNGAPI ++png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, + png_sPLT_tpp spalettes) + { + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) + { + *spalettes = info_ptr->splt_palettes; +- return ((png_uint_32)info_ptr->splt_palettes_num); ++ return info_ptr->splt_palettes_num; + } + + return (0); +@@ -648,13 +803,13 @@ + + #ifdef PNG_hIST_SUPPORTED + png_uint_32 PNGAPI +-png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_16p *hist) + { + png_debug1(1, "in %s retrieval function", "hIST"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) +- && hist != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) + { + *hist = info_ptr->hist; + return (PNG_INFO_hIST); +@@ -665,11 +820,10 @@ + #endif + + png_uint_32 PNGAPI +-png_get_IHDR(png_structp png_ptr, png_infop info_ptr, ++png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, + int *color_type, int *interlace_type, int *compression_type, + int *filter_type) +- + { + png_debug1(1, "in %s retrieval function", "IHDR"); + +@@ -696,7 +850,7 @@ + * application has ignored our advice not to mess with the members + * of info_ptr directly. + */ +- png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, ++ png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, + info_ptr->compression_type, info_ptr->filter_type); + +@@ -705,13 +859,14 @@ + + #ifdef PNG_oFFs_SUPPORTED + png_uint_32 PNGAPI +-png_get_oFFs(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) + { + png_debug1(1, "in %s retrieval function", "oFFs"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) +- && offset_x != NULL && offset_y != NULL && unit_type != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_oFFs) != 0 && ++ offset_x != NULL && offset_y != NULL && unit_type != NULL) + { + *offset_x = info_ptr->x_offset; + *offset_y = info_ptr->y_offset; +@@ -725,14 +880,15 @@ + + #ifdef PNG_pCAL_SUPPORTED + png_uint_32 PNGAPI +-png_get_pCAL(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, + png_charp *units, png_charpp *params) + { + png_debug1(1, "in %s retrieval function", "pCAL"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) +- && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_pCAL) != 0 && ++ purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && + nparams != NULL && units != NULL && params != NULL) + { + *purpose = info_ptr->pcal_purpose; +@@ -751,16 +907,20 @@ + + #ifdef PNG_sCAL_SUPPORTED + # ifdef PNG_FIXED_POINT_SUPPORTED +-# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED ++# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ ++ defined(PNG_FLOATING_POINT_SUPPORTED) + png_uint_32 PNGAPI +-png_get_sCAL_fixed(png_structp png_ptr, png_const_infop info_ptr, ++png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, png_fixed_point *width, png_fixed_point *height) + { + if (png_ptr != NULL && info_ptr != NULL && +- (info_ptr->valid & PNG_INFO_sCAL)) ++ (info_ptr->valid & PNG_INFO_sCAL) != 0) + { + *unit = info_ptr->scal_unit; +- /*TODO: make this work without FP support */ ++ /*TODO: make this work without FP support; the API is currently eliminated ++ * if neither floating point APIs nor internal floating point arithmetic ++ * are enabled. ++ */ + *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); + *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), + "sCAL height"); +@@ -773,11 +933,11 @@ + # endif /* FIXED_POINT */ + # ifdef PNG_FLOATING_POINT_SUPPORTED + png_uint_32 PNGAPI +-png_get_sCAL(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, double *width, double *height) + { + if (png_ptr != NULL && info_ptr != NULL && +- (info_ptr->valid & PNG_INFO_sCAL)) ++ (info_ptr->valid & PNG_INFO_sCAL) != 0) + { + *unit = info_ptr->scal_unit; + *width = atof(info_ptr->scal_s_width); +@@ -789,11 +949,11 @@ + } + # endif /* FLOATING POINT */ + png_uint_32 PNGAPI +-png_get_sCAL_s(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, png_charpp width, png_charpp height) + { + if (png_ptr != NULL && info_ptr != NULL && +- (info_ptr->valid & PNG_INFO_sCAL)) ++ (info_ptr->valid & PNG_INFO_sCAL) != 0) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_s_width; +@@ -807,7 +967,7 @@ + + #ifdef PNG_pHYs_SUPPORTED + png_uint_32 PNGAPI +-png_get_pHYs(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) + { + png_uint_32 retval = 0; +@@ -815,7 +975,7 @@ + png_debug1(1, "in %s retrieval function", "pHYs"); + + if (png_ptr != NULL && info_ptr != NULL && +- (info_ptr->valid & PNG_INFO_pHYs)) ++ (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + if (res_x != NULL) + { +@@ -841,13 +1001,13 @@ + #endif /* pHYs */ + + png_uint_32 PNGAPI +-png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, + png_colorp *palette, int *num_palette) + { + png_debug1(1, "in %s retrieval function", "PLTE"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) +- && palette != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL) + { + *palette = info_ptr->palette; + *num_palette = info_ptr->num_palette; +@@ -860,13 +1020,13 @@ + + #ifdef PNG_sBIT_SUPPORTED + png_uint_32 PNGAPI +-png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr, ++png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, + png_color_8p *sig_bit) + { + png_debug1(1, "in %s retrieval function", "sBIT"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) +- && sig_bit != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) + { + *sig_bit = &(info_ptr->sig_bit); + return (PNG_INFO_sBIT); +@@ -877,15 +1037,14 @@ + #endif + + #ifdef PNG_TEXT_SUPPORTED +-png_uint_32 PNGAPI +-png_get_text(png_const_structp png_ptr, png_const_infop info_ptr, ++int PNGAPI ++png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, + png_textp *text_ptr, int *num_text) + { + if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) + { +- png_debug1(1, "in %s retrieval function", +- (png_ptr->chunk_name[0] == '\0' ? "text" : +- (png_const_charp)png_ptr->chunk_name)); ++ png_debug1(1, "in 0x%lx retrieval function", ++ (unsigned long)png_ptr->chunk_name); + + if (text_ptr != NULL) + *text_ptr = info_ptr->text; +@@ -893,7 +1052,7 @@ + if (num_text != NULL) + *num_text = info_ptr->num_text; + +- return ((png_uint_32)info_ptr->num_text); ++ return info_ptr->num_text; + } + + if (num_text != NULL) +@@ -905,12 +1064,13 @@ + + #ifdef PNG_tIME_SUPPORTED + png_uint_32 PNGAPI +-png_get_tIME(png_const_structp png_ptr, png_infop info_ptr, png_timep *mod_time) ++png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, ++ png_timep *mod_time) + { + png_debug1(1, "in %s retrieval function", "tIME"); + +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) +- && mod_time != NULL) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) + { + *mod_time = &(info_ptr->mod_time); + return (PNG_INFO_tIME); +@@ -922,11 +1082,12 @@ + + #ifdef PNG_tRNS_SUPPORTED + png_uint_32 PNGAPI +-png_get_tRNS(png_const_structp png_ptr, png_infop info_ptr, ++png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) + { + png_uint_32 retval = 0; +- if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) ++ if (png_ptr != NULL && info_ptr != NULL && ++ (info_ptr->valid & PNG_INFO_tRNS) != 0) + { + png_debug1(1, "in %s retrieval function", "tRNS"); + +@@ -965,9 +1126,9 @@ + } + #endif + +-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED ++#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + int PNGAPI +-png_get_unknown_chunks(png_const_structp png_ptr, png_const_infop info_ptr, ++png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, + png_unknown_chunkpp unknowns) + { + if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) +@@ -982,7 +1143,7 @@ + + #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte PNGAPI +-png_get_rgb_to_gray_status (png_const_structp png_ptr) ++png_get_rgb_to_gray_status (png_const_structrp png_ptr) + { + return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); + } +@@ -990,71 +1151,91 @@ + + #ifdef PNG_USER_CHUNKS_SUPPORTED + png_voidp PNGAPI +-png_get_user_chunk_ptr(png_const_structp png_ptr) ++png_get_user_chunk_ptr(png_const_structrp png_ptr) + { + return (png_ptr ? png_ptr->user_chunk_ptr : NULL); + } + #endif + + png_size_t PNGAPI +-png_get_compression_buffer_size(png_const_structp png_ptr) ++png_get_compression_buffer_size(png_const_structrp png_ptr) + { +- return (png_ptr ? png_ptr->zbuf_size : 0L); ++ if (png_ptr == NULL) ++ return 0; ++ ++# ifdef PNG_WRITE_SUPPORTED ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) ++# endif ++ { ++# ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++ return png_ptr->IDAT_read_size; ++# else ++ return PNG_IDAT_READ_SIZE; ++# endif ++ } ++ ++# ifdef PNG_WRITE_SUPPORTED ++ else ++ return png_ptr->zbuffer_size; ++# endif + } + +- + #ifdef PNG_SET_USER_LIMITS_SUPPORTED + /* These functions were added to libpng 1.2.6 and were enabled + * by default in libpng-1.4.0 */ + png_uint_32 PNGAPI +-png_get_user_width_max (png_const_structp png_ptr) ++png_get_user_width_max (png_const_structrp png_ptr) + { + return (png_ptr ? png_ptr->user_width_max : 0); + } + + png_uint_32 PNGAPI +-png_get_user_height_max (png_const_structp png_ptr) ++png_get_user_height_max (png_const_structrp png_ptr) + { + return (png_ptr ? png_ptr->user_height_max : 0); + } + + /* This function was added to libpng 1.4.0 */ + png_uint_32 PNGAPI +-png_get_chunk_cache_max (png_const_structp png_ptr) ++png_get_chunk_cache_max (png_const_structrp png_ptr) + { + return (png_ptr ? png_ptr->user_chunk_cache_max : 0); + } + + /* This function was added to libpng 1.4.1 */ + png_alloc_size_t PNGAPI +-png_get_chunk_malloc_max (png_const_structp png_ptr) ++png_get_chunk_malloc_max (png_const_structrp png_ptr) + { + return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); + } +-#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ ++#endif /* SET_USER_LIMITS */ + + /* These functions were added to libpng 1.4.0 */ + #ifdef PNG_IO_STATE_SUPPORTED + png_uint_32 PNGAPI +-png_get_io_state (png_structp png_ptr) ++png_get_io_state (png_const_structrp png_ptr) + { + return png_ptr->io_state; + } + + png_uint_32 PNGAPI +-png_get_io_chunk_type (png_const_structp png_ptr) +-{ +- return ((png_ptr->chunk_name[0] << 24) + +- (png_ptr->chunk_name[1] << 16) + +- (png_ptr->chunk_name[2] << 8) + +- (png_ptr->chunk_name[3])); +-} +- +-png_const_bytep PNGAPI +-png_get_io_chunk_name (png_structp png_ptr) ++png_get_io_chunk_type (png_const_structrp png_ptr) + { + return png_ptr->chunk_name; + } +-#endif /* ?PNG_IO_STATE_SUPPORTED */ ++#endif /* IO_STATE */ + +-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ ++#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED ++# ifdef PNG_GET_PALETTE_MAX_SUPPORTED ++int PNGAPI ++png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) ++{ ++ if (png_ptr != NULL && info_ptr != NULL) ++ return png_ptr->num_palette_max; ++ ++ return (-1); ++} ++# endif ++#endif ++ ++#endif /* READ || WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pnginfo.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pnginfo.h Thu Feb 05 13:00:26 2015 +0100 +@@ -29,11 +29,11 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +- * Last changed in libpng 1.5.0 [January 6, 2011] ++ * Last changed in libpng 1.6.1 [March 28, 2013] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer +@@ -83,7 +83,7 @@ + + struct png_info_def + { +- /* the following are necessary for every PNG file */ ++ /* The following are necessary for every PNG file */ + png_uint_32 width; /* width of image in pixels (from IHDR) */ + png_uint_32 height; /* height of image in pixels (from IHDR) */ + png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ +@@ -98,11 +98,17 @@ + png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ + png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + +- /* The following is informational only on read, and not used on writes. */ ++ /* The following are set by png_set_IHDR, called from the application on ++ * write, but the are never actually used by the write code. ++ */ + png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte spare_byte; /* to align the data, and for future use */ ++ ++#ifdef PNG_READ_SUPPORTED ++ /* This is never set during write */ + png_byte signature[8]; /* magic bytes read by libpng from start of file */ ++#endif + + /* The rest of the data is optional. If you are reading, check the + * valid field to see if the information in these are valid. If you +@@ -110,18 +116,25 @@ + * and initialize the appropriate fields below. + */ + +-#if defined(PNG_gAMA_SUPPORTED) +- /* The gAMA chunk describes the gamma characteristics of the system +- * on which the image was created, normally in the range [1.0, 2.5]. +- * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. ++#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) ++ /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are ++ * defined. When COLORSPACE is switched on all the colorspace-defining ++ * chunks should be enabled, when GAMMA is switched on all the gamma-defining ++ * chunks should be enabled. If this is not done it becomes possible to read ++ * inconsistent PNG files and assign a probably incorrect interpretation to ++ * the information. (In other words, by carefully choosing which chunks to ++ * recognize the system configuration can select an interpretation for PNG ++ * files containing ambiguous data and this will result in inconsistent ++ * behavior between different libpng builds!) + */ +- png_fixed_point gamma; ++ png_colorspace colorspace; + #endif + +-#ifdef PNG_sRGB_SUPPORTED +- /* GR-P, 0.96a */ +- /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ +- png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ ++#ifdef PNG_iCCP_SUPPORTED ++ /* iCCP chunk data. */ ++ png_charp iccp_name; /* profile name */ ++ png_bytep iccp_profile; /* International Color Consortium profile data */ ++ png_uint_32 iccp_proflen; /* ICC profile data length */ + #endif + + #ifdef PNG_TEXT_SUPPORTED +@@ -136,7 +149,7 @@ + int num_text; /* number of comments read or comments to write */ + int max_text; /* current size of text array */ + png_textp text; /* array of comments read or comments to write */ +-#endif /* PNG_TEXT_SUPPORTED */ ++#endif /* TEXT */ + + #ifdef PNG_tIME_SUPPORTED + /* The tIME chunk holds the last time the displayed image data was +@@ -211,23 +224,6 @@ + png_uint_16p hist; + #endif + +-#ifdef PNG_cHRM_SUPPORTED +- /* The cHRM chunk describes the CIE color characteristics of the monitor +- * on which the PNG was created. This data allows the viewer to do gamut +- * mapping of the input image to ensure that the viewer sees the same +- * colors in the image as the creator. Values are in the range +- * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. +- */ +- png_fixed_point x_white; +- png_fixed_point y_white; +- png_fixed_point x_red; +- png_fixed_point y_red; +- png_fixed_point x_green; +- png_fixed_point y_green; +- png_fixed_point x_blue; +- png_fixed_point y_blue; +-#endif +- + #ifdef PNG_pCAL_SUPPORTED + /* The pCAL chunk describes a transformation between the stored pixel + * values and original physical data values used to create the image. +@@ -252,25 +248,20 @@ + /* New members added in libpng-1.0.6 */ + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + +-#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ +- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) ++#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + /* Storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; +- int unknown_chunks_num; +-#endif + +-#ifdef PNG_iCCP_SUPPORTED +- /* iCCP chunk data. */ +- png_charp iccp_name; /* profile name */ +- png_bytep iccp_profile; /* International Color Consortium profile data */ +- png_uint_32 iccp_proflen; /* ICC profile data length */ +- png_byte iccp_compression; /* Always zero */ ++ /* The type of this field is limited by the type of ++ * png_struct::user_chunk_cache_max, else overflow can occur. ++ */ ++ int unknown_chunks_num; + #endif + + #ifdef PNG_sPLT_SUPPORTED + /* Data on sPLT chunks (there may be more than one). */ + png_sPLT_tp splt_palettes; +- png_uint_32 splt_palettes_num; ++ int splt_palettes_num; /* Match type returned by png_get API */ + #endif + + #ifdef PNG_sCAL_SUPPORTED +--- ./jdk/src/share/native/sun/awt/libpng/pnglibconf.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pnglibconf.h Thu Feb 05 13:00:26 2015 +0100 +@@ -34,69 +34,47 @@ + * file and, per its terms, should not be removed: + */ + +-/* libpng version 1.5.4 - last changed on June 22, 2011 */ ++/* libpng version 1.6.16,December 22, 2014 */ + +-/* Copyright (c) 1998-2011 Glenn Randers-Pehrson */ ++/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ + + /* This code is released under the libpng license. */ + /* For conditions of distribution and use, see the disclaimer */ + /* and license in png.h */ + + /* pnglibconf.h */ ++/* Machine generated file: DO NOT EDIT */ + /* Derived from: scripts/pnglibconf.dfa */ +-/* If you edit this file by hand you must obey the rules expressed in */ +-/* pnglibconf.dfa with respect to the dependencies between the following */ +-/* symbols. It is much better to generate a new file using */ +-/* scripts/libpngconf.mak */ +- + #ifndef PNGLCONF_H + #define PNGLCONF_H +-/* settings */ +-#define PNG_API_RULE 0 +-#define PNG_CALLOC_SUPPORTED +-#define PNG_COST_SHIFT 3 +-#define PNG_DEFAULT_READ_MACROS 1 +-#define PNG_GAMMA_THRESHOLD_FIXED 5000 +-#define PNG_MAX_GAMMA_8 11 +-#define PNG_QUANTIZE_BLUE_BITS 5 +-#define PNG_QUANTIZE_GREEN_BITS 5 +-#define PNG_QUANTIZE_RED_BITS 5 +-#define PNG_sCAL_PRECISION 5 +-#define PNG_USER_CHUNK_CACHE_MAX 0 +-#define PNG_USER_CHUNK_MALLOC_MAX 0 +-#define PNG_USER_HEIGHT_MAX 1000000L +-#define PNG_USER_WIDTH_MAX 1000000L +-#define PNG_WEIGHT_SHIFT 8 +-#define PNG_ZBUF_SIZE 8192 +-/* end of settings */ + /* options */ + #define PNG_16BIT_SUPPORTED +-#define PNG_ALIGN_MEMORY_SUPPORTED ++#define PNG_ALIGNED_MEMORY_SUPPORTED ++/*#undef PNG_ARM_NEON_API_SUPPORTED*/ ++/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ + #define PNG_BENIGN_ERRORS_SUPPORTED +-#define PNG_bKGD_SUPPORTED ++#define PNG_BENIGN_READ_ERRORS_SUPPORTED ++/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ + #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +-#define PNG_CHECK_cHRM_SUPPORTED +-#define PNG_cHRM_SUPPORTED ++#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED ++#define PNG_COLORSPACE_SUPPORTED + #define PNG_CONSOLE_IO_SUPPORTED +-#define PNG_CONVERT_tIME_SUPPORTED ++/*#undef PNG_CONVERT_tIME_SUPPORTED*/ + #define PNG_EASY_ACCESS_SUPPORTED + /*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ + #define PNG_ERROR_TEXT_SUPPORTED + #define PNG_FIXED_POINT_SUPPORTED + #define PNG_FLOATING_ARITHMETIC_SUPPORTED + #define PNG_FLOATING_POINT_SUPPORTED +-#define PNG_gAMA_SUPPORTED ++#define PNG_FORMAT_AFIRST_SUPPORTED ++#define PNG_FORMAT_BGR_SUPPORTED ++#define PNG_GAMMA_SUPPORTED ++#define PNG_GET_PALETTE_MAX_SUPPORTED + #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +-#define PNG_hIST_SUPPORTED +-#define PNG_iCCP_SUPPORTED + #define PNG_INCH_CONVERSIONS_SUPPORTED + #define PNG_INFO_IMAGE_SUPPORTED + #define PNG_IO_STATE_SUPPORTED +-#define PNG_iTXt_SUPPORTED + #define PNG_MNG_FEATURES_SUPPORTED +-#define PNG_oFFs_SUPPORTED +-#define PNG_pCAL_SUPPORTED +-#define PNG_pHYs_SUPPORTED + #define PNG_POINTER_INDEXING_SUPPORTED + #define PNG_PROGRESSIVE_READ_SUPPORTED + #define PNG_READ_16BIT_SUPPORTED +@@ -104,67 +82,73 @@ + #define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED + #define PNG_READ_BACKGROUND_SUPPORTED + #define PNG_READ_BGR_SUPPORTED +-#define PNG_READ_bKGD_SUPPORTED +-#define PNG_READ_cHRM_SUPPORTED ++#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + #define PNG_READ_COMPOSITE_NODIV_SUPPORTED + #define PNG_READ_COMPRESSED_TEXT_SUPPORTED + #define PNG_READ_EXPAND_16_SUPPORTED + #define PNG_READ_EXPAND_SUPPORTED + #define PNG_READ_FILLER_SUPPORTED +-#define PNG_READ_gAMA_SUPPORTED + #define PNG_READ_GAMMA_SUPPORTED ++#define PNG_READ_GET_PALETTE_MAX_SUPPORTED + #define PNG_READ_GRAY_TO_RGB_SUPPORTED +-#define PNG_READ_hIST_SUPPORTED +-#define PNG_READ_iCCP_SUPPORTED + #define PNG_READ_INTERLACING_SUPPORTED + #define PNG_READ_INT_FUNCTIONS_SUPPORTED + #define PNG_READ_INVERT_ALPHA_SUPPORTED + #define PNG_READ_INVERT_SUPPORTED +-#define PNG_READ_iTXt_SUPPORTED +-#define PNG_READ_oFFs_SUPPORTED + #define PNG_READ_OPT_PLTE_SUPPORTED ++#define PNG_READ_PACKSWAP_SUPPORTED + #define PNG_READ_PACK_SUPPORTED +-#define PNG_READ_PACKSWAP_SUPPORTED +-#define PNG_READ_pCAL_SUPPORTED +-#define PNG_READ_pHYs_SUPPORTED + #define PNG_READ_QUANTIZE_SUPPORTED + #define PNG_READ_RGB_TO_GRAY_SUPPORTED +-#define PNG_READ_sBIT_SUPPORTED + #define PNG_READ_SCALE_16_TO_8_SUPPORTED +-#define PNG_READ_sCAL_SUPPORTED + #define PNG_READ_SHIFT_SUPPORTED +-#define PNG_READ_sPLT_SUPPORTED +-#define PNG_READ_sRGB_SUPPORTED + #define PNG_READ_STRIP_16_TO_8_SUPPORTED + #define PNG_READ_STRIP_ALPHA_SUPPORTED + #define PNG_READ_SUPPORTED + #define PNG_READ_SWAP_ALPHA_SUPPORTED + #define PNG_READ_SWAP_SUPPORTED +-#define PNG_READ_tEXt_SUPPORTED + #define PNG_READ_TEXT_SUPPORTED +-#define PNG_READ_tIME_SUPPORTED + #define PNG_READ_TRANSFORMS_SUPPORTED +-#define PNG_READ_tRNS_SUPPORTED + #define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + #define PNG_READ_USER_CHUNKS_SUPPORTED + #define PNG_READ_USER_TRANSFORM_SUPPORTED ++#define PNG_READ_bKGD_SUPPORTED ++#define PNG_READ_cHRM_SUPPORTED ++#define PNG_READ_gAMA_SUPPORTED ++#define PNG_READ_hIST_SUPPORTED ++#define PNG_READ_iCCP_SUPPORTED ++#define PNG_READ_iTXt_SUPPORTED ++#define PNG_READ_oFFs_SUPPORTED ++#define PNG_READ_pCAL_SUPPORTED ++#define PNG_READ_pHYs_SUPPORTED ++#define PNG_READ_sBIT_SUPPORTED ++#define PNG_READ_sCAL_SUPPORTED ++#define PNG_READ_sPLT_SUPPORTED ++#define PNG_READ_sRGB_SUPPORTED ++#define PNG_READ_tEXt_SUPPORTED ++#define PNG_READ_tIME_SUPPORTED ++#define PNG_READ_tRNS_SUPPORTED + #define PNG_READ_zTXt_SUPPORTED +-#define PNG_SAVE_INT_32_SUPPORTED +-#define PNG_sBIT_SUPPORTED +-#define PNG_sCAL_SUPPORTED ++/*#undef PNG_SAFE_LIMITS_SUPPORTED*/ ++/*#undef PNG_SAVE_INT_32_SUPPORTED*/ ++#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED + #define PNG_SEQUENTIAL_READ_SUPPORTED ++#define PNG_SETJMP_SUPPORTED + #define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED + #define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +-#define PNG_SETJMP_SUPPORTED ++#define PNG_SET_OPTION_SUPPORTED ++#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + #define PNG_SET_USER_LIMITS_SUPPORTED +-#define PNG_sPLT_SUPPORTED +-#define PNG_sRGB_SUPPORTED ++#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED ++#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED ++#define PNG_SIMPLIFIED_READ_SUPPORTED ++/*#undef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED*/ ++/*#undef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED*/ ++/*#undef PNG_SIMPLIFIED_WRITE_SUPPORTED*/ + #define PNG_STDIO_SUPPORTED +-#define PNG_tEXt_SUPPORTED ++#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + #define PNG_TEXT_SUPPORTED + #define PNG_TIME_RFC1123_SUPPORTED +-#define PNG_tIME_SUPPORTED +-#define PNG_tRNS_SUPPORTED + #define PNG_UNKNOWN_CHUNKS_SUPPORTED + #define PNG_USER_CHUNKS_SUPPORTED + #define PNG_USER_LIMITS_SUPPORTED +@@ -172,6 +156,91 @@ + #define PNG_USER_TRANSFORM_INFO_SUPPORTED + #define PNG_USER_TRANSFORM_PTR_SUPPORTED + #define PNG_WARNINGS_SUPPORTED ++/*#undef PNG_WRITE_16BIT_SUPPORTED*/ ++/*#undef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED*/ ++/*#undef PNG_WRITE_BGR_SUPPORTED*/ ++/*#undef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED*/ ++/*#undef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED*/ ++/*#undef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED*/ ++/*#undef PNG_WRITE_FILLER_SUPPORTED*/ ++/*#undef PNG_WRITE_FILTER_SUPPORTED*/ ++/*#undef PNG_WRITE_FLUSH_SUPPORTED*/ ++/*#undef PNG_WRITE_GET_PALETTE_MAX_SUPPORTED*/ ++/*#undef PNG_WRITE_INTERLACING_SUPPORTED*/ ++/*#undef PNG_WRITE_INT_FUNCTIONS_SUPPORTED*/ ++/*#undef PNG_WRITE_INVERT_ALPHA_SUPPORTED*/ ++/*#undef PNG_WRITE_INVERT_SUPPORTED*/ ++/*#undef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED*/ ++/*#undef PNG_WRITE_PACKSWAP_SUPPORTED*/ ++/*#undef PNG_WRITE_PACK_SUPPORTED*/ ++/*#undef PNG_WRITE_SHIFT_SUPPORTED*/ ++/*#undef PNG_WRITE_SUPPORTED*/ ++/*#undef PNG_WRITE_SWAP_ALPHA_SUPPORTED*/ ++/*#undef PNG_WRITE_SWAP_SUPPORTED*/ ++/*#undef PNG_WRITE_TEXT_SUPPORTED*/ ++/*#undef PNG_WRITE_TRANSFORMS_SUPPORTED*/ ++/*#undef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED*/ ++/*#undef PNG_WRITE_USER_TRANSFORM_SUPPORTED*/ ++/*#undef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED*/ ++/*#undef PNG_WRITE_bKGD_SUPPORTED*/ ++/*#undef PNG_WRITE_cHRM_SUPPORTED*/ ++/*#undef PNG_WRITE_gAMA_SUPPORTED*/ ++/*#undef PNG_WRITE_hIST_SUPPORTED*/ ++/*#undef PNG_WRITE_iCCP_SUPPORTED*/ ++/*#undef PNG_WRITE_iTXt_SUPPORTED*/ ++/*#undef PNG_WRITE_oFFs_SUPPORTED*/ ++/*#undef PNG_WRITE_pCAL_SUPPORTED*/ ++/*#undef PNG_WRITE_pHYs_SUPPORTED*/ ++/*#undef PNG_WRITE_sBIT_SUPPORTED*/ ++/*#undef PNG_WRITE_sCAL_SUPPORTED*/ ++/*#undef PNG_WRITE_sPLT_SUPPORTED*/ ++/*#undef PNG_WRITE_sRGB_SUPPORTED*/ ++/*#undef PNG_WRITE_tEXt_SUPPORTED*/ ++/*#undef PNG_WRITE_tIME_SUPPORTED*/ ++/*#undef PNG_WRITE_tRNS_SUPPORTED*/ ++/*#undef PNG_WRITE_zTXt_SUPPORTED*/ ++#define PNG_bKGD_SUPPORTED ++#define PNG_cHRM_SUPPORTED ++#define PNG_gAMA_SUPPORTED ++#define PNG_hIST_SUPPORTED ++#define PNG_iCCP_SUPPORTED ++#define PNG_iTXt_SUPPORTED ++#define PNG_oFFs_SUPPORTED ++#define PNG_pCAL_SUPPORTED ++#define PNG_pHYs_SUPPORTED ++#define PNG_sBIT_SUPPORTED ++#define PNG_sCAL_SUPPORTED ++#define PNG_sPLT_SUPPORTED ++#define PNG_sRGB_SUPPORTED ++#define PNG_tEXt_SUPPORTED ++#define PNG_tIME_SUPPORTED ++#define PNG_tRNS_SUPPORTED + #define PNG_zTXt_SUPPORTED + /* end of options */ ++/* settings */ ++#define PNG_API_RULE 0 ++#define PNG_COST_SHIFT 3 ++#define PNG_DEFAULT_READ_MACROS 1 ++#define PNG_GAMMA_THRESHOLD_FIXED 5000 ++#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE ++#define PNG_INFLATE_BUF_SIZE 1024 ++#define PNG_MAX_GAMMA_8 11 ++#define PNG_QUANTIZE_BLUE_BITS 5 ++#define PNG_QUANTIZE_GREEN_BITS 5 ++#define PNG_QUANTIZE_RED_BITS 5 ++#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) ++#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 ++#define PNG_USER_CHUNK_CACHE_MAX 0 ++#define PNG_USER_CHUNK_MALLOC_MAX 0 ++#define PNG_USER_HEIGHT_MAX 1000000 ++#define PNG_USER_WIDTH_MAX 1000000 ++#define PNG_WEIGHT_SHIFT 8 ++#define PNG_ZBUF_SIZE 8192 ++#define PNG_ZLIB_VERNUM 0 ++#define PNG_Z_DEFAULT_COMPRESSION (-1) ++#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 ++#define PNG_Z_DEFAULT_STRATEGY 1 ++#define PNG_sCAL_PRECISION 5 ++#define PNG_sRGB_PROFILE_CHECKS 2 ++/* end of settings */ + #endif /* PNGLCONF_H */ +--- ./jdk/src/share/native/sun/awt/libpng/pngmem.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngmem.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -48,457 +48,23 @@ + #include "pngpriv.h" + + #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) ++/* Free a png_struct */ ++void /* PRIVATE */ ++png_destroy_png_struct(png_structrp png_ptr) ++{ ++ if (png_ptr != NULL) ++ { ++ /* png_free might call png_error and may certainly call ++ * png_get_mem_ptr, so fake a temporary png_struct to support this. ++ */ ++ png_struct dummy_struct = *png_ptr; ++ memset(png_ptr, 0, (sizeof *png_ptr)); ++ png_free(&dummy_struct, png_ptr); + +-/* Borland DOS special memory handler */ +-#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +-/* If you change this, be sure to change the one in png.h also */ +- +-/* Allocate memory for a png_struct. The malloc and memset can be replaced +- by a single call to calloc() if this is thought to improve performance. */ +-PNG_FUNCTION(png_voidp /* PRIVATE */, +-png_create_struct,(int type),PNG_ALLOCATED) +-{ +-# ifdef PNG_USER_MEM_SUPPORTED +- return (png_create_struct_2(type, NULL, NULL)); +-} +- +-/* Alternate version of png_create_struct, for use with user-defined malloc. */ +-PNG_FUNCTION(png_voidp /* PRIVATE */, +-png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), +- PNG_ALLOCATED) +-{ +-# endif /* PNG_USER_MEM_SUPPORTED */ +- png_size_t size; +- png_voidp struct_ptr; +- +- if (type == PNG_STRUCT_INFO) +- size = png_sizeof(png_info); +- +- else if (type == PNG_STRUCT_PNG) +- size = png_sizeof(png_struct); +- +- else +- return (png_get_copyright(NULL)); +- +-# ifdef PNG_USER_MEM_SUPPORTED +- if (malloc_fn != NULL) +- { +- png_struct dummy_struct; +- png_structp png_ptr = &dummy_struct; +- png_ptr->mem_ptr=mem_ptr; +- struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); +- } +- +- else +-# endif /* PNG_USER_MEM_SUPPORTED */ +- struct_ptr = (png_voidp)farmalloc(size); +- if (struct_ptr != NULL) +- png_memset(struct_ptr, 0, size); +- +- return (struct_ptr); +-} +- +-/* Free memory allocated by a png_create_struct() call */ +-void /* PRIVATE */ +-png_destroy_struct(png_voidp struct_ptr) +-{ +-# ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2(struct_ptr, NULL, NULL); +-} +- +-/* Free memory allocated by a png_create_struct() call */ +-void /* PRIVATE */ +-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, +- png_voidp mem_ptr) +-{ +-# endif +- if (struct_ptr != NULL) +- { +-# ifdef PNG_USER_MEM_SUPPORTED +- if (free_fn != NULL) +- { +- png_struct dummy_struct; +- png_structp png_ptr = &dummy_struct; +- png_ptr->mem_ptr=mem_ptr; +- (*(free_fn))(png_ptr, struct_ptr); +- return; +- } +- +-# endif /* PNG_USER_MEM_SUPPORTED */ +- farfree (struct_ptr); +- } +-} +- +-/* Allocate memory. For reasonable files, size should never exceed +- * 64K. However, zlib may allocate more then 64K if you don't tell +- * it not to. See zconf.h and png.h for more information. zlib does +- * need to allocate exactly 64K, so whatever you call here must +- * have the ability to do that. +- * +- * Borland seems to have a problem in DOS mode for exactly 64K. +- * It gives you a segment with an offset of 8 (perhaps to store its +- * memory stuff). zlib doesn't like this at all, so we have to +- * detect and deal with it. This code should not be needed in +- * Windows or OS/2 modes, and only in 16 bit mode. This code has +- * been updated by Alexander Lehmann for version 0.89 to waste less +- * memory. +- * +- * Note that we can't use png_size_t for the "size" declaration, +- * since on some systems a png_size_t is a 16-bit quantity, and as a +- * result, we would be truncating potentially larger memory requests +- * (which should cause a fatal error) and introducing major problems. +- */ +-PNG_FUNCTION(png_voidp,PNGAPI +-png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +-{ +- png_voidp ret; +- +- ret = (png_malloc(png_ptr, size)); +- +- if (ret != NULL) +- png_memset(ret,0,(png_size_t)size); +- +- return (ret); +-} +- +-PNG_FUNCTION(png_voidp,PNGAPI +-png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +-{ +- png_voidp ret; +- +- if (png_ptr == NULL || size == 0) +- return (NULL); +- +-# ifdef PNG_USER_MEM_SUPPORTED +- if (png_ptr->malloc_fn != NULL) +- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); +- +- else +- ret = (png_malloc_default(png_ptr, size)); +- +- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Out of memory"); +- +- return (ret); +-} +- +-PNG_FUNCTION(png_voidp,PNGAPI +-png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +-{ +- png_voidp ret; +-# endif /* PNG_USER_MEM_SUPPORTED */ +- +- if (png_ptr == NULL || size == 0) +- return (NULL); +- +-# ifdef PNG_MAX_MALLOC_64K +- if (size > (png_uint_32)65536L) +- { +- png_warning(png_ptr, "Cannot Allocate > 64K"); +- ret = NULL; +- } +- +- else +-# endif +- +- if (size != (size_t)size) +- ret = NULL; +- +- else if (size == (png_uint_32)65536L) +- { +- if (png_ptr->offset_table == NULL) +- { +- /* Try to see if we need to do any of this fancy stuff */ +- ret = farmalloc(size); +- if (ret == NULL || ((png_size_t)ret & 0xffff)) +- { +- int num_blocks; +- png_uint_32 total_size; +- png_bytep table; +- int i, mem_level, window_bits; +- png_byte huge * hptr; +- int window_bits +- +- if (ret != NULL) +- { +- farfree(ret); +- ret = NULL; +- } +- +- window_bits = +- png_ptr->zlib_window_bits >= png_ptr->zlib_text_window_bits ? +- png_ptr->zlib_window_bits : png_ptr->zlib_text_window_bits; +- +- if (window_bits > 14) +- num_blocks = (int)(1 << (window_bits - 14)); +- +- else +- num_blocks = 1; +- +- mem_level = +- png_ptr->zlib_mem_level >= png_ptr->zlib_text_mem_level ? +- png_ptr->zlib_mem_level : png_ptr->zlib_text_mem_level; +- +- if (mem_level >= 7) +- num_blocks += (int)(1 << (mem_level - 7)); +- +- else +- num_blocks++; +- +- total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; +- +- table = farmalloc(total_size); +- +- if (table == NULL) +- { +-# ifndef PNG_USER_MEM_SUPPORTED +- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */ +- +- else +- png_warning(png_ptr, "Out Of Memory"); +-# endif +- return (NULL); +- } +- +- if ((png_size_t)table & 0xfff0) +- { +-# ifndef PNG_USER_MEM_SUPPORTED +- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, +- "Farmalloc didn't return normalized pointer"); +- +- else +- png_warning(png_ptr, +- "Farmalloc didn't return normalized pointer"); +-# endif +- return (NULL); +- } +- +- png_ptr->offset_table = table; +- png_ptr->offset_table_ptr = farmalloc(num_blocks * +- png_sizeof(png_bytep)); +- +- if (png_ptr->offset_table_ptr == NULL) +- { +-# ifndef PNG_USER_MEM_SUPPORTED +- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */ +- +- else +- png_warning(png_ptr, "Out Of memory"); +-# endif +- return (NULL); +- } +- +- hptr = (png_byte huge *)table; +- if ((png_size_t)hptr & 0xf) +- { +- hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); +- hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ +- } +- +- for (i = 0; i < num_blocks; i++) +- { +- png_ptr->offset_table_ptr[i] = (png_bytep)hptr; +- hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ +- } +- +- png_ptr->offset_table_number = num_blocks; +- png_ptr->offset_table_count = 0; +- png_ptr->offset_table_count_free = 0; +- } +- } +- +- if (png_ptr->offset_table_count >= png_ptr->offset_table_number) +- { +-# ifndef PNG_USER_MEM_SUPPORTED +- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Out of Memory"); /* Note "O" and "M" */ +- +- else +- png_warning(png_ptr, "Out of Memory"); +-# endif +- return (NULL); +- } +- +- ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; +- } +- +- else +- ret = farmalloc(size); +- +-# ifndef PNG_USER_MEM_SUPPORTED +- if (ret == NULL) +- { +- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */ +- +- else +- png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */ +- } +-# endif +- +- return (ret); +-} +- +-/* Free a pointer allocated by png_malloc(). In the default +- * configuration, png_ptr is not used, but is passed in case it +- * is needed. If ptr is NULL, return without taking any action. +- */ +-void PNGAPI +-png_free(png_structp png_ptr, png_voidp ptr) +-{ +- if (png_ptr == NULL || ptr == NULL) +- return; +- +-# ifdef PNG_USER_MEM_SUPPORTED +- if (png_ptr->free_fn != NULL) +- { +- (*(png_ptr->free_fn))(png_ptr, ptr); +- return; +- } +- +- else +- png_free_default(png_ptr, ptr); +-} +- +-void PNGAPI +-png_free_default(png_structp png_ptr, png_voidp ptr) +-{ +-# endif /* PNG_USER_MEM_SUPPORTED */ +- +- if (png_ptr == NULL || ptr == NULL) +- return; +- +- if (png_ptr->offset_table != NULL) +- { +- int i; +- +- for (i = 0; i < png_ptr->offset_table_count; i++) +- { +- if (ptr == png_ptr->offset_table_ptr[i]) +- { +- ptr = NULL; +- png_ptr->offset_table_count_free++; +- break; +- } +- } +- if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) +- { +- farfree(png_ptr->offset_table); +- farfree(png_ptr->offset_table_ptr); +- png_ptr->offset_table = NULL; +- png_ptr->offset_table_ptr = NULL; +- } +- } +- +- if (ptr != NULL) +- farfree(ptr); +-} +- +-#else /* Not the Borland DOS special memory handler */ +- +-/* Allocate memory for a png_struct or a png_info. The malloc and +- memset can be replaced by a single call to calloc() if this is thought +- to improve performance noticably. */ +-PNG_FUNCTION(png_voidp /* PRIVATE */, +-png_create_struct,(int type),PNG_ALLOCATED) +-{ +-# ifdef PNG_USER_MEM_SUPPORTED +- return (png_create_struct_2(type, NULL, NULL)); +-} +- +-/* Allocate memory for a png_struct or a png_info. The malloc and +- memset can be replaced by a single call to calloc() if this is thought +- to improve performance noticably. */ +-PNG_FUNCTION(png_voidp /* PRIVATE */, +-png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), +- PNG_ALLOCATED) +-{ +-# endif /* PNG_USER_MEM_SUPPORTED */ +- png_size_t size; +- png_voidp struct_ptr; +- +- if (type == PNG_STRUCT_INFO) +- size = png_sizeof(png_info); +- +- else if (type == PNG_STRUCT_PNG) +- size = png_sizeof(png_struct); +- +- else +- return (NULL); +- +-# ifdef PNG_USER_MEM_SUPPORTED +- if (malloc_fn != NULL) +- { +- png_struct dummy_struct; +- png_structp png_ptr = &dummy_struct; +- png_ptr->mem_ptr=mem_ptr; +- struct_ptr = (*(malloc_fn))(png_ptr, size); +- +- if (struct_ptr != NULL) +- png_memset(struct_ptr, 0, size); +- +- return (struct_ptr); +- } +-# endif /* PNG_USER_MEM_SUPPORTED */ +- +-# if defined(__TURBOC__) && !defined(__FLAT__) +- struct_ptr = (png_voidp)farmalloc(size); +-# else +-# if defined(_MSC_VER) && defined(MAXSEG_64K) +- struct_ptr = (png_voidp)halloc(size, 1); +-# else +- struct_ptr = (png_voidp)malloc(size); +-# endif +-# endif +- +- if (struct_ptr != NULL) +- png_memset(struct_ptr, 0, size); +- +- return (struct_ptr); +-} +- +- +-/* Free memory allocated by a png_create_struct() call */ +-void /* PRIVATE */ +-png_destroy_struct(png_voidp struct_ptr) +-{ +-# ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2(struct_ptr, NULL, NULL); +-} +- +-/* Free memory allocated by a png_create_struct() call */ +-void /* PRIVATE */ +-png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, +- png_voidp mem_ptr) +-{ +-# endif /* PNG_USER_MEM_SUPPORTED */ +- if (struct_ptr != NULL) +- { +-# ifdef PNG_USER_MEM_SUPPORTED +- if (free_fn != NULL) +- { +- png_struct dummy_struct; +- png_structp png_ptr = &dummy_struct; +- png_ptr->mem_ptr=mem_ptr; +- (*(free_fn))(png_ptr, struct_ptr); +- return; +- } +-# endif /* PNG_USER_MEM_SUPPORTED */ +-# if defined(__TURBOC__) && !defined(__FLAT__) +- farfree(struct_ptr); +- +-# else +-# if defined(_MSC_VER) && defined(MAXSEG_64K) +- hfree(struct_ptr); +- +-# else +- free(struct_ptr); +- +-# endif +-# endif ++# ifdef PNG_SETJMP_SUPPORTED ++ /* We may have a jmp_buf left to deallocate. */ ++ png_free_jmpbuf(&dummy_struct); ++# endif + } + } + +@@ -508,167 +74,215 @@ + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + */ +- + PNG_FUNCTION(png_voidp,PNGAPI +-png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) ++png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) + { + png_voidp ret; + +- ret = (png_malloc(png_ptr, size)); ++ ret = png_malloc(png_ptr, size); + + if (ret != NULL) +- png_memset(ret,0,(png_size_t)size); ++ memset(ret, 0, size); + +- return (ret); ++ return ret; + } + ++/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of ++ * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. ++ * Checking and error handling must happen outside this routine; it returns NULL ++ * if the allocation cannot be done (for any reason.) ++ */ ++PNG_FUNCTION(png_voidp /* PRIVATE */, ++png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), ++ PNG_ALLOCATED) ++{ ++ /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS ++ * allocators have also been removed in 1.6.0, so any 16-bit system now has ++ * to implement a user memory handler. This checks to be sure it isn't ++ * called with big numbers. ++ */ ++#ifndef PNG_USER_MEM_SUPPORTED ++ PNG_UNUSED(png_ptr) ++#endif ++ ++ if (size > 0 && size <= PNG_SIZE_MAX ++# ifdef PNG_MAX_MALLOC_64K ++ && size <= 65536U ++# endif ++ ) ++ { ++#ifdef PNG_USER_MEM_SUPPORTED ++ if (png_ptr != NULL && png_ptr->malloc_fn != NULL) ++ return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); ++ ++ else ++#endif ++ return malloc((size_t)size); /* checked for truncation above */ ++ } ++ ++ else ++ return NULL; ++} ++ ++#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ ++ defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ++/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 ++ * that arises because of the checks in png_realloc_array that are repeated in ++ * png_malloc_array. ++ */ ++static png_voidp ++png_malloc_array_checked(png_const_structrp png_ptr, int nelements, ++ size_t element_size) ++{ ++ png_alloc_size_t req = nelements; /* known to be > 0 */ ++ ++ if (req <= PNG_SIZE_MAX/element_size) ++ return png_malloc_base(png_ptr, req * element_size); ++ ++ /* The failure case when the request is too large */ ++ return NULL; ++} ++ ++PNG_FUNCTION(png_voidp /* PRIVATE */, ++png_malloc_array,(png_const_structrp png_ptr, int nelements, ++ size_t element_size),PNG_ALLOCATED) ++{ ++ if (nelements <= 0 || element_size == 0) ++ png_error(png_ptr, "internal error: array alloc"); ++ ++ return png_malloc_array_checked(png_ptr, nelements, element_size); ++} ++ ++PNG_FUNCTION(png_voidp /* PRIVATE */, ++png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, ++ int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) ++{ ++ /* These are internal errors: */ ++ if (add_elements <= 0 || element_size == 0 || old_elements < 0 || ++ (old_array == NULL && old_elements > 0)) ++ png_error(png_ptr, "internal error: array realloc"); ++ ++ /* Check for overflow on the elements count (so the caller does not have to ++ * check.) ++ */ ++ if (add_elements <= INT_MAX - old_elements) ++ { ++ png_voidp new_array = png_malloc_array_checked(png_ptr, ++ old_elements+add_elements, element_size); ++ ++ if (new_array != NULL) ++ { ++ /* Because png_malloc_array worked the size calculations below cannot ++ * overflow. ++ */ ++ if (old_elements > 0) ++ memcpy(new_array, old_array, element_size*(unsigned)old_elements); ++ ++ memset((char*)new_array + element_size*(unsigned)old_elements, 0, ++ element_size*(unsigned)add_elements); ++ ++ return new_array; ++ } ++ } ++ ++ return NULL; /* error */ ++} ++#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ ++ ++/* Various functions that have different error handling are derived from this. ++ * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate ++ * function png_malloc_default is also provided. ++ */ + PNG_FUNCTION(png_voidp,PNGAPI +-png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) ++png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) + { + png_voidp ret; + +-# ifdef PNG_USER_MEM_SUPPORTED +- if (png_ptr == NULL || size == 0) +- return (NULL); ++ if (png_ptr == NULL) ++ return NULL; + +- if (png_ptr->malloc_fn != NULL) +- ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); ++ ret = png_malloc_base(png_ptr, size); + +- else +- ret = (png_malloc_default(png_ptr, size)); ++ if (ret == NULL) ++ png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */ + +- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Out of Memory"); +- +- return (ret); ++ return ret; + } + ++#ifdef PNG_USER_MEM_SUPPORTED + PNG_FUNCTION(png_voidp,PNGAPI +-png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) ++png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), ++ PNG_ALLOCATED PNG_DEPRECATED) + { + png_voidp ret; +-# endif /* PNG_USER_MEM_SUPPORTED */ + +- if (png_ptr == NULL || size == 0) +- return (NULL); ++ if (png_ptr == NULL) ++ return NULL; + +-# ifdef PNG_MAX_MALLOC_64K +- if (size > (png_uint_32)65536L) ++ /* Passing 'NULL' here bypasses the application provided memory handler. */ ++ ret = png_malloc_base(NULL/*use malloc*/, size); ++ ++ if (ret == NULL) ++ png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */ ++ ++ return ret; ++} ++#endif /* USER_MEM */ ++ ++/* This function was added at libpng version 1.2.3. The png_malloc_warn() ++ * function will issue a png_warning and return NULL instead of issuing a ++ * png_error, if it fails to allocate the requested memory. ++ */ ++PNG_FUNCTION(png_voidp,PNGAPI ++png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), ++ PNG_ALLOCATED) ++{ ++ if (png_ptr != NULL) + { +-# ifndef PNG_USER_MEM_SUPPORTED +- if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Cannot Allocate > 64K"); ++ png_voidp ret = png_malloc_base(png_ptr, size); + +- else +-# endif +- return NULL; ++ if (ret != NULL) ++ return ret; ++ ++ png_warning(png_ptr, "Out of memory"); + } +-# endif + +- /* Check for overflow */ +-# if defined(__TURBOC__) && !defined(__FLAT__) +- +- if (size != (unsigned long)size) +- ret = NULL; +- +- else +- ret = farmalloc(size); +- +-# else +-# if defined(_MSC_VER) && defined(MAXSEG_64K) +- if (size != (unsigned long)size) +- ret = NULL; +- +- else +- ret = halloc(size, 1); +- +-# else +- if (size != (size_t)size) +- ret = NULL; +- +- else +- ret = malloc((size_t)size); +-# endif +-# endif +- +-# ifndef PNG_USER_MEM_SUPPORTED +- if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) +- png_error(png_ptr, "Out of Memory"); +-# endif +- +- return (ret); ++ return NULL; + } + + /* Free a pointer allocated by png_malloc(). If ptr is NULL, return + * without taking any action. + */ + void PNGAPI +-png_free(png_structp png_ptr, png_voidp ptr) ++png_free(png_const_structrp png_ptr, png_voidp ptr) + { + if (png_ptr == NULL || ptr == NULL) + return; + +-# ifdef PNG_USER_MEM_SUPPORTED ++#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) +- { +- (*(png_ptr->free_fn))(png_ptr, ptr); +- return; +- } ++ png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); + + else + png_free_default(png_ptr, ptr); + } + +-void PNGAPI +-png_free_default(png_structp png_ptr, png_voidp ptr) ++PNG_FUNCTION(void,PNGAPI ++png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED) + { + if (png_ptr == NULL || ptr == NULL) + return; ++#endif /* USER_MEM */ + +-# endif /* PNG_USER_MEM_SUPPORTED */ +- +-# if defined(__TURBOC__) && !defined(__FLAT__) +- farfree(ptr); +- +-# else +-# if defined(_MSC_VER) && defined(MAXSEG_64K) +- hfree(ptr); +- +-# else + free(ptr); +- +-# endif +-# endif + } +-#endif /* Not Borland DOS special memory handler */ +- +-/* This function was added at libpng version 1.2.3. The png_malloc_warn() +- * function will set up png_malloc() to issue a png_warning and return NULL +- * instead of issuing a png_error, if it fails to allocate the requested +- * memory. +- */ +-PNG_FUNCTION(png_voidp,PNGAPI +-png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) +-{ +- png_voidp ptr; +- png_uint_32 save_flags; +- if (png_ptr == NULL) +- return (NULL); +- +- save_flags = png_ptr->flags; +- png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; +- ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); +- png_ptr->flags=save_flags; +- return(ptr); +-} +- + + #ifdef PNG_USER_MEM_SUPPORTED + /* This function is called when the application wants to use another method + * of allocating and freeing memory. + */ + void PNGAPI +-png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr ++png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr + malloc_fn, png_free_ptr free_fn) + { + if (png_ptr != NULL) +@@ -684,12 +298,12 @@ + * pointer before png_write_destroy and png_read_destroy are called. + */ + png_voidp PNGAPI +-png_get_mem_ptr(png_const_structp png_ptr) ++png_get_mem_ptr(png_const_structrp png_ptr) + { + if (png_ptr == NULL) +- return (NULL); ++ return NULL; + +- return ((png_voidp)png_ptr->mem_ptr); ++ return png_ptr->mem_ptr; + } +-#endif /* PNG_USER_MEM_SUPPORTED */ +-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ ++#endif /* USER_MEM */ ++#endif /* READ || WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pngpread.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngpread.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.2 [March 31, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -54,8 +54,15 @@ + #define PNG_READ_iTXt_MODE 7 + #define PNG_ERROR_MODE 8 + ++#define PNG_PUSH_SAVE_BUFFER_IF_FULL \ ++if (png_ptr->push_length + 4 > png_ptr->buffer_size) \ ++ { png_push_save_buffer(png_ptr); return; } ++#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ ++if (png_ptr->buffer_size < N) \ ++ { png_push_save_buffer(png_ptr); return; } ++ + void PNGAPI +-png_process_data(png_structp png_ptr, png_infop info_ptr, ++png_process_data(png_structrp png_ptr, png_inforp info_ptr, + png_bytep buffer, png_size_t buffer_size) + { + if (png_ptr == NULL || info_ptr == NULL) +@@ -70,14 +77,14 @@ + } + + png_size_t PNGAPI +-png_process_data_pause(png_structp png_ptr, int save) ++png_process_data_pause(png_structrp png_ptr, int save) + { + if (png_ptr != NULL) + { +- /* It's easiest for the caller if we do the save, then the caller doesn't ++ /* It's easiest for the caller if we do the save; then the caller doesn't + * have to supply the same data again: + */ +- if (save) ++ if (save != 0) + png_push_save_buffer(png_ptr); + else + { +@@ -97,7 +104,7 @@ + } + + png_uint_32 PNGAPI +-png_process_data_skip(png_structp png_ptr) ++png_process_data_skip(png_structrp png_ptr) + { + png_uint_32 remaining = 0; + +@@ -131,7 +138,7 @@ + * doing before we ran out of data... + */ + void /* PRIVATE */ +-png_process_some_data(png_structp png_ptr, png_infop info_ptr) ++png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) + { + if (png_ptr == NULL) + return; +@@ -156,30 +163,6 @@ + break; + } + +-#ifdef PNG_READ_tEXt_SUPPORTED +- case PNG_READ_tEXt_MODE: +- { +- png_push_read_tEXt(png_ptr, info_ptr); +- break; +- } +- +-#endif +-#ifdef PNG_READ_zTXt_SUPPORTED +- case PNG_READ_zTXt_MODE: +- { +- png_push_read_zTXt(png_ptr, info_ptr); +- break; +- } +- +-#endif +-#ifdef PNG_READ_iTXt_SUPPORTED +- case PNG_READ_iTXt_MODE: +- { +- png_push_read_iTXt(png_ptr, info_ptr); +- break; +- } +- +-#endif + case PNG_SKIP_MODE: + { + png_push_crc_finish(png_ptr); +@@ -201,9 +184,9 @@ + * routine. + */ + void /* PRIVATE */ +-png_push_read_sig(png_structp png_ptr, png_infop info_ptr) ++png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) + { +- png_size_t num_checked = png_ptr->sig_bytes, ++ png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ + num_to_check = 8 - num_checked; + + if (png_ptr->buffer_size < num_to_check) +@@ -234,114 +217,75 @@ + } + + void /* PRIVATE */ +-png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) ++png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) + { +- PNG_IHDR; +- PNG_IDAT; +- PNG_IEND; +- PNG_PLTE; +-#ifdef PNG_READ_bKGD_SUPPORTED +- PNG_bKGD; +-#endif +-#ifdef PNG_READ_cHRM_SUPPORTED +- PNG_cHRM; +-#endif +-#ifdef PNG_READ_gAMA_SUPPORTED +- PNG_gAMA; +-#endif +-#ifdef PNG_READ_hIST_SUPPORTED +- PNG_hIST; +-#endif +-#ifdef PNG_READ_iCCP_SUPPORTED +- PNG_iCCP; +-#endif +-#ifdef PNG_READ_iTXt_SUPPORTED +- PNG_iTXt; +-#endif +-#ifdef PNG_READ_oFFs_SUPPORTED +- PNG_oFFs; +-#endif +-#ifdef PNG_READ_pCAL_SUPPORTED +- PNG_pCAL; +-#endif +-#ifdef PNG_READ_pHYs_SUPPORTED +- PNG_pHYs; +-#endif +-#ifdef PNG_READ_sBIT_SUPPORTED +- PNG_sBIT; +-#endif +-#ifdef PNG_READ_sCAL_SUPPORTED +- PNG_sCAL; +-#endif +-#ifdef PNG_READ_sRGB_SUPPORTED +- PNG_sRGB; +-#endif +-#ifdef PNG_READ_sPLT_SUPPORTED +- PNG_sPLT; +-#endif +-#ifdef PNG_READ_tEXt_SUPPORTED +- PNG_tEXt; +-#endif +-#ifdef PNG_READ_tIME_SUPPORTED +- PNG_tIME; +-#endif +-#ifdef PNG_READ_tRNS_SUPPORTED +- PNG_tRNS; +-#endif +-#ifdef PNG_READ_zTXt_SUPPORTED +- PNG_zTXt; ++ png_uint_32 chunk_name; ++#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED ++ int keep; /* unknown handling method */ + #endif + +- /* First we make sure we have enough data for the 4 byte chunk name +- * and the 4 byte chunk length before proceeding with decoding the ++ /* First we make sure we have enough data for the 4-byte chunk name ++ * and the 4-byte chunk length before proceeding with decoding the + * chunk data. To fully decode each of these chunks, we also make +- * sure we have enough data in the buffer for the 4 byte CRC at the ++ * sure we have enough data in the buffer for the 4-byte CRC at the + * end of every chunk (except IDAT, which is handled separately). + */ +- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) ++ if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) + { + png_byte chunk_length[4]; ++ png_byte chunk_tag[4]; + +- if (png_ptr->buffer_size < 8) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_LT(8) + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); + png_reset_crc(png_ptr); +- png_crc_read(png_ptr, png_ptr->chunk_name, 4); ++ png_crc_read(png_ptr, chunk_tag, 4); ++ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + } + +- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) +- if (png_ptr->mode & PNG_AFTER_IDAT) ++ chunk_name = png_ptr->chunk_name; ++ ++ if (chunk_name == png_IDAT) ++ { ++ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + +- if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) ++ /* If we reach an IDAT chunk, this means we have read all of the ++ * header chunks, and we can start reading the image (or if this ++ * is called after the image has been read - we have an error). ++ */ ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_error(png_ptr, "Missing IHDR before IDAT"); ++ ++ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && ++ (png_ptr->mode & PNG_HAVE_PLTE) == 0) ++ png_error(png_ptr, "Missing PLTE before IDAT"); ++ ++ png_ptr->mode |= PNG_HAVE_IDAT; ++ png_ptr->process_mode = PNG_READ_IDAT_MODE; ++ ++ if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) ++ if (png_ptr->push_length == 0) ++ return; ++ ++ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) ++ png_benign_error(png_ptr, "Too many IDATs found"); ++ } ++ ++ if (chunk_name == png_IHDR) + { + if (png_ptr->push_length != 13) + png_error(png_ptr, "Invalid IHDR length"); + +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); + } + +- else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) ++ else if (chunk_name == png_IEND) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); + + png_ptr->process_mode = PNG_READ_DONE_MODE; +@@ -349,70 +293,25 @@ + } + + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +- else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) ++ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } ++ PNG_PUSH_SAVE_BUFFER_IF_FULL ++ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); + +- if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) +- png_ptr->mode |= PNG_HAVE_IDAT; ++ if (chunk_name == png_PLTE) ++ png_ptr->mode |= PNG_HAVE_PLTE; ++ } ++#endif + +- png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); +- +- if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) +- png_ptr->mode |= PNG_HAVE_PLTE; +- +- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) +- { +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before IDAT"); +- +- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && +- !(png_ptr->mode & PNG_HAVE_PLTE)) +- png_error(png_ptr, "Missing PLTE before IDAT"); +- } +- } +- +-#endif +- else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) ++ else if (chunk_name == png_PLTE) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); + } + +- else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) ++ else if (chunk_name == png_IDAT) + { +- /* If we reach an IDAT chunk, this means we have read all of the +- * header chunks, and we can start reading the image (or if this +- * is called after the image has been read - we have an error). +- */ +- +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before IDAT"); +- +- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && +- !(png_ptr->mode & PNG_HAVE_PLTE)) +- png_error(png_ptr, "Missing PLTE before IDAT"); +- +- if (png_ptr->mode & PNG_HAVE_IDAT) +- { +- if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) +- if (png_ptr->push_length == 0) +- return; +- +- if (png_ptr->mode & PNG_AFTER_IDAT) +- png_benign_error(png_ptr, "Too many IDATs found"); +- } +- + png_ptr->idat_size = png_ptr->push_length; +- png_ptr->mode |= PNG_HAVE_IDAT; + png_ptr->process_mode = PNG_READ_IDAT_MODE; + png_push_have_info(png_ptr, info_ptr); + png_ptr->zstream.avail_out = +@@ -423,250 +322,162 @@ + } + + #ifdef PNG_READ_gAMA_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) ++ else if (png_ptr->chunk_name == png_gAMA) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_sBIT_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) ++ else if (png_ptr->chunk_name == png_sBIT) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_cHRM_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) ++ else if (png_ptr->chunk_name == png_cHRM) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_sRGB_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) ++ else if (chunk_name == png_sRGB) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_iCCP_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) ++ else if (png_ptr->chunk_name == png_iCCP) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_sPLT_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) ++ else if (chunk_name == png_sPLT) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_tRNS_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) ++ else if (chunk_name == png_tRNS) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_bKGD_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) ++ else if (chunk_name == png_bKGD) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_hIST_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) ++ else if (chunk_name == png_hIST) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_pHYs_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) ++ else if (chunk_name == png_pHYs) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_oFFs_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) ++ else if (chunk_name == png_oFFs) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); + } + #endif + + #ifdef PNG_READ_pCAL_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) ++ else if (chunk_name == png_pCAL) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_sCAL_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) ++ else if (chunk_name == png_sCAL) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_tIME_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) ++ else if (chunk_name == png_tIME) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_tEXt_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) ++ else if (chunk_name == png_tEXt) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- +- png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); ++ PNG_PUSH_SAVE_BUFFER_IF_FULL ++ png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_zTXt_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) ++ else if (chunk_name == png_zTXt) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- +- png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); ++ PNG_PUSH_SAVE_BUFFER_IF_FULL ++ png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); + } + + #endif + #ifdef PNG_READ_iTXt_SUPPORTED +- else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) ++ else if (chunk_name == png_iTXt) + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } ++ PNG_PUSH_SAVE_BUFFER_IF_FULL ++ png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); ++ } ++#endif + +- png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); +- } +- +-#endif + else + { +- if (png_ptr->push_length + 4 > png_ptr->buffer_size) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); ++ PNG_PUSH_SAVE_BUFFER_IF_FULL ++ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, ++ PNG_HANDLE_CHUNK_AS_DEFAULT); + } + + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; + } + + void /* PRIVATE */ +-png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) ++png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip) + { + png_ptr->process_mode = PNG_SKIP_MODE; + png_ptr->skip_length = skip; + } + + void /* PRIVATE */ +-png_push_crc_finish(png_structp png_ptr) ++png_push_crc_finish(png_structrp png_ptr) + { +- if (png_ptr->skip_length && png_ptr->save_buffer_size) ++ if (png_ptr->skip_length != 0 && png_ptr->save_buffer_size != 0) + { + png_size_t save_size = png_ptr->save_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; +@@ -690,7 +501,7 @@ + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } +- if (png_ptr->skip_length && png_ptr->current_buffer_size) ++ if (png_ptr->skip_length != 0 && png_ptr->current_buffer_size != 0) + { + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; +@@ -711,14 +522,9 @@ + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } +- if (!png_ptr->skip_length) ++ if (png_ptr->skip_length == 0) + { +- if (png_ptr->buffer_size < 4) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_LT(4) + png_crc_finish(png_ptr, 0); + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } +@@ -733,7 +539,7 @@ + return; + + ptr = buffer; +- if (png_ptr->save_buffer_size) ++ if (png_ptr->save_buffer_size != 0) + { + png_size_t save_size; + +@@ -743,14 +549,14 @@ + else + save_size = png_ptr->save_buffer_size; + +- png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); ++ memcpy(ptr, png_ptr->save_buffer_ptr, save_size); + length -= save_size; + ptr += save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } +- if (length && png_ptr->current_buffer_size) ++ if (length != 0 && png_ptr->current_buffer_size != 0) + { + png_size_t save_size; + +@@ -760,7 +566,7 @@ + else + save_size = png_ptr->current_buffer_size; + +- png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); ++ memcpy(ptr, png_ptr->current_buffer_ptr, save_size); + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; +@@ -768,9 +574,9 @@ + } + + void /* PRIVATE */ +-png_push_save_buffer(png_structp png_ptr) ++png_push_save_buffer(png_structrp png_ptr) + { +- if (png_ptr->save_buffer_size) ++ if (png_ptr->save_buffer_size != 0) + { + if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) + { +@@ -806,16 +612,18 @@ + if (png_ptr->save_buffer == NULL) + { + png_free(png_ptr, old_buffer); ++ old_buffer = NULL; + png_error(png_ptr, "Insufficient memory for save_buffer"); + } + +- png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); ++ memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); + png_free(png_ptr, old_buffer); ++ old_buffer = NULL; + png_ptr->save_buffer_max = new_max; + } + if (png_ptr->current_buffer_size) + { +- png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, ++ memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, + png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); + png_ptr->save_buffer_size += png_ptr->current_buffer_size; + png_ptr->current_buffer_size = 0; +@@ -825,7 +633,7 @@ + } + + void /* PRIVATE */ +-png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, ++png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, + png_size_t buffer_length) + { + png_ptr->current_buffer = buffer; +@@ -835,30 +643,27 @@ + } + + void /* PRIVATE */ +-png_push_read_IDAT(png_structp png_ptr) ++png_push_read_IDAT(png_structrp png_ptr) + { +- PNG_IDAT; +- if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) ++ if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) + { + png_byte chunk_length[4]; ++ png_byte chunk_tag[4]; + +- if (png_ptr->buffer_size < 8) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ /* TODO: this code can be commoned up with the same code in push_read */ ++ PNG_PUSH_SAVE_BUFFER_IF_LT(8) + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); + png_reset_crc(png_ptr); +- png_crc_read(png_ptr, png_ptr->chunk_name, 4); ++ png_crc_read(png_ptr, chunk_tag, 4); ++ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + +- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) ++ if (png_ptr->chunk_name != png_IDAT) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + +- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) ++ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) + png_error(png_ptr, "Not enough compressed data"); + + return; +@@ -866,7 +671,8 @@ + + png_ptr->idat_size = png_ptr->push_length; + } +- if (png_ptr->idat_size && png_ptr->save_buffer_size) ++ ++ if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) + { + png_size_t save_size = png_ptr->save_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; +@@ -893,7 +699,7 @@ + png_ptr->save_buffer_ptr += save_size; + } + +- if (png_ptr->idat_size && png_ptr->current_buffer_size) ++ if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) + { + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; +@@ -918,22 +724,18 @@ + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } +- if (!png_ptr->idat_size) ++ if (png_ptr->idat_size == 0) + { +- if (png_ptr->buffer_size < 4) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- ++ PNG_PUSH_SAVE_BUFFER_IF_LT(4) + png_crc_finish(png_ptr, 0); + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; + png_ptr->mode |= PNG_AFTER_IDAT; ++ png_ptr->zowner = 0; + } + } + + void /* PRIVATE */ +-png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, ++png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, + png_size_t buffer_length) + { + /* The caller checks for a non-zero buffer length. */ +@@ -945,13 +747,14 @@ + * handle the uncompressed results. + */ + png_ptr->zstream.next_in = buffer; ++ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ + png_ptr->zstream.avail_in = (uInt)buffer_length; + + /* Keep going until the decompressed data is all processed + * or the stream marked as finished. + */ + while (png_ptr->zstream.avail_in > 0 && +- !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) ++ !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) + { + int ret; + +@@ -962,9 +765,9 @@ + */ + if (!(png_ptr->zstream.avail_out > 0)) + { +- png_ptr->zstream.avail_out = +- (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, +- png_ptr->iwidth) + 1; ++ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ ++ png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, ++ png_ptr->iwidth) + 1); + + png_ptr->zstream.next_out = png_ptr->row_buf; + } +@@ -982,7 +785,8 @@ + if (ret != Z_OK && ret != Z_STREAM_END) + { + /* Terminate the decompression. */ +- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; ++ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; ++ png_ptr->zowner = 0; + + /* This may be a truncated stream (missing or + * damaged end code). Treat that as a warning. +@@ -1010,7 +814,8 @@ + { + /* Extra data. */ + png_warning(png_ptr, "Extra compressed data in IDAT"); +- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; ++ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; ++ png_ptr->zowner = 0; + + /* Do no more processing; skip the unprocessed + * input check below. +@@ -1025,7 +830,7 @@ + + /* And check for the end of the stream. */ + if (ret == Z_STREAM_END) +- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; ++ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + } + + /* All the data should have been processed, if anything +@@ -1037,41 +842,62 @@ + } + + void /* PRIVATE */ +-png_push_process_row(png_structp png_ptr) ++png_push_process_row(png_structrp png_ptr) + { +- png_ptr->row_info.color_type = png_ptr->color_type; +- png_ptr->row_info.width = png_ptr->iwidth; +- png_ptr->row_info.channels = png_ptr->channels; +- png_ptr->row_info.bit_depth = png_ptr->bit_depth; +- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; ++ /* 1.5.6: row_info moved out of png_struct to a local here. */ ++ png_row_info row_info; + +- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, +- png_ptr->row_info.width); ++ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ ++ row_info.color_type = png_ptr->color_type; ++ row_info.bit_depth = png_ptr->bit_depth; ++ row_info.channels = png_ptr->channels; ++ row_info.pixel_depth = png_ptr->pixel_depth; ++ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + +- png_read_filter_row(png_ptr, &(png_ptr->row_info), +- png_ptr->row_buf + 1, png_ptr->prev_row + 1, +- (int)(png_ptr->row_buf[0])); ++ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) ++ { ++ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) ++ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, ++ png_ptr->prev_row + 1, png_ptr->row_buf[0]); ++ else ++ png_error(png_ptr, "bad adaptive filter value"); ++ } + +- png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); ++ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before ++ * 1.5.6, while the buffer really is this big in current versions of libpng ++ * it may not be in the future, so this was changed just to copy the ++ * interlaced row count: ++ */ ++ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + + #ifdef PNG_READ_TRANSFORMS_SUPPORTED +- if (png_ptr->transformations) +- png_do_read_transformations(png_ptr); ++ if (png_ptr->transformations != 0) ++ png_do_read_transformations(png_ptr, &row_info); + #endif + ++ /* The transformed pixel depth should match the depth now in row_info. */ ++ if (png_ptr->transformed_pixel_depth == 0) ++ { ++ png_ptr->transformed_pixel_depth = row_info.pixel_depth; ++ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) ++ png_error(png_ptr, "progressive row overflow"); ++ } ++ ++ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) ++ png_error(png_ptr, "internal progressive row size calculation error"); ++ ++ + #ifdef PNG_READ_INTERLACING_SUPPORTED +- /* Blow up interlaced rows to full size */ +- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) ++ /* Expand interlaced rows to full size */ ++ if (png_ptr->interlaced != 0 && ++ (png_ptr->transformations & PNG_INTERLACE) != 0) + { + if (png_ptr->pass < 6) +-/* old interface (pre-1.0.9): +- png_do_read_interlace(&(png_ptr->row_info), +- png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); +- */ +- png_do_read_interlace(png_ptr); ++ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, ++ png_ptr->transformations); + +- switch (png_ptr->pass) +- { ++ switch (png_ptr->pass) ++ { + case 0: + { + int i; +@@ -1238,7 +1064,6 @@ + } + } + else +-#endif + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); +@@ -1246,36 +1071,36 @@ + } + + void /* PRIVATE */ +-png_read_push_finish_row(png_structp png_ptr) ++png_read_push_finish_row(png_structrp png_ptr) + { + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ +- PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; ++ static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ +- PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ +- PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; ++ static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ +- PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; ++ static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + + /* Height of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h +- PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + */ ++#endif + + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + +-#ifdef PNG_READ_INTERLACING_SUPPORTED +- if (png_ptr->interlaced) ++ if (png_ptr->interlaced != 0) + { + png_ptr->row_number = 0; +- png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); ++ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + do + { +@@ -1296,7 +1121,7 @@ + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + +- if (png_ptr->transformations & PNG_INTERLACE) ++ if ((png_ptr->transformations & PNG_INTERLACE) != 0) + break; + + png_ptr->num_rows = (png_ptr->height + +@@ -1306,538 +1131,24 @@ + + } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); + } +-#endif /* PNG_READ_INTERLACING_SUPPORTED */ +-} +- +-#ifdef PNG_READ_tEXt_SUPPORTED +-void /* PRIVATE */ +-png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 +- length) +-{ +- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) +- { +- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ +- png_error(png_ptr, "Out of place tEXt"); +- /* NOT REACHED */ +- } +- +-#ifdef PNG_MAX_MALLOC_64K +- png_ptr->skip_length = 0; /* This may not be necessary */ +- +- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ +- { +- png_warning(png_ptr, "tEXt chunk too large to fit in memory"); +- png_ptr->skip_length = length - (png_uint_32)65535L; +- length = (png_uint_32)65535L; +- } +-#endif +- +- png_ptr->current_text = (png_charp)png_malloc(png_ptr, +- (png_size_t)(length + 1)); +- png_ptr->current_text[length] = '\0'; +- png_ptr->current_text_ptr = png_ptr->current_text; +- png_ptr->current_text_size = (png_size_t)length; +- png_ptr->current_text_left = (png_size_t)length; +- png_ptr->process_mode = PNG_READ_tEXt_MODE; + } + + void /* PRIVATE */ +-png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) +-{ +- if (png_ptr->buffer_size && png_ptr->current_text_left) +- { +- png_size_t text_size; +- +- if (png_ptr->buffer_size < png_ptr->current_text_left) +- text_size = png_ptr->buffer_size; +- +- else +- text_size = png_ptr->current_text_left; +- +- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); +- png_ptr->current_text_left -= text_size; +- png_ptr->current_text_ptr += text_size; +- } +- if (!(png_ptr->current_text_left)) +- { +- png_textp text_ptr; +- png_charp text; +- png_charp key; +- int ret; +- +- if (png_ptr->buffer_size < 4) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- +- png_push_crc_finish(png_ptr); +- +-#ifdef PNG_MAX_MALLOC_64K +- if (png_ptr->skip_length) +- return; +-#endif +- +- key = png_ptr->current_text; +- +- for (text = key; *text; text++) +- /* Empty loop */ ; +- +- if (text < key + png_ptr->current_text_size) +- text++; +- +- text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text)); +- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; +- text_ptr->key = key; +- text_ptr->itxt_length = 0; +- text_ptr->lang = NULL; +- text_ptr->lang_key = NULL; +- text_ptr->text = text; +- +- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); +- +- png_free(png_ptr, key); +- png_free(png_ptr, text_ptr); +- png_ptr->current_text = NULL; +- +- if (ret) +- png_warning(png_ptr, "Insufficient memory to store text chunk"); +- } +-} +-#endif +- +-#ifdef PNG_READ_zTXt_SUPPORTED +-void /* PRIVATE */ +-png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 +- length) +-{ +- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) +- { +- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ +- png_error(png_ptr, "Out of place zTXt"); +- /* NOT REACHED */ +- } +- +-#ifdef PNG_MAX_MALLOC_64K +- /* We can't handle zTXt chunks > 64K, since we don't have enough space +- * to be able to store the uncompressed data. Actually, the threshold +- * is probably around 32K, but it isn't as definite as 64K is. +- */ +- if (length > (png_uint_32)65535L) +- { +- png_warning(png_ptr, "zTXt chunk too large to fit in memory"); +- png_push_crc_skip(png_ptr, length); +- return; +- } +-#endif +- +- png_ptr->current_text = (png_charp)png_malloc(png_ptr, +- (png_size_t)(length + 1)); +- png_ptr->current_text[length] = '\0'; +- png_ptr->current_text_ptr = png_ptr->current_text; +- png_ptr->current_text_size = (png_size_t)length; +- png_ptr->current_text_left = (png_size_t)length; +- png_ptr->process_mode = PNG_READ_zTXt_MODE; +-} +- +-void /* PRIVATE */ +-png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) +-{ +- if (png_ptr->buffer_size && png_ptr->current_text_left) +- { +- png_size_t text_size; +- +- if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) +- text_size = png_ptr->buffer_size; +- +- else +- text_size = png_ptr->current_text_left; +- +- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); +- png_ptr->current_text_left -= text_size; +- png_ptr->current_text_ptr += text_size; +- } +- if (!(png_ptr->current_text_left)) +- { +- png_textp text_ptr; +- png_charp text; +- png_charp key; +- int ret; +- png_size_t text_size, key_size; +- +- if (png_ptr->buffer_size < 4) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- +- png_push_crc_finish(png_ptr); +- +- key = png_ptr->current_text; +- +- for (text = key; *text; text++) +- /* Empty loop */ ; +- +- /* zTXt can't have zero text */ +- if (text >= key + png_ptr->current_text_size) +- { +- png_ptr->current_text = NULL; +- png_free(png_ptr, key); +- return; +- } +- +- text++; +- +- if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ +- { +- png_ptr->current_text = NULL; +- png_free(png_ptr, key); +- return; +- } +- +- text++; +- +- png_ptr->zstream.next_in = (png_bytep)text; +- png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - +- (text - key)); +- png_ptr->zstream.next_out = png_ptr->zbuf; +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +- +- key_size = text - key; +- text_size = 0; +- text = NULL; +- ret = Z_STREAM_END; +- +- while (png_ptr->zstream.avail_in) +- { +- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); +- if (ret != Z_OK && ret != Z_STREAM_END) +- { +- inflateReset(&png_ptr->zstream); +- png_ptr->zstream.avail_in = 0; +- png_ptr->current_text = NULL; +- png_free(png_ptr, key); +- png_free(png_ptr, text); +- return; +- } +- +- if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) +- { +- if (text == NULL) +- { +- text = (png_charp)png_malloc(png_ptr, +- (png_ptr->zbuf_size +- - png_ptr->zstream.avail_out + key_size + 1)); +- +- png_memcpy(text + key_size, png_ptr->zbuf, +- png_ptr->zbuf_size - png_ptr->zstream.avail_out); +- +- png_memcpy(text, key, key_size); +- +- text_size = key_size + png_ptr->zbuf_size - +- png_ptr->zstream.avail_out; +- +- *(text + text_size) = '\0'; +- } +- +- else +- { +- png_charp tmp; +- +- tmp = text; +- text = (png_charp)png_malloc(png_ptr, text_size + +- (png_ptr->zbuf_size +- - png_ptr->zstream.avail_out + 1)); +- +- png_memcpy(text, tmp, text_size); +- png_free(png_ptr, tmp); +- +- png_memcpy(text + text_size, png_ptr->zbuf, +- png_ptr->zbuf_size - png_ptr->zstream.avail_out); +- +- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; +- *(text + text_size) = '\0'; +- } +- +- if (ret != Z_STREAM_END) +- { +- png_ptr->zstream.next_out = png_ptr->zbuf; +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +- } +- } +- else +- { +- break; +- } +- +- if (ret == Z_STREAM_END) +- break; +- } +- +- inflateReset(&png_ptr->zstream); +- png_ptr->zstream.avail_in = 0; +- +- if (ret != Z_STREAM_END) +- { +- png_ptr->current_text = NULL; +- png_free(png_ptr, key); +- png_free(png_ptr, text); +- return; +- } +- +- png_ptr->current_text = NULL; +- png_free(png_ptr, key); +- key = text; +- text += key_size; +- +- text_ptr = (png_textp)png_malloc(png_ptr, +- png_sizeof(png_text)); +- text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; +- text_ptr->key = key; +- text_ptr->itxt_length = 0; +- text_ptr->lang = NULL; +- text_ptr->lang_key = NULL; +- text_ptr->text = text; +- +- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); +- +- png_free(png_ptr, key); +- png_free(png_ptr, text_ptr); +- +- if (ret) +- png_warning(png_ptr, "Insufficient memory to store text chunk"); +- } +-} +-#endif +- +-#ifdef PNG_READ_iTXt_SUPPORTED +-void /* PRIVATE */ +-png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 +- length) +-{ +- if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) +- { +- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ +- png_error(png_ptr, "Out of place iTXt"); +- /* NOT REACHED */ +- } +- +-#ifdef PNG_MAX_MALLOC_64K +- png_ptr->skip_length = 0; /* This may not be necessary */ +- +- if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ +- { +- png_warning(png_ptr, "iTXt chunk too large to fit in memory"); +- png_ptr->skip_length = length - (png_uint_32)65535L; +- length = (png_uint_32)65535L; +- } +-#endif +- +- png_ptr->current_text = (png_charp)png_malloc(png_ptr, +- (png_size_t)(length + 1)); +- png_ptr->current_text[length] = '\0'; +- png_ptr->current_text_ptr = png_ptr->current_text; +- png_ptr->current_text_size = (png_size_t)length; +- png_ptr->current_text_left = (png_size_t)length; +- png_ptr->process_mode = PNG_READ_iTXt_MODE; +-} +- +-void /* PRIVATE */ +-png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) +-{ +- +- if (png_ptr->buffer_size && png_ptr->current_text_left) +- { +- png_size_t text_size; +- +- if (png_ptr->buffer_size < png_ptr->current_text_left) +- text_size = png_ptr->buffer_size; +- +- else +- text_size = png_ptr->current_text_left; +- +- png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); +- png_ptr->current_text_left -= text_size; +- png_ptr->current_text_ptr += text_size; +- } +- +- if (!(png_ptr->current_text_left)) +- { +- png_textp text_ptr; +- png_charp key; +- int comp_flag; +- png_charp lang; +- png_charp lang_key; +- png_charp text; +- int ret; +- +- if (png_ptr->buffer_size < 4) +- { +- png_push_save_buffer(png_ptr); +- return; +- } +- +- png_push_crc_finish(png_ptr); +- +-#ifdef PNG_MAX_MALLOC_64K +- if (png_ptr->skip_length) +- return; +-#endif +- +- key = png_ptr->current_text; +- +- for (lang = key; *lang; lang++) +- /* Empty loop */ ; +- +- if (lang < key + png_ptr->current_text_size - 3) +- lang++; +- +- comp_flag = *lang++; +- lang++; /* Skip comp_type, always zero */ +- +- for (lang_key = lang; *lang_key; lang_key++) +- /* Empty loop */ ; +- +- lang_key++; /* Skip NUL separator */ +- +- text=lang_key; +- +- if (lang_key < key + png_ptr->current_text_size - 1) +- { +- for (; *text; text++) +- /* Empty loop */ ; +- } +- +- if (text < key + png_ptr->current_text_size) +- text++; +- +- text_ptr = (png_textp)png_malloc(png_ptr, +- png_sizeof(png_text)); +- +- text_ptr->compression = comp_flag + 2; +- text_ptr->key = key; +- text_ptr->lang = lang; +- text_ptr->lang_key = lang_key; +- text_ptr->text = text; +- text_ptr->text_length = 0; +- text_ptr->itxt_length = png_strlen(text); +- +- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); +- +- png_ptr->current_text = NULL; +- +- png_free(png_ptr, text_ptr); +- if (ret) +- png_warning(png_ptr, "Insufficient memory to store iTXt chunk"); +- } +-} +-#endif +- +-/* This function is called when we haven't found a handler for this +- * chunk. If there isn't a problem with the chunk itself (ie a bad chunk +- * name or a critical chunk), the chunk is (currently) silently ignored. +- */ +-void /* PRIVATE */ +-png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 +- length) +-{ +- png_uint_32 skip = 0; +- +- if (!(png_ptr->chunk_name[0] & 0x20)) +- { +-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != +- PNG_HANDLE_CHUNK_ALWAYS +-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +- && png_ptr->read_user_chunk_fn == NULL +-#endif +- ) +-#endif +- png_chunk_error(png_ptr, "unknown critical chunk"); +- +- PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ +- } +- +-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +- if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) +- { +-#ifdef PNG_MAX_MALLOC_64K +- if (length > (png_uint_32)65535L) +- { +- png_warning(png_ptr, "unknown chunk too large to fit in memory"); +- skip = length - (png_uint_32)65535L; +- length = (png_uint_32)65535L; +- } +-#endif +- png_memcpy((png_charp)png_ptr->unknown_chunk.name, +- (png_charp)png_ptr->chunk_name, +- png_sizeof(png_ptr->unknown_chunk.name)); +- png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] +- = '\0'; +- +- png_ptr->unknown_chunk.size = (png_size_t)length; +- +- if (length == 0) +- png_ptr->unknown_chunk.data = NULL; +- +- else +- { +- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, +- (png_size_t)length); +- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); +- } +- +-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +- if (png_ptr->read_user_chunk_fn != NULL) +- { +- /* Callback to user unknown chunk handler */ +- int ret; +- ret = (*(png_ptr->read_user_chunk_fn)) +- (png_ptr, &png_ptr->unknown_chunk); +- +- if (ret < 0) +- png_chunk_error(png_ptr, "error in user chunk"); +- +- if (ret == 0) +- { +- if (!(png_ptr->chunk_name[0] & 0x20)) +- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != +- PNG_HANDLE_CHUNK_ALWAYS) +- png_chunk_error(png_ptr, "unknown critical chunk"); +- png_set_unknown_chunks(png_ptr, info_ptr, +- &png_ptr->unknown_chunk, 1); +- } +- } +- +- else +-#endif +- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); +- png_free(png_ptr, png_ptr->unknown_chunk.data); +- png_ptr->unknown_chunk.data = NULL; +- } +- +- else +-#endif +- skip=length; +- png_push_crc_skip(png_ptr, skip); +-} +- +-void /* PRIVATE */ +-png_push_have_info(png_structp png_ptr, png_infop info_ptr) ++png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) + { + if (png_ptr->info_fn != NULL) + (*(png_ptr->info_fn))(png_ptr, info_ptr); + } + + void /* PRIVATE */ +-png_push_have_end(png_structp png_ptr, png_infop info_ptr) ++png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) + { + if (png_ptr->end_fn != NULL) + (*(png_ptr->end_fn))(png_ptr, info_ptr); + } + + void /* PRIVATE */ +-png_push_have_row(png_structp png_ptr, png_bytep row) ++png_push_have_row(png_structrp png_ptr, png_bytep row) + { + if (png_ptr->row_fn != NULL) + (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, +@@ -1845,21 +1156,22 @@ + } + + void PNGAPI +-png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, ++png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, + png_const_bytep new_row) + { +- PNG_CONST int FARDATA png_pass_dsp_mask[7] = +- {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; +- + if (png_ptr == NULL) + return; + +- if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ +- png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); ++ /* new_row is a flag here - if it is NULL then the app callback was called ++ * from an empty row (see the calls to png_struct::row_fn below), otherwise ++ * it must be png_ptr->row_buf+1 ++ */ ++ if (new_row != NULL) ++ png_combine_row(png_ptr, old_row, 1/*blocky display*/); + } + + void PNGAPI +-png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, ++png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) + { +@@ -1874,11 +1186,11 @@ + } + + png_voidp PNGAPI +-png_get_progressive_ptr(png_const_structp png_ptr) ++png_get_progressive_ptr(png_const_structrp png_ptr) + { + if (png_ptr == NULL) + return (NULL); + + return png_ptr->io_ptr; + } +-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ ++#endif /* PROGRESSIVE_READ */ +--- ./jdk/src/share/native/sun/awt/libpng/pngpriv.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngpriv.h Thu Feb 05 13:00:26 2015 +0100 +@@ -30,11 +30,11 @@ + * file and, per its terms, should not be removed: + * + * For conditions of distribution and use, see copyright notice in png.h +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +- * Last changed in libpng 1.5.4 [July 7, 2011] ++ * Last changed in libpng 1.6.10 [March 6, 1014]] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer +@@ -42,7 +42,7 @@ + */ + + /* The symbols declared in this file (including the functions declared +- * as PNG_EXTERN) are PRIVATE. They are not part of the libpng public ++ * as extern) are PRIVATE. They are not part of the libpng public + * interface, and are not recommended for use by regular applications. + * Some of them may become public in the future; others may stay private, + * change in an incompatible way, or even disappear. +@@ -67,12 +67,44 @@ + */ + #define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ + +-/* This is required for the definition of abort(), used as a last ditch +- * error handler when all else fails. ++#ifndef PNG_VERSION_INFO_ONLY ++/* Standard library headers not required by png.h: */ ++# include <stdlib.h> ++# include <string.h> ++#endif ++ ++#define PNGLIB_BUILD /*libpng is being built, not used*/ ++ ++/* If HAVE_CONFIG_H is defined during the build then the build system must ++ * provide an appropriate "config.h" file on the include path. The header file ++ * must provide definitions as required below (search for "HAVE_CONFIG_H"); ++ * see configure.ac for more details of the requirements. The macro ++ * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on ++ * 'configure'; define this macro to prevent the configure build including the ++ * configure generated config.h. Libpng is expected to compile without *any* ++ * special build system support on a reasonably ANSI-C compliant system. + */ +-#include <stdlib.h> ++#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) ++# include <config.h> + +-#define PNGLIB_BUILD ++ /* Pick up the definition of 'restrict' from config.h if it was read: */ ++# define PNG_RESTRICT restrict ++#endif ++ ++/* To support symbol prefixing it is necessary to know *before* including png.h ++ * whether the fixed point (and maybe other) APIs are exported, because if they ++ * are not internal definitions may be required. This is handled below just ++ * before png.h is included, but load the configuration now if it is available. ++ */ ++#ifndef PNGLCONF_H ++# include "pnglibconf.h" ++#endif ++ ++/* Local renames may change non-exported API functions from png.h */ ++#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) ++# include "pngprefix.h" ++#endif ++ + #ifdef PNG_USER_CONFIG + # include "pngusr.h" + /* These should have been defined in pngusr.h */ +@@ -83,25 +115,253 @@ + # define PNG_USER_DLLFNAME_POSTFIX "Cb" + # endif + #endif ++ ++/* Compile time options. ++ * ===================== ++ * In a multi-arch build the compiler may compile the code several times for the ++ * same object module, producing different binaries for different architectures. ++ * When this happens configure-time setting of the target host options cannot be ++ * done and this interferes with the handling of the ARM NEON optimizations, and ++ * possibly other similar optimizations. Put additional tests here; in general ++ * this is needed when the same option can be changed at both compile time and ++ * run time depending on the target OS (i.e. iOS vs Android.) ++ * ++ * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because ++ * this is not possible with certain compilers (Oracle SUN OS CC), as a result ++ * it is necessary to ensure that all extern functions that *might* be used ++ * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__ ++ * below is one example of this behavior because it is controlled by the ++ * presence or not of -mfpu=neon on the GCC command line, it is possible to do ++ * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely ++ * do this. ++ */ ++#ifndef PNG_ARM_NEON_OPT ++ /* ARM NEON optimizations are being controlled by the compiler settings, ++ * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon ++ * with GCC) then the compiler will define __ARM_NEON__ and we can rely ++ * unconditionally on NEON instructions not crashing, otherwise we must ++ * disable use of NEON instructions. ++ * ++ * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they ++ * can only be turned on automatically if that is supported too. If ++ * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail ++ * to compile with an appropriate #error if ALIGNED_MEMORY has been turned ++ * off. ++ * ++ * Note that gcc-4.9 defines __ARM_NEON instead of __ARM_NEON__, so we ++ * check both variants. ++ */ ++# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \ ++ defined(PNG_ALIGNED_MEMORY_SUPPORTED) ++# define PNG_ARM_NEON_OPT 2 ++# else ++# define PNG_ARM_NEON_OPT 0 ++# endif ++#endif ++ ++#if PNG_ARM_NEON_OPT > 0 ++ /* NEON optimizations are to be at least considered by libpng, so enable the ++ * callbacks to do this. ++ */ ++# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon ++ ++ /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used ++ * if possible - if __ARM_NEON__ is set and the compiler version is not known ++ * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can ++ * be: ++ * ++ * 1 The intrinsics code (the default with __ARM_NEON__) ++ * 2 The hand coded assembler (the default without __ARM_NEON__) ++ * ++ * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however ++ * this is *NOT* supported and may cease to work even after a minor revision ++ * to libpng. It *is* valid to do this for testing purposes, e.g. speed ++ * testing or a new compiler, but the results should be communicated to the ++ * libpng implementation list for incorporation in the next minor release. ++ */ ++# ifndef PNG_ARM_NEON_IMPLEMENTATION ++# if defined(__ARM_NEON__) || defined(__ARM_NEON) ++# if defined(__clang__) ++ /* At present it is unknown by the libpng developers which versions ++ * of clang support the intrinsics, however some or perhaps all ++ * versions do not work with the assembler so this may be ++ * irrelevant, so just use the default (do nothing here.) ++ */ ++# elif defined(__GNUC__) ++ /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to ++ * work, so if this *is* GCC, or G++, look for a version >4.5 ++ */ ++# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6) ++# define PNG_ARM_NEON_IMPLEMENTATION 2 ++# endif /* no GNUC support */ ++# endif /* __GNUC__ */ ++# else /* !defined __ARM_NEON__ */ ++ /* The 'intrinsics' code simply won't compile without this -mfpu=neon: ++ */ ++# define PNG_ARM_NEON_IMPLEMENTATION 2 ++# endif /* __ARM_NEON__ */ ++# endif /* !PNG_ARM_NEON_IMPLEMENTATION */ ++ ++# ifndef PNG_ARM_NEON_IMPLEMENTATION ++ /* Use the intrinsics code by default. */ ++# define PNG_ARM_NEON_IMPLEMENTATION 1 ++# endif ++#endif /* PNG_ARM_NEON_OPT > 0 */ ++ ++/* Is this a build of a DLL where compilation of the object modules requires ++ * different preprocessor settings to those required for a simple library? If ++ * so PNG_BUILD_DLL must be set. ++ * ++ * If libpng is used inside a DLL but that DLL does not export the libpng APIs ++ * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a ++ * static library of libpng then link the DLL against that. ++ */ ++#ifndef PNG_BUILD_DLL ++# ifdef DLL_EXPORT ++ /* This is set by libtool when files are compiled for a DLL; libtool ++ * always compiles twice, even on systems where it isn't necessary. Set ++ * PNG_BUILD_DLL in case it is necessary: ++ */ ++# define PNG_BUILD_DLL ++# else ++# ifdef _WINDLL ++ /* This is set by the Microsoft Visual Studio IDE in projects that ++ * build a DLL. It can't easily be removed from those projects (it ++ * isn't visible in the Visual Studio UI) so it is a fairly reliable ++ * indication that PNG_IMPEXP needs to be set to the DLL export ++ * attributes. ++ */ ++# define PNG_BUILD_DLL ++# else ++# ifdef __DLL__ ++ /* This is set by the Borland C system when compiling for a DLL ++ * (as above.) ++ */ ++# define PNG_BUILD_DLL ++# else ++ /* Add additional compiler cases here. */ ++# endif ++# endif ++# endif ++#endif /* Setting PNG_BUILD_DLL if required */ ++ ++/* See pngconf.h for more details: the builder of the library may set this on ++ * the command line to the right thing for the specific compilation system or it ++ * may be automagically set above (at present we know of no system where it does ++ * need to be set on the command line.) ++ * ++ * PNG_IMPEXP must be set here when building the library to prevent pngconf.h ++ * setting it to the "import" setting for a DLL build. ++ */ ++#ifndef PNG_IMPEXP ++# ifdef PNG_BUILD_DLL ++# define PNG_IMPEXP PNG_DLL_EXPORT ++# else ++ /* Not building a DLL, or the DLL doesn't require specific export ++ * definitions. ++ */ ++# define PNG_IMPEXP ++# endif ++#endif ++ ++/* No warnings for private or deprecated functions in the build: */ ++#ifndef PNG_DEPRECATED ++# define PNG_DEPRECATED ++#endif ++#ifndef PNG_PRIVATE ++# define PNG_PRIVATE ++#endif ++ ++/* Symbol preprocessing support. ++ * ++ * To enable listing global, but internal, symbols the following macros should ++ * always be used to declare an extern data or function object in this file. ++ */ ++#ifndef PNG_INTERNAL_DATA ++# define PNG_INTERNAL_DATA(type, name, array) extern type name array ++#endif ++ ++#ifndef PNG_INTERNAL_FUNCTION ++# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ ++ extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) ++#endif ++ ++#ifndef PNG_INTERNAL_CALLBACK ++# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ ++ extern PNG_FUNCTION(type, (PNGCBAPI name), args, PNG_EMPTY attributes) ++#endif ++ ++/* If floating or fixed point APIs are disabled they may still be compiled ++ * internally. To handle this make sure they are declared as the appropriate ++ * internal extern function (otherwise the symbol prefixing stuff won't work and ++ * the functions will be used without definitions.) ++ * ++ * NOTE: although all the API functions are declared here they are not all ++ * actually built! Because the declarations are still made it is necessary to ++ * fake out types that they depend on. ++ */ ++#ifndef PNG_FP_EXPORT ++# ifndef PNG_FLOATING_POINT_SUPPORTED ++# define PNG_FP_EXPORT(ordinal, type, name, args)\ ++ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); ++# ifndef PNG_VERSION_INFO_ONLY ++ typedef struct png_incomplete png_double; ++ typedef png_double* png_doublep; ++ typedef const png_double* png_const_doublep; ++ typedef png_double** png_doublepp; ++# endif ++# endif ++#endif ++#ifndef PNG_FIXED_EXPORT ++# ifndef PNG_FIXED_POINT_SUPPORTED ++# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ ++ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); ++# endif ++#endif ++ + #include "png.h" +-#include "pnginfo.h" +-#include "pngstruct.h" + +-/* This is used for 16 bit gamma tables - only the top level pointers are const, +- * this could be changed: ++/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ ++#ifndef PNG_DLL_EXPORT ++# define PNG_DLL_EXPORT ++#endif ++ ++/* SECURITY and SAFETY: ++ * ++ * By default libpng is built without any internal limits on image size, ++ * individual heap (png_malloc) allocations or the total amount of memory used. ++ * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used ++ * (unless individually overridden). These limits are believed to be fairly ++ * safe, but builders of secure systems should verify the values against the ++ * real system capabilities. + */ +-typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp; +- +-/* Added at libpng-1.2.9 */ +-/* Moved to pngpriv.h at libpng-1.5.0 */ +- +-/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" +- * script. We may need it here to get the correct configuration on things +- * like limits. +- */ +-#ifdef PNG_CONFIGURE_LIBPNG +-# ifdef HAVE_CONFIG_H +-# include "config.h" ++#ifdef PNG_SAFE_LIMITS_SUPPORTED ++ /* 'safe' limits */ ++# ifndef PNG_USER_WIDTH_MAX ++# define PNG_USER_WIDTH_MAX 1000000 ++# endif ++# ifndef PNG_USER_HEIGHT_MAX ++# define PNG_USER_HEIGHT_MAX 1000000 ++# endif ++# ifndef PNG_USER_CHUNK_CACHE_MAX ++# define PNG_USER_CHUNK_CACHE_MAX 128 ++# endif ++# ifndef PNG_USER_CHUNK_MALLOC_MAX ++# define PNG_USER_CHUNK_MALLOC_MAX 8000000 ++# endif ++#else ++ /* values for no limits */ ++# ifndef PNG_USER_WIDTH_MAX ++# define PNG_USER_WIDTH_MAX 0x7fffffff ++# endif ++# ifndef PNG_USER_HEIGHT_MAX ++# define PNG_USER_HEIGHT_MAX 0x7fffffff ++# endif ++# ifndef PNG_USER_CHUNK_CACHE_MAX ++# define PNG_USER_CHUNK_CACHE_MAX 0 ++# endif ++# ifndef PNG_USER_CHUNK_MALLOC_MAX ++# define PNG_USER_CHUNK_MALLOC_MAX 0 + # endif + #endif + +@@ -143,13 +403,6 @@ + # define PNG_ZBUF_SIZE 65536L + #endif + +-/* PNG_STATIC is used to mark internal file scope functions if they need to be +- * accessed for implementation tests (see the code in tests/?*). +- */ +-#ifndef PNG_STATIC +-# define PNG_STATIC static +-#endif +- + /* If warnings or errors are turned off the code is disabled or redirected here. + * From 1.5.4 functions have been added to allow very limited formatting of + * error and warning messages - this code will also be disabled here. +@@ -157,8 +410,6 @@ + #ifdef PNG_WARNINGS_SUPPORTED + # define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; + #else +-# define png_warning(s1,s2) ((void)(s1)) +-# define png_chunk_warning(s1,s2) ((void)(s1)) + # define png_warning_parameter(p,number,string) ((void)0) + # define png_warning_parameter_unsigned(p,number,format,value) ((void)0) + # define png_warning_parameter_signed(p,number,format,value) ((void)0) +@@ -166,21 +417,27 @@ + # define PNG_WARNING_PARAMETERS(p) + #endif + #ifndef PNG_ERROR_TEXT_SUPPORTED +-# define png_error(s1,s2) png_err(s1) +-# define png_chunk_error(s1,s2) png_err(s1) + # define png_fixed_error(s1,s2) png_err(s1) + #endif + +-#ifndef PNG_EXTERN +-/* The functions exported by PNG_EXTERN are internal functions, which +- * aren't usually used outside the library (as far as I know), so it is +- * debatable if they should be exported at all. In the future, when it +- * is possible to have run-time registry of chunk-handling functions, +- * some of these might be made available again. +-# define PNG_EXTERN extern ++/* C allows up-casts from (void*) to any pointer and (const void*) to any ++ * pointer to a const object. C++ regards this as a type error and requires an ++ * explicit, static, cast and provides the static_cast<> rune to ensure that ++ * const is not cast away. + */ +-# define PNG_EXTERN +-#endif ++#ifdef __cplusplus ++# define png_voidcast(type, value) static_cast<type>(value) ++# define png_constcast(type, value) const_cast<type>(value) ++# define png_aligncast(type, value) \ ++ static_cast<type>(static_cast<void*>(value)) ++# define png_aligncastconst(type, value) \ ++ static_cast<type>(static_cast<const void*>(value)) ++#else ++# define png_voidcast(type, value) (value) ++# define png_constcast(type, value) ((type)(value)) ++# define png_aligncast(type, value) ((void*)(value)) ++# define png_aligncastconst(type, value) ((const void*)(value)) ++#endif /* __cplusplus */ + + /* Some fixed point APIs are still required even if not exported because + * they get used by the corresponding floating point APIs. This magic +@@ -192,6 +449,7 @@ + # define PNGFAPI /* PRIVATE */ + #endif + ++#ifndef PNG_VERSION_INFO_ONLY + /* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ +@@ -236,6 +494,7 @@ + defined(_WIN32) || defined(__WIN32__) + # include <windows.h> /* defines _WINDOWS_ macro */ + #endif ++#endif /* PNG_VERSION_INFO_ONLY */ + + /* Moved here around 1.5.0beta36 from pngconf.h */ + /* Users may want to use these so they are not private. Any library +@@ -251,33 +510,51 @@ + # endif + #endif + +-#ifdef USE_FAR_KEYWORD +-/* Use this to make far-to-near assignments */ +-# define CHECK 1 +-# define NOCHECK 0 +-# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +-# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +-# define png_strlen _fstrlen +-# define png_memcmp _fmemcmp /* SJT: added */ +-# define png_memcpy _fmemcpy +-# define png_memset _fmemset ++/* These macros may need to be architecture dependent. */ ++#define PNG_ALIGN_NONE 0 /* do not use data alignment */ ++#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ ++#ifdef offsetof ++# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ + #else +-# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ +-# define CVT_PTR(ptr) (ptr) +-# define CVT_PTR_NOCHECK(ptr) (ptr) +-# define png_strlen lstrlenA +-# define png_memcmp memcmp +-# define png_memcpy CopyMemory +-# define png_memset memset ++# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ ++#endif ++#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ ++ ++#ifndef PNG_ALIGN_TYPE ++ /* Default to using aligned access optimizations and requiring alignment to a ++ * multiple of the data type size. Override in a compiler specific fashion ++ * if necessary by inserting tests here: ++ */ ++# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE ++#endif ++ ++#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE ++ /* This is used because in some compiler implementations non-aligned ++ * structure members are supported, so the offsetof approach below fails. ++ * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access ++ * is good for performance. Do not do this unless you have tested the result ++ * and understand it. ++ */ ++# define png_alignof(type) (sizeof (type)) ++#else ++# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET ++# define png_alignof(type) offsetof(struct{char c; type t;}, t) + # else +-# define CVT_PTR(ptr) (ptr) +-# define CVT_PTR_NOCHECK(ptr) (ptr) +-# define png_strlen strlen +-# define png_memcmp memcmp /* SJT: added */ +-# define png_memcpy memcpy +-# define png_memset memset ++# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS ++# define png_alignof(type) (1) ++# endif ++ /* Else leave png_alignof undefined to prevent use thereof */ + # endif + #endif ++ ++/* This implicitly assumes alignment is always to a power of 2. */ ++#ifdef png_alignof ++# define png_isaligned(ptr, type)\ ++ ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) ++#else ++# define png_isaligned(ptr, type) 0 ++#endif ++ + /* End of memory model/platform independent support */ + /* End of 1.5.0beta36 move from pngconf.h */ + +@@ -295,15 +572,17 @@ + #define PNG_HAVE_IDAT 0x04 + /* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */ + #define PNG_HAVE_IEND 0x10 +-#define PNG_HAVE_gAMA 0x20 +-#define PNG_HAVE_cHRM 0x40 +-#define PNG_HAVE_sRGB 0x80 ++ /* 0x20 (unused) */ ++ /* 0x40 (unused) */ ++ /* 0x80 (unused) */ + #define PNG_HAVE_CHUNK_HEADER 0x100 + #define PNG_WROTE_tIME 0x200 + #define PNG_WROTE_INFO_BEFORE_PLTE 0x400 + #define PNG_BACKGROUND_IS_GRAY 0x800 + #define PNG_HAVE_PNG_SIGNATURE 0x1000 + #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ ++ /* 0x4000 (unused) */ ++#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */ + + /* Flags for the transformations the PNG library does on the image data */ + #define PNG_BGR 0x0001 +@@ -321,24 +600,23 @@ + #define PNG_EXPAND 0x1000 + #define PNG_GAMMA 0x2000 + #define PNG_GRAY_TO_RGB 0x4000 +-#define PNG_FILLER 0x8000L +-#define PNG_PACKSWAP 0x10000L +-#define PNG_SWAP_ALPHA 0x20000L +-#define PNG_STRIP_ALPHA 0x40000L +-#define PNG_INVERT_ALPHA 0x80000L +-#define PNG_USER_TRANSFORM 0x100000L +-#define PNG_RGB_TO_GRAY_ERR 0x200000L +-#define PNG_RGB_TO_GRAY_WARN 0x400000L +-#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ +-#define PNG_ENCODE_ALPHA 0x800000L /* Added to libpng-1.5.4 */ +-#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ +-#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ +-#define PNG_SCALE_16_TO_8 0x4000000L /* Added to libpng-1.5.4 */ +- /* 0x8000000L unused */ +- /* 0x10000000L unused */ +- /* 0x20000000L unused */ +- /* 0x40000000L unused */ +- ++#define PNG_FILLER 0x8000 ++#define PNG_PACKSWAP 0x10000 ++#define PNG_SWAP_ALPHA 0x20000 ++#define PNG_STRIP_ALPHA 0x40000 ++#define PNG_INVERT_ALPHA 0x80000 ++#define PNG_USER_TRANSFORM 0x100000 ++#define PNG_RGB_TO_GRAY_ERR 0x200000 ++#define PNG_RGB_TO_GRAY_WARN 0x400000 ++#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */ ++#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */ ++#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */ ++#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */ ++#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */ ++ /* 0x8000000 unused */ ++ /* 0x10000000 unused */ ++ /* 0x20000000 unused */ ++ /* 0x40000000 unused */ + /* Flags for png_create_struct */ + #define PNG_STRUCT_PNG 0x0001 + #define PNG_STRUCT_INFO 0x0002 +@@ -349,36 +627,36 @@ + + /* Flags for the png_ptr->flags rather than declaring a byte for each one */ + #define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +-#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +-#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +-#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +-#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +-#define PNG_FLAG_ZLIB_FINISHED 0x0020 ++#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */ ++ /* 0x0004 unused */ ++#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */ ++ /* 0x0010 unused */ ++ /* 0x0020 unused */ + #define PNG_FLAG_ROW_INIT 0x0040 + #define PNG_FLAG_FILLER_AFTER 0x0080 + #define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 + #define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 + #define PNG_FLAG_CRC_CRITICAL_USE 0x0400 + #define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +-#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ +-#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ +-#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ +-#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L +-#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L +-#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L +-#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L +-#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +-#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L +- /* 0x200000L unused */ +- /* 0x400000L unused */ +-#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000L /* Added to libpng-1.4.0 */ +-#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000L /* 5 lines added */ +-#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000L /* to libpng-1.5.4 */ +-#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000L +-#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000L +-#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000L +- /* 0x20000000L unused */ +- /* 0x40000000L unused */ ++#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ ++#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ ++#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ ++/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 */ ++/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 */ ++#define PNG_FLAG_LIBRARY_MISMATCH 0x20000 ++#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000 ++#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 ++#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */ ++#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */ ++#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */ ++ /* 0x800000 unused */ ++ /* 0x1000000 unused */ ++ /* 0x2000000 unused */ ++ /* 0x4000000 unused */ ++ /* 0x8000000 unused */ ++ /* 0x10000000 unused */ ++ /* 0x20000000 unused */ ++ /* 0x40000000 unused */ + + #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) +@@ -389,24 +667,23 @@ + #define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +-/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib +- * can handle at once. This type need be no larger than 16 bits (so maximum of +- * 65535), this define allows us to discover how big it is, but limited by the +- * maximuum for png_size_t. The value can be overriden in a library build +- * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably +- * lower value (e.g. 255 works). A lower value may help memory usage (slightly) +- * and may even improve performance on some systems (and degrade it on others.) +- */ +-#ifndef ZLIB_IO_MAX +-# define ZLIB_IO_MAX ((uInt)-1) +-#endif +- + /* Save typing and make code easier to understand */ + + #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + ++/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255 ++ * by dividing by 257 *with rounding*. This macro is exact for the given range. ++ * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the ++ * macro were established by experiment (modifying the added value). The macro ++ * has a second variant that takes a value already scaled by 255 and divides by ++ * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it ++ * only gives off-by-one errors and only for 0.5% (1 in 200) of the values. ++ */ ++#define PNG_DIV65535(v24) (((v24) + 32895) >> 16) ++#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255) ++ + /* Added to libpng-1.2.6 JB */ + #define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ +@@ -454,151 +731,314 @@ + #ifdef PNG_FIXED_POINT_MACRO_SUPPORTED + #define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ + ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) +-#else +-PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, +- png_const_charp text)); + #endif ++/* else the corresponding function is defined below, inside the scope of the ++ * cplusplus test. ++ */ + #endif + +-/* Constant strings for known chunk types. If you need to add a chunk, +- * define the name here, and add an invocation of the macro wherever it's +- * needed. ++/* Constants for known chunk types. If you need to add a chunk, define the name ++ * here. For historical reasons these constants have the form png_<name>; i.e. ++ * the prefix is lower case. Please use decimal values as the parameters to ++ * match the ISO PNG specification and to avoid relying on the C locale ++ * interpretation of character values. ++ * ++ * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values ++ * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string ++ * to be generated if required. ++ * ++ * PNG_32b correctly produces a value shifted by up to 24 bits, even on ++ * architectures where (int) is only 16 bits. + */ +-#define PNG_IHDR PNG_CONST png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +-#define PNG_IDAT PNG_CONST png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +-#define PNG_IEND PNG_CONST png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +-#define PNG_PLTE PNG_CONST png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +-#define PNG_bKGD PNG_CONST png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +-#define PNG_cHRM PNG_CONST png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +-#define PNG_gAMA PNG_CONST png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +-#define PNG_hIST PNG_CONST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +-#define PNG_iCCP PNG_CONST png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +-#define PNG_iTXt PNG_CONST png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +-#define PNG_oFFs PNG_CONST png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +-#define PNG_pCAL PNG_CONST png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +-#define PNG_sCAL PNG_CONST png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +-#define PNG_pHYs PNG_CONST png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +-#define PNG_sBIT PNG_CONST png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +-#define PNG_sPLT PNG_CONST png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +-#define PNG_sRGB PNG_CONST png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +-#define PNG_sTER PNG_CONST png_byte png_sTER[5] = {115, 84, 69, 82, '\0'} +-#define PNG_tEXt PNG_CONST png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +-#define PNG_tIME PNG_CONST png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +-#define PNG_tRNS PNG_CONST png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +-#define PNG_zTXt PNG_CONST png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} ++#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) ++#define PNG_U32(b1,b2,b3,b4) \ ++ (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) ++ ++/* Constants for known chunk types. ++ * ++ * MAINTAINERS: If you need to add a chunk, define the name here. ++ * For historical reasons these constants have the form png_<name>; i.e. ++ * the prefix is lower case. Please use decimal values as the parameters to ++ * match the ISO PNG specification and to avoid relying on the C locale ++ * interpretation of character values. Please keep the list sorted. ++ * ++ * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk ++ * type. In fact the specification does not express chunk types this way, ++ * however using a 32-bit value means that the chunk type can be read from the ++ * stream using exactly the same code as used for a 32-bit unsigned value and ++ * can be examined far more efficiently (using one arithmetic compare). ++ * ++ * Prior to 1.5.6 the chunk type constants were expressed as C strings. The ++ * libpng API still uses strings for 'unknown' chunks and a macro, ++ * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice ++ * that for portable code numeric values must still be used; the string "IHDR" ++ * is not portable and neither is PNG_U32('I', 'H', 'D', 'R'). ++ * ++ * In 1.7.0 the definitions will be made public in png.h to avoid having to ++ * duplicate the same definitions in application code. ++ */ ++#define png_IDAT PNG_U32( 73, 68, 65, 84) ++#define png_IEND PNG_U32( 73, 69, 78, 68) ++#define png_IHDR PNG_U32( 73, 72, 68, 82) ++#define png_PLTE PNG_U32( 80, 76, 84, 69) ++#define png_bKGD PNG_U32( 98, 75, 71, 68) ++#define png_cHRM PNG_U32( 99, 72, 82, 77) ++#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ ++#define png_gAMA PNG_U32(103, 65, 77, 65) ++#define png_gIFg PNG_U32(103, 73, 70, 103) ++#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ ++#define png_gIFx PNG_U32(103, 73, 70, 120) ++#define png_hIST PNG_U32(104, 73, 83, 84) ++#define png_iCCP PNG_U32(105, 67, 67, 80) ++#define png_iTXt PNG_U32(105, 84, 88, 116) ++#define png_oFFs PNG_U32(111, 70, 70, 115) ++#define png_pCAL PNG_U32(112, 67, 65, 76) ++#define png_pHYs PNG_U32(112, 72, 89, 115) ++#define png_sBIT PNG_U32(115, 66, 73, 84) ++#define png_sCAL PNG_U32(115, 67, 65, 76) ++#define png_sPLT PNG_U32(115, 80, 76, 84) ++#define png_sRGB PNG_U32(115, 82, 71, 66) ++#define png_sTER PNG_U32(115, 84, 69, 82) ++#define png_tEXt PNG_U32(116, 69, 88, 116) ++#define png_tIME PNG_U32(116, 73, 77, 69) ++#define png_tRNS PNG_U32(116, 82, 78, 83) ++#define png_zTXt PNG_U32(122, 84, 88, 116) ++ ++/* The following will work on (signed char*) strings, whereas the get_uint_32 ++ * macro will fail on top-bit-set values because of the sign extension. ++ */ ++#define PNG_CHUNK_FROM_STRING(s)\ ++ PNG_U32(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3]) ++ ++/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is ++ * signed and the argument is a (char[]) This macro will fail miserably on ++ * systems where (char) is more than 8 bits. ++ */ ++#define PNG_STRING_FROM_CHUNK(s,c)\ ++ (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\ ++ ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c))) ++ ++/* Do the same but terminate with a null character. */ ++#define PNG_CSTRING_FROM_CHUNK(s,c)\ ++ (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) ++ ++/* Test on flag values as defined in the spec (section 5.4): */ ++#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29)) ++#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c)) ++#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) ++#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) ++#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) + + /* Gamma values (new at libpng-1.5.4): */ + #define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ + #define PNG_GAMMA_MAC_INVERSE 65909 + #define PNG_GAMMA_sRGB_INVERSE 45455 + ++/* Almost everything below is C specific; the #defines above can be used in ++ * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. ++ */ ++#ifndef PNG_VERSION_INFO_ONLY ++ ++#include "pngstruct.h" ++#include "pnginfo.h" ++ ++/* Validate the include paths - the include path used to generate pnglibconf.h ++ * must match that used in the build, or we must be using pnglibconf.h.prebuilt: ++ */ ++#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM ++# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \ ++ "-I (include path) error: see the notes in pngpriv.h" ++ /* This means that when pnglibconf.h was built the copy of zlib.h that it ++ * used is not the same as the one being used here. Because the build of ++ * libpng makes decisions to use inflateInit2 and inflateReset2 based on the ++ * zlib version number and because this affects handling of certain broken ++ * PNG files the -I directives must match. ++ * ++ * The most likely explanation is that you passed a -I in CFLAGS. This will ++ * not work; all the preprocessor directories and in particular all the -I ++ * directives must be in CPPFLAGS. ++ */ ++#endif ++ ++/* This is used for 16 bit gamma tables -- only the top level pointers are ++ * const; this could be changed: ++ */ ++typedef const png_uint_16p * png_const_uint_16pp; ++ ++/* Added to libpng-1.5.7: sRGB conversion tables */ ++#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ ++ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) ++#ifdef PNG_SIMPLIFIED_READ_SUPPORTED ++PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]); ++ /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value, ++ * 0..65535. This table gives the closest 16-bit answers (no errors). ++ */ ++#endif ++ ++PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]); ++PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]); ++ ++#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\ ++ ((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)) ++ /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB ++ * encoded value with maximum error 0.646365. Note that the input is not a ++ * 16-bit value; it has been multiplied by 255! */ ++#endif /* SIMPLIFIED_READ/WRITE */ ++ + + /* Inhibit C++ name-mangling for libpng functions but not for system calls. */ + #ifdef __cplusplus + extern "C" { + #endif /* __cplusplus */ + +-/* These functions are used internally in the code. They generally +- * shouldn't be used unless you are writing code to add or replace some +- * functionality in libpng. More information about most functions can +- * be found in the files where the functions are located. ++/* Internal functions; these are not exported from a DLL however because they ++ * are used within several of the C source files they have to be C extern. ++ * ++ * All of these functions must be declared with PNG_INTERNAL_FUNCTION. + */ + ++/* Zlib support */ ++#define PNG_UNEXPECTED_ZLIB_RETURN (-7) ++PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret), ++ PNG_EMPTY); ++ /* Used by the zlib handling functions to ensure that z_stream::msg is always ++ * set before they return. ++ */ ++ ++#ifdef PNG_WRITE_SUPPORTED ++PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr, ++ png_compression_bufferp *list),PNG_EMPTY); ++ /* Free the buffer list used by the compressed write code. */ ++#endif ++ ++#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ ++ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ ++ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ ++ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ ++ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ ++ (defined(PNG_sCAL_SUPPORTED) && \ ++ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) ++PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr, ++ double fp, png_const_charp text),PNG_EMPTY); ++#endif ++ + /* Check the user version string for compatibility, returns false if the version + * numbers aren't compatible. + */ +-PNG_EXTERN int png_user_version_check(png_structp png_ptr, +- png_const_charp user_png_ver); ++PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr, ++ png_const_charp user_png_ver),PNG_EMPTY); + +-/* Allocate memory for an internal libpng struct */ +-PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct,PNGARG((int type)), ++/* Internal base allocator - no messages, NULL on failure to allocate. This ++ * does, however, call the application provided allocator and that could call ++ * png_error (although that would be a bug in the application implementation.) ++ */ ++PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr, ++ png_alloc_size_t size),PNG_ALLOCATED); ++ ++#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ ++ defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ++/* Internal array allocator, outputs no error or warning messages on failure, ++ * just returns NULL. ++ */ ++PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr, ++ int nelements, size_t element_size),PNG_ALLOCATED); ++ ++/* The same but an existing array is extended by add_elements. This function ++ * also memsets the new elements to 0 and copies the old elements. The old ++ * array is not freed or altered. ++ */ ++PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr, ++ png_const_voidp array, int old_elements, int add_elements, ++ size_t element_size),PNG_ALLOCATED); ++#endif /* text, sPLT or unknown chunks */ ++ ++/* Magic to create a struct when there is no struct to call the user supplied ++ * memory allocators. Because error handling has not been set up the memory ++ * handlers can't safely call png_error, but this is an obscure and undocumented ++ * restriction so libpng has to assume that the 'free' handler, at least, might ++ * call png_error. ++ */ ++PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct, ++ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, ++ png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, ++ png_free_ptr free_fn),PNG_ALLOCATED); ++ ++/* Free memory from internal libpng struct */ ++PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr), ++ PNG_EMPTY); ++ ++/* Free an allocated jmp_buf (always succeeds) */ ++PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY); ++ ++/* Function to allocate memory for zlib. PNGAPI is disallowed. */ ++PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size), + PNG_ALLOCATED); + +-/* Free memory from internal libpng struct */ +-PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); +- +-PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct_2, +- PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)), +- PNG_ALLOCATED); +-PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, +- png_free_ptr free_fn, png_voidp mem_ptr)); +- +-/* Free any memory that info_ptr points to and reset struct. */ +-PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, +- png_infop info_ptr)); +- +-/* Function to allocate memory for zlib. PNGAPI is disallowed. */ +-PNG_EXTERN PNG_FUNCTION(voidpf,png_zalloc,PNGARG((voidpf png_ptr, uInt items, +- uInt size)),PNG_ALLOCATED); +- + /* Function to free memory for zlib. PNGAPI is disallowed. */ +-PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); ++PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); + + /* Next four functions are used internally as callbacks. PNGCBAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to + * PNGCBAPI at 1.5.0 + */ + +-PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr, +- png_bytep data, png_size_t length)); ++PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, ++ png_bytep data, png_size_t length),PNG_EMPTY); + + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED +-PNG_EXTERN void PNGCBAPI png_push_fill_buffer PNGARG((png_structp png_ptr, +- png_bytep buffer, png_size_t length)); ++PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, ++ png_bytep buffer, png_size_t length),PNG_EMPTY); + #endif + +-PNG_EXTERN void PNGCBAPI png_default_write_data PNGARG((png_structp png_ptr, +- png_bytep data, png_size_t length)); ++PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, ++ png_bytep data, png_size_t length),PNG_EMPTY); + + #ifdef PNG_WRITE_FLUSH_SUPPORTED + # ifdef PNG_STDIO_SUPPORTED +-PNG_EXTERN void PNGCBAPI png_default_flush PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr), ++ PNG_EMPTY); + # endif + #endif + + /* Reset the CRC variable */ +-PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY); + + /* Write the "data" buffer to whatever output you are using */ +-PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, +- png_const_bytep data, png_size_t length)); ++PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, ++ png_const_bytep data, png_size_t length),PNG_EMPTY); + + /* Read and check the PNG file signature */ +-PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); + + /* Read the chunk header (length + type name) */ +-PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr), ++ PNG_EMPTY); + + /* Read data from whatever input you are using into the "data" buffer */ +-PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, +- png_size_t length)); ++PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data, ++ png_size_t length),PNG_EMPTY); + + /* Read bytes into buf, and update png_ptr->crc */ +-PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, +- png_size_t length)); +- +-/* Decompress data in a chunk that uses compression */ +-#if defined(PNG_READ_COMPRESSED_TEXT_SUPPORTED) +-PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, +- int comp_type, png_size_t chunklength, png_size_t prefix_length, +- png_size_t *data_length)); +-#endif ++PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, ++ png_uint_32 length),PNG_EMPTY); + + /* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +-PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); ++PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr, ++ png_uint_32 skip),PNG_EMPTY); + + /* Read the CRC from the file and compare it to the libpng calculated CRC */ +-PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY); + + /* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +-PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, +- png_const_bytep ptr, png_size_t length)); ++PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, ++ png_const_bytep ptr, png_size_t length),PNG_EMPTY); + + #ifdef PNG_WRITE_FLUSH_SUPPORTED +-PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY); + #endif + + /* Write various chunks */ +@@ -606,317 +1046,256 @@ + /* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +-PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, +- png_uint_32 height, +- int bit_depth, int color_type, int compression_method, int filter_method, +- int interlace_method)); ++PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr, ++ png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, ++ int compression_method, int filter_method, int interlace_method),PNG_EMPTY); + +-PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, +- png_const_colorp palette, png_uint_32 num_pal)); ++PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr, ++ png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY); + +-PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, +- png_size_t length)); ++PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr, ++ png_const_bytep row_data, png_alloc_size_t row_data_length, int flush), ++ PNG_EMPTY); + +-PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY); + + #ifdef PNG_WRITE_gAMA_SUPPORTED +-# ifdef PNG_FLOATING_POINT_SUPPORTED +-PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); +-# endif +-# ifdef PNG_FIXED_POINT_SUPPORTED +-PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, +- png_fixed_point file_gamma)); +-# endif ++PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr, ++ png_fixed_point file_gamma),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_sBIT_SUPPORTED +-PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, +- png_const_color_8p sbit, int color_type)); ++PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr, ++ png_const_color_8p sbit, int color_type),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_cHRM_SUPPORTED +-# ifdef PNG_FLOATING_POINT_SUPPORTED +-PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, +- double white_x, double white_y, +- double red_x, double red_y, double green_x, double green_y, +- double blue_x, double blue_y)); +-# endif +-PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, +- png_fixed_point int_white_x, png_fixed_point int_white_y, +- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point +- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, +- png_fixed_point int_blue_y)); ++PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, ++ const png_xy *xy), PNG_EMPTY); ++ /* The xy value must have been previously validated */ + #endif + + #ifdef PNG_WRITE_sRGB_SUPPORTED +-PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, +- int intent)); ++PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr, ++ int intent),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_iCCP_SUPPORTED +-PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, +- png_const_charp name, int compression_type, +- png_const_charp profile, int proflen)); +- /* Note to maintainer: profile should be png_bytep */ ++PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, ++ png_const_charp name, png_const_bytep profile), PNG_EMPTY); ++ /* The profile must have been previously validated for correctness, the ++ * length comes from the first four bytes. Only the base, deflate, ++ * compression is supported. ++ */ + #endif + + #ifdef PNG_WRITE_sPLT_SUPPORTED +-PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, +- png_const_sPLT_tp palette)); ++PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr, ++ png_const_sPLT_tp palette),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_tRNS_SUPPORTED +-PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, ++PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr, + png_const_bytep trans, png_const_color_16p values, int number, +- int color_type)); ++ int color_type),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_bKGD_SUPPORTED +-PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, +- png_const_color_16p values, int color_type)); ++PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr, ++ png_const_color_16p values, int color_type),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_hIST_SUPPORTED +-PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, +- png_const_uint_16p hist, int num_hist)); ++PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr, ++ png_const_uint_16p hist, int num_hist),PNG_EMPTY); + #endif + + /* Chunks that have keywords */ +-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ +- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +-PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, +- png_const_charp key, png_charpp new_key)); +-#endif +- + #ifdef PNG_WRITE_tEXt_SUPPORTED +-PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key, +- png_const_charp text, png_size_t text_len)); ++PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, ++ png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_zTXt_SUPPORTED +-PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_const_charp key, +- png_const_charp text, png_size_t text_len, int compression)); ++PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp ++ key, png_const_charp text, int compression),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_iTXt_SUPPORTED +-PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, ++PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr, + int compression, png_const_charp key, png_const_charp lang, +- png_const_charp lang_key, png_const_charp text)); ++ png_const_charp lang_key, png_const_charp text),PNG_EMPTY); + #endif + + #ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ +-PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, +- png_infop info_ptr, png_const_textp text_ptr, int num_text)); ++PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_oFFs_SUPPORTED +-PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, +- png_int_32 x_offset, png_int_32 y_offset, int unit_type)); ++PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr, ++ png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_pCAL_SUPPORTED +-PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, +- png_int_32 X0, png_int_32 X1, int type, int nparams, +- png_const_charp units, png_charpp params)); ++PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr, ++ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, ++ png_const_charp units, png_charpp params),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_pHYs_SUPPORTED +-PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, ++PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, +- int unit_type)); ++ int unit_type),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_tIME_SUPPORTED +-PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, +- png_const_timep mod_time)); ++PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr, ++ png_const_timep mod_time),PNG_EMPTY); + #endif + + #ifdef PNG_WRITE_sCAL_SUPPORTED +-PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, +- int unit, png_const_charp width, png_const_charp height)); ++PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr, ++ int unit, png_const_charp width, png_const_charp height),PNG_EMPTY); + #endif + + /* Called when finished processing a row of data */ +-PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr), ++ PNG_EMPTY); + + /* Internal use only. Called before first row of data */ +-PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr), ++ PNG_EMPTY); + +-/* Combine a row of data, dealing with alpha, etc. if requested */ +-PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, +- int mask)); ++/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an ++ * array of png_ptr->width pixels. If the image is not interlaced or this ++ * is the final pass this just does a memcpy, otherwise the "display" flag ++ * is used to determine whether to copy pixels that are not in the current pass. ++ * ++ * Because 'png_do_read_interlace' (below) replicates pixels this allows this ++ * function to achieve the documented 'blocky' appearance during interlaced read ++ * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' ++ * are not changed if they are not in the current pass, when display is 0. ++ * ++ * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. ++ * ++ * The API always reads from the png_struct row buffer and always assumes that ++ * it is full width (png_do_read_interlace has already been called.) ++ * ++ * This function is only ever used to write to row buffers provided by the ++ * caller of the relevant libpng API and the row must have already been ++ * transformed by the read transformations. ++ * ++ * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed ++ * bitmasks for use within the code, otherwise runtime generated masks are used. ++ * The default is compile time masks. ++ */ ++#ifndef PNG_USE_COMPILE_TIME_MASKS ++# define PNG_USE_COMPILE_TIME_MASKS 1 ++#endif ++PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr, ++ png_bytep row, int display),PNG_EMPTY); + + #ifdef PNG_READ_INTERLACING_SUPPORTED +-/* Expand an interlaced row */ +-/* OLD pre-1.0.9 interface: +-PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, +- png_bytep row, int pass, png_uint_32 transformations)); ++/* Expand an interlaced row: the 'row_info' describes the pass data that has ++ * been read in and must correspond to the pixels in 'row', the pixels are ++ * expanded (moved apart) in 'row' to match the final layout, when doing this ++ * the pixels are *replicated* to the intervening space. This is essential for ++ * the correct operation of png_combine_row, above. + */ +-PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info, ++ png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY); + #endif + + /* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + + #ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Grab pixels out of a row for an interlaced pass */ +-PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, +- png_bytep row, int pass)); ++PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info, ++ png_bytep row, int pass),PNG_EMPTY); + #endif + +-/* Unfilter a row */ +-PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, +- png_row_infop row_info, png_bytep row, png_const_bytep prev_row, +- int filter)); ++/* Unfilter a row: check the filter value before calling this, there is no point ++ * calling it for PNG_FILTER_VALUE_NONE. ++ */ ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop ++ row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY); ++ ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info, ++ png_bytep row, png_const_bytep prev_row),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop ++ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop ++ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop ++ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop ++ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop ++ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop ++ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); + + /* Choose the best filter to use and filter the row data */ +-PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, +- png_row_infop row_info)); ++PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, ++ png_row_infop row_info),PNG_EMPTY); + +-/* Finish a row while reading, dealing with interlacing passes, etc. */ +-PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); ++#ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr, ++ png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY); ++ /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer ++ * is NULL the function checks, instead, for the end of the stream. In this ++ * case a benign error will be issued if the stream end is not found or if ++ * extra data has to be consumed. ++ */ ++PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr), ++ PNG_EMPTY); ++ /* This cleans up when the IDAT LZ stream does not end when the last image ++ * byte is read; there is still some pending input. ++ */ ++ ++PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr), ++ PNG_EMPTY); ++ /* Finish a row while reading, dealing with interlacing passes, etc. */ ++#endif /* SEQUENTIAL_READ */ + + /* Initialize the row buffers, etc. */ +-PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); + + #ifdef PNG_READ_TRANSFORMS_SUPPORTED + /* Optional call to update the users info structure */ +-PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, +- png_infop info_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); + #endif + +-/* These are the functions that do the transformations */ +-#ifdef PNG_READ_FILLER_SUPPORTED +-PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, +- png_bytep row, png_uint_32 filler, png_uint_32 flags)); +-#endif +- +-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +-PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +-PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +-PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +-PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- ++/* Shared transform functions, defined in pngtran.c */ + #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +-PNG_EXTERN void png_do_strip_channel PNGARG((png_row_infop row_info, +- png_bytep row, int at_start)); ++PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info, ++ png_bytep row, int at_start),PNG_EMPTY); + #endif + + #ifdef PNG_16BIT_SUPPORTED + #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +-PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, +- png_bytep row)); ++PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info, ++ png_bytep row),PNG_EMPTY); + #endif + #endif + + #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +-PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +-PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, +- png_row_infop row_info, png_bytep row)); +-#endif +- +-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +-PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_READ_PACK_SUPPORTED +-PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_READ_SHIFT_SUPPORTED +-PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, +- png_bytep row, png_const_color_8p sig_bits)); ++PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info, ++ png_bytep row),PNG_EMPTY); + #endif + + #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +-PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +-PNG_EXTERN void png_do_scale_16_to_8 PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +-PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_READ_QUANTIZE_SUPPORTED +-PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info, +- png_bytep row, png_const_bytep palette_lookup, +- png_const_bytep quantize_lookup)); +- +-# ifdef PNG_CORRECT_PALETTE_SUPPORTED +-PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, +- png_colorp palette, int num_palette)); +-# endif ++PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info, ++ png_bytep row),PNG_EMPTY); + #endif + + #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +-PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, +- png_bytep row)); +-#endif +- +-#ifdef PNG_WRITE_PACK_SUPPORTED +-PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, +- png_bytep row, png_uint_32 bit_depth)); +-#endif +- +-#ifdef PNG_WRITE_SHIFT_SUPPORTED +-PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, +- png_bytep row, png_const_color_8p bit_depth)); +-#endif +- +-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ +- defined(PNG_READ_ALPHA_MODE_SUPPORTED) +-PNG_EXTERN void png_do_compose PNGARG((png_row_infop row_info, +- png_bytep row, png_structp png_ptr)); +-#endif +- +-#ifdef PNG_READ_GAMMA_SUPPORTED +-PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, +- png_bytep row, png_structp png_ptr)); +-#endif +- +-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +-PNG_EXTERN void png_do_encode_alpha PNGARG((png_row_infop row_info, +- png_bytep row, png_structp png_ptr)); +-#endif +- +-#ifdef PNG_READ_EXPAND_SUPPORTED +-PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, +- png_bytep row, png_const_colorp palette, png_const_bytep trans, +- int num_trans)); +-PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, +- png_bytep row, png_const_color_16p trans_color)); +-#endif +- +-#ifdef PNG_READ_EXPAND_16_SUPPORTED +-PNG_EXTERN void png_do_expand_16 PNGARG((png_row_infop row_info, +- png_bytep row)); ++PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info, ++ png_bytep row),PNG_EMPTY); + #endif + + /* The following decodes the appropriate chunks, and does error correction, +@@ -924,208 +1303,283 @@ + */ + + /* Decode the IHDR chunk */ +-PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); +-PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); +-PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + + #ifdef PNG_READ_bKGD_SUPPORTED +-PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_cHRM_SUPPORTED +-PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_gAMA_SUPPORTED +-PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_hIST_SUPPORTED +-PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_iCCP_SUPPORTED +-PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); +-#endif /* PNG_READ_iCCP_SUPPORTED */ ++PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++#endif /* READ_iCCP */ + + #ifdef PNG_READ_iTXt_SUPPORTED +-PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_oFFs_SUPPORTED +-PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_pCAL_SUPPORTED +-PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_pHYs_SUPPORTED +-PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_sBIT_SUPPORTED +-PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_sCAL_SUPPORTED +-PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_sPLT_SUPPORTED +-PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); +-#endif /* PNG_READ_sPLT_SUPPORTED */ ++PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++#endif /* READ_sPLT */ + + #ifdef PNG_READ_sRGB_SUPPORTED +-PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_tEXt_SUPPORTED +-PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_tIME_SUPPORTED +-PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_tRNS_SUPPORTED +-PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + + #ifdef PNG_READ_zTXt_SUPPORTED +-PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, +- png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); + #endif + +-PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, +- png_infop info_ptr, png_uint_32 length)); ++PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr, ++ png_uint_32 chunk_name),PNG_EMPTY); + +-PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, +- png_const_bytep chunk_name)); ++PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); ++ /* This is the function that gets called for unknown chunks. The 'keep' ++ * argument is either non-zero for a known chunk that has been set to be ++ * handled as unknown or zero for an unknown chunk. By default the function ++ * just skips the chunk or errors out if it is critical. ++ */ ++ ++#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ ++ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) ++PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling, ++ (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY); ++ /* Exactly as the API png_handle_as_unknown() except that the argument is a ++ * 32-bit chunk name, not a string. ++ */ ++#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ + + /* Handle the transformations for reading and writing */ + #ifdef PNG_READ_TRANSFORMS_SUPPORTED +-PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr, ++ png_row_infop row_info),PNG_EMPTY); + #endif + #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +-PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr, ++ png_row_infop row_info),PNG_EMPTY); + #endif + + #ifdef PNG_READ_TRANSFORMS_SUPPORTED +-PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr), ++ PNG_EMPTY); + #endif + + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED +-PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, +- png_infop info_ptr)); +-PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, +- png_infop info_ptr)); +-PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); +-PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, +- png_uint_32 length)); +-PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); +-PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); +-PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, +- png_bytep buffer, png_size_t buffer_length)); +-PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); +-PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, +- png_bytep buffer, png_size_t buffer_length)); +-PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); +-PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, +- png_infop info_ptr, png_uint_32 length)); +-PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, +- png_infop info_ptr)); +-PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, +- png_infop info_ptr)); +-PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +-PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, +- png_infop info_ptr)); +-PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, +- png_infop info_ptr)); +-PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_crc_skip,(png_structrp png_ptr, ++ png_uint_32 length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_crc_finish,(png_structrp png_ptr), ++ PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr), ++ PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, ++ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, ++ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), ++ PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr, ++ png_bytep row),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr), ++ PNG_EMPTY); + # ifdef PNG_READ_tEXt_SUPPORTED +-PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, +- png_infop info_ptr, png_uint_32 length)); +-PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, +- png_infop info_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); + # endif + # ifdef PNG_READ_zTXt_SUPPORTED +-PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, +- png_infop info_ptr, png_uint_32 length)); +-PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, +- png_infop info_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); + # endif + # ifdef PNG_READ_iTXt_SUPPORTED +-PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, +- png_infop info_ptr, png_uint_32 length)); +-PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, +- png_infop info_ptr)); ++PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr, ++ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr, ++ png_inforp info_ptr),PNG_EMPTY); + # endif + +-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ ++#endif /* PROGRESSIVE_READ */ + +-#ifdef PNG_MNG_FEATURES_SUPPORTED +-PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, +- png_bytep row)); +-PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, +- png_bytep row)); ++/* Added at libpng version 1.6.0 */ ++#ifdef PNG_GAMMA_SUPPORTED ++PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY); ++ /* Set the colorspace gamma with a value provided by the application or by ++ * the gAMA chunk on read. The value will override anything set by an ICC ++ * profile. ++ */ ++ ++PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, ++ png_inforp info_ptr), PNG_EMPTY); ++ /* Synchronize the info 'valid' flags with the colorspace */ ++ ++PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, ++ png_inforp info_ptr), PNG_EMPTY); ++ /* Copy the png_struct colorspace to the info_struct and call the above to ++ * synchronize the flags. Checks for NULL info_ptr and does nothing. ++ */ + #endif + + /* Added at libpng version 1.4.0 */ +-#ifdef PNG_CHECK_cHRM_SUPPORTED +-PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, +- png_fixed_point int_white_x, png_fixed_point int_white_y, +- png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point +- int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, +- png_fixed_point int_blue_y)); ++#ifdef PNG_COLORSPACE_SUPPORTED ++/* These internal functions are for maintaining the colorspace structure within ++ * a png_info or png_struct (or, indeed, both). ++ */ ++PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities, ++ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy, ++ int preferred), PNG_EMPTY); ++ ++PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints, ++ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ, ++ int preferred), PNG_EMPTY); ++ ++#ifdef PNG_sRGB_SUPPORTED ++PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, int intent), PNG_EMPTY); ++ /* This does set the colorspace gAMA and cHRM values too, but doesn't set the ++ * flags to write them, if it returns false there was a problem and an error ++ * message has already been output (but the colorspace may still need to be ++ * synced to record the invalid flag). ++ */ ++#endif /* sRGB */ ++ ++#ifdef PNG_iCCP_SUPPORTED ++PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, png_const_charp name, ++ png_uint_32 profile_length, png_const_bytep profile, int color_type), ++ PNG_EMPTY); ++ /* The 'name' is used for information only */ ++ ++/* Routines for checking parts of an ICC profile. */ ++PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, png_const_charp name, ++ png_uint_32 profile_length), PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, png_const_charp name, ++ png_uint_32 profile_length, ++ png_const_bytep profile /* first 132 bytes only */, int color_type), ++ PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr, ++ png_colorspacerp colorspace, png_const_charp name, ++ png_uint_32 profile_length, ++ png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY); ++#ifdef PNG_sRGB_SUPPORTED ++PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,( ++ png_const_structrp png_ptr, png_colorspacerp colorspace, ++ png_const_bytep profile, uLong adler), PNG_EMPTY); ++ /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may ++ * be zero to indicate that it is not available. It is used, if provided, ++ * as a fast check on the profile when checking to see if it is sRGB. ++ */ ++#endif ++#endif /* iCCP */ ++ ++#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED ++PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients, ++ (png_structrp png_ptr), PNG_EMPTY); ++ /* Set the rgb_to_gray coefficients from the colorspace Y values */ ++#endif /* READ_RGB_TO_GRAY */ ++#endif /* COLORSPACE */ ++ ++/* Added at libpng version 1.4.0 */ ++PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr, ++ png_uint_32 width, png_uint_32 height, int bit_depth, ++ int color_type, int interlace_type, int compression_type, ++ int filter_type),PNG_EMPTY); ++ ++/* Added at libpng version 1.5.10 */ ++#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ ++ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) ++PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes, ++ (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); + #endif + +-#ifdef PNG_CHECK_cHRM_SUPPORTED +-/* Added at libpng version 1.2.34 and 1.4.0 */ +-/* Currently only used by png_check_cHRM_fixed */ +-PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, +- unsigned long *hi_product, unsigned long *lo_product)); +-#endif +- +-/* Added at libpng version 1.4.0 */ +-PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, +- png_uint_32 width, png_uint_32 height, int bit_depth, +- int color_type, int interlace_type, int compression_type, +- int filter_type)); +- +-/* Free all memory used by the read (old method - NOT DLL EXPORTED) */ +-PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, +- png_infop info_ptr, png_infop end_info_ptr)); +- +-/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +-PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr)); +- +-#ifdef USE_FAR_KEYWORD /* memory model conversion function */ +-PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr, +- int check)); +-#endif /* USE_FAR_KEYWORD */ +- + #if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +-PNG_EXTERN PNG_FUNCTION(void, png_fixed_error, (png_structp png_ptr, ++PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr, + png_const_charp name),PNG_NORETURN); + #endif + +@@ -1133,8 +1587,8 @@ + * the end. Always leaves the buffer nul terminated. Never errors out (and + * there is no error code.) + */ +-PNG_EXTERN size_t png_safecat(png_charp buffer, size_t bufsize, size_t pos, +- png_const_charp string); ++PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize, ++ size_t pos, png_const_charp string),PNG_EMPTY); + + /* Various internal functions to handle formatted warning messages, currently + * only implemented for warnings. +@@ -1145,8 +1599,8 @@ + * Returns the pointer to the start of the formatted string. This utility only + * does unsigned values. + */ +-PNG_EXTERN png_charp png_format_number(png_const_charp start, png_charp end, +- int format, png_alloc_size_t number); ++PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start, ++ png_charp end, int format, png_alloc_size_t number),PNG_EMPTY); + + /* Convenience macro that takes an array: */ + #define PNG_FORMAT_NUMBER(buffer,format,number) \ +@@ -1170,7 +1624,7 @@ + #ifdef PNG_WARNINGS_SUPPORTED + /* New defines and members adding in libpng-1.5.4 */ + # define PNG_WARNING_PARAMETER_SIZE 32 +-# define PNG_WARNING_PARAMETER_COUNT 8 ++# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */ + + /* An l-value of this type has to be passed to the APIs below to cache the + * values of the parameters to a formatted warning message. +@@ -1178,48 +1632,97 @@ + typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ + PNG_WARNING_PARAMETER_SIZE]; + +-PNG_EXTERN void png_warning_parameter(png_warning_parameters p, int number, +- png_const_charp string); +- /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, +- * including the trailing '\0'. +- */ +-PNG_EXTERN void png_warning_parameter_unsigned(png_warning_parameters p, +- int number, int format, png_alloc_size_t value); +- /* Use png_alloc_size_t because it is an unsigned type as big as any we +- * need to output. Use the following for a signed value. +- */ +-PNG_EXTERN void png_warning_parameter_signed(png_warning_parameters p, +- int number, int format, png_int_32 value); ++PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p, ++ int number, png_const_charp string),PNG_EMPTY); ++ /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, ++ * including the trailing '\0'. ++ */ ++PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned, ++ (png_warning_parameters p, int number, int format, png_alloc_size_t value), ++ PNG_EMPTY); ++ /* Use png_alloc_size_t because it is an unsigned type as big as any we ++ * need to output. Use the following for a signed value. ++ */ ++PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed, ++ (png_warning_parameters p, int number, int format, png_int_32 value), ++ PNG_EMPTY); + +-PNG_EXTERN void png_formatted_warning(png_structp png_ptr, +- png_warning_parameters p, png_const_charp message); +- /* 'message' follows the X/Open approach of using @1, @2 to insert +- * parameters previously supplied using the above functions. Errors in +- * specifying the parameters will simple result in garbage substitutions. +- */ ++PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr, ++ png_warning_parameters p, png_const_charp message),PNG_EMPTY); ++ /* 'message' follows the X/Open approach of using @1, @2 to insert ++ * parameters previously supplied using the above functions. Errors in ++ * specifying the parameters will simply result in garbage substitutions. ++ */ + #endif + ++#ifdef PNG_BENIGN_ERRORS_SUPPORTED ++/* Application errors (new in 1.6); use these functions (declared below) for ++ * errors in the parameters or order of API function calls on read. The ++ * 'warning' should be used for an error that can be handled completely; the ++ * 'error' for one which can be handled safely but which may lose application ++ * information or settings. ++ * ++ * By default these both result in a png_error call prior to release, while in a ++ * released version the 'warning' is just a warning. However if the application ++ * explicitly disables benign errors (explicitly permitting the code to lose ++ * information) they both turn into warnings. ++ * ++ * If benign errors aren't supported they end up as the corresponding base call ++ * (png_warning or png_error.) ++ */ ++PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr, ++ png_const_charp message),PNG_EMPTY); ++ /* The application provided invalid parameters to an API function or called ++ * an API function at the wrong time, libpng can completely recover. ++ */ ++ ++PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr, ++ png_const_charp message),PNG_EMPTY); ++ /* As above but libpng will ignore the call, or attempt some other partial ++ * recovery from the error. ++ */ ++#else ++# define png_app_warning(pp,s) png_warning(pp,s) ++# define png_app_error(pp,s) png_error(pp,s) ++#endif ++ ++PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr, ++ png_const_charp message, int error),PNG_EMPTY); ++ /* Report a recoverable issue in chunk data. On read this is used to report ++ * a problem found while reading a particular chunk and the ++ * png_chunk_benign_error or png_chunk_warning function is used as ++ * appropriate. On write this is used to report an error that comes from ++ * data set via an application call to a png_set_ API and png_app_error or ++ * png_app_warning is used as appropriate. ++ * ++ * The 'error' parameter must have one of the following values: ++ */ ++#define PNG_CHUNK_WARNING 0 /* never an error */ ++#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */ ++#define PNG_CHUNK_ERROR 2 /* always an error */ ++ + /* ASCII to FP interfaces, currently only implemented if sCAL + * support is required. + */ +-#if defined(PNG_READ_sCAL_SUPPORTED) ++#if defined(PNG_sCAL_SUPPORTED) + /* MAX_DIGITS is actually the maximum number of characters in an sCAL + * width or height, derived from the precision (number of significant +- * digits - a build time settable option) and assumpitions about the ++ * digits - a build time settable option) and assumptions about the + * maximum ridiculous exponent. + */ + #define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) + + #ifdef PNG_FLOATING_POINT_SUPPORTED +-PNG_EXTERN void png_ascii_from_fp PNGARG((png_structp png_ptr, png_charp ascii, +- png_size_t size, double fp, unsigned int precision)); ++PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, ++ png_charp ascii, png_size_t size, double fp, unsigned int precision), ++ PNG_EMPTY); + #endif /* FLOATING_POINT */ + + #ifdef PNG_FIXED_POINT_SUPPORTED +-PNG_EXTERN void png_ascii_from_fixed PNGARG((png_structp png_ptr, +- png_charp ascii, png_size_t size, png_fixed_point fp)); ++PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, ++ png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY); + #endif /* FIXED_POINT */ +-#endif /* READ_sCAL */ ++#endif /* sCAL */ + + #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) + /* An internal API to validate the format of a floating point number. +@@ -1243,7 +1746,7 @@ + * NOTE: The dangling E problem. + * There is a PNG valid floating point number in the following: + * +- * PNG floating point numb1.ers are not greedy. ++ * PNG floating point numbers are not greedy. + * + * Working this out requires *TWO* character lookahead (because of the + * sign), the parser does not do this - it will fail at the 'r' - this +@@ -1294,14 +1797,14 @@ + #define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) + #define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) + +-/* The actual parser. This can be called repeatedly, it updates ++/* The actual parser. This can be called repeatedly. It updates + * the index into the string and the state variable (which must +- * be initialzed to 0). It returns a result code, as above. There ++ * be initialized to 0). It returns a result code, as above. There + * is no point calling the parser any more if it fails to advance to + * the end of the string - it is stuck on an invalid character (or + * terminated by '\0'). + * +- * Note that the pointer will consume an E or even an E+ then leave ++ * Note that the pointer will consume an E or even an E+ and then leave + * a 'maybe' state even though a preceding integer.fraction is valid. + * The PNG_FP_WAS_VALID flag indicates that a preceding substring was + * a valid number. It's possible to recover from this by calling +@@ -1309,8 +1812,8 @@ + * that omits the last character (i.e. set the size to the index of + * the problem character.) This has not been tested within libpng. + */ +-PNG_EXTERN int png_check_fp_number PNGARG((png_const_charp string, +- png_size_t size, int *statep, png_size_tp whereami)); ++PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, ++ png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); + + /* This is the same but it checks a complete string and returns true + * only if it just contains a floating point number. As of 1.5.4 this +@@ -1318,11 +1821,11 @@ + * it was valid (otherwise it returns 0.) This can be used for testing + * for negative or zero values using the sticky flag. + */ +-PNG_EXTERN int png_check_fp_string PNGARG((png_const_charp string, +- png_size_t size)); ++PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, ++ png_size_t size),PNG_EMPTY); + #endif /* pCAL || sCAL */ + +-#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ ++#if defined(PNG_GAMMA_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) + /* Added at libpng version 1.5.0 */ + /* This is a utility to provide a*times/div (rounded) and indicate +@@ -1330,29 +1833,37 @@ + * for overflow, true (1) if no overflow, in which case *res + * holds the result. + */ +-PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a, +- png_int_32 multiplied_by, png_int_32 divided_by)); ++PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a, ++ png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY); + #endif + + #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) + /* Same deal, but issue a warning on overflow and return 0. */ +-PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr, +- png_fixed_point a, png_int_32 multiplied_by, png_int_32 divided_by)); ++PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn, ++ (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by, ++ png_int_32 divided_by),PNG_EMPTY); + #endif + +-#ifdef PNG_READ_GAMMA_SUPPORTED ++#ifdef PNG_GAMMA_SUPPORTED + /* Calculate a reciprocal - used for gamma values. This returns +- * 0 if the argument is 0 in order to maintain an undefined value, ++ * 0 if the argument is 0 in order to maintain an undefined value; + * there are no warnings. + */ +-PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a)); ++PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a), ++ PNG_EMPTY); + ++#ifdef PNG_READ_GAMMA_SUPPORTED + /* The same but gives a reciprocal of the product of two fixed point + * values. Accuracy is suitable for gamma calculations but this is +- * not exact - use png_muldiv for that. ++ * not exact - use png_muldiv for that. Only required at present on read. + */ +-PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a, +- png_fixed_point b)); ++PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a, ++ png_fixed_point b),PNG_EMPTY); ++#endif ++ ++/* Return true if the gamma value is significantly different from 1.0 */ ++PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value), ++ PNG_EMPTY); + #endif + + #ifdef PNG_READ_GAMMA_SUPPORTED +@@ -1363,19 +1874,93 @@ + * While the input is an 'unsigned' value it must actually be the + * correct bit value - 0..255 or 0..65535 as required. + */ +-PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr, +- unsigned int value, png_fixed_point gamma_value)); +-PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma_value)); +-PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value, +- png_fixed_point gamma_value)); +-PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, +- png_fixed_point gamma_value)); +-PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, +- int bit_depth)); ++PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr, ++ unsigned int value, png_fixed_point gamma_value),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value, ++ png_fixed_point gamma_value),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value, ++ png_fixed_point gamma_value),PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr), ++ PNG_EMPTY); ++PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr, ++ int bit_depth),PNG_EMPTY); + #endif + +-/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ ++/* SIMPLIFIED READ/WRITE SUPPORT */ ++#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ ++ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) ++/* The internal structure that png_image::opaque points to. */ ++typedef struct png_control ++{ ++ png_structp png_ptr; ++ png_infop info_ptr; ++ png_voidp error_buf; /* Always a jmp_buf at present. */ + ++ png_const_bytep memory; /* Memory buffer. */ ++ png_size_t size; /* Size of the memory buffer. */ ++ ++ unsigned int for_write :1; /* Otherwise it is a read structure */ ++ unsigned int owned_file :1; /* We own the file in io_ptr */ ++} png_control; ++ ++/* Return the pointer to the jmp_buf from a png_control: necessary because C ++ * does not reveal the type of the elements of jmp_buf. ++ */ ++#ifdef __cplusplus ++# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0]) ++#else ++# define png_control_jmp_buf(pc) ((pc)->error_buf) ++#endif ++ ++/* Utility to safely execute a piece of libpng code catching and logging any ++ * errors that might occur. Returns true on success, false on failure (either ++ * of the function or as a result of a png_error.) ++ */ ++PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr, ++ png_const_charp error_message),PNG_NORETURN); ++ ++#ifdef PNG_WARNINGS_SUPPORTED ++PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr, ++ png_const_charp warning_message),PNG_EMPTY); ++#else ++# define png_safe_warning 0/*dummy argument*/ ++#endif ++ ++PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image, ++ int (*function)(png_voidp), png_voidp arg),PNG_EMPTY); ++ ++/* Utility to log an error; this also cleans up the png_image; the function ++ * always returns 0 (false). ++ */ ++PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image, ++ png_const_charp error_message),PNG_EMPTY); ++ ++#ifndef PNG_SIMPLIFIED_READ_SUPPORTED ++/* png_image_free is used by the write code but not exported */ ++PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY); ++#endif /* !SIMPLIFIED_READ */ ++ ++#endif /* SIMPLIFIED READ/WRITE */ ++ ++/* These are initialization functions for hardware specific PNG filter ++ * optimizations; list these here then select the appropriate one at compile ++ * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined ++ * the generic code is used. ++ */ ++#ifdef PNG_FILTER_OPTIMIZATIONS ++PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr, ++ unsigned int bpp), PNG_EMPTY); ++ /* Just declare the optimization that will be used */ ++#else ++ /* List *all* the possible optimizations here - this branch is required if ++ * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in ++ * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. ++ */ ++PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, ++ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); ++#endif ++ ++/* Maintainer: Put new private prototypes here ^ */ + + #include "pngdebug.h" + +@@ -1383,4 +1968,5 @@ + } + #endif + ++#endif /* PNG_VERSION_INFO_ONLY */ + #endif /* PNGPRIV_H */ +--- ./jdk/src/share/native/sun/awt/libpng/pngread.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngread.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -43,6 +43,9 @@ + */ + + #include "pngpriv.h" ++#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) ++# include <errno.h> ++#endif + + #ifdef PNG_READ_SUPPORTED + +@@ -51,10 +54,12 @@ + png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) + { +- +-#ifdef PNG_USER_MEM_SUPPORTED +- return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, +- warn_fn, NULL, NULL, NULL)); ++#ifndef PNG_USER_MEM_SUPPORTED ++ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, ++ error_fn, warn_fn, NULL, NULL, NULL); ++#else ++ return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, ++ warn_fn, NULL, NULL, NULL); + } + + /* Alternate create PNG structure for reading, and allocate any memory +@@ -65,134 +70,40 @@ + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) + { +-#endif /* PNG_USER_MEM_SUPPORTED */ +- +-#ifdef PNG_SETJMP_SUPPORTED +- volatile +-#endif +- png_structp png_ptr; +- volatile int png_cleanup_needed = 0; +- +-#ifdef PNG_SETJMP_SUPPORTED +-#ifdef USE_FAR_KEYWORD +- jmp_buf tmp_jmpbuf; +-#endif +-#endif +- +- png_debug(1, "in png_create_read_struct"); +- +-#ifdef PNG_USER_MEM_SUPPORTED +- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, +- malloc_fn, mem_ptr); +-#else +- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +-#endif +- if (png_ptr == NULL) +- return (NULL); +- +- /* Added at libpng-1.2.6 */ +-#ifdef PNG_USER_LIMITS_SUPPORTED +- png_ptr->user_width_max = PNG_USER_WIDTH_MAX; +- png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; +- +-# ifdef PNG_USER_CHUNK_CACHE_MAX +- /* Added at libpng-1.2.43 and 1.4.0 */ +- png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; +-# endif +- +-# ifdef PNG_SET_USER_CHUNK_MALLOC_MAX +- /* Added at libpng-1.2.43 and 1.4.1 */ +- png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; +-# endif +-#endif +- +-#ifdef PNG_SETJMP_SUPPORTED +-/* Applications that neglect to set up their own setjmp() and then +- encounter a png_error() will longjmp here. Since the jmpbuf is +- then meaningless we abort instead of returning. */ +-#ifdef USE_FAR_KEYWORD +- if (setjmp(tmp_jmpbuf)) +-#else +- if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ +-#endif +- PNG_ABORT(); +-#ifdef USE_FAR_KEYWORD +- png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +-#endif +-#endif /* PNG_SETJMP_SUPPORTED */ +- +-#ifdef PNG_USER_MEM_SUPPORTED +- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +-#endif +- +- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); +- +- /* Call the general version checker (shared with read and write code): */ +- if (!png_user_version_check(png_ptr, user_png_ver)) +- png_cleanup_needed = 1; +- +- if (!png_cleanup_needed) ++ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, ++ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); ++#endif /* USER_MEM */ ++ ++ if (png_ptr != NULL) + { +- /* Initialize zbuf - compression buffer */ +- png_ptr->zbuf_size = PNG_ZBUF_SIZE; +- png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); +- +- if (png_ptr->zbuf == NULL) +- png_cleanup_needed = 1; ++ png_ptr->mode = PNG_IS_READ_STRUCT; ++ ++ /* Added in libpng-1.6.0; this can be used to detect a read structure if ++ * required (it will be zero in a write structure.) ++ */ ++# ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++ png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; ++# endif ++ ++# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED ++ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; ++ ++ /* In stable builds only warn if an application error can be completely ++ * handled. ++ */ ++# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC ++ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; ++# endif ++# endif ++ ++ /* TODO: delay this, it can be done in png_init_io (if the app doesn't ++ * do it itself) avoiding setting the default function if it is not ++ * required. ++ */ ++ png_set_read_fn(png_ptr, NULL, NULL); + } + +- png_ptr->zstream.zalloc = png_zalloc; +- png_ptr->zstream.zfree = png_zfree; +- png_ptr->zstream.opaque = (voidpf)png_ptr; +- +- if (!png_cleanup_needed) +- { +- switch (inflateInit(&png_ptr->zstream)) +- { +- case Z_OK: +- break; /* Do nothing */ +- +- case Z_MEM_ERROR: +- png_warning(png_ptr, "zlib memory error"); +- png_cleanup_needed = 1; +- break; +- +- case Z_STREAM_ERROR: +- png_warning(png_ptr, "zlib stream error"); +- png_cleanup_needed = 1; +- break; +- +- case Z_VERSION_ERROR: +- png_warning(png_ptr, "zlib version error"); +- png_cleanup_needed = 1; +- break; +- +- default: png_warning(png_ptr, "Unknown zlib error"); +- png_cleanup_needed = 1; +- } +- } +- +- if (png_cleanup_needed) +- { +- /* Clean up PNG structure and deallocate any memory. */ +- png_free(png_ptr, png_ptr->zbuf); +- png_ptr->zbuf = NULL; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2((png_voidp)png_ptr, +- (png_free_ptr)free_fn, (png_voidp)mem_ptr); +-#else +- png_destroy_struct((png_voidp)png_ptr); +-#endif +- return (NULL); +- } +- +- png_ptr->zstream.next_out = png_ptr->zbuf; +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +- +- png_set_read_fn(png_ptr, NULL, NULL); +- +- +- return (png_ptr); ++ return png_ptr; + } + + +@@ -206,8 +117,12 @@ + * read if it is determined that this isn't a valid PNG file. + */ + void PNGAPI +-png_read_info(png_structp png_ptr, png_infop info_ptr) ++png_read_info(png_structrp png_ptr, png_inforp info_ptr) + { ++#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED ++ int keep; ++#endif ++ + png_debug(1, "in png_read_info"); + + if (png_ptr == NULL || info_ptr == NULL) +@@ -218,231 +133,179 @@ + + for (;;) + { +- PNG_IHDR; +- PNG_IDAT; +- PNG_IEND; +- PNG_PLTE; +-#ifdef PNG_READ_bKGD_SUPPORTED +- PNG_bKGD; +-#endif +-#ifdef PNG_READ_cHRM_SUPPORTED +- PNG_cHRM; +-#endif +-#ifdef PNG_READ_gAMA_SUPPORTED +- PNG_gAMA; +-#endif +-#ifdef PNG_READ_hIST_SUPPORTED +- PNG_hIST; +-#endif +-#ifdef PNG_READ_iCCP_SUPPORTED +- PNG_iCCP; +-#endif +-#ifdef PNG_READ_iTXt_SUPPORTED +- PNG_iTXt; +-#endif +-#ifdef PNG_READ_oFFs_SUPPORTED +- PNG_oFFs; +-#endif +-#ifdef PNG_READ_pCAL_SUPPORTED +- PNG_pCAL; +-#endif +-#ifdef PNG_READ_pHYs_SUPPORTED +- PNG_pHYs; +-#endif +-#ifdef PNG_READ_sBIT_SUPPORTED +- PNG_sBIT; +-#endif +-#ifdef PNG_READ_sCAL_SUPPORTED +- PNG_sCAL; +-#endif +-#ifdef PNG_READ_sPLT_SUPPORTED +- PNG_sPLT; +-#endif +-#ifdef PNG_READ_sRGB_SUPPORTED +- PNG_sRGB; +-#endif +-#ifdef PNG_READ_tEXt_SUPPORTED +- PNG_tEXt; +-#endif +-#ifdef PNG_READ_tIME_SUPPORTED +- PNG_tIME; +-#endif +-#ifdef PNG_READ_tRNS_SUPPORTED +- PNG_tRNS; +-#endif +-#ifdef PNG_READ_zTXt_SUPPORTED +- PNG_zTXt; +-#endif + png_uint_32 length = png_read_chunk_header(png_ptr); +- PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; ++ png_uint_32 chunk_name = png_ptr->chunk_name; ++ ++ /* IDAT logic needs to happen here to simplify getting the two flags ++ * right. ++ */ ++ if (chunk_name == png_IDAT) ++ { ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "Missing IHDR before IDAT"); ++ ++ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && ++ (png_ptr->mode & PNG_HAVE_PLTE) == 0) ++ png_chunk_error(png_ptr, "Missing PLTE before IDAT"); ++ ++ else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) ++ png_chunk_benign_error(png_ptr, "Too many IDATs found"); ++ ++ png_ptr->mode |= PNG_HAVE_IDAT; ++ } ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) ++ png_ptr->mode |= PNG_AFTER_IDAT; + + /* This should be a binary subdivision search or a hash for + * matching the chunk name rather than a linear search. + */ +- if (!png_memcmp(chunk_name, png_IDAT, 4)) +- if (png_ptr->mode & PNG_AFTER_IDAT) +- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; +- +- if (!png_memcmp(chunk_name, png_IHDR, 4)) ++ if (chunk_name == png_IHDR) + png_handle_IHDR(png_ptr, info_ptr, length); + +- else if (!png_memcmp(chunk_name, png_IEND, 4)) ++ else if (chunk_name == png_IEND) + png_handle_IEND(png_ptr, info_ptr, length); + + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +- else if (png_handle_as_unknown(png_ptr, chunk_name)) ++ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { +- if (!png_memcmp(chunk_name, png_IDAT, 4)) +- png_ptr->mode |= PNG_HAVE_IDAT; +- +- png_handle_unknown(png_ptr, info_ptr, length); +- +- if (!png_memcmp(chunk_name, png_PLTE, 4)) ++ png_handle_unknown(png_ptr, info_ptr, length, keep); ++ ++ if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + +- else if (!png_memcmp(chunk_name, png_IDAT, 4)) ++ else if (chunk_name == png_IDAT) + { +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before IDAT"); +- +- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && +- !(png_ptr->mode & PNG_HAVE_PLTE)) +- png_error(png_ptr, "Missing PLTE before IDAT"); +- ++ png_ptr->idat_size = 0; /* It has been consumed */ + break; + } + } + #endif +- else if (!png_memcmp(chunk_name, png_PLTE, 4)) ++ else if (chunk_name == png_PLTE) + png_handle_PLTE(png_ptr, info_ptr, length); + +- else if (!png_memcmp(chunk_name, png_IDAT, 4)) ++ else if (chunk_name == png_IDAT) + { +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before IDAT"); +- +- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && +- !(png_ptr->mode & PNG_HAVE_PLTE)) +- png_error(png_ptr, "Missing PLTE before IDAT"); +- + png_ptr->idat_size = length; +- png_ptr->mode |= PNG_HAVE_IDAT; + break; + } + + #ifdef PNG_READ_bKGD_SUPPORTED +- else if (!png_memcmp(chunk_name, png_bKGD, 4)) ++ else if (chunk_name == png_bKGD) + png_handle_bKGD(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_cHRM_SUPPORTED +- else if (!png_memcmp(chunk_name, png_cHRM, 4)) ++ else if (chunk_name == png_cHRM) + png_handle_cHRM(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_gAMA_SUPPORTED +- else if (!png_memcmp(chunk_name, png_gAMA, 4)) ++ else if (chunk_name == png_gAMA) + png_handle_gAMA(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_hIST_SUPPORTED +- else if (!png_memcmp(chunk_name, png_hIST, 4)) ++ else if (chunk_name == png_hIST) + png_handle_hIST(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_oFFs_SUPPORTED +- else if (!png_memcmp(chunk_name, png_oFFs, 4)) ++ else if (chunk_name == png_oFFs) + png_handle_oFFs(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_pCAL_SUPPORTED +- else if (!png_memcmp(chunk_name, png_pCAL, 4)) ++ else if (chunk_name == png_pCAL) + png_handle_pCAL(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sCAL_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sCAL, 4)) ++ else if (chunk_name == png_sCAL) + png_handle_sCAL(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_pHYs_SUPPORTED +- else if (!png_memcmp(chunk_name, png_pHYs, 4)) ++ else if (chunk_name == png_pHYs) + png_handle_pHYs(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sBIT_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sBIT, 4)) ++ else if (chunk_name == png_sBIT) + png_handle_sBIT(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sRGB_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sRGB, 4)) ++ else if (chunk_name == png_sRGB) + png_handle_sRGB(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_iCCP_SUPPORTED +- else if (!png_memcmp(chunk_name, png_iCCP, 4)) ++ else if (chunk_name == png_iCCP) + png_handle_iCCP(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sPLT_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sPLT, 4)) ++ else if (chunk_name == png_sPLT) + png_handle_sPLT(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_tEXt_SUPPORTED +- else if (!png_memcmp(chunk_name, png_tEXt, 4)) ++ else if (chunk_name == png_tEXt) + png_handle_tEXt(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_tIME_SUPPORTED +- else if (!png_memcmp(chunk_name, png_tIME, 4)) ++ else if (chunk_name == png_tIME) + png_handle_tIME(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_tRNS_SUPPORTED +- else if (!png_memcmp(chunk_name, png_tRNS, 4)) ++ else if (chunk_name == png_tRNS) + png_handle_tRNS(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_zTXt_SUPPORTED +- else if (!png_memcmp(chunk_name, png_zTXt, 4)) ++ else if (chunk_name == png_zTXt) + png_handle_zTXt(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_iTXt_SUPPORTED +- else if (!png_memcmp(chunk_name, png_iTXt, 4)) ++ else if (chunk_name == png_iTXt) + png_handle_iTXt(png_ptr, info_ptr, length); + #endif + + else +- png_handle_unknown(png_ptr, info_ptr, length); ++ png_handle_unknown(png_ptr, info_ptr, length, ++ PNG_HANDLE_CHUNK_AS_DEFAULT); + } + } +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ ++#endif /* SEQUENTIAL_READ */ + + /* Optional call to update the users info_ptr structure */ + void PNGAPI +-png_read_update_info(png_structp png_ptr, png_infop info_ptr) ++png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) + { + png_debug(1, "in png_read_update_info"); + +- if (png_ptr == NULL) +- return; +- +- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) +- png_read_start_row(png_ptr); +- +- else +- png_warning(png_ptr, +- "Ignoring extra png_read_update_info() call;" +- " row buffer not reallocated"); +- +-#ifdef PNG_READ_TRANSFORMS_SUPPORTED +- png_read_transform_info(png_ptr, info_ptr); +-#else +- PNG_UNUSED(info_ptr) +-#endif ++ if (png_ptr != NULL) ++ { ++ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) ++ { ++ png_read_start_row(png_ptr); ++ ++# ifdef PNG_READ_TRANSFORMS_SUPPORTED ++ png_read_transform_info(png_ptr, info_ptr); ++# else ++ PNG_UNUSED(info_ptr) ++# endif ++ } ++ ++ /* New in 1.6.0 this avoids the bug of doing the initializations twice */ ++ else ++ png_app_error(png_ptr, ++ "png_read_update_info/png_start_read_image: duplicate call"); ++ } + } + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED +@@ -452,86 +315,166 @@ + * If the user doesn't call this, we will do it ourselves. + */ + void PNGAPI +-png_start_read_image(png_structp png_ptr) ++png_start_read_image(png_structrp png_ptr) + { + png_debug(1, "in png_start_read_image"); + ++ if (png_ptr != NULL) ++ { ++ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) ++ png_read_start_row(png_ptr); ++ ++ /* New in 1.6.0 this avoids the bug of doing the initializations twice */ ++ else ++ png_app_error(png_ptr, ++ "png_start_read_image/png_read_update_info: duplicate call"); ++ } ++} ++#endif /* SEQUENTIAL_READ */ ++ ++#ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++#ifdef PNG_MNG_FEATURES_SUPPORTED ++/* Undoes intrapixel differencing, ++ * NOTE: this is apparently only supported in the 'sequential' reader. ++ */ ++static void ++png_do_read_intrapixel(png_row_infop row_info, png_bytep row) ++{ ++ png_debug(1, "in png_do_read_intrapixel"); ++ ++ if ( ++ (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) ++ { ++ int bytes_per_pixel; ++ png_uint_32 row_width = row_info->width; ++ ++ if (row_info->bit_depth == 8) ++ { ++ png_bytep rp; ++ png_uint_32 i; ++ ++ if (row_info->color_type == PNG_COLOR_TYPE_RGB) ++ bytes_per_pixel = 3; ++ ++ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) ++ bytes_per_pixel = 4; ++ ++ else ++ return; ++ ++ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) ++ { ++ *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); ++ *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); ++ } ++ } ++ else if (row_info->bit_depth == 16) ++ { ++ png_bytep rp; ++ png_uint_32 i; ++ ++ if (row_info->color_type == PNG_COLOR_TYPE_RGB) ++ bytes_per_pixel = 6; ++ ++ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) ++ bytes_per_pixel = 8; ++ ++ else ++ return; ++ ++ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) ++ { ++ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); ++ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); ++ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); ++ png_uint_32 red = (s0 + s1 + 65536) & 0xffff; ++ png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; ++ *(rp ) = (png_byte)((red >> 8) & 0xff); ++ *(rp + 1) = (png_byte)(red & 0xff); ++ *(rp + 4) = (png_byte)((blue >> 8) & 0xff); ++ *(rp + 5) = (png_byte)(blue & 0xff); ++ } ++ } ++ } ++} ++#endif /* MNG_FEATURES */ ++ ++void PNGAPI ++png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) ++{ ++ png_row_info row_info; ++ + if (png_ptr == NULL) + return; + +- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) +- png_read_start_row(png_ptr); +- else +- png_warning(png_ptr, +- "Ignoring extra png_start_read_image() call;" +- " row buffer not reallocated"); +-} +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ +- +-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +-void PNGAPI +-png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) +-{ +- PNG_IDAT; +-#ifdef PNG_READ_INTERLACING_SUPPORTED +- PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, +- 0xff}; +- PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; +-#endif +- int ret; +- +- if (png_ptr == NULL) +- return; +- + png_debug2(1, "in png_read_row (row %lu, pass %d)", + (unsigned long)png_ptr->row_number, png_ptr->pass); + +- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) ++ /* png_read_start_row sets the information (in particular iwidth) for this ++ * interlace pass. ++ */ ++ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + png_read_start_row(png_ptr); + ++ /* 1.5.6: row_info moved out of png_struct to a local here. */ ++ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ ++ row_info.color_type = png_ptr->color_type; ++ row_info.bit_depth = png_ptr->bit_depth; ++ row_info.channels = png_ptr->channels; ++ row_info.pixel_depth = png_ptr->pixel_depth; ++ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); ++ ++#ifdef PNG_WARNINGS_SUPPORTED + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* Check for transforms that have been set but were defined out */ + #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) +- if (png_ptr->transformations & PNG_INVERT_MONO) ++ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); + #endif + + #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) +- if (png_ptr->transformations & PNG_FILLER) ++ if ((png_ptr->transformations & PNG_FILLER) != 0) + png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); + #endif + + #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ + !defined(PNG_READ_PACKSWAP_SUPPORTED) +- if (png_ptr->transformations & PNG_PACKSWAP) ++ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); + #endif + + #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) +- if (png_ptr->transformations & PNG_PACK) ++ if ((png_ptr->transformations & PNG_PACK) != 0) + png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); + #endif + + #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) +- if (png_ptr->transformations & PNG_SHIFT) ++ if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); + #endif + + #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) +- if (png_ptr->transformations & PNG_BGR) ++ if ((png_ptr->transformations & PNG_BGR) != 0) + png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); + #endif + + #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) +- if (png_ptr->transformations & PNG_SWAP_BYTES) ++ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); + #endif + } ++#endif /* WARNINGS */ + + #ifdef PNG_READ_INTERLACING_SUPPORTED +- /* If interlaced and we do not need a new row, combine row and return */ +- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) ++ /* If interlaced and we do not need a new row, combine row and return. ++ * Notice that the pixels we have from previous rows have been transformed ++ * already; we can only combine like with like (transformed or ++ * untransformed) and, because of the libpng API for interlaced images, this ++ * means we must transform before de-interlacing. ++ */ ++ if (png_ptr->interlaced != 0 && ++ (png_ptr->transformations & PNG_INTERLACE) != 0) + { + switch (png_ptr->pass) + { +@@ -539,8 +482,7 @@ + if (png_ptr->row_number & 0x07) + { + if (dsp_row != NULL) +- png_combine_row(png_ptr, dsp_row, +- png_pass_dsp_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, dsp_row, 1/*display*/); + png_read_finish_row(png_ptr); + return; + } +@@ -550,8 +492,7 @@ + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + if (dsp_row != NULL) +- png_combine_row(png_ptr, dsp_row, +- png_pass_dsp_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; +@@ -562,8 +503,7 @@ + if ((png_ptr->row_number & 0x07) != 4) + { + if (dsp_row != NULL && (png_ptr->row_number & 4)) +- png_combine_row(png_ptr, dsp_row, +- png_pass_dsp_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; +@@ -574,8 +514,7 @@ + if ((png_ptr->row_number & 3) || png_ptr->width < 3) + { + if (dsp_row != NULL) +- png_combine_row(png_ptr, dsp_row, +- png_pass_dsp_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; +@@ -586,19 +525,18 @@ + if ((png_ptr->row_number & 3) != 2) + { + if (dsp_row != NULL && (png_ptr->row_number & 2)) +- png_combine_row(png_ptr, dsp_row, +- png_pass_dsp_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; ++ + case 5: + if ((png_ptr->row_number & 1) || png_ptr->width < 2) + { + if (dsp_row != NULL) +- png_combine_row(png_ptr, dsp_row, +- png_pass_dsp_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; +@@ -607,7 +545,7 @@ + + default: + case 6: +- if (!(png_ptr->row_number & 1)) ++ if ((png_ptr->row_number & 1) == 0) + { + png_read_finish_row(png_ptr); + return; +@@ -617,117 +555,85 @@ + } + #endif + +- if (!(png_ptr->mode & PNG_HAVE_IDAT)) ++ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) + png_error(png_ptr, "Invalid attempt to read row data"); + +- png_ptr->zstream.next_out = png_ptr->row_buf; +- png_ptr->zstream.avail_out = +- (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, +- png_ptr->iwidth) + 1); +- +- do ++ /* Fill the row with IDAT data: */ ++ png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); ++ ++ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { +- if (!(png_ptr->zstream.avail_in)) +- { +- while (!png_ptr->idat_size) +- { +- png_crc_finish(png_ptr, 0); +- +- png_ptr->idat_size = png_read_chunk_header(png_ptr); +- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) +- png_error(png_ptr, "Not enough image data"); +- } +- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; +- png_ptr->zstream.next_in = png_ptr->zbuf; +- if (png_ptr->zbuf_size > png_ptr->idat_size) +- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; +- png_crc_read(png_ptr, png_ptr->zbuf, +- (png_size_t)png_ptr->zstream.avail_in); +- png_ptr->idat_size -= png_ptr->zstream.avail_in; +- } +- +- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); +- +- if (ret == Z_STREAM_END) +- { +- if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || +- png_ptr->idat_size) +- png_benign_error(png_ptr, "Extra compressed data"); +- png_ptr->mode |= PNG_AFTER_IDAT; +- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; +- break; +- } +- +- if (ret != Z_OK) +- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : +- "Decompression error"); +- +- } while (png_ptr->zstream.avail_out); +- +- png_ptr->row_info.color_type = png_ptr->color_type; +- png_ptr->row_info.width = png_ptr->iwidth; +- png_ptr->row_info.channels = png_ptr->channels; +- png_ptr->row_info.bit_depth = png_ptr->bit_depth; +- png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; +- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, +- png_ptr->row_info.width); +- +- if (png_ptr->row_buf[0]) +- png_read_filter_row(png_ptr, &(png_ptr->row_info), +- png_ptr->row_buf + 1, png_ptr->prev_row + 1, +- (int)(png_ptr->row_buf[0])); +- +- png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); ++ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) ++ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, ++ png_ptr->prev_row + 1, png_ptr->row_buf[0]); ++ else ++ png_error(png_ptr, "bad adaptive filter value"); ++ } ++ ++ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before ++ * 1.5.6, while the buffer really is this big in current versions of libpng ++ * it may not be in the future, so this was changed just to copy the ++ * interlaced count: ++ */ ++ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + + #ifdef PNG_MNG_FEATURES_SUPPORTED +- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && ++ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ +- png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); ++ png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); + } + #endif + +- + #ifdef PNG_READ_TRANSFORMS_SUPPORTED + if (png_ptr->transformations) +- png_do_read_transformations(png_ptr); ++ png_do_read_transformations(png_ptr, &row_info); + #endif + ++ /* The transformed pixel depth should match the depth now in row_info. */ ++ if (png_ptr->transformed_pixel_depth == 0) ++ { ++ png_ptr->transformed_pixel_depth = row_info.pixel_depth; ++ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) ++ png_error(png_ptr, "sequential row overflow"); ++ } ++ ++ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) ++ png_error(png_ptr, "internal sequential row size calculation error"); ++ + #ifdef PNG_READ_INTERLACING_SUPPORTED +- /* Blow up interlaced rows to full size */ +- if (png_ptr->interlaced && +- (png_ptr->transformations & PNG_INTERLACE)) ++ /* Expand interlaced rows to full size */ ++ if (png_ptr->interlaced != 0 && ++ (png_ptr->transformations & PNG_INTERLACE) != 0) + { + if (png_ptr->pass < 6) +- /* Old interface (pre-1.0.9): +- * png_do_read_interlace(&(png_ptr->row_info), +- * png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); +- */ +- png_do_read_interlace(png_ptr); ++ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, ++ png_ptr->transformations); + + if (dsp_row != NULL) +- png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, dsp_row, 1/*display*/); + + if (row != NULL) +- png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]); ++ png_combine_row(png_ptr, row, 0/*row*/); + } + + else + #endif + { + if (row != NULL) +- png_combine_row(png_ptr, row, 0xff); ++ png_combine_row(png_ptr, row, -1/*ignored*/); + + if (dsp_row != NULL) +- png_combine_row(png_ptr, dsp_row, 0xff); ++ png_combine_row(png_ptr, dsp_row, -1/*ignored*/); + } + png_read_finish_row(png_ptr); + + if (png_ptr->read_row_fn != NULL) + (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); ++ + } +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ ++#endif /* SEQUENTIAL_READ */ + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read one or more rows of image data. If the image is interlaced, +@@ -755,7 +661,7 @@ + */ + + void PNGAPI +-png_read_rows(png_structp png_ptr, png_bytepp row, ++png_read_rows(png_structrp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows) + { + png_uint_32 i; +@@ -794,7 +700,7 @@ + dp++; + } + } +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ ++#endif /* SEQUENTIAL_READ */ + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read the entire image. If the image has an alpha channel or a tRNS +@@ -810,7 +716,7 @@ + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ + void PNGAPI +-png_read_image(png_structp png_ptr, png_bytepp image) ++png_read_image(png_structrp png_ptr, png_bytepp image) + { + png_uint_32 i, image_height; + int pass, j; +@@ -822,7 +728,7 @@ + return; + + #ifdef PNG_READ_INTERLACING_SUPPORTED +- if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) ++ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + { + pass = png_set_interlace_handling(png_ptr); + /* And make sure transforms are initialized. */ +@@ -830,7 +736,8 @@ + } + else + { +- if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) ++ if (png_ptr->interlaced != 0 && ++ (png_ptr->transformations & PNG_INTERLACE) == 0) + { + /* Caller called png_start_read_image or png_read_update_info without + * first turning on the PNG_INTERLACE transform. We can fix this here, +@@ -867,7 +774,7 @@ + } + } + } +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ ++#endif /* SEQUENTIAL_READ */ + + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + /* Read the end of the PNG file. Will not read past the end of the +@@ -875,416 +782,261 @@ + * or time information at the end of the file, if info is not NULL. + */ + void PNGAPI +-png_read_end(png_structp png_ptr, png_infop info_ptr) ++png_read_end(png_structrp png_ptr, png_inforp info_ptr) + { ++#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED ++ int keep; ++#endif ++ + png_debug(1, "in png_read_end"); + + if (png_ptr == NULL) + return; + +- png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ ++ /* If png_read_end is called in the middle of reading the rows there may ++ * still be pending IDAT data and an owned zstream. Deal with this here. ++ */ ++#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED ++ if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) ++#endif ++ png_read_finish_IDAT(png_ptr); ++ ++#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED ++ /* Report invalid palette index; added at libng-1.5.10 */ ++ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && ++ png_ptr->num_palette_max > png_ptr->num_palette) ++ png_benign_error(png_ptr, "Read palette index exceeding num_palette"); ++#endif + + do + { +- PNG_IHDR; +- PNG_IDAT; +- PNG_IEND; +- PNG_PLTE; +-#ifdef PNG_READ_bKGD_SUPPORTED +- PNG_bKGD; +-#endif +-#ifdef PNG_READ_cHRM_SUPPORTED +- PNG_cHRM; +-#endif +-#ifdef PNG_READ_gAMA_SUPPORTED +- PNG_gAMA; +-#endif +-#ifdef PNG_READ_hIST_SUPPORTED +- PNG_hIST; +-#endif +-#ifdef PNG_READ_iCCP_SUPPORTED +- PNG_iCCP; +-#endif +-#ifdef PNG_READ_iTXt_SUPPORTED +- PNG_iTXt; +-#endif +-#ifdef PNG_READ_oFFs_SUPPORTED +- PNG_oFFs; +-#endif +-#ifdef PNG_READ_pCAL_SUPPORTED +- PNG_pCAL; +-#endif +-#ifdef PNG_READ_pHYs_SUPPORTED +- PNG_pHYs; +-#endif +-#ifdef PNG_READ_sBIT_SUPPORTED +- PNG_sBIT; +-#endif +-#ifdef PNG_READ_sCAL_SUPPORTED +- PNG_sCAL; +-#endif +-#ifdef PNG_READ_sPLT_SUPPORTED +- PNG_sPLT; +-#endif +-#ifdef PNG_READ_sRGB_SUPPORTED +- PNG_sRGB; +-#endif +-#ifdef PNG_READ_tEXt_SUPPORTED +- PNG_tEXt; +-#endif +-#ifdef PNG_READ_tIME_SUPPORTED +- PNG_tIME; +-#endif +-#ifdef PNG_READ_tRNS_SUPPORTED +- PNG_tRNS; +-#endif +-#ifdef PNG_READ_zTXt_SUPPORTED +- PNG_zTXt; +-#endif + png_uint_32 length = png_read_chunk_header(png_ptr); +- PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; +- +- if (!png_memcmp(chunk_name, png_IHDR, 4)) ++ png_uint_32 chunk_name = png_ptr->chunk_name; ++ ++ if (chunk_name == png_IEND) ++ png_handle_IEND(png_ptr, info_ptr, length); ++ ++ else if (chunk_name == png_IHDR) + png_handle_IHDR(png_ptr, info_ptr, length); + +- else if (!png_memcmp(chunk_name, png_IEND, 4)) +- png_handle_IEND(png_ptr, info_ptr, length); ++ else if (info_ptr == NULL) ++ png_crc_finish(png_ptr, length); + + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +- else if (png_handle_as_unknown(png_ptr, chunk_name)) ++ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { +- if (!png_memcmp(chunk_name, png_IDAT, 4)) ++ if (chunk_name == png_IDAT) + { +- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) ++ if ((length > 0) || ++ (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) + png_benign_error(png_ptr, "Too many IDATs found"); + } +- png_handle_unknown(png_ptr, info_ptr, length); +- if (!png_memcmp(chunk_name, png_PLTE, 4)) ++ png_handle_unknown(png_ptr, info_ptr, length, keep); ++ if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + } + #endif + +- else if (!png_memcmp(chunk_name, png_IDAT, 4)) ++ else if (chunk_name == png_IDAT) + { + /* Zero length IDATs are legal after the last IDAT has been + * read, but not after other chunks have been read. + */ +- if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) ++ if ((length > 0) || ++ (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) + png_benign_error(png_ptr, "Too many IDATs found"); + + png_crc_finish(png_ptr, length); + } +- else if (!png_memcmp(chunk_name, png_PLTE, 4)) ++ else if (chunk_name == png_PLTE) + png_handle_PLTE(png_ptr, info_ptr, length); + + #ifdef PNG_READ_bKGD_SUPPORTED +- else if (!png_memcmp(chunk_name, png_bKGD, 4)) ++ else if (chunk_name == png_bKGD) + png_handle_bKGD(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_cHRM_SUPPORTED +- else if (!png_memcmp(chunk_name, png_cHRM, 4)) ++ else if (chunk_name == png_cHRM) + png_handle_cHRM(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_gAMA_SUPPORTED +- else if (!png_memcmp(chunk_name, png_gAMA, 4)) ++ else if (chunk_name == png_gAMA) + png_handle_gAMA(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_hIST_SUPPORTED +- else if (!png_memcmp(chunk_name, png_hIST, 4)) ++ else if (chunk_name == png_hIST) + png_handle_hIST(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_oFFs_SUPPORTED +- else if (!png_memcmp(chunk_name, png_oFFs, 4)) ++ else if (chunk_name == png_oFFs) + png_handle_oFFs(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_pCAL_SUPPORTED +- else if (!png_memcmp(chunk_name, png_pCAL, 4)) ++ else if (chunk_name == png_pCAL) + png_handle_pCAL(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sCAL_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sCAL, 4)) ++ else if (chunk_name == png_sCAL) + png_handle_sCAL(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_pHYs_SUPPORTED +- else if (!png_memcmp(chunk_name, png_pHYs, 4)) ++ else if (chunk_name == png_pHYs) + png_handle_pHYs(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sBIT_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sBIT, 4)) ++ else if (chunk_name == png_sBIT) + png_handle_sBIT(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sRGB_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sRGB, 4)) ++ else if (chunk_name == png_sRGB) + png_handle_sRGB(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_iCCP_SUPPORTED +- else if (!png_memcmp(chunk_name, png_iCCP, 4)) ++ else if (chunk_name == png_iCCP) + png_handle_iCCP(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_sPLT_SUPPORTED +- else if (!png_memcmp(chunk_name, png_sPLT, 4)) ++ else if (chunk_name == png_sPLT) + png_handle_sPLT(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_tEXt_SUPPORTED +- else if (!png_memcmp(chunk_name, png_tEXt, 4)) ++ else if (chunk_name == png_tEXt) + png_handle_tEXt(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_tIME_SUPPORTED +- else if (!png_memcmp(chunk_name, png_tIME, 4)) ++ else if (chunk_name == png_tIME) + png_handle_tIME(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_tRNS_SUPPORTED +- else if (!png_memcmp(chunk_name, png_tRNS, 4)) ++ else if (chunk_name == png_tRNS) + png_handle_tRNS(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_zTXt_SUPPORTED +- else if (!png_memcmp(chunk_name, png_zTXt, 4)) ++ else if (chunk_name == png_zTXt) + png_handle_zTXt(png_ptr, info_ptr, length); + #endif + + #ifdef PNG_READ_iTXt_SUPPORTED +- else if (!png_memcmp(chunk_name, png_iTXt, 4)) ++ else if (chunk_name == png_iTXt) + png_handle_iTXt(png_ptr, info_ptr, length); + #endif + + else +- png_handle_unknown(png_ptr, info_ptr, length); +- } while (!(png_ptr->mode & PNG_HAVE_IEND)); ++ png_handle_unknown(png_ptr, info_ptr, length, ++ PNG_HANDLE_CHUNK_AS_DEFAULT); ++ } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); + } +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ ++#endif /* SEQUENTIAL_READ */ ++ ++/* Free all memory used in the read struct */ ++static void ++png_read_destroy(png_structrp png_ptr) ++{ ++ png_debug(1, "in png_read_destroy"); ++ ++#ifdef PNG_READ_GAMMA_SUPPORTED ++ png_destroy_gamma_table(png_ptr); ++#endif ++ ++ png_free(png_ptr, png_ptr->big_row_buf); ++ png_ptr->big_row_buf = NULL; ++ png_free(png_ptr, png_ptr->big_prev_row); ++ png_ptr->big_prev_row = NULL; ++ png_free(png_ptr, png_ptr->read_buffer); ++ png_ptr->read_buffer = NULL; ++ ++#ifdef PNG_READ_QUANTIZE_SUPPORTED ++ png_free(png_ptr, png_ptr->palette_lookup); ++ png_ptr->palette_lookup = NULL; ++ png_free(png_ptr, png_ptr->quantize_index); ++ png_ptr->quantize_index = NULL; ++#endif ++ ++ if ((png_ptr->free_me & PNG_FREE_PLTE) != 0) ++ { ++ png_zfree(png_ptr, png_ptr->palette); ++ png_ptr->palette = NULL; ++ } ++ png_ptr->free_me &= ~PNG_FREE_PLTE; ++ ++#if defined(PNG_tRNS_SUPPORTED) || \ ++ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ++ if ((png_ptr->free_me & PNG_FREE_TRNS) != 0) ++ { ++ png_free(png_ptr, png_ptr->trans_alpha); ++ png_ptr->trans_alpha = NULL; ++ } ++ png_ptr->free_me &= ~PNG_FREE_TRNS; ++#endif ++ ++ inflateEnd(&png_ptr->zstream); ++ ++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED ++ png_free(png_ptr, png_ptr->save_buffer); ++ png_ptr->save_buffer = NULL; ++#endif ++ ++#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \ ++ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ++ png_free(png_ptr, png_ptr->unknown_chunk.data); ++ png_ptr->unknown_chunk.data = NULL; ++#endif ++ ++#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++ png_free(png_ptr, png_ptr->chunk_list); ++ png_ptr->chunk_list = NULL; ++#endif ++ ++ /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error ++ * callbacks are still set at this point. They are required to complete the ++ * destruction of the png_struct itself. ++ */ ++} + + /* Free all memory used by the read */ + void PNGAPI + png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, + png_infopp end_info_ptr_ptr) + { +- png_structp png_ptr = NULL; +- png_infop info_ptr = NULL, end_info_ptr = NULL; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_free_ptr free_fn = NULL; +- png_voidp mem_ptr = NULL; +-#endif ++ png_structrp png_ptr = NULL; + + png_debug(1, "in png_destroy_read_struct"); + + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; ++ + if (png_ptr == NULL) + return; + +-#ifdef PNG_USER_MEM_SUPPORTED +- free_fn = png_ptr->free_fn; +- mem_ptr = png_ptr->mem_ptr; +-#endif +- +- if (info_ptr_ptr != NULL) +- info_ptr = *info_ptr_ptr; +- +- if (end_info_ptr_ptr != NULL) +- end_info_ptr = *end_info_ptr_ptr; +- +- png_read_destroy(png_ptr, info_ptr, end_info_ptr); +- +- if (info_ptr != NULL) +- { +-#ifdef PNG_TEXT_SUPPORTED +- png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); +-#endif +- +-#ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, +- (png_voidp)mem_ptr); +-#else +- png_destroy_struct((png_voidp)info_ptr); +-#endif +- *info_ptr_ptr = NULL; +- } +- +- if (end_info_ptr != NULL) +- { +-#ifdef PNG_READ_TEXT_SUPPORTED +- png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); +-#endif +-#ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, +- (png_voidp)mem_ptr); +-#else +- png_destroy_struct((png_voidp)end_info_ptr); +-#endif +- *end_info_ptr_ptr = NULL; +- } +- +- if (png_ptr != NULL) +- { +-#ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, +- (png_voidp)mem_ptr); +-#else +- png_destroy_struct((png_voidp)png_ptr); +-#endif +- *png_ptr_ptr = NULL; +- } ++ /* libpng 1.6.0: use the API to destroy info structs to ensure consistent ++ * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. ++ * The extra was, apparently, unnecessary yet this hides memory leak bugs. ++ */ ++ png_destroy_info_struct(png_ptr, end_info_ptr_ptr); ++ png_destroy_info_struct(png_ptr, info_ptr_ptr); ++ ++ *png_ptr_ptr = NULL; ++ png_read_destroy(png_ptr); ++ png_destroy_png_struct(png_ptr); + } + +-/* Free all memory used by the read (old method) */ +-void /* PRIVATE */ +-png_read_destroy(png_structp png_ptr, png_infop info_ptr, +- png_infop end_info_ptr) +-{ +-#ifdef PNG_SETJMP_SUPPORTED +- jmp_buf tmp_jmp; +-#endif +- png_error_ptr error_fn; +-#ifdef PNG_WARNINGS_SUPPORTED +- png_error_ptr warning_fn; +-#endif +- png_voidp error_ptr; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_free_ptr free_fn; +-#endif +- +- png_debug(1, "in png_read_destroy"); +- +- if (info_ptr != NULL) +- png_info_destroy(png_ptr, info_ptr); +- +- if (end_info_ptr != NULL) +- png_info_destroy(png_ptr, end_info_ptr); +- +- png_free(png_ptr, png_ptr->zbuf); +- png_free(png_ptr, png_ptr->big_row_buf); +- png_free(png_ptr, png_ptr->prev_row); +- png_free(png_ptr, png_ptr->chunkdata); +- +-#ifdef PNG_READ_QUANTIZE_SUPPORTED +- png_free(png_ptr, png_ptr->palette_lookup); +- png_free(png_ptr, png_ptr->quantize_index); +-#endif +- +-#ifdef PNG_READ_GAMMA_SUPPORTED +- png_free(png_ptr, png_ptr->gamma_table); +-#endif +- +-#ifdef PNG_READ_BACKGROUND_SUPPORTED +- png_free(png_ptr, png_ptr->gamma_from_1); +- png_free(png_ptr, png_ptr->gamma_to_1); +-#endif +- +- if (png_ptr->free_me & PNG_FREE_PLTE) +- png_zfree(png_ptr, png_ptr->palette); +- png_ptr->free_me &= ~PNG_FREE_PLTE; +- +-#if defined(PNG_tRNS_SUPPORTED) || \ +- defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +- if (png_ptr->free_me & PNG_FREE_TRNS) +- png_free(png_ptr, png_ptr->trans_alpha); +- png_ptr->free_me &= ~PNG_FREE_TRNS; +-#endif +- +-#ifdef PNG_READ_hIST_SUPPORTED +- if (png_ptr->free_me & PNG_FREE_HIST) +- png_free(png_ptr, png_ptr->hist); +- png_ptr->free_me &= ~PNG_FREE_HIST; +-#endif +- +-#ifdef PNG_READ_GAMMA_SUPPORTED +- if (png_ptr->gamma_16_table != NULL) +- { +- int i; +- int istop = (1 << (8 - png_ptr->gamma_shift)); +- for (i = 0; i < istop; i++) +- { +- png_free(png_ptr, png_ptr->gamma_16_table[i]); +- } +- png_free(png_ptr, png_ptr->gamma_16_table); +- } +- +-#ifdef PNG_READ_BACKGROUND_SUPPORTED +- if (png_ptr->gamma_16_from_1 != NULL) +- { +- int i; +- int istop = (1 << (8 - png_ptr->gamma_shift)); +- for (i = 0; i < istop; i++) +- { +- png_free(png_ptr, png_ptr->gamma_16_from_1[i]); +- } +- png_free(png_ptr, png_ptr->gamma_16_from_1); +- } +- if (png_ptr->gamma_16_to_1 != NULL) +- { +- int i; +- int istop = (1 << (8 - png_ptr->gamma_shift)); +- for (i = 0; i < istop; i++) +- { +- png_free(png_ptr, png_ptr->gamma_16_to_1[i]); +- } +- png_free(png_ptr, png_ptr->gamma_16_to_1); +- } +-#endif +-#endif +- +- inflateEnd(&png_ptr->zstream); +- +-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +- png_free(png_ptr, png_ptr->save_buffer); +-#endif +- +-#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +-#ifdef PNG_TEXT_SUPPORTED +- png_free(png_ptr, png_ptr->current_text); +-#endif /* PNG_TEXT_SUPPORTED */ +-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ +- +- /* Save the important info out of the png_struct, in case it is +- * being used again. +- */ +-#ifdef PNG_SETJMP_SUPPORTED +- png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); +-#endif +- +- error_fn = png_ptr->error_fn; +-#ifdef PNG_WARNINGS_SUPPORTED +- warning_fn = png_ptr->warning_fn; +-#endif +- error_ptr = png_ptr->error_ptr; +-#ifdef PNG_USER_MEM_SUPPORTED +- free_fn = png_ptr->free_fn; +-#endif +- +- png_memset(png_ptr, 0, png_sizeof(png_struct)); +- +- png_ptr->error_fn = error_fn; +-#ifdef PNG_WARNINGS_SUPPORTED +- png_ptr->warning_fn = warning_fn; +-#endif +- png_ptr->error_ptr = error_ptr; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_ptr->free_fn = free_fn; +-#endif +- +-#ifdef PNG_SETJMP_SUPPORTED +- png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); +-#endif +- +-} +- + void PNGAPI +-png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) ++png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) + { + if (png_ptr == NULL) + return; +@@ -1296,12 +1048,10 @@ + #ifdef PNG_SEQUENTIAL_READ_SUPPORTED + #ifdef PNG_INFO_IMAGE_SUPPORTED + void PNGAPI +-png_read_png(png_structp png_ptr, png_infop info_ptr, ++png_read_png(png_structrp png_ptr, png_inforp info_ptr, + int transforms, + voidp params) + { +- int row; +- + if (png_ptr == NULL || info_ptr == NULL) + return; + +@@ -1309,130 +1059,153 @@ + * PNG file before the first IDAT (image data chunk). + */ + png_read_info(png_ptr, info_ptr); +- if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) ++ if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep))) + png_error(png_ptr, "Image is too high to process with png_read_png()"); + + /* -------------- image transformations start here ------------------- */ +- +-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED ++ /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM ++ * is not implemented. This will only happen in de-configured (non-default) ++ * libpng builds. The results can be unexpected - png_read_png may return ++ * short or mal-formed rows because the transform is skipped. ++ */ ++ + /* Tell libpng to strip 16-bit/color files down to 8 bits per color. + */ +- if (transforms & PNG_TRANSFORM_SCALE_16) +- { ++ if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) + /* Added at libpng-1.5.4. "strip_16" produces the same result that it + * did in earlier versions, while "scale_16" is now more accurate. + */ ++#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_set_scale_16(png_ptr); +- } ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); + #endif + +-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* If both SCALE and STRIP are required pngrtran will effectively cancel the + * latter by doing SCALE first. This is ok and allows apps not to check for + * which is supported to get the right answer. + */ +- if (transforms & PNG_TRANSFORM_STRIP_16) ++ if ((transforms & PNG_TRANSFORM_STRIP_16) != 0) ++#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + png_set_strip_16(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); + #endif + +-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + /* Strip alpha bytes from the input data without combining with + * the background (not recommended). + */ +- if (transforms & PNG_TRANSFORM_STRIP_ALPHA) ++ if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0) ++#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + png_set_strip_alpha(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); + #endif + +-#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) + /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ +- if (transforms & PNG_TRANSFORM_PACKING) ++ if ((transforms & PNG_TRANSFORM_PACKING) != 0) ++#ifdef PNG_READ_PACK_SUPPORTED + png_set_packing(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); + #endif + +-#ifdef PNG_READ_PACKSWAP_SUPPORTED + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). + */ +- if (transforms & PNG_TRANSFORM_PACKSWAP) ++ if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) ++#ifdef PNG_READ_PACKSWAP_SUPPORTED + png_set_packswap(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); + #endif + +-#ifdef PNG_READ_EXPAND_SUPPORTED + /* Expand paletted colors into true RGB triplets + * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel + * Expand paletted or RGB images with transparency to full alpha + * channels so the data will be available as RGBA quartets. + */ +- if (transforms & PNG_TRANSFORM_EXPAND) +- if ((png_ptr->bit_depth < 8) || +- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || +- (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) +- png_set_expand(png_ptr); ++ if ((transforms & PNG_TRANSFORM_EXPAND) != 0) ++#ifdef PNG_READ_EXPAND_SUPPORTED ++ png_set_expand(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); + #endif + + /* We don't handle background color or gamma transformation or quantizing. + */ + +-#ifdef PNG_READ_INVERT_SUPPORTED + /* Invert monochrome files to have 0 as white and 1 as black + */ +- if (transforms & PNG_TRANSFORM_INVERT_MONO) ++ if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) ++#ifdef PNG_READ_INVERT_SUPPORTED + png_set_invert_mono(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); + #endif + +-#ifdef PNG_READ_SHIFT_SUPPORTED + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ +- if ((transforms & PNG_TRANSFORM_SHIFT) +- && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) +- { +- png_color_8p sig_bit; +- +- png_get_sBIT(png_ptr, info_ptr, &sig_bit); +- png_set_shift(png_ptr, sig_bit); +- } ++ if ((transforms & PNG_TRANSFORM_SHIFT) != 0) ++#ifdef PNG_READ_SHIFT_SUPPORTED ++ if ((info_ptr->valid & PNG_INFO_sBIT) != 0) ++ png_set_shift(png_ptr, &info_ptr->sig_bit); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); + #endif + ++ /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ ++ if ((transforms & PNG_TRANSFORM_BGR) != 0) + #ifdef PNG_READ_BGR_SUPPORTED +- /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ +- if (transforms & PNG_TRANSFORM_BGR) + png_set_bgr(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); + #endif + ++ /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ ++ if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) + #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +- /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ +- if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); + #endif + ++ /* Swap bytes of 16-bit files to least significant byte first */ ++ if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) + #ifdef PNG_READ_SWAP_SUPPORTED +- /* Swap bytes of 16-bit files to least significant byte first */ +- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) + png_set_swap(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); + #endif + + /* Added at libpng-1.2.41 */ ++ /* Invert the alpha channel from opacity to transparency */ ++ if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) + #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +- /* Invert the alpha channel from opacity to transparency */ +- if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); + #endif + + /* Added at libpng-1.2.41 */ ++ /* Expand grayscale image to RGB */ ++ if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0) + #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +- /* Expand grayscale image to RGB */ +- if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) + png_set_gray_to_rgb(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); + #endif + + /* Added at libpng-1.5.4 */ ++ if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0) + #ifdef PNG_READ_EXPAND_16_SUPPORTED +- if (transforms & PNG_TRANSFORM_EXPAND_16) + png_set_expand_16(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); + #endif + + /* We don't handle adding filler bytes */ +@@ -1455,16 +1228,17 @@ + { + png_uint_32 iptr; + +- info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, +- info_ptr->height * png_sizeof(png_bytep)); ++ info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr, ++ info_ptr->height * (sizeof (png_bytep)))); ++ + for (iptr=0; iptr<info_ptr->height; iptr++) + info_ptr->row_pointers[iptr] = NULL; + + info_ptr->free_me |= PNG_FREE_ROWS; + +- for (row = 0; row < (int)info_ptr->height; row++) +- info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, +- png_get_rowbytes(png_ptr, info_ptr)); ++ for (iptr = 0; iptr < info_ptr->height; iptr++) ++ info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, ++ png_malloc(png_ptr, info_ptr->rowbytes)); + } + + png_read_image(png_ptr, info_ptr->row_pointers); +@@ -1473,10 +1247,2903 @@ + /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); + +- PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) +- + } +-#endif /* PNG_INFO_IMAGE_SUPPORTED */ +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ +-#endif /* PNG_READ_SUPPORTED */ ++#endif /* INFO_IMAGE */ ++#endif /* SEQUENTIAL_READ */ ++ ++#ifdef PNG_SIMPLIFIED_READ_SUPPORTED ++/* SIMPLIFIED READ ++ * ++ * This code currently relies on the sequential reader, though it could easily ++ * be made to work with the progressive one. ++ */ ++/* Arguments to png_image_finish_read: */ ++ ++/* Encoding of PNG data (used by the color-map code) */ ++# define P_NOTSET 0 /* File encoding not yet known */ ++# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ ++# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ ++# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ ++# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ ++ ++/* Color-map processing: after libpng has run on the PNG image further ++ * processing may be needed to convert the data to color-map indices. ++ */ ++#define PNG_CMAP_NONE 0 ++#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ ++#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ ++#define PNG_CMAP_RGB 3 /* Process RGB data */ ++#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ ++ ++/* The following document where the background is for each processing case. */ ++#define PNG_CMAP_NONE_BACKGROUND 256 ++#define PNG_CMAP_GA_BACKGROUND 231 ++#define PNG_CMAP_TRANS_BACKGROUND 254 ++#define PNG_CMAP_RGB_BACKGROUND 256 ++#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 ++ ++typedef struct ++{ ++ /* Arguments: */ ++ png_imagep image; ++ png_voidp buffer; ++ png_int_32 row_stride; ++ png_voidp colormap; ++ png_const_colorp background; ++ /* Local variables: */ ++ png_voidp local_row; ++ png_voidp first_row; ++ ptrdiff_t row_bytes; /* step between rows */ ++ int file_encoding; /* E_ values above */ ++ png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */ ++ int colormap_processing; /* PNG_CMAP_ values above */ ++} png_image_read_control; ++ ++/* Do all the *safe* initialization - 'safe' means that png_error won't be ++ * called, so setting up the jmp_buf is not required. This means that anything ++ * called from here must *not* call png_malloc - it has to call png_malloc_warn ++ * instead so that control is returned safely back to this routine. ++ */ ++static int ++png_image_read_init(png_imagep image) ++{ ++ if (image->opaque == NULL) ++ { ++ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, ++ png_safe_error, png_safe_warning); ++ ++ /* And set the rest of the structure to NULL to ensure that the various ++ * fields are consistent. ++ */ ++ memset(image, 0, (sizeof *image)); ++ image->version = PNG_IMAGE_VERSION; ++ ++ if (png_ptr != NULL) ++ { ++ png_infop info_ptr = png_create_info_struct(png_ptr); ++ ++ if (info_ptr != NULL) ++ { ++ png_controlp control = png_voidcast(png_controlp, ++ png_malloc_warn(png_ptr, (sizeof *control))); ++ ++ if (control != NULL) ++ { ++ memset(control, 0, (sizeof *control)); ++ ++ control->png_ptr = png_ptr; ++ control->info_ptr = info_ptr; ++ control->for_write = 0; ++ ++ image->opaque = control; ++ return 1; ++ } ++ ++ /* Error clean up */ ++ png_destroy_info_struct(png_ptr, &info_ptr); ++ } ++ ++ png_destroy_read_struct(&png_ptr, NULL, NULL); ++ } ++ ++ return png_image_error(image, "png_image_read: out of memory"); ++ } ++ ++ return png_image_error(image, "png_image_read: opaque pointer not NULL"); ++} ++ ++/* Utility to find the base format of a PNG file from a png_struct. */ ++static png_uint_32 ++png_image_format(png_structrp png_ptr) ++{ ++ png_uint_32 format = 0; ++ ++ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) ++ format |= PNG_FORMAT_FLAG_COLOR; ++ ++ if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) ++ format |= PNG_FORMAT_FLAG_ALPHA; ++ ++ /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS ++ * sets the png_struct fields; that's all we are interested in here. The ++ * precise interaction with an app call to png_set_tRNS and PNG file reading ++ * is unclear. ++ */ ++ else if (png_ptr->num_trans > 0) ++ format |= PNG_FORMAT_FLAG_ALPHA; ++ ++ if (png_ptr->bit_depth == 16) ++ format |= PNG_FORMAT_FLAG_LINEAR; ++ ++ if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0) ++ format |= PNG_FORMAT_FLAG_COLORMAP; ++ ++ return format; ++} ++ ++/* Is the given gamma significantly different from sRGB? The test is the same ++ * one used in pngrtran.c when deciding whether to do gamma correction. The ++ * arithmetic optimizes the division by using the fact that the inverse of the ++ * file sRGB gamma is 2.2 ++ */ ++static int ++png_gamma_not_sRGB(png_fixed_point g) ++{ ++ if (g < PNG_FP_1) ++ { ++ /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ ++ if (g == 0) ++ return 0; ++ ++ return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); ++ } ++ ++ return 1; ++} ++ ++/* Do the main body of a 'png_image_begin_read' function; read the PNG file ++ * header and fill in all the information. This is executed in a safe context, ++ * unlike the init routine above. ++ */ ++static int ++png_image_read_header(png_voidp argument) ++{ ++ png_imagep image = png_voidcast(png_imagep, argument); ++ png_structrp png_ptr = image->opaque->png_ptr; ++ png_inforp info_ptr = image->opaque->info_ptr; ++ ++ png_set_benign_errors(png_ptr, 1/*warn*/); ++ png_read_info(png_ptr, info_ptr); ++ ++ /* Do this the fast way; just read directly out of png_struct. */ ++ image->width = png_ptr->width; ++ image->height = png_ptr->height; ++ ++ { ++ png_uint_32 format = png_image_format(png_ptr); ++ ++ image->format = format; ++ ++#ifdef PNG_COLORSPACE_SUPPORTED ++ /* Does the colorspace match sRGB? If there is no color endpoint ++ * (colorant) information assume yes, otherwise require the ++ * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the ++ * colorspace has been determined to be invalid ignore it. ++ */ ++ if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags ++ & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| ++ PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) ++ image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; ++#endif ++ } ++ ++ /* We need the maximum number of entries regardless of the format the ++ * application sets here. ++ */ ++ { ++ png_uint_32 cmap_entries; ++ ++ switch (png_ptr->color_type) ++ { ++ case PNG_COLOR_TYPE_GRAY: ++ cmap_entries = 1U << png_ptr->bit_depth; ++ break; ++ ++ case PNG_COLOR_TYPE_PALETTE: ++ cmap_entries = png_ptr->num_palette; ++ break; ++ ++ default: ++ cmap_entries = 256; ++ break; ++ } ++ ++ if (cmap_entries > 256) ++ cmap_entries = 256; ++ ++ image->colormap_entries = cmap_entries; ++ } ++ ++ return 1; ++} ++ ++#ifdef PNG_STDIO_SUPPORTED ++int PNGAPI ++png_image_begin_read_from_stdio(png_imagep image, FILE* file) ++{ ++ if (image != NULL && image->version == PNG_IMAGE_VERSION) ++ { ++ if (file != NULL) ++ { ++ if (png_image_read_init(image) != 0) ++ { ++ /* This is slightly evil, but png_init_io doesn't do anything other ++ * than this and we haven't changed the standard IO functions so ++ * this saves a 'safe' function. ++ */ ++ image->opaque->png_ptr->io_ptr = file; ++ return png_safe_execute(image, png_image_read_header, image); ++ } ++ } ++ ++ else ++ return png_image_error(image, ++ "png_image_begin_read_from_stdio: invalid argument"); ++ } ++ ++ else if (image != NULL) ++ return png_image_error(image, ++ "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); ++ ++ return 0; ++} ++ ++int PNGAPI ++png_image_begin_read_from_file(png_imagep image, const char *file_name) ++{ ++ if (image != NULL && image->version == PNG_IMAGE_VERSION) ++ { ++ if (file_name != NULL) ++ { ++ FILE *fp = fopen(file_name, "rb"); ++ ++ if (fp != NULL) ++ { ++ if (png_image_read_init(image) != 0) ++ { ++ image->opaque->png_ptr->io_ptr = fp; ++ image->opaque->owned_file = 1; ++ return png_safe_execute(image, png_image_read_header, image); ++ } ++ ++ /* Clean up: just the opened file. */ ++ (void)fclose(fp); ++ } ++ ++ else ++ return png_image_error(image, strerror(errno)); ++ } ++ ++ else ++ return png_image_error(image, ++ "png_image_begin_read_from_file: invalid argument"); ++ } ++ ++ else if (image != NULL) ++ return png_image_error(image, ++ "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); ++ ++ return 0; ++} ++#endif /* STDIO */ ++ ++static void PNGCBAPI ++png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) ++{ ++ if (png_ptr != NULL) ++ { ++ png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); ++ if (image != NULL) ++ { ++ png_controlp cp = image->opaque; ++ if (cp != NULL) ++ { ++ png_const_bytep memory = cp->memory; ++ png_size_t size = cp->size; ++ ++ if (memory != NULL && size >= need) ++ { ++ memcpy(out, memory, need); ++ cp->memory = memory + need; ++ cp->size = size - need; ++ return; ++ } ++ ++ png_error(png_ptr, "read beyond end of data"); ++ } ++ } ++ ++ png_error(png_ptr, "invalid memory read"); ++ } ++} ++ ++int PNGAPI png_image_begin_read_from_memory(png_imagep image, ++ png_const_voidp memory, png_size_t size) ++{ ++ if (image != NULL && image->version == PNG_IMAGE_VERSION) ++ { ++ if (memory != NULL && size > 0) ++ { ++ if (png_image_read_init(image) != 0) ++ { ++ /* Now set the IO functions to read from the memory buffer and ++ * store it into io_ptr. Again do this in-place to avoid calling a ++ * libpng function that requires error handling. ++ */ ++ image->opaque->memory = png_voidcast(png_const_bytep, memory); ++ image->opaque->size = size; ++ image->opaque->png_ptr->io_ptr = image; ++ image->opaque->png_ptr->read_data_fn = png_image_memory_read; ++ ++ return png_safe_execute(image, png_image_read_header, image); ++ } ++ } ++ ++ else ++ return png_image_error(image, ++ "png_image_begin_read_from_memory: invalid argument"); ++ } ++ ++ else if (image != NULL) ++ return png_image_error(image, ++ "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); ++ ++ return 0; ++} ++ ++/* Utility function to skip chunks that are not used by the simplified image ++ * read functions and an appropriate macro to call it. ++ */ ++#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED ++static void ++png_image_skip_unused_chunks(png_structrp png_ptr) ++{ ++ /* Prepare the reader to ignore all recognized chunks whose data will not ++ * be used, i.e., all chunks recognized by libpng except for those ++ * involved in basic image reading: ++ * ++ * IHDR, PLTE, IDAT, IEND ++ * ++ * Or image data handling: ++ * ++ * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. ++ * ++ * This provides a small performance improvement and eliminates any ++ * potential vulnerability to security problems in the unused chunks. ++ * ++ * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored ++ * too. This allows the simplified API to be compiled without iCCP support, ++ * however if the support is there the chunk is still checked to detect ++ * errors (which are unfortunately quite common.) ++ */ ++ { ++ static PNG_CONST png_byte chunks_to_process[] = { ++ 98, 75, 71, 68, '\0', /* bKGD */ ++ 99, 72, 82, 77, '\0', /* cHRM */ ++ 103, 65, 77, 65, '\0', /* gAMA */ ++# ifdef PNG_READ_iCCP_SUPPORTED ++ 105, 67, 67, 80, '\0', /* iCCP */ ++# endif ++ 115, 66, 73, 84, '\0', /* sBIT */ ++ 115, 82, 71, 66, '\0', /* sRGB */ ++ }; ++ ++ /* Ignore unknown chunks and all other chunks except for the ++ * IHDR, PLTE, tRNS, IDAT, and IEND chunks. ++ */ ++ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, ++ NULL, -1); ++ ++ /* But do not ignore image data handling chunks */ ++ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, ++ chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); ++ } ++} ++ ++# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) ++#else ++# define PNG_SKIP_CHUNKS(p) ((void)0) ++#endif /* HANDLE_AS_UNKNOWN */ ++ ++/* The following macro gives the exact rounded answer for all values in the ++ * range 0..255 (it actually divides by 51.2, but the rounding still generates ++ * the correct numbers 0..5 ++ */ ++#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) ++ ++/* Utility functions to make particular color-maps */ ++static void ++set_file_encoding(png_image_read_control *display) ++{ ++ png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; ++ if (png_gamma_significant(g) != 0) ++ { ++ if (png_gamma_not_sRGB(g) != 0) ++ { ++ display->file_encoding = P_FILE; ++ display->gamma_to_linear = png_reciprocal(g); ++ } ++ ++ else ++ display->file_encoding = P_sRGB; ++ } ++ ++ else ++ display->file_encoding = P_LINEAR8; ++} ++ ++static unsigned int ++decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) ++{ ++ if (encoding == P_FILE) /* double check */ ++ encoding = display->file_encoding; ++ ++ if (encoding == P_NOTSET) /* must be the file encoding */ ++ { ++ set_file_encoding(display); ++ encoding = display->file_encoding; ++ } ++ ++ switch (encoding) ++ { ++ case P_FILE: ++ value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); ++ break; ++ ++ case P_sRGB: ++ value = png_sRGB_table[value]; ++ break; ++ ++ case P_LINEAR: ++ break; ++ ++ case P_LINEAR8: ++ value *= 257; ++ break; ++ ++ default: ++ png_error(display->image->opaque->png_ptr, ++ "unexpected encoding (internal error)"); ++ break; ++ } ++ ++ return value; ++} ++ ++static png_uint_32 ++png_colormap_compose(png_image_read_control *display, ++ png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, ++ png_uint_32 background, int encoding) ++{ ++ /* The file value is composed on the background, the background has the given ++ * encoding and so does the result, the file is encoded with P_FILE and the ++ * file and alpha are 8-bit values. The (output) encoding will always be ++ * P_LINEAR or P_sRGB. ++ */ ++ png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); ++ png_uint_32 b = decode_gamma(display, background, encoding); ++ ++ /* The alpha is always an 8-bit value (it comes from the palette), the value ++ * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. ++ */ ++ f = f * alpha + b * (255-alpha); ++ ++ if (encoding == P_LINEAR) ++ { ++ /* Scale to 65535; divide by 255, approximately (in fact this is extremely ++ * accurate, it divides by 255.00000005937181414556, with no overflow.) ++ */ ++ f *= 257; /* Now scaled by 65535 */ ++ f += f >> 16; ++ f = (f+32768) >> 16; ++ } ++ ++ else /* P_sRGB */ ++ f = PNG_sRGB_FROM_LINEAR(f); ++ ++ return f; ++} ++ ++/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must ++ * be 8-bit. ++ */ ++static void ++png_create_colormap_entry(png_image_read_control *display, ++ png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, ++ png_uint_32 alpha, int encoding) ++{ ++ png_imagep image = display->image; ++ const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? ++ P_LINEAR : P_sRGB; ++ const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && ++ (red != green || green != blue); ++ ++ if (ip > 255) ++ png_error(image->opaque->png_ptr, "color-map index out of range"); ++ ++ /* Update the cache with whether the file gamma is significantly different ++ * from sRGB. ++ */ ++ if (encoding == P_FILE) ++ { ++ if (display->file_encoding == P_NOTSET) ++ set_file_encoding(display); ++ ++ /* Note that the cached value may be P_FILE too, but if it is then the ++ * gamma_to_linear member has been set. ++ */ ++ encoding = display->file_encoding; ++ } ++ ++ if (encoding == P_FILE) ++ { ++ png_fixed_point g = display->gamma_to_linear; ++ ++ red = png_gamma_16bit_correct(red*257, g); ++ green = png_gamma_16bit_correct(green*257, g); ++ blue = png_gamma_16bit_correct(blue*257, g); ++ ++ if (convert_to_Y != 0 || output_encoding == P_LINEAR) ++ { ++ alpha *= 257; ++ encoding = P_LINEAR; ++ } ++ ++ else ++ { ++ red = PNG_sRGB_FROM_LINEAR(red * 255); ++ green = PNG_sRGB_FROM_LINEAR(green * 255); ++ blue = PNG_sRGB_FROM_LINEAR(blue * 255); ++ encoding = P_sRGB; ++ } ++ } ++ ++ else if (encoding == P_LINEAR8) ++ { ++ /* This encoding occurs quite frequently in test cases because PngSuite ++ * includes a gAMA 1.0 chunk with most images. ++ */ ++ red *= 257; ++ green *= 257; ++ blue *= 257; ++ alpha *= 257; ++ encoding = P_LINEAR; ++ } ++ ++ else if (encoding == P_sRGB && ++ (convert_to_Y != 0 || output_encoding == P_LINEAR)) ++ { ++ /* The values are 8-bit sRGB values, but must be converted to 16-bit ++ * linear. ++ */ ++ red = png_sRGB_table[red]; ++ green = png_sRGB_table[green]; ++ blue = png_sRGB_table[blue]; ++ alpha *= 257; ++ encoding = P_LINEAR; ++ } ++ ++ /* This is set if the color isn't gray but the output is. */ ++ if (encoding == P_LINEAR) ++ { ++ if (convert_to_Y != 0) ++ { ++ /* NOTE: these values are copied from png_do_rgb_to_gray */ ++ png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + ++ (png_uint_32)2366 * blue; ++ ++ if (output_encoding == P_LINEAR) ++ y = (y + 16384) >> 15; ++ ++ else ++ { ++ /* y is scaled by 32768, we need it scaled by 255: */ ++ y = (y + 128) >> 8; ++ y *= 255; ++ y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); ++ encoding = P_sRGB; ++ } ++ ++ blue = red = green = y; ++ } ++ ++ else if (output_encoding == P_sRGB) ++ { ++ red = PNG_sRGB_FROM_LINEAR(red * 255); ++ green = PNG_sRGB_FROM_LINEAR(green * 255); ++ blue = PNG_sRGB_FROM_LINEAR(blue * 255); ++ alpha = PNG_DIV257(alpha); ++ encoding = P_sRGB; ++ } ++ } ++ ++ if (encoding != output_encoding) ++ png_error(image->opaque->png_ptr, "bad encoding (internal error)"); ++ ++ /* Store the value. */ ++ { ++# ifdef PNG_FORMAT_AFIRST_SUPPORTED ++ const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && ++ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; ++# else ++# define afirst 0 ++# endif ++# ifdef PNG_FORMAT_BGR_SUPPORTED ++ const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; ++# else ++# define bgr 0 ++# endif ++ ++ if (output_encoding == P_LINEAR) ++ { ++ png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); ++ ++ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); ++ ++ /* The linear 16-bit values must be pre-multiplied by the alpha channel ++ * value, if less than 65535 (this is, effectively, composite on black ++ * if the alpha channel is removed.) ++ */ ++ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) ++ { ++ case 4: ++ entry[afirst ? 0 : 3] = (png_uint_16)alpha; ++ /* FALL THROUGH */ ++ ++ case 3: ++ if (alpha < 65535) ++ { ++ if (alpha > 0) ++ { ++ blue = (blue * alpha + 32767U)/65535U; ++ green = (green * alpha + 32767U)/65535U; ++ red = (red * alpha + 32767U)/65535U; ++ } ++ ++ else ++ red = green = blue = 0; ++ } ++ entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; ++ entry[afirst + 1] = (png_uint_16)green; ++ entry[afirst + bgr] = (png_uint_16)red; ++ break; ++ ++ case 2: ++ entry[1 ^ afirst] = (png_uint_16)alpha; ++ /* FALL THROUGH */ ++ ++ case 1: ++ if (alpha < 65535) ++ { ++ if (alpha > 0) ++ green = (green * alpha + 32767U)/65535U; ++ ++ else ++ green = 0; ++ } ++ entry[afirst] = (png_uint_16)green; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ else /* output encoding is P_sRGB */ ++ { ++ png_bytep entry = png_voidcast(png_bytep, display->colormap); ++ ++ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); ++ ++ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) ++ { ++ case 4: ++ entry[afirst ? 0 : 3] = (png_byte)alpha; ++ case 3: ++ entry[afirst + (2 ^ bgr)] = (png_byte)blue; ++ entry[afirst + 1] = (png_byte)green; ++ entry[afirst + bgr] = (png_byte)red; ++ break; ++ ++ case 2: ++ entry[1 ^ afirst] = (png_byte)alpha; ++ case 1: ++ entry[afirst] = (png_byte)green; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++# ifdef afirst ++# undef afirst ++# endif ++# ifdef bgr ++# undef bgr ++# endif ++ } ++} ++ ++static int ++make_gray_file_colormap(png_image_read_control *display) ++{ ++ unsigned int i; ++ ++ for (i=0; i<256; ++i) ++ png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); ++ ++ return i; ++} ++ ++static int ++make_gray_colormap(png_image_read_control *display) ++{ ++ unsigned int i; ++ ++ for (i=0; i<256; ++i) ++ png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); ++ ++ return i; ++} ++#define PNG_GRAY_COLORMAP_ENTRIES 256 ++ ++static int ++make_ga_colormap(png_image_read_control *display) ++{ ++ unsigned int i, a; ++ ++ /* Alpha is retained, the output will be a color-map with entries ++ * selected by six levels of alpha. One transparent entry, 6 gray ++ * levels for all the intermediate alpha values, leaving 230 entries ++ * for the opaque grays. The color-map entries are the six values ++ * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the ++ * relevant entry. ++ * ++ * if (alpha > 229) // opaque ++ * { ++ * // The 231 entries are selected to make the math below work: ++ * base = 0; ++ * entry = (231 * gray + 128) >> 8; ++ * } ++ * else if (alpha < 26) // transparent ++ * { ++ * base = 231; ++ * entry = 0; ++ * } ++ * else // partially opaque ++ * { ++ * base = 226 + 6 * PNG_DIV51(alpha); ++ * entry = PNG_DIV51(gray); ++ * } ++ */ ++ i = 0; ++ while (i < 231) ++ { ++ unsigned int gray = (i * 256 + 115) / 231; ++ png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); ++ } ++ ++ /* 255 is used here for the component values for consistency with the code ++ * that undoes premultiplication in pngwrite.c. ++ */ ++ png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); ++ ++ for (a=1; a<5; ++a) ++ { ++ unsigned int g; ++ ++ for (g=0; g<6; ++g) ++ png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, ++ P_sRGB); ++ } ++ ++ return i; ++} ++ ++#define PNG_GA_COLORMAP_ENTRIES 256 ++ ++static int ++make_rgb_colormap(png_image_read_control *display) ++{ ++ unsigned int i, r; ++ ++ /* Build a 6x6x6 opaque RGB cube */ ++ for (i=r=0; r<6; ++r) ++ { ++ unsigned int g; ++ ++ for (g=0; g<6; ++g) ++ { ++ unsigned int b; ++ ++ for (b=0; b<6; ++b) ++ png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, ++ P_sRGB); ++ } ++ } ++ ++ return i; ++} ++ ++#define PNG_RGB_COLORMAP_ENTRIES 216 ++ ++/* Return a palette index to the above palette given three 8-bit sRGB values. */ ++#define PNG_RGB_INDEX(r,g,b) \ ++ ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) ++ ++static int ++png_image_read_colormap(png_voidp argument) ++{ ++ png_image_read_control *display = ++ png_voidcast(png_image_read_control*, argument); ++ const png_imagep image = display->image; ++ ++ const png_structrp png_ptr = image->opaque->png_ptr; ++ const png_uint_32 output_format = image->format; ++ const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? ++ P_LINEAR : P_sRGB; ++ ++ unsigned int cmap_entries; ++ unsigned int output_processing; /* Output processing option */ ++ unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ ++ ++ /* Background information; the background color and the index of this color ++ * in the color-map if it exists (else 256). ++ */ ++ unsigned int background_index = 256; ++ png_uint_32 back_r, back_g, back_b; ++ ++ /* Flags to accumulate things that need to be done to the input. */ ++ int expand_tRNS = 0; ++ ++ /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is ++ * very difficult to do, the results look awful, and it is difficult to see ++ * what possible use it is because the application can't control the ++ * color-map. ++ */ ++ if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || ++ png_ptr->num_trans > 0) /* alpha in input */ && ++ ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) ++ { ++ if (output_encoding == P_LINEAR) /* compose on black */ ++ back_b = back_g = back_r = 0; ++ ++ else if (display->background == NULL /* no way to remove it */) ++ png_error(png_ptr, ++ "a background color must be supplied to remove alpha/transparency"); ++ ++ /* Get a copy of the background color (this avoids repeating the checks ++ * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the ++ * output format. ++ */ ++ else ++ { ++ back_g = display->background->green; ++ if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0) ++ { ++ back_r = display->background->red; ++ back_b = display->background->blue; ++ } ++ else ++ back_b = back_r = back_g; ++ } ++ } ++ ++ else if (output_encoding == P_LINEAR) ++ back_b = back_r = back_g = 65535; ++ ++ else ++ back_b = back_r = back_g = 255; ++ ++ /* Default the input file gamma if required - this is necessary because ++ * libpng assumes that if no gamma information is present the data is in the ++ * output format, but the simplified API deduces the gamma from the input ++ * format. ++ */ ++ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) ++ { ++ /* Do this directly, not using the png_colorspace functions, to ensure ++ * that it happens even if the colorspace is invalid (though probably if ++ * it is the setting will be ignored) Note that the same thing can be ++ * achieved at the application interface with png_set_gAMA. ++ */ ++ if (png_ptr->bit_depth == 16 && ++ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) ++ png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; ++ ++ else ++ png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; ++ ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; ++ } ++ ++ /* Decide what to do based on the PNG color type of the input data. The ++ * utility function png_create_colormap_entry deals with most aspects of the ++ * output transformations; this code works out how to produce bytes of ++ * color-map entries from the original format. ++ */ ++ switch (png_ptr->color_type) ++ { ++ case PNG_COLOR_TYPE_GRAY: ++ if (png_ptr->bit_depth <= 8) ++ { ++ /* There at most 256 colors in the output, regardless of ++ * transparency. ++ */ ++ unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; ++ ++ cmap_entries = 1U << png_ptr->bit_depth; ++ if (cmap_entries > image->colormap_entries) ++ png_error(png_ptr, "gray[8] color-map: too few entries"); ++ ++ step = 255 / (cmap_entries - 1); ++ output_processing = PNG_CMAP_NONE; ++ ++ /* If there is a tRNS chunk then this either selects a transparent ++ * value or, if the output has no alpha, the background color. ++ */ ++ if (png_ptr->num_trans > 0) ++ { ++ trans = png_ptr->trans_color.gray; ++ ++ if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) ++ back_alpha = output_encoding == P_LINEAR ? 65535 : 255; ++ } ++ ++ /* png_create_colormap_entry just takes an RGBA and writes the ++ * corresponding color-map entry using the format from 'image', ++ * including the required conversion to sRGB or linear as ++ * appropriate. The input values are always either sRGB (if the ++ * gamma correction flag is 0) or 0..255 scaled file encoded values ++ * (if the function must gamma correct them). ++ */ ++ for (i=val=0; i<cmap_entries; ++i, val += step) ++ { ++ /* 'i' is a file value. While this will result in duplicated ++ * entries for 8-bit non-sRGB encoded files it is necessary to ++ * have non-gamma corrected values to do tRNS handling. ++ */ ++ if (i != trans) ++ png_create_colormap_entry(display, i, val, val, val, 255, ++ P_FILE/*8-bit with file gamma*/); ++ ++ /* Else this entry is transparent. The colors don't matter if ++ * there is an alpha channel (back_alpha == 0), but it does no ++ * harm to pass them in; the values are not set above so this ++ * passes in white. ++ * ++ * NOTE: this preserves the full precision of the application ++ * supplied background color when it is used. ++ */ ++ else ++ png_create_colormap_entry(display, i, back_r, back_g, back_b, ++ back_alpha, output_encoding); ++ } ++ ++ /* We need libpng to preserve the original encoding. */ ++ data_encoding = P_FILE; ++ ++ /* The rows from libpng, while technically gray values, are now also ++ * color-map indices; however, they may need to be expanded to 1 ++ * byte per pixel. This is what png_set_packing does (i.e., it ++ * unpacks the bit values into bytes.) ++ */ ++ if (png_ptr->bit_depth < 8) ++ png_set_packing(png_ptr); ++ } ++ ++ else /* bit depth is 16 */ ++ { ++ /* The 16-bit input values can be converted directly to 8-bit gamma ++ * encoded values; however, if a tRNS chunk is present 257 color-map ++ * entries are required. This means that the extra entry requires ++ * special processing; add an alpha channel, sacrifice gray level ++ * 254 and convert transparent (alpha==0) entries to that. ++ * ++ * Use libpng to chop the data to 8 bits. Convert it to sRGB at the ++ * same time to minimize quality loss. If a tRNS chunk is present ++ * this means libpng must handle it too; otherwise it is impossible ++ * to do the exact match on the 16-bit value. ++ * ++ * If the output has no alpha channel *and* the background color is ++ * gray then it is possible to let libpng handle the substitution by ++ * ensuring that the corresponding gray level matches the background ++ * color exactly. ++ */ ++ data_encoding = P_sRGB; ++ ++ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) ++ png_error(png_ptr, "gray[16] color-map: too few entries"); ++ ++ cmap_entries = make_gray_colormap(display); ++ ++ if (png_ptr->num_trans > 0) ++ { ++ unsigned int back_alpha; ++ ++ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ back_alpha = 0; ++ ++ else ++ { ++ if (back_r == back_g && back_g == back_b) ++ { ++ /* Background is gray; no special processing will be ++ * required. ++ */ ++ png_color_16 c; ++ png_uint_32 gray = back_g; ++ ++ if (output_encoding == P_LINEAR) ++ { ++ gray = PNG_sRGB_FROM_LINEAR(gray * 255); ++ ++ /* And make sure the corresponding palette entry ++ * matches. ++ */ ++ png_create_colormap_entry(display, gray, back_g, back_g, ++ back_g, 65535, P_LINEAR); ++ } ++ ++ /* The background passed to libpng, however, must be the ++ * sRGB value. ++ */ ++ c.index = 0; /*unused*/ ++ c.gray = c.red = c.green = c.blue = (png_uint_16)gray; ++ ++ /* NOTE: does this work without expanding tRNS to alpha? ++ * It should be the color->gray case below apparently ++ * doesn't. ++ */ ++ png_set_background_fixed(png_ptr, &c, ++ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, ++ 0/*gamma: not used*/); ++ ++ output_processing = PNG_CMAP_NONE; ++ break; ++ } ++ ++ back_alpha = output_encoding == P_LINEAR ? 65535 : 255; ++ } ++ ++ /* output_processing means that the libpng-processed row will be ++ * 8-bit GA and it has to be processing to single byte color-map ++ * values. Entry 254 is replaced by either a completely ++ * transparent entry or by the background color at full ++ * precision (and the background color is not a simple gray ++ * level in this case.) ++ */ ++ expand_tRNS = 1; ++ output_processing = PNG_CMAP_TRANS; ++ background_index = 254; ++ ++ /* And set (overwrite) color-map entry 254 to the actual ++ * background color at full precision. ++ */ ++ png_create_colormap_entry(display, 254, back_r, back_g, back_b, ++ back_alpha, output_encoding); ++ } ++ ++ else ++ output_processing = PNG_CMAP_NONE; ++ } ++ break; ++ ++ case PNG_COLOR_TYPE_GRAY_ALPHA: ++ /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum ++ * of 65536 combinations. If, however, the alpha channel is to be ++ * removed there are only 256 possibilities if the background is gray. ++ * (Otherwise there is a subset of the 65536 possibilities defined by ++ * the triangle between black, white and the background color.) ++ * ++ * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to ++ * worry about tRNS matching - tRNS is ignored if there is an alpha ++ * channel. ++ */ ++ data_encoding = P_sRGB; ++ ++ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) ++ png_error(png_ptr, "gray+alpha color-map: too few entries"); ++ ++ cmap_entries = make_ga_colormap(display); ++ ++ background_index = PNG_CMAP_GA_BACKGROUND; ++ output_processing = PNG_CMAP_GA; ++ } ++ ++ else /* alpha is removed */ ++ { ++ /* Alpha must be removed as the PNG data is processed when the ++ * background is a color because the G and A channels are ++ * independent and the vector addition (non-parallel vectors) is a ++ * 2-D problem. ++ * ++ * This can be reduced to the same algorithm as above by making a ++ * colormap containing gray levels (for the opaque grays), a ++ * background entry (for a transparent pixel) and a set of four six ++ * level color values, one set for each intermediate alpha value. ++ * See the comments in make_ga_colormap for how this works in the ++ * per-pixel processing. ++ * ++ * If the background is gray, however, we only need a 256 entry gray ++ * level color map. It is sufficient to make the entry generated ++ * for the background color be exactly the color specified. ++ */ ++ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || ++ (back_r == back_g && back_g == back_b)) ++ { ++ /* Background is gray; no special processing will be required. */ ++ png_color_16 c; ++ png_uint_32 gray = back_g; ++ ++ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) ++ png_error(png_ptr, "gray-alpha color-map: too few entries"); ++ ++ cmap_entries = make_gray_colormap(display); ++ ++ if (output_encoding == P_LINEAR) ++ { ++ gray = PNG_sRGB_FROM_LINEAR(gray * 255); ++ ++ /* And make sure the corresponding palette entry matches. */ ++ png_create_colormap_entry(display, gray, back_g, back_g, ++ back_g, 65535, P_LINEAR); ++ } ++ ++ /* The background passed to libpng, however, must be the sRGB ++ * value. ++ */ ++ c.index = 0; /*unused*/ ++ c.gray = c.red = c.green = c.blue = (png_uint_16)gray; ++ ++ png_set_background_fixed(png_ptr, &c, ++ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, ++ 0/*gamma: not used*/); ++ ++ output_processing = PNG_CMAP_NONE; ++ } ++ ++ else ++ { ++ png_uint_32 i, a; ++ ++ /* This is the same as png_make_ga_colormap, above, except that ++ * the entries are all opaque. ++ */ ++ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) ++ png_error(png_ptr, "ga-alpha color-map: too few entries"); ++ ++ i = 0; ++ while (i < 231) ++ { ++ png_uint_32 gray = (i * 256 + 115) / 231; ++ png_create_colormap_entry(display, i++, gray, gray, gray, ++ 255, P_sRGB); ++ } ++ ++ /* NOTE: this preserves the full precision of the application ++ * background color. ++ */ ++ background_index = i; ++ png_create_colormap_entry(display, i++, back_r, back_g, back_b, ++ output_encoding == P_LINEAR ? 65535U : 255U, output_encoding); ++ ++ /* For non-opaque input composite on the sRGB background - this ++ * requires inverting the encoding for each component. The input ++ * is still converted to the sRGB encoding because this is a ++ * reasonable approximate to the logarithmic curve of human ++ * visual sensitivity, at least over the narrow range which PNG ++ * represents. Consequently 'G' is always sRGB encoded, while ++ * 'A' is linear. We need the linear background colors. ++ */ ++ if (output_encoding == P_sRGB) /* else already linear */ ++ { ++ /* This may produce a value not exactly matching the ++ * background, but that's ok because these numbers are only ++ * used when alpha != 0 ++ */ ++ back_r = png_sRGB_table[back_r]; ++ back_g = png_sRGB_table[back_g]; ++ back_b = png_sRGB_table[back_b]; ++ } ++ ++ for (a=1; a<5; ++a) ++ { ++ unsigned int g; ++ ++ /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled ++ * by an 8-bit alpha value (0..255). ++ */ ++ png_uint_32 alpha = 51 * a; ++ png_uint_32 back_rx = (255-alpha) * back_r; ++ png_uint_32 back_gx = (255-alpha) * back_g; ++ png_uint_32 back_bx = (255-alpha) * back_b; ++ ++ for (g=0; g<6; ++g) ++ { ++ png_uint_32 gray = png_sRGB_table[g*51] * alpha; ++ ++ png_create_colormap_entry(display, i++, ++ PNG_sRGB_FROM_LINEAR(gray + back_rx), ++ PNG_sRGB_FROM_LINEAR(gray + back_gx), ++ PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); ++ } ++ } ++ ++ cmap_entries = i; ++ output_processing = PNG_CMAP_GA; ++ } ++ } ++ break; ++ ++ case PNG_COLOR_TYPE_RGB: ++ case PNG_COLOR_TYPE_RGB_ALPHA: ++ /* Exclude the case where the output is gray; we can always handle this ++ * with the cases above. ++ */ ++ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) ++ { ++ /* The color-map will be grayscale, so we may as well convert the ++ * input RGB values to a simple grayscale and use the grayscale ++ * code above. ++ * ++ * NOTE: calling this apparently damages the recognition of the ++ * transparent color in background color handling; call ++ * png_set_tRNS_to_alpha before png_set_background_fixed. ++ */ ++ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, ++ -1); ++ data_encoding = P_sRGB; ++ ++ /* The output will now be one or two 8-bit gray or gray+alpha ++ * channels. The more complex case arises when the input has alpha. ++ */ ++ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || ++ png_ptr->num_trans > 0) && ++ (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++ /* Both input and output have an alpha channel, so no background ++ * processing is required; just map the GA bytes to the right ++ * color-map entry. ++ */ ++ expand_tRNS = 1; ++ ++ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) ++ png_error(png_ptr, "rgb[ga] color-map: too few entries"); ++ ++ cmap_entries = make_ga_colormap(display); ++ background_index = PNG_CMAP_GA_BACKGROUND; ++ output_processing = PNG_CMAP_GA; ++ } ++ ++ else ++ { ++ /* Either the input or the output has no alpha channel, so there ++ * will be no non-opaque pixels in the color-map; it will just be ++ * grayscale. ++ */ ++ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) ++ png_error(png_ptr, "rgb[gray] color-map: too few entries"); ++ ++ /* Ideally this code would use libpng to do the gamma correction, ++ * but if an input alpha channel is to be removed we will hit the ++ * libpng bug in gamma+compose+rgb-to-gray (the double gamma ++ * correction bug). Fix this by dropping the gamma correction in ++ * this case and doing it in the palette; this will result in ++ * duplicate palette entries, but that's better than the ++ * alternative of double gamma correction. ++ */ ++ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || ++ png_ptr->num_trans > 0) && ++ png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) ++ { ++ cmap_entries = make_gray_file_colormap(display); ++ data_encoding = P_FILE; ++ } ++ ++ else ++ cmap_entries = make_gray_colormap(display); ++ ++ /* But if the input has alpha or transparency it must be removed ++ */ ++ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || ++ png_ptr->num_trans > 0) ++ { ++ png_color_16 c; ++ png_uint_32 gray = back_g; ++ ++ /* We need to ensure that the application background exists in ++ * the colormap and that completely transparent pixels map to ++ * it. Achieve this simply by ensuring that the entry ++ * selected for the background really is the background color. ++ */ ++ if (data_encoding == P_FILE) /* from the fixup above */ ++ { ++ /* The app supplied a gray which is in output_encoding, we ++ * need to convert it to a value of the input (P_FILE) ++ * encoding then set this palette entry to the required ++ * output encoding. ++ */ ++ if (output_encoding == P_sRGB) ++ gray = png_sRGB_table[gray]; /* now P_LINEAR */ ++ ++ gray = PNG_DIV257(png_gamma_16bit_correct(gray, ++ png_ptr->colorspace.gamma)); /* now P_FILE */ ++ ++ /* And make sure the corresponding palette entry contains ++ * exactly the required sRGB value. ++ */ ++ png_create_colormap_entry(display, gray, back_g, back_g, ++ back_g, 0/*unused*/, output_encoding); ++ } ++ ++ else if (output_encoding == P_LINEAR) ++ { ++ gray = PNG_sRGB_FROM_LINEAR(gray * 255); ++ ++ /* And make sure the corresponding palette entry matches. ++ */ ++ png_create_colormap_entry(display, gray, back_g, back_g, ++ back_g, 0/*unused*/, P_LINEAR); ++ } ++ ++ /* The background passed to libpng, however, must be the ++ * output (normally sRGB) value. ++ */ ++ c.index = 0; /*unused*/ ++ c.gray = c.red = c.green = c.blue = (png_uint_16)gray; ++ ++ /* NOTE: the following is apparently a bug in libpng. Without ++ * it the transparent color recognition in ++ * png_set_background_fixed seems to go wrong. ++ */ ++ expand_tRNS = 1; ++ png_set_background_fixed(png_ptr, &c, ++ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, ++ 0/*gamma: not used*/); ++ } ++ ++ output_processing = PNG_CMAP_NONE; ++ } ++ } ++ ++ else /* output is color */ ++ { ++ /* We could use png_quantize here so long as there is no transparent ++ * color or alpha; png_quantize ignores alpha. Easier overall just ++ * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. ++ * Consequently we always want libpng to produce sRGB data. ++ */ ++ data_encoding = P_sRGB; ++ ++ /* Is there any transparency or alpha? */ ++ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || ++ png_ptr->num_trans > 0) ++ { ++ /* Is there alpha in the output too? If so all four channels are ++ * processed into a special RGB cube with alpha support. ++ */ ++ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++ png_uint_32 r; ++ ++ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) ++ png_error(png_ptr, "rgb+alpha color-map: too few entries"); ++ ++ cmap_entries = make_rgb_colormap(display); ++ ++ /* Add a transparent entry. */ ++ png_create_colormap_entry(display, cmap_entries, 255, 255, ++ 255, 0, P_sRGB); ++ ++ /* This is stored as the background index for the processing ++ * algorithm. ++ */ ++ background_index = cmap_entries++; ++ ++ /* Add 27 r,g,b entries each with alpha 0.5. */ ++ for (r=0; r<256; r = (r << 1) | 0x7f) ++ { ++ png_uint_32 g; ++ ++ for (g=0; g<256; g = (g << 1) | 0x7f) ++ { ++ png_uint_32 b; ++ ++ /* This generates components with the values 0, 127 and ++ * 255 ++ */ ++ for (b=0; b<256; b = (b << 1) | 0x7f) ++ png_create_colormap_entry(display, cmap_entries++, ++ r, g, b, 128, P_sRGB); ++ } ++ } ++ ++ expand_tRNS = 1; ++ output_processing = PNG_CMAP_RGB_ALPHA; ++ } ++ ++ else ++ { ++ /* Alpha/transparency must be removed. The background must ++ * exist in the color map (achieved by setting adding it after ++ * the 666 color-map). If the standard processing code will ++ * pick up this entry automatically that's all that is ++ * required; libpng can be called to do the background ++ * processing. ++ */ ++ unsigned int sample_size = ++ PNG_IMAGE_SAMPLE_SIZE(output_format); ++ png_uint_32 r, g, b; /* sRGB background */ ++ ++ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) ++ png_error(png_ptr, "rgb-alpha color-map: too few entries"); ++ ++ cmap_entries = make_rgb_colormap(display); ++ ++ png_create_colormap_entry(display, cmap_entries, back_r, ++ back_g, back_b, 0/*unused*/, output_encoding); ++ ++ if (output_encoding == P_LINEAR) ++ { ++ r = PNG_sRGB_FROM_LINEAR(back_r * 255); ++ g = PNG_sRGB_FROM_LINEAR(back_g * 255); ++ b = PNG_sRGB_FROM_LINEAR(back_b * 255); ++ } ++ ++ else ++ { ++ r = back_r; ++ g = back_g; ++ b = back_g; ++ } ++ ++ /* Compare the newly-created color-map entry with the one the ++ * PNG_CMAP_RGB algorithm will use. If the two entries don't ++ * match, add the new one and set this as the background ++ * index. ++ */ ++ if (memcmp((png_const_bytep)display->colormap + ++ sample_size * cmap_entries, ++ (png_const_bytep)display->colormap + ++ sample_size * PNG_RGB_INDEX(r,g,b), ++ sample_size) != 0) ++ { ++ /* The background color must be added. */ ++ background_index = cmap_entries++; ++ ++ /* Add 27 r,g,b entries each with created by composing with ++ * the background at alpha 0.5. ++ */ ++ for (r=0; r<256; r = (r << 1) | 0x7f) ++ { ++ for (g=0; g<256; g = (g << 1) | 0x7f) ++ { ++ /* This generates components with the values 0, 127 ++ * and 255 ++ */ ++ for (b=0; b<256; b = (b << 1) | 0x7f) ++ png_create_colormap_entry(display, cmap_entries++, ++ png_colormap_compose(display, r, P_sRGB, 128, ++ back_r, output_encoding), ++ png_colormap_compose(display, g, P_sRGB, 128, ++ back_g, output_encoding), ++ png_colormap_compose(display, b, P_sRGB, 128, ++ back_b, output_encoding), ++ 0/*unused*/, output_encoding); ++ } ++ } ++ ++ expand_tRNS = 1; ++ output_processing = PNG_CMAP_RGB_ALPHA; ++ } ++ ++ else /* background color is in the standard color-map */ ++ { ++ png_color_16 c; ++ ++ c.index = 0; /*unused*/ ++ c.red = (png_uint_16)back_r; ++ c.gray = c.green = (png_uint_16)back_g; ++ c.blue = (png_uint_16)back_b; ++ ++ png_set_background_fixed(png_ptr, &c, ++ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, ++ 0/*gamma: not used*/); ++ ++ output_processing = PNG_CMAP_RGB; ++ } ++ } ++ } ++ ++ else /* no alpha or transparency in the input */ ++ { ++ /* Alpha in the output is irrelevant, simply map the opaque input ++ * pixels to the 6x6x6 color-map. ++ */ ++ if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) ++ png_error(png_ptr, "rgb color-map: too few entries"); ++ ++ cmap_entries = make_rgb_colormap(display); ++ output_processing = PNG_CMAP_RGB; ++ } ++ } ++ break; ++ ++ case PNG_COLOR_TYPE_PALETTE: ++ /* It's already got a color-map. It may be necessary to eliminate the ++ * tRNS entries though. ++ */ ++ { ++ unsigned int num_trans = png_ptr->num_trans; ++ png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; ++ png_const_colorp colormap = png_ptr->palette; ++ const int do_background = trans != NULL && ++ (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; ++ unsigned int i; ++ ++ /* Just in case: */ ++ if (trans == NULL) ++ num_trans = 0; ++ ++ output_processing = PNG_CMAP_NONE; ++ data_encoding = P_FILE; /* Don't change from color-map indices */ ++ cmap_entries = png_ptr->num_palette; ++ if (cmap_entries > 256) ++ cmap_entries = 256; ++ ++ if (cmap_entries > image->colormap_entries) ++ png_error(png_ptr, "palette color-map: too few entries"); ++ ++ for (i=0; i < cmap_entries; ++i) ++ { ++ if (do_background != 0 && i < num_trans && trans[i] < 255) ++ { ++ if (trans[i] == 0) ++ png_create_colormap_entry(display, i, back_r, back_g, ++ back_b, 0, output_encoding); ++ ++ else ++ { ++ /* Must compose the PNG file color in the color-map entry ++ * on the sRGB color in 'back'. ++ */ ++ png_create_colormap_entry(display, i, ++ png_colormap_compose(display, colormap[i].red, P_FILE, ++ trans[i], back_r, output_encoding), ++ png_colormap_compose(display, colormap[i].green, P_FILE, ++ trans[i], back_g, output_encoding), ++ png_colormap_compose(display, colormap[i].blue, P_FILE, ++ trans[i], back_b, output_encoding), ++ output_encoding == P_LINEAR ? trans[i] * 257U : ++ trans[i], ++ output_encoding); ++ } ++ } ++ ++ else ++ png_create_colormap_entry(display, i, colormap[i].red, ++ colormap[i].green, colormap[i].blue, ++ i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); ++ } ++ ++ /* The PNG data may have indices packed in fewer than 8 bits, it ++ * must be expanded if so. ++ */ ++ if (png_ptr->bit_depth < 8) ++ png_set_packing(png_ptr); ++ } ++ break; ++ ++ default: ++ png_error(png_ptr, "invalid PNG color type"); ++ /*NOT REACHED*/ ++ break; ++ } ++ ++ /* Now deal with the output processing */ ++ if (expand_tRNS != 0 && png_ptr->num_trans > 0 && ++ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) ++ png_set_tRNS_to_alpha(png_ptr); ++ ++ switch (data_encoding) ++ { ++ default: ++ png_error(png_ptr, "bad data option (internal error)"); ++ break; ++ ++ case P_sRGB: ++ /* Change to 8-bit sRGB */ ++ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); ++ /* FALL THROUGH */ ++ ++ case P_FILE: ++ if (png_ptr->bit_depth > 8) ++ png_set_scale_16(png_ptr); ++ break; ++ } ++ ++ if (cmap_entries > 256 || cmap_entries > image->colormap_entries) ++ png_error(png_ptr, "color map overflow (BAD internal error)"); ++ ++ image->colormap_entries = cmap_entries; ++ ++ /* Double check using the recorded background index */ ++ switch (output_processing) ++ { ++ case PNG_CMAP_NONE: ++ if (background_index != PNG_CMAP_NONE_BACKGROUND) ++ goto bad_background; ++ break; ++ ++ case PNG_CMAP_GA: ++ if (background_index != PNG_CMAP_GA_BACKGROUND) ++ goto bad_background; ++ break; ++ ++ case PNG_CMAP_TRANS: ++ if (background_index >= cmap_entries || ++ background_index != PNG_CMAP_TRANS_BACKGROUND) ++ goto bad_background; ++ break; ++ ++ case PNG_CMAP_RGB: ++ if (background_index != PNG_CMAP_RGB_BACKGROUND) ++ goto bad_background; ++ break; ++ ++ case PNG_CMAP_RGB_ALPHA: ++ if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) ++ goto bad_background; ++ break; ++ ++ default: ++ png_error(png_ptr, "bad processing option (internal error)"); ++ ++ bad_background: ++ png_error(png_ptr, "bad background index (internal error)"); ++ } ++ ++ display->colormap_processing = output_processing; ++ ++ return 1/*ok*/; ++} ++ ++/* The final part of the color-map read called from png_image_finish_read. */ ++static int ++png_image_read_and_map(png_voidp argument) ++{ ++ png_image_read_control *display = png_voidcast(png_image_read_control*, ++ argument); ++ png_imagep image = display->image; ++ png_structrp png_ptr = image->opaque->png_ptr; ++ int passes; ++ ++ /* Called when the libpng data must be transformed into the color-mapped ++ * form. There is a local row buffer in display->local and this routine must ++ * do the interlace handling. ++ */ ++ switch (png_ptr->interlaced) ++ { ++ case PNG_INTERLACE_NONE: ++ passes = 1; ++ break; ++ ++ case PNG_INTERLACE_ADAM7: ++ passes = PNG_INTERLACE_ADAM7_PASSES; ++ break; ++ ++ default: ++ png_error(png_ptr, "unknown interlace type"); ++ } ++ ++ { ++ png_uint_32 height = image->height; ++ png_uint_32 width = image->width; ++ int proc = display->colormap_processing; ++ png_bytep first_row = png_voidcast(png_bytep, display->first_row); ++ ptrdiff_t step_row = display->row_bytes; ++ int pass; ++ ++ for (pass = 0; pass < passes; ++pass) ++ { ++ unsigned int startx, stepx, stepy; ++ png_uint_32 y; ++ ++ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) ++ { ++ /* The row may be empty for a short image: */ ++ if (PNG_PASS_COLS(width, pass) == 0) ++ continue; ++ ++ startx = PNG_PASS_START_COL(pass); ++ stepx = PNG_PASS_COL_OFFSET(pass); ++ y = PNG_PASS_START_ROW(pass); ++ stepy = PNG_PASS_ROW_OFFSET(pass); ++ } ++ ++ else ++ { ++ y = 0; ++ startx = 0; ++ stepx = stepy = 1; ++ } ++ ++ for (; y<height; y += stepy) ++ { ++ png_bytep inrow = png_voidcast(png_bytep, display->local_row); ++ png_bytep outrow = first_row + y * step_row; ++ png_const_bytep end_row = outrow + width; ++ ++ /* Read read the libpng data into the temporary buffer. */ ++ png_read_row(png_ptr, inrow, NULL); ++ ++ /* Now process the row according to the processing option, note ++ * that the caller verifies that the format of the libpng output ++ * data is as required. ++ */ ++ outrow += startx; ++ switch (proc) ++ { ++ case PNG_CMAP_GA: ++ for (; outrow < end_row; outrow += stepx) ++ { ++ /* The data is always in the PNG order */ ++ unsigned int gray = *inrow++; ++ unsigned int alpha = *inrow++; ++ unsigned int entry; ++ ++ /* NOTE: this code is copied as a comment in ++ * make_ga_colormap above. Please update the ++ * comment if you change this code! ++ */ ++ if (alpha > 229) /* opaque */ ++ { ++ entry = (231 * gray + 128) >> 8; ++ } ++ else if (alpha < 26) /* transparent */ ++ { ++ entry = 231; ++ } ++ else /* partially opaque */ ++ { ++ entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); ++ } ++ ++ *outrow = (png_byte)entry; ++ } ++ break; ++ ++ case PNG_CMAP_TRANS: ++ for (; outrow < end_row; outrow += stepx) ++ { ++ png_byte gray = *inrow++; ++ png_byte alpha = *inrow++; ++ ++ if (alpha == 0) ++ *outrow = PNG_CMAP_TRANS_BACKGROUND; ++ ++ else if (gray != PNG_CMAP_TRANS_BACKGROUND) ++ *outrow = gray; ++ ++ else ++ *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); ++ } ++ break; ++ ++ case PNG_CMAP_RGB: ++ for (; outrow < end_row; outrow += stepx) ++ { ++ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); ++ inrow += 3; ++ } ++ break; ++ ++ case PNG_CMAP_RGB_ALPHA: ++ for (; outrow < end_row; outrow += stepx) ++ { ++ unsigned int alpha = inrow[3]; ++ ++ /* Because the alpha entries only hold alpha==0.5 values ++ * split the processing at alpha==0.25 (64) and 0.75 ++ * (196). ++ */ ++ ++ if (alpha >= 196) ++ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], ++ inrow[2]); ++ ++ else if (alpha < 64) ++ *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; ++ ++ else ++ { ++ /* Likewise there are three entries for each of r, g ++ * and b. We could select the entry by popcount on ++ * the top two bits on those architectures that ++ * support it, this is what the code below does, ++ * crudely. ++ */ ++ unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; ++ ++ /* Here are how the values map: ++ * ++ * 0x00 .. 0x3f -> 0 ++ * 0x40 .. 0xbf -> 1 ++ * 0xc0 .. 0xff -> 2 ++ * ++ * So, as above with the explicit alpha checks, the ++ * breakpoints are at 64 and 196. ++ */ ++ if (inrow[0] & 0x80) back_i += 9; /* red */ ++ if (inrow[0] & 0x40) back_i += 9; ++ if (inrow[0] & 0x80) back_i += 3; /* green */ ++ if (inrow[0] & 0x40) back_i += 3; ++ if (inrow[0] & 0x80) back_i += 1; /* blue */ ++ if (inrow[0] & 0x40) back_i += 1; ++ ++ *outrow = (png_byte)back_i; ++ } ++ ++ inrow += 4; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ } ++ } ++ } ++ ++ return 1; ++} ++ ++static int ++png_image_read_colormapped(png_voidp argument) ++{ ++ png_image_read_control *display = png_voidcast(png_image_read_control*, ++ argument); ++ png_imagep image = display->image; ++ png_controlp control = image->opaque; ++ png_structrp png_ptr = control->png_ptr; ++ png_inforp info_ptr = control->info_ptr; ++ ++ int passes = 0; /* As a flag */ ++ ++ PNG_SKIP_CHUNKS(png_ptr); ++ ++ /* Update the 'info' structure and make sure the result is as required; first ++ * make sure to turn on the interlace handling if it will be required ++ * (because it can't be turned on *after* the call to png_read_update_info!) ++ */ ++ if (display->colormap_processing == PNG_CMAP_NONE) ++ passes = png_set_interlace_handling(png_ptr); ++ ++ png_read_update_info(png_ptr, info_ptr); ++ ++ /* The expected output can be deduced from the colormap_processing option. */ ++ switch (display->colormap_processing) ++ { ++ case PNG_CMAP_NONE: ++ /* Output must be one channel and one byte per pixel, the output ++ * encoding can be anything. ++ */ ++ if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || ++ info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && ++ info_ptr->bit_depth == 8) ++ break; ++ ++ goto bad_output; ++ ++ case PNG_CMAP_TRANS: ++ case PNG_CMAP_GA: ++ /* Output must be two channels and the 'G' one must be sRGB, the latter ++ * can be checked with an exact number because it should have been set ++ * to this number above! ++ */ ++ if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && ++ info_ptr->bit_depth == 8 && ++ png_ptr->screen_gamma == PNG_GAMMA_sRGB && ++ image->colormap_entries == 256) ++ break; ++ ++ goto bad_output; ++ ++ case PNG_CMAP_RGB: ++ /* Output must be 8-bit sRGB encoded RGB */ ++ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && ++ info_ptr->bit_depth == 8 && ++ png_ptr->screen_gamma == PNG_GAMMA_sRGB && ++ image->colormap_entries == 216) ++ break; ++ ++ goto bad_output; ++ ++ case PNG_CMAP_RGB_ALPHA: ++ /* Output must be 8-bit sRGB encoded RGBA */ ++ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && ++ info_ptr->bit_depth == 8 && ++ png_ptr->screen_gamma == PNG_GAMMA_sRGB && ++ image->colormap_entries == 244 /* 216 + 1 + 27 */) ++ break; ++ ++ /* goto bad_output; */ ++ /* FALL THROUGH */ ++ ++ default: ++ bad_output: ++ png_error(png_ptr, "bad color-map processing (internal error)"); ++ } ++ ++ /* Now read the rows. Do this here if it is possible to read directly into ++ * the output buffer, otherwise allocate a local row buffer of the maximum ++ * size libpng requires and call the relevant processing routine safely. ++ */ ++ { ++ png_voidp first_row = display->buffer; ++ ptrdiff_t row_bytes = display->row_stride; ++ ++ /* The following expression is designed to work correctly whether it gives ++ * a signed or an unsigned result. ++ */ ++ if (row_bytes < 0) ++ { ++ char *ptr = png_voidcast(char*, first_row); ++ ptr += (image->height-1) * (-row_bytes); ++ first_row = png_voidcast(png_voidp, ptr); ++ } ++ ++ display->first_row = first_row; ++ display->row_bytes = row_bytes; ++ } ++ ++ if (passes == 0) ++ { ++ int result; ++ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); ++ ++ display->local_row = row; ++ result = png_safe_execute(image, png_image_read_and_map, display); ++ display->local_row = NULL; ++ png_free(png_ptr, row); ++ ++ return result; ++ } ++ ++ else ++ { ++ png_alloc_size_t row_bytes = display->row_bytes; ++ ++ while (--passes >= 0) ++ { ++ png_uint_32 y = image->height; ++ png_bytep row = png_voidcast(png_bytep, display->first_row); ++ ++ while (y-- > 0) ++ { ++ png_read_row(png_ptr, row, NULL); ++ row += row_bytes; ++ } ++ } ++ ++ return 1; ++ } ++} ++ ++/* Just the row reading part of png_image_read. */ ++static int ++png_image_read_composite(png_voidp argument) ++{ ++ png_image_read_control *display = png_voidcast(png_image_read_control*, ++ argument); ++ png_imagep image = display->image; ++ png_structrp png_ptr = image->opaque->png_ptr; ++ int passes; ++ ++ switch (png_ptr->interlaced) ++ { ++ case PNG_INTERLACE_NONE: ++ passes = 1; ++ break; ++ ++ case PNG_INTERLACE_ADAM7: ++ passes = PNG_INTERLACE_ADAM7_PASSES; ++ break; ++ ++ default: ++ png_error(png_ptr, "unknown interlace type"); ++ } ++ ++ { ++ png_uint_32 height = image->height; ++ png_uint_32 width = image->width; ++ ptrdiff_t step_row = display->row_bytes; ++ unsigned int channels = ++ (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; ++ int pass; ++ ++ for (pass = 0; pass < passes; ++pass) ++ { ++ unsigned int startx, stepx, stepy; ++ png_uint_32 y; ++ ++ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) ++ { ++ /* The row may be empty for a short image: */ ++ if (PNG_PASS_COLS(width, pass) == 0) ++ continue; ++ ++ startx = PNG_PASS_START_COL(pass) * channels; ++ stepx = PNG_PASS_COL_OFFSET(pass) * channels; ++ y = PNG_PASS_START_ROW(pass); ++ stepy = PNG_PASS_ROW_OFFSET(pass); ++ } ++ ++ else ++ { ++ y = 0; ++ startx = 0; ++ stepx = channels; ++ stepy = 1; ++ } ++ ++ for (; y<height; y += stepy) ++ { ++ png_bytep inrow = png_voidcast(png_bytep, display->local_row); ++ png_bytep outrow; ++ png_const_bytep end_row; ++ ++ /* Read the row, which is packed: */ ++ png_read_row(png_ptr, inrow, NULL); ++ ++ outrow = png_voidcast(png_bytep, display->first_row); ++ outrow += y * step_row; ++ end_row = outrow + width * channels; ++ ++ /* Now do the composition on each pixel in this row. */ ++ outrow += startx; ++ for (; outrow < end_row; outrow += stepx) ++ { ++ png_byte alpha = inrow[channels]; ++ ++ if (alpha > 0) /* else no change to the output */ ++ { ++ unsigned int c; ++ ++ for (c=0; c<channels; ++c) ++ { ++ png_uint_32 component = inrow[c]; ++ ++ if (alpha < 255) /* else just use component */ ++ { ++ /* This is PNG_OPTIMIZED_ALPHA, the component value ++ * is a linear 8-bit value. Combine this with the ++ * current outrow[c] value which is sRGB encoded. ++ * Arithmetic here is 16-bits to preserve the output ++ * values correctly. ++ */ ++ component *= 257*255; /* =65535 */ ++ component += (255-alpha)*png_sRGB_table[outrow[c]]; ++ ++ /* So 'component' is scaled by 255*65535 and is ++ * therefore appropriate for the sRGB to linear ++ * conversion table. ++ */ ++ component = PNG_sRGB_FROM_LINEAR(component); ++ } ++ ++ outrow[c] = (png_byte)component; ++ } ++ } ++ ++ inrow += channels+1; /* components and alpha channel */ ++ } ++ } ++ } ++ } ++ ++ return 1; ++} ++ ++/* The do_local_background case; called when all the following transforms are to ++ * be done: ++ * ++ * PNG_RGB_TO_GRAY ++ * PNG_COMPOSITE ++ * PNG_GAMMA ++ * ++ * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and ++ * PNG_COMPOSITE code performs gamma correction, so we get double gamma ++ * correction. The fix-up is to prevent the PNG_COMPOSITE operation from ++ * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha ++ * row and handles the removal or pre-multiplication of the alpha channel. ++ */ ++static int ++png_image_read_background(png_voidp argument) ++{ ++ png_image_read_control *display = png_voidcast(png_image_read_control*, ++ argument); ++ png_imagep image = display->image; ++ png_structrp png_ptr = image->opaque->png_ptr; ++ png_inforp info_ptr = image->opaque->info_ptr; ++ png_uint_32 height = image->height; ++ png_uint_32 width = image->width; ++ int pass, passes; ++ ++ /* Double check the convoluted logic below. We expect to get here with ++ * libpng doing rgb to gray and gamma correction but background processing ++ * left to the png_image_read_background function. The rows libpng produce ++ * might be 8 or 16-bit but should always have two channels; gray plus alpha. ++ */ ++ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) ++ png_error(png_ptr, "lost rgb to gray"); ++ ++ if ((png_ptr->transformations & PNG_COMPOSE) != 0) ++ png_error(png_ptr, "unexpected compose"); ++ ++ if (png_get_channels(png_ptr, info_ptr) != 2) ++ png_error(png_ptr, "lost/gained channels"); ++ ++ /* Expect the 8-bit case to always remove the alpha channel */ ++ if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && ++ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ png_error(png_ptr, "unexpected 8-bit transformation"); ++ ++ switch (png_ptr->interlaced) ++ { ++ case PNG_INTERLACE_NONE: ++ passes = 1; ++ break; ++ ++ case PNG_INTERLACE_ADAM7: ++ passes = PNG_INTERLACE_ADAM7_PASSES; ++ break; ++ ++ default: ++ png_error(png_ptr, "unknown interlace type"); ++ } ++ ++ /* Use direct access to info_ptr here because otherwise the simplified API ++ * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is ++ * checking the value after libpng expansions, not the original value in the ++ * PNG. ++ */ ++ switch (info_ptr->bit_depth) ++ { ++ default: ++ png_error(png_ptr, "unexpected bit depth"); ++ break; ++ ++ case 8: ++ /* 8-bit sRGB gray values with an alpha channel; the alpha channel is ++ * to be removed by composing on a background: either the row if ++ * display->background is NULL or display->background->green if not. ++ * Unlike the code above ALPHA_OPTIMIZED has *not* been done. ++ */ ++ { ++ png_bytep first_row = png_voidcast(png_bytep, display->first_row); ++ ptrdiff_t step_row = display->row_bytes; ++ ++ for (pass = 0; pass < passes; ++pass) ++ { ++ png_bytep row = png_voidcast(png_bytep, ++ display->first_row); ++ unsigned int startx, stepx, stepy; ++ png_uint_32 y; ++ ++ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) ++ { ++ /* The row may be empty for a short image: */ ++ if (PNG_PASS_COLS(width, pass) == 0) ++ continue; ++ ++ startx = PNG_PASS_START_COL(pass); ++ stepx = PNG_PASS_COL_OFFSET(pass); ++ y = PNG_PASS_START_ROW(pass); ++ stepy = PNG_PASS_ROW_OFFSET(pass); ++ } ++ ++ else ++ { ++ y = 0; ++ startx = 0; ++ stepx = stepy = 1; ++ } ++ ++ if (display->background == NULL) ++ { ++ for (; y<height; y += stepy) ++ { ++ png_bytep inrow = png_voidcast(png_bytep, ++ display->local_row); ++ png_bytep outrow = first_row + y * step_row; ++ png_const_bytep end_row = outrow + width; ++ ++ /* Read the row, which is packed: */ ++ png_read_row(png_ptr, inrow, NULL); ++ ++ /* Now do the composition on each pixel in this row. */ ++ outrow += startx; ++ for (; outrow < end_row; outrow += stepx) ++ { ++ png_byte alpha = inrow[1]; ++ ++ if (alpha > 0) /* else no change to the output */ ++ { ++ png_uint_32 component = inrow[0]; ++ ++ if (alpha < 255) /* else just use component */ ++ { ++ /* Since PNG_OPTIMIZED_ALPHA was not set it is ++ * necessary to invert the sRGB transfer ++ * function and multiply the alpha out. ++ */ ++ component = png_sRGB_table[component] * alpha; ++ component += png_sRGB_table[outrow[0]] * ++ (255-alpha); ++ component = PNG_sRGB_FROM_LINEAR(component); ++ } ++ ++ outrow[0] = (png_byte)component; ++ } ++ ++ inrow += 2; /* gray and alpha channel */ ++ } ++ } ++ } ++ ++ else /* constant background value */ ++ { ++ png_byte background8 = display->background->green; ++ png_uint_16 background = png_sRGB_table[background8]; ++ ++ for (; y<height; y += stepy) ++ { ++ png_bytep inrow = png_voidcast(png_bytep, ++ display->local_row); ++ png_bytep outrow = first_row + y * step_row; ++ png_const_bytep end_row = outrow + width; ++ ++ /* Read the row, which is packed: */ ++ png_read_row(png_ptr, inrow, NULL); ++ ++ /* Now do the composition on each pixel in this row. */ ++ outrow += startx; ++ for (; outrow < end_row; outrow += stepx) ++ { ++ png_byte alpha = inrow[1]; ++ ++ if (alpha > 0) /* else use background */ ++ { ++ png_uint_32 component = inrow[0]; ++ ++ if (alpha < 255) /* else just use component */ ++ { ++ component = png_sRGB_table[component] * alpha; ++ component += background * (255-alpha); ++ component = PNG_sRGB_FROM_LINEAR(component); ++ } ++ ++ outrow[0] = (png_byte)component; ++ } ++ ++ else ++ outrow[0] = background8; ++ ++ inrow += 2; /* gray and alpha channel */ ++ } ++ ++ row += display->row_bytes; ++ } ++ } ++ } ++ } ++ break; ++ ++ case 16: ++ /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must ++ * still be done and, maybe, the alpha channel removed. This code also ++ * handles the alpha-first option. ++ */ ++ { ++ png_uint_16p first_row = png_voidcast(png_uint_16p, ++ display->first_row); ++ /* The division by two is safe because the caller passed in a ++ * stride which was multiplied by 2 (below) to get row_bytes. ++ */ ++ ptrdiff_t step_row = display->row_bytes / 2; ++ int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; ++ unsigned int outchannels = 1+preserve_alpha; ++ int swap_alpha = 0; ++ ++# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED ++ if (preserve_alpha != 0 && ++ (image->format & PNG_FORMAT_FLAG_AFIRST) != 0) ++ swap_alpha = 1; ++# endif ++ ++ for (pass = 0; pass < passes; ++pass) ++ { ++ unsigned int startx, stepx, stepy; ++ png_uint_32 y; ++ ++ /* The 'x' start and step are adjusted to output components here. ++ */ ++ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) ++ { ++ /* The row may be empty for a short image: */ ++ if (PNG_PASS_COLS(width, pass) == 0) ++ continue; ++ ++ startx = PNG_PASS_START_COL(pass) * outchannels; ++ stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; ++ y = PNG_PASS_START_ROW(pass); ++ stepy = PNG_PASS_ROW_OFFSET(pass); ++ } ++ ++ else ++ { ++ y = 0; ++ startx = 0; ++ stepx = outchannels; ++ stepy = 1; ++ } ++ ++ for (; y<height; y += stepy) ++ { ++ png_const_uint_16p inrow; ++ png_uint_16p outrow = first_row + y*step_row; ++ png_uint_16p end_row = outrow + width * outchannels; ++ ++ /* Read the row, which is packed: */ ++ png_read_row(png_ptr, png_voidcast(png_bytep, ++ display->local_row), NULL); ++ inrow = png_voidcast(png_const_uint_16p, display->local_row); ++ ++ /* Now do the pre-multiplication on each pixel in this row. ++ */ ++ outrow += startx; ++ for (; outrow < end_row; outrow += stepx) ++ { ++ png_uint_32 component = inrow[0]; ++ png_uint_16 alpha = inrow[1]; ++ ++ if (alpha > 0) /* else 0 */ ++ { ++ if (alpha < 65535) /* else just use component */ ++ { ++ component *= alpha; ++ component += 32767; ++ component /= 65535; ++ } ++ } ++ ++ else ++ component = 0; ++ ++ outrow[swap_alpha] = (png_uint_16)component; ++ if (preserve_alpha != 0) ++ outrow[1 ^ swap_alpha] = alpha; ++ ++ inrow += 2; /* components and alpha channel */ ++ } ++ } ++ } ++ } ++ break; ++ } ++ ++ return 1; ++} ++ ++/* The guts of png_image_finish_read as a png_safe_execute callback. */ ++static int ++png_image_read_direct(png_voidp argument) ++{ ++ png_image_read_control *display = png_voidcast(png_image_read_control*, ++ argument); ++ png_imagep image = display->image; ++ png_structrp png_ptr = image->opaque->png_ptr; ++ png_inforp info_ptr = image->opaque->info_ptr; ++ ++ png_uint_32 format = image->format; ++ int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; ++ int do_local_compose = 0; ++ int do_local_background = 0; /* to avoid double gamma correction bug */ ++ int passes = 0; ++ ++ /* Add transforms to ensure the correct output format is produced then check ++ * that the required implementation support is there. Always expand; always ++ * need 8 bits minimum, no palette and expanded tRNS. ++ */ ++ png_set_expand(png_ptr); ++ ++ /* Now check the format to see if it was modified. */ ++ { ++ png_uint_32 base_format = png_image_format(png_ptr) & ++ ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; ++ png_uint_32 change = format ^ base_format; ++ png_fixed_point output_gamma; ++ int mode; /* alpha mode */ ++ ++ /* Do this first so that we have a record if rgb to gray is happening. */ ++ if ((change & PNG_FORMAT_FLAG_COLOR) != 0) ++ { ++ /* gray<->color transformation required. */ ++ if ((format & PNG_FORMAT_FLAG_COLOR) != 0) ++ png_set_gray_to_rgb(png_ptr); ++ ++ else ++ { ++ /* libpng can't do both rgb to gray and ++ * background/pre-multiplication if there is also significant gamma ++ * correction, because both operations require linear colors and ++ * the code only supports one transform doing the gamma correction. ++ * Handle this by doing the pre-multiplication or background ++ * operation in this code, if necessary. ++ * ++ * TODO: fix this by rewriting pngrtran.c (!) ++ * ++ * For the moment (given that fixing this in pngrtran.c is an ++ * enormous change) 'do_local_background' is used to indicate that ++ * the problem exists. ++ */ ++ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ do_local_background = 1/*maybe*/; ++ ++ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, ++ PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); ++ } ++ ++ change &= ~PNG_FORMAT_FLAG_COLOR; ++ } ++ ++ /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. ++ */ ++ { ++ png_fixed_point input_gamma_default; ++ ++ if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && ++ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) ++ input_gamma_default = PNG_GAMMA_LINEAR; ++ else ++ input_gamma_default = PNG_DEFAULT_sRGB; ++ ++ /* Call png_set_alpha_mode to set the default for the input gamma; the ++ * output gamma is set by a second call below. ++ */ ++ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); ++ } ++ ++ if (linear != 0) ++ { ++ /* If there *is* an alpha channel in the input it must be multiplied ++ * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. ++ */ ++ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ mode = PNG_ALPHA_STANDARD; /* associated alpha */ ++ ++ else ++ mode = PNG_ALPHA_PNG; ++ ++ output_gamma = PNG_GAMMA_LINEAR; ++ } ++ ++ else ++ { ++ mode = PNG_ALPHA_PNG; ++ output_gamma = PNG_DEFAULT_sRGB; ++ } ++ ++ /* If 'do_local_background' is set check for the presence of gamma ++ * correction; this is part of the work-round for the libpng bug ++ * described above. ++ * ++ * TODO: fix libpng and remove this. ++ */ ++ if (do_local_background != 0) ++ { ++ png_fixed_point gtest; ++ ++ /* This is 'png_gamma_threshold' from pngrtran.c; the test used for ++ * gamma correction, the screen gamma hasn't been set on png_struct ++ * yet; it's set below. png_struct::gamma, however, is set to the ++ * final value. ++ */ ++ if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, ++ PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) ++ do_local_background = 0; ++ ++ else if (mode == PNG_ALPHA_STANDARD) ++ { ++ do_local_background = 2/*required*/; ++ mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ ++ } ++ ++ /* else leave as 1 for the checks below */ ++ } ++ ++ /* If the bit-depth changes then handle that here. */ ++ if ((change & PNG_FORMAT_FLAG_LINEAR) != 0) ++ { ++ if (linear != 0 /*16-bit output*/) ++ png_set_expand_16(png_ptr); ++ ++ else /* 8-bit output */ ++ png_set_scale_16(png_ptr); ++ ++ change &= ~PNG_FORMAT_FLAG_LINEAR; ++ } ++ ++ /* Now the background/alpha channel changes. */ ++ if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++ /* Removing an alpha channel requires composition for the 8-bit ++ * formats; for the 16-bit it is already done, above, by the ++ * pre-multiplication and the channel just needs to be stripped. ++ */ ++ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++ /* If RGB->gray is happening the alpha channel must be left and the ++ * operation completed locally. ++ * ++ * TODO: fix libpng and remove this. ++ */ ++ if (do_local_background != 0) ++ do_local_background = 2/*required*/; ++ ++ /* 16-bit output: just remove the channel */ ++ else if (linear != 0) /* compose on black (well, pre-multiply) */ ++ png_set_strip_alpha(png_ptr); ++ ++ /* 8-bit output: do an appropriate compose */ ++ else if (display->background != NULL) ++ { ++ png_color_16 c; ++ ++ c.index = 0; /*unused*/ ++ c.red = display->background->red; ++ c.green = display->background->green; ++ c.blue = display->background->blue; ++ c.gray = display->background->green; ++ ++ /* This is always an 8-bit sRGB value, using the 'green' channel ++ * for gray is much better than calculating the luminance here; ++ * we can get off-by-one errors in that calculation relative to ++ * the app expectations and that will show up in transparent ++ * pixels. ++ */ ++ png_set_background_fixed(png_ptr, &c, ++ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, ++ 0/*gamma: not used*/); ++ } ++ ++ else /* compose on row: implemented below. */ ++ { ++ do_local_compose = 1; ++ /* This leaves the alpha channel in the output, so it has to be ++ * removed by the code below. Set the encoding to the 'OPTIMIZE' ++ * one so the code only has to hack on the pixels that require ++ * composition. ++ */ ++ mode = PNG_ALPHA_OPTIMIZED; ++ } ++ } ++ ++ else /* output needs an alpha channel */ ++ { ++ /* This is tricky because it happens before the swap operation has ++ * been accomplished; however, the swap does *not* swap the added ++ * alpha channel (weird API), so it must be added in the correct ++ * place. ++ */ ++ png_uint_32 filler; /* opaque filler */ ++ int where; ++ ++ if (linear != 0) ++ filler = 65535; ++ ++ else ++ filler = 255; ++ ++# ifdef PNG_FORMAT_AFIRST_SUPPORTED ++ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) ++ { ++ where = PNG_FILLER_BEFORE; ++ change &= ~PNG_FORMAT_FLAG_AFIRST; ++ } ++ ++ else ++# endif ++ where = PNG_FILLER_AFTER; ++ ++ png_set_add_alpha(png_ptr, filler, where); ++ } ++ ++ /* This stops the (irrelevant) call to swap_alpha below. */ ++ change &= ~PNG_FORMAT_FLAG_ALPHA; ++ } ++ ++ /* Now set the alpha mode correctly; this is always done, even if there is ++ * no alpha channel in either the input or the output because it correctly ++ * sets the output gamma. ++ */ ++ png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); ++ ++# ifdef PNG_FORMAT_BGR_SUPPORTED ++ if ((change & PNG_FORMAT_FLAG_BGR) != 0) ++ { ++ /* Check only the output format; PNG is never BGR; don't do this if ++ * the output is gray, but fix up the 'format' value in that case. ++ */ ++ if ((format & PNG_FORMAT_FLAG_COLOR) != 0) ++ png_set_bgr(png_ptr); ++ ++ else ++ format &= ~PNG_FORMAT_FLAG_BGR; ++ ++ change &= ~PNG_FORMAT_FLAG_BGR; ++ } ++# endif ++ ++# ifdef PNG_FORMAT_AFIRST_SUPPORTED ++ if ((change & PNG_FORMAT_FLAG_AFIRST) != 0) ++ { ++ /* Only relevant if there is an alpha channel - it's particularly ++ * important to handle this correctly because do_local_compose may ++ * be set above and then libpng will keep the alpha channel for this ++ * code to remove. ++ */ ++ if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++ /* Disable this if doing a local background, ++ * TODO: remove this when local background is no longer required. ++ */ ++ if (do_local_background != 2) ++ png_set_swap_alpha(png_ptr); ++ } ++ ++ else ++ format &= ~PNG_FORMAT_FLAG_AFIRST; ++ ++ change &= ~PNG_FORMAT_FLAG_AFIRST; ++ } ++# endif ++ ++ /* If the *output* is 16-bit then we need to check for a byte-swap on this ++ * architecture. ++ */ ++ if (linear != 0) ++ { ++ PNG_CONST png_uint_16 le = 0x0001; ++ ++ if ((*(png_const_bytep) & le) != 0) ++ png_set_swap(png_ptr); ++ } ++ ++ /* If change is not now 0 some transformation is missing - error out. */ ++ if (change != 0) ++ png_error(png_ptr, "png_read_image: unsupported transformation"); ++ } ++ ++ PNG_SKIP_CHUNKS(png_ptr); ++ ++ /* Update the 'info' structure and make sure the result is as required; first ++ * make sure to turn on the interlace handling if it will be required ++ * (because it can't be turned on *after* the call to png_read_update_info!) ++ * ++ * TODO: remove the do_local_background fixup below. ++ */ ++ if (do_local_compose == 0 && do_local_background != 2) ++ passes = png_set_interlace_handling(png_ptr); ++ ++ png_read_update_info(png_ptr, info_ptr); ++ ++ { ++ png_uint_32 info_format = 0; ++ ++ if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) ++ info_format |= PNG_FORMAT_FLAG_COLOR; ++ ++ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) ++ { ++ /* do_local_compose removes this channel below. */ ++ if (do_local_compose == 0) ++ { ++ /* do_local_background does the same if required. */ ++ if (do_local_background != 2 || ++ (format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ info_format |= PNG_FORMAT_FLAG_ALPHA; ++ } ++ } ++ ++ else if (do_local_compose != 0) /* internal error */ ++ png_error(png_ptr, "png_image_read: alpha channel lost"); ++ ++ if (info_ptr->bit_depth == 16) ++ info_format |= PNG_FORMAT_FLAG_LINEAR; ++ ++# ifdef PNG_FORMAT_BGR_SUPPORTED ++ if ((png_ptr->transformations & PNG_BGR) != 0) ++ info_format |= PNG_FORMAT_FLAG_BGR; ++# endif ++ ++# ifdef PNG_FORMAT_AFIRST_SUPPORTED ++ if (do_local_background == 2) ++ { ++ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) ++ info_format |= PNG_FORMAT_FLAG_AFIRST; ++ } ++ ++ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || ++ ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && ++ (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) ++ { ++ if (do_local_background == 2) ++ png_error(png_ptr, "unexpected alpha swap transformation"); ++ ++ info_format |= PNG_FORMAT_FLAG_AFIRST; ++ } ++# endif ++ ++ /* This is actually an internal error. */ ++ if (info_format != format) ++ png_error(png_ptr, "png_read_image: invalid transformations"); ++ } ++ ++ /* Now read the rows. If do_local_compose is set then it is necessary to use ++ * a local row buffer. The output will be GA, RGBA or BGRA and must be ++ * converted to G, RGB or BGR as appropriate. The 'local_row' member of the ++ * display acts as a flag. ++ */ ++ { ++ png_voidp first_row = display->buffer; ++ ptrdiff_t row_bytes = display->row_stride; ++ ++ if (linear != 0) ++ row_bytes *= 2; ++ ++ /* The following expression is designed to work correctly whether it gives ++ * a signed or an unsigned result. ++ */ ++ if (row_bytes < 0) ++ { ++ char *ptr = png_voidcast(char*, first_row); ++ ptr += (image->height-1) * (-row_bytes); ++ first_row = png_voidcast(png_voidp, ptr); ++ } ++ ++ display->first_row = first_row; ++ display->row_bytes = row_bytes; ++ } ++ ++ if (do_local_compose != 0) ++ { ++ int result; ++ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); ++ ++ display->local_row = row; ++ result = png_safe_execute(image, png_image_read_composite, display); ++ display->local_row = NULL; ++ png_free(png_ptr, row); ++ ++ return result; ++ } ++ ++ else if (do_local_background == 2) ++ { ++ int result; ++ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); ++ ++ display->local_row = row; ++ result = png_safe_execute(image, png_image_read_background, display); ++ display->local_row = NULL; ++ png_free(png_ptr, row); ++ ++ return result; ++ } ++ ++ else ++ { ++ png_alloc_size_t row_bytes = display->row_bytes; ++ ++ while (--passes >= 0) ++ { ++ png_uint_32 y = image->height; ++ png_bytep row = png_voidcast(png_bytep, display->first_row); ++ ++ while (y-- > 0) ++ { ++ png_read_row(png_ptr, row, NULL); ++ row += row_bytes; ++ } ++ } ++ ++ return 1; ++ } ++} ++ ++int PNGAPI ++png_image_finish_read(png_imagep image, png_const_colorp background, ++ void *buffer, png_int_32 row_stride, void *colormap) ++{ ++ if (image != NULL && image->version == PNG_IMAGE_VERSION) ++ { ++ png_uint_32 check; ++ ++ if (row_stride == 0) ++ row_stride = PNG_IMAGE_ROW_STRIDE(*image); ++ ++ if (row_stride < 0) ++ check = -row_stride; ++ ++ else ++ check = row_stride; ++ ++ if (image->opaque != NULL && buffer != NULL && ++ check >= PNG_IMAGE_ROW_STRIDE(*image)) ++ { ++ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || ++ (image->colormap_entries > 0 && colormap != NULL)) ++ { ++ int result; ++ png_image_read_control display; ++ ++ memset(&display, 0, (sizeof display)); ++ display.image = image; ++ display.buffer = buffer; ++ display.row_stride = row_stride; ++ display.colormap = colormap; ++ display.background = background; ++ display.local_row = NULL; ++ ++ /* Choose the correct 'end' routine; for the color-map case all the ++ * setup has already been done. ++ */ ++ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) ++ result = ++ png_safe_execute(image, png_image_read_colormap, &display) && ++ png_safe_execute(image, png_image_read_colormapped, &display); ++ ++ else ++ result = ++ png_safe_execute(image, png_image_read_direct, &display); ++ ++ png_image_free(image); ++ return result; ++ } ++ ++ else ++ return png_image_error(image, ++ "png_image_finish_read[color-map]: no color-map"); ++ } ++ ++ else ++ return png_image_error(image, ++ "png_image_finish_read: invalid argument"); ++ } ++ ++ else if (image != NULL) ++ return png_image_error(image, ++ "png_image_finish_read: damaged PNG_IMAGE_VERSION"); ++ ++ return 0; ++} ++ ++#endif /* SIMPLIFIED_READ */ ++#endif /* READ */ +--- ./jdk/src/share/native/sun/awt/libpng/pngrio.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngrio.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.0 [January 6, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -57,7 +57,7 @@ + * to read more then 64K on a 16 bit machine. + */ + void /* PRIVATE */ +-png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) ++png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length) + { + png_debug1(4, "reading %d bytes", (int)length); + +@@ -74,7 +74,6 @@ + * read_data function and use it at run time with png_set_read_fn(), rather + * than changing the library. + */ +-# ifndef USE_FAR_KEYWORD + void PNGCBAPI + png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) + { +@@ -86,68 +85,11 @@ + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ +- check = fread(data, 1, length, (png_FILE_p)png_ptr->io_ptr); ++ check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); + + if (check != length) + png_error(png_ptr, "Read Error"); + } +-# else +-/* This is the model-independent version. Since the standard I/O library +- can't handle far buffers in the medium and small models, we have to copy +- the data. +-*/ +- +-#define NEAR_BUF_SIZE 1024 +-#define MIN(a,b) (a <= b ? a : b) +- +-static void PNGCBAPI +-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +-{ +- png_size_t check; +- png_byte *n_data; +- png_FILE_p io_ptr; +- +- if (png_ptr == NULL) +- return; +- +- /* Check if data really is near. If so, use usual code. */ +- n_data = (png_byte *)CVT_PTR_NOCHECK(data); +- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); +- +- if ((png_bytep)n_data == data) +- { +- check = fread(n_data, 1, length, io_ptr); +- } +- +- else +- { +- png_byte buf[NEAR_BUF_SIZE]; +- png_size_t read, remaining, err; +- check = 0; +- remaining = length; +- +- do +- { +- read = MIN(NEAR_BUF_SIZE, remaining); +- err = fread(buf, 1, read, io_ptr); +- png_memcpy(data, buf, read); /* copy far buffer to near buffer */ +- +- if (err != read) +- break; +- +- else +- check += err; +- +- data += read; +- remaining -= read; +- } +- while (remaining != 0); +- } +- +- if ((png_uint_32)check != (png_uint_32)length) +- png_error(png_ptr, "read Error"); +-} +-# endif + #endif + + /* This function allows the application to supply a new input function +@@ -170,7 +112,7 @@ + * be used. + */ + void PNGAPI +-png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, ++png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn) + { + if (png_ptr == NULL) +@@ -188,6 +130,7 @@ + png_ptr->read_data_fn = read_data_fn; + #endif + ++#ifdef PNG_WRITE_SUPPORTED + /* It is an error to write to a read device */ + if (png_ptr->write_data_fn != NULL) + { +@@ -196,9 +139,10 @@ + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } ++#endif + + #ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = NULL; + #endif + } +-#endif /* PNG_READ_SUPPORTED */ ++#endif /* READ */ +--- ./jdk/src/share/native/sun/awt/libpng/pngrtran.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngrtran.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -50,7 +50,7 @@ + + /* Set the action on getting a CRC error for an ancillary or critical chunk. */ + void PNGAPI +-png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) ++png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) + { + png_debug(1, "in png_set_crc_action"); + +@@ -116,16 +116,47 @@ + } + } + ++#ifdef PNG_READ_TRANSFORMS_SUPPORTED ++/* Is it OK to set a transformation now? Only if png_start_read_image or ++ * png_read_update_info have not been called. It is not necessary for the IHDR ++ * to have been read in all cases; the need_IHDR parameter allows for this ++ * check too. ++ */ ++static int ++png_rtran_ok(png_structrp png_ptr, int need_IHDR) ++{ ++ if (png_ptr != NULL) ++ { ++ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) ++ png_app_error(png_ptr, ++ "invalid after png_start_read_image or png_read_update_info"); ++ ++ else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_app_error(png_ptr, "invalid before the PNG header has been read"); ++ ++ else ++ { ++ /* Turn on failure to initialize correctly for all transforms. */ ++ png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; ++ ++ return 1; /* Ok */ ++ } ++ } ++ ++ return 0; /* no png_error possible! */ ++} ++#endif ++ + #ifdef PNG_READ_BACKGROUND_SUPPORTED + /* Handle alpha and tRNS via a background color */ + void PNGFAPI +-png_set_background_fixed(png_structp png_ptr, ++png_set_background_fixed(png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma) + { + png_debug(1, "in png_set_background_fixed"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL) + return; + + if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) +@@ -138,11 +169,10 @@ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + +- png_memcpy(&(png_ptr->background), background_color, +- png_sizeof(png_color_16)); ++ png_ptr->background = *background_color; + png_ptr->background_gamma = background_gamma; + png_ptr->background_gamma_type = (png_byte)(background_gamma_code); +- if (need_expand) ++ if (need_expand != 0) + png_ptr->transformations |= PNG_BACKGROUND_EXPAND; + else + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; +@@ -150,7 +180,7 @@ + + # ifdef PNG_FLOATING_POINT_SUPPORTED + void PNGAPI +-png_set_background(png_structp png_ptr, ++png_set_background(png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) + { +@@ -166,11 +196,11 @@ + */ + #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + void PNGAPI +-png_set_scale_16(png_structp png_ptr) ++png_set_scale_16(png_structrp png_ptr) + { + png_debug(1, "in png_set_scale_16"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_SCALE_16_TO_8; +@@ -180,11 +210,11 @@ + #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* Chop 16-bit depth files to 8-bit depth */ + void PNGAPI +-png_set_strip_16(png_structp png_ptr) ++png_set_strip_16(png_structrp png_ptr) + { + png_debug(1, "in png_set_strip_16"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_16_TO_8; +@@ -193,11 +223,11 @@ + + #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + void PNGAPI +-png_set_strip_alpha(png_structp png_ptr) ++png_set_strip_alpha(png_structrp png_ptr) + { + png_debug(1, "in png_set_strip_alpha"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_STRIP_ALPHA; +@@ -206,7 +236,7 @@ + + #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) + static png_fixed_point +-translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, ++translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, + int is_screen) + { + /* Check for flag values. The main reason for having the old Mac value as a +@@ -222,8 +252,10 @@ + */ + # ifdef PNG_READ_sRGB_SUPPORTED + png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; ++# else ++ PNG_UNUSED(png_ptr) + # endif +- if (is_screen) ++ if (is_screen != 0) + output_gamma = PNG_GAMMA_sRGB; + else + output_gamma = PNG_GAMMA_sRGB_INVERSE; +@@ -232,7 +264,7 @@ + else if (output_gamma == PNG_GAMMA_MAC_18 || + output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) + { +- if (is_screen) ++ if (is_screen != 0) + output_gamma = PNG_GAMMA_MAC_OLD; + else + output_gamma = PNG_GAMMA_MAC_INVERSE; +@@ -243,7 +275,7 @@ + + # ifdef PNG_FLOATING_POINT_SUPPORTED + static png_fixed_point +-convert_gamma_value(png_structp png_ptr, double output_gamma) ++convert_gamma_value(png_structrp png_ptr, double output_gamma) + { + /* The following silently ignores cases where fixed point (times 100,000) + * gamma values are passed to the floating point API. This is safe and it +@@ -268,7 +300,7 @@ + + #ifdef PNG_READ_ALPHA_MODE_SUPPORTED + void PNGFAPI +-png_set_alpha_mode_fixed(png_structp png_ptr, int mode, ++png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, + png_fixed_point output_gamma) + { + int compose = 0; +@@ -276,7 +308,7 @@ + + png_debug(1, "in png_set_alpha_mode"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); +@@ -348,8 +380,11 @@ + * the side effect that the gamma in a second call to png_set_alpha_mode will + * be ignored.) + */ +- if (png_ptr->gamma == 0) +- png_ptr->gamma = file_gamma; ++ if (png_ptr->colorspace.gamma == 0) ++ { ++ png_ptr->colorspace.gamma = file_gamma; ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; ++ } + + /* But always set the output gamma: */ + png_ptr->screen_gamma = output_gamma; +@@ -357,28 +392,25 @@ + /* Finally, if pre-multiplying, set the background fields to achieve the + * desired result. + */ +- if (compose) ++ if (compose != 0) + { + /* And obtain alpha pre-multiplication by composing on black: */ +- png_memset(&png_ptr->background, 0, sizeof png_ptr->background); +- png_ptr->background_gamma = png_ptr->gamma; /* just in case */ ++ memset(&png_ptr->background, 0, (sizeof png_ptr->background)); ++ png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; + +- if (png_ptr->transformations & PNG_COMPOSE) ++ if ((png_ptr->transformations & PNG_COMPOSE) != 0) + png_error(png_ptr, + "conflicting calls to set alpha mode and background"); + + png_ptr->transformations |= PNG_COMPOSE; + } +- +- /* New API, make sure apps call the correct initializers: */ +- png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; + } + + # ifdef PNG_FLOATING_POINT_SUPPORTED + void PNGAPI +-png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) ++png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) + { + png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, + output_gamma)); +@@ -398,31 +430,31 @@ + + typedef struct png_dsort_struct + { +- struct png_dsort_struct FAR * next; ++ struct png_dsort_struct * next; + png_byte left; + png_byte right; + } png_dsort; +-typedef png_dsort FAR * png_dsortp; +-typedef png_dsort FAR * FAR * png_dsortpp; ++typedef png_dsort * png_dsortp; ++typedef png_dsort * * png_dsortpp; + + void PNGAPI +-png_set_quantize(png_structp png_ptr, png_colorp palette, ++png_set_quantize(png_structrp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize) + { + png_debug(1, "in png_set_quantize"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_QUANTIZE; + +- if (!full_quantize) ++ if (full_quantize == 0) + { + int i; + + png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, +- (png_uint_32)(num_palette * png_sizeof(png_byte))); ++ (png_uint_32)(num_palette * (sizeof (png_byte)))); + for (i = 0; i < num_palette; i++) + png_ptr->quantize_index[i] = (png_byte)i; + } +@@ -439,7 +471,7 @@ + + /* Initialize an array to sort colors */ + png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, +- (png_uint_32)(num_palette * png_sizeof(png_byte))); ++ (png_uint_32)(num_palette * (sizeof (png_byte)))); + + /* Initialize the quantize_sort array */ + for (i = 0; i < num_palette; i++) +@@ -472,12 +504,12 @@ + } + } + +- if (done) ++ if (done != 0) + break; + } + + /* Swap the palette around, and set up a table, if necessary */ +- if (full_quantize) ++ if (full_quantize != 0) + { + int j = num_palette; + +@@ -573,9 +605,9 @@ + + /* Initialize palette index arrays */ + png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, +- (png_uint_32)(num_palette * png_sizeof(png_byte))); ++ (png_uint_32)(num_palette * (sizeof (png_byte)))); + png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, +- (png_uint_32)(num_palette * png_sizeof(png_byte))); ++ (png_uint_32)(num_palette * (sizeof (png_byte)))); + + /* Initialize the sort array */ + for (i = 0; i < num_palette; i++) +@@ -585,7 +617,7 @@ + } + + hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * +- png_sizeof(png_dsortp))); ++ (sizeof (png_dsortp)))); + + num_new_palette = num_palette; + +@@ -615,7 +647,7 @@ + { + + t = (png_dsortp)png_malloc_warn(png_ptr, +- (png_uint_32)(png_sizeof(png_dsort))); ++ (png_uint_32)(sizeof (png_dsort))); + + if (t == NULL) + break; +@@ -660,7 +692,7 @@ + num_new_palette--; + palette[png_ptr->index_to_palette[j]] + = palette[num_new_palette]; +- if (!full_quantize) ++ if (full_quantize == 0) + { + int k; + +@@ -728,7 +760,7 @@ + } + png_ptr->num_palette = (png_uint_16)num_palette; + +- if (full_quantize) ++ if (full_quantize != 0) + { + int i; + png_bytep distance; +@@ -740,12 +772,12 @@ + png_size_t num_entries = ((png_size_t)1 << total_bits); + + png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, +- (png_uint_32)(num_entries * png_sizeof(png_byte))); ++ (png_uint_32)(num_entries * (sizeof (png_byte)))); + + distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * +- png_sizeof(png_byte))); +- +- png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); ++ (sizeof (png_byte)))); ++ ++ memset(distance, 0xff, num_entries * (sizeof (png_byte))); + + for (i = 0; i < num_palette; i++) + { +@@ -790,23 +822,22 @@ + png_free(png_ptr, distance); + } + } +-#endif /* PNG_READ_QUANTIZE_SUPPORTED */ ++#endif /* READ_QUANTIZE */ + + #ifdef PNG_READ_GAMMA_SUPPORTED + void PNGFAPI +-png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, ++png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, + png_fixed_point file_gamma) + { + png_debug(1, "in png_set_gamma_fixed"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + /* New in libpng-1.5.4 - reserve particular negative values as flags. */ + scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); + file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); + +-#if PNG_LIBPNG_VER >= 10600 + /* Checking the gamma values for being >0 was added in 1.5.4 along with the + * premultiplied alpha support; this actually hides an undocumented feature + * of the previous implementation which allowed gamma processing to be +@@ -815,31 +846,32 @@ + * accept '0' for the gamma value it takes, because it isn't always used. + * + * Since this is an API change (albeit a very minor one that removes an +- * undocumented API feature) it will not be made until libpng-1.6.0. ++ * undocumented API feature) the following checks were only enabled in ++ * libpng-1.6.0. + */ + if (file_gamma <= 0) + png_error(png_ptr, "invalid file gamma in png_set_gamma"); + + if (scrn_gamma <= 0) + png_error(png_ptr, "invalid screen gamma in png_set_gamma"); +-#endif + + /* Set the gamma values unconditionally - this overrides the value in the PNG + * file if a gAMA chunk was present. png_set_alpha_mode provides a + * different, easier, way to default the file gamma. + */ +- png_ptr->gamma = file_gamma; ++ png_ptr->colorspace.gamma = file_gamma; ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + png_ptr->screen_gamma = scrn_gamma; + } + + # ifdef PNG_FLOATING_POINT_SUPPORTED + void PNGAPI +-png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) ++png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) + { + png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), + convert_gamma_value(png_ptr, file_gamma)); + } +-# endif /* FLOATING_POINT_SUPPORTED */ ++# endif /* FLOATING_POINT */ + #endif /* READ_GAMMA */ + + #ifdef PNG_READ_EXPAND_SUPPORTED +@@ -848,15 +880,14 @@ + * to alpha channels. + */ + void PNGAPI +-png_set_expand(png_structp png_ptr) ++png_set_expand(png_structrp png_ptr) + { + png_debug(1, "in png_set_expand"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + } + + /* GRR 19990627: the following three functions currently are identical +@@ -879,100 +910,95 @@ + + /* Expand paletted images to RGB. */ + void PNGAPI +-png_set_palette_to_rgb(png_structp png_ptr) ++png_set_palette_to_rgb(png_structrp png_ptr) + { + png_debug(1, "in png_set_palette_to_rgb"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + } + + /* Expand grayscale images of less than 8-bit depth to 8 bits. */ + void PNGAPI +-png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) ++png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) + { + png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_EXPAND; +- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + } + +- +- + /* Expand tRNS chunks to alpha channels. */ + void PNGAPI +-png_set_tRNS_to_alpha(png_structp png_ptr) ++png_set_tRNS_to_alpha(png_structrp png_ptr) + { + png_debug(1, "in png_set_tRNS_to_alpha"); + ++ if (png_rtran_ok(png_ptr, 0) == 0) ++ return; ++ + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; + } +-#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ ++#endif /* READ_EXPAND */ + + #ifdef PNG_READ_EXPAND_16_SUPPORTED + /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise + * it may not work correctly.) + */ + void PNGAPI +-png_set_expand_16(png_structp png_ptr) ++png_set_expand_16(png_structrp png_ptr) + { + png_debug(1, "in png_set_expand_16"); + +- if (png_ptr == NULL) ++ if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); +- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +- +- /* New API, make sure apps call the correct initializers: */ +- png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; + } + #endif + + #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + void PNGAPI +-png_set_gray_to_rgb(png_structp png_ptr) ++png_set_gray_to_rgb(png_structrp png_ptr) + { + png_debug(1, "in png_set_gray_to_rgb"); + +- if (png_ptr != NULL) +- { +- /* Because rgb must be 8 bits or more: */ +- png_set_expand_gray_1_2_4_to_8(png_ptr); +- png_ptr->transformations |= PNG_GRAY_TO_RGB; +- png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +- } ++ if (png_rtran_ok(png_ptr, 0) == 0) ++ return; ++ ++ /* Because rgb must be 8 bits or more: */ ++ png_set_expand_gray_1_2_4_to_8(png_ptr); ++ png_ptr->transformations |= PNG_GRAY_TO_RGB; + } + #endif + + #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + void PNGFAPI +-png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, ++png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, + png_fixed_point red, png_fixed_point green) + { + png_debug(1, "in png_set_rgb_to_gray"); + +- if (png_ptr == NULL) ++ /* Need the IHDR here because of the check on color_type below. */ ++ /* TODO: fix this */ ++ if (png_rtran_ok(png_ptr, 1) == 0) + return; + +- switch(error_action) ++ switch (error_action) + { +- case 1: ++ case PNG_ERROR_ACTION_NONE: + png_ptr->transformations |= PNG_RGB_TO_GRAY; + break; + +- case 2: ++ case PNG_ERROR_ACTION_WARN: + png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; + break; + +- case 3: ++ case PNG_ERROR_ACTION_ERROR: + png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; + break; + +@@ -980,15 +1006,19 @@ + png_error(png_ptr, "invalid error action to rgb_to_gray"); + break; + } ++ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + #ifdef PNG_READ_EXPAND_SUPPORTED + png_ptr->transformations |= PNG_EXPAND; + #else + { +- png_warning(png_ptr, ++ /* Make this an error in 1.6 because otherwise the application may assume ++ * that it just worked and get a memory overwrite. ++ */ ++ png_error(png_ptr, + "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); + +- png_ptr->transformations &= ~PNG_RGB_TO_GRAY; ++ /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ + } + #endif + { +@@ -996,32 +1026,37 @@ + { + png_uint_16 red_int, green_int; + +- red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); +- green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); ++ /* NOTE: this calculation does not round, but this behavior is retained ++ * for consistency; the inaccuracy is very small. The code here always ++ * overwrites the coefficients, regardless of whether they have been ++ * defaulted or set already. ++ */ ++ red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); ++ green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); + + png_ptr->rgb_to_gray_red_coeff = red_int; + png_ptr->rgb_to_gray_green_coeff = green_int; +- png_ptr->rgb_to_gray_blue_coeff = +- (png_uint_16)(32768 - red_int - green_int); ++ png_ptr->rgb_to_gray_coefficients_set = 1; + } + + else + { + if (red >= 0 && green >= 0) +- png_warning(png_ptr, ++ png_app_warning(png_ptr, + "ignoring out of range rgb_to_gray coefficients"); + +- /* Use the defaults, from the cHRM chunk if set, else the built in Rec +- * 709 values (which correspond to sRGB, so we don't have to worry +- * about the sRGB chunk!) ++ /* Use the defaults, from the cHRM chunk if set, else the historical ++ * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See ++ * png_do_rgb_to_gray for more discussion of the values. In this case ++ * the coefficients are not marked as 'set' and are not overwritten if ++ * something has already provided a default. + */ + if (png_ptr->rgb_to_gray_red_coeff == 0 && +- png_ptr->rgb_to_gray_green_coeff == 0 && +- png_ptr->rgb_to_gray_blue_coeff == 0) ++ png_ptr->rgb_to_gray_green_coeff == 0) + { +- png_ptr->rgb_to_gray_red_coeff = 6968; /* .212671 * 32768 + .5 */ +- png_ptr->rgb_to_gray_green_coeff = 23434; /* .715160 * 32768 + .5 */ +- png_ptr->rgb_to_gray_blue_coeff = 2366; ++ png_ptr->rgb_to_gray_red_coeff = 6968; ++ png_ptr->rgb_to_gray_green_coeff = 23434; ++ /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ + } + } + } +@@ -1033,31 +1068,25 @@ + */ + + void PNGAPI +-png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, ++png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, + double green) + { +- if (png_ptr == NULL) +- return; +- + png_set_rgb_to_gray_fixed(png_ptr, error_action, + png_fixed(png_ptr, red, "rgb to gray red coefficient"), + png_fixed(png_ptr, green, "rgb to gray green coefficient")); + } + #endif /* FLOATING POINT */ + +-#endif ++#endif /* RGB_TO_GRAY */ + + #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + void PNGAPI +-png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr ++png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr + read_user_transform_fn) + { + png_debug(1, "in png_set_read_user_transform_fn"); + +- if (png_ptr == NULL) +- return; +- + #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->read_user_transform_fn = read_user_transform_fn; +@@ -1091,13 +1120,13 @@ + * the palette. + */ + +-/*For the moment 'png_init_palette_transformations' and ++/* For the moment 'png_init_palette_transformations' and + * 'png_init_rgb_transformations' only do some flag canceling optimizations. + * The intent is that these two routines should have palette or rgb operations + * extracted from 'png_init_read_transformations'. + */ + static void /* PRIVATE */ +-png_init_palette_transformations(png_structp png_ptr) ++png_init_palette_transformations(png_structrp png_ptr) + { + /* Called to handle the (input) palette case. In png_do_read_transformations + * the first step is to expand the palette if requested, so this code must +@@ -1116,25 +1145,31 @@ + + /* Ignore if all the entries are opaque (unlikely!) */ + for (i=0; i<png_ptr->num_trans; ++i) ++ { + if (png_ptr->trans_alpha[i] == 255) + continue; + else if (png_ptr->trans_alpha[i] == 0) + input_has_transparency = 1; + else ++ { ++ input_has_transparency = 1; + input_has_alpha = 1; ++ break; ++ } ++ } + } + + /* If no alpha we can optimize. */ +- if (!input_has_alpha) ++ if (input_has_alpha == 0) + { + /* Any alpha means background and associative alpha processing is +- * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA ++ * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + +- if (!input_has_transparency) ++ if (input_has_transparency == 0) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +@@ -1147,8 +1182,8 @@ + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ +- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && +- (png_ptr->transformations & PNG_EXPAND)) ++ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && ++ (png_ptr->transformations & PNG_EXPAND) != 0) + { + { + png_ptr->background.red = +@@ -1159,9 +1194,9 @@ + png_ptr->palette[png_ptr->background.index].blue; + + #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +- if (png_ptr->transformations & PNG_INVERT_ALPHA) ++ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + { +- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) ++ if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) + { + /* Invert the alpha channel (in tRNS) unless the pixels are + * going to be expanded, in which case leave it for later +@@ -1173,14 +1208,14 @@ + png_ptr->trans_alpha[i]); + } + } +-#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ ++#endif /* READ_INVERT_ALPHA */ + } + } /* background expand and (therefore) no alpha association. */ +-#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ ++#endif /* READ_EXPAND && READ_BACKGROUND */ + } + + static void /* PRIVATE */ +-png_init_rgb_transformations(png_structp png_ptr) ++png_init_rgb_transformations(png_structrp png_ptr) + { + /* Added to libpng-1.5.4: check the color type to determine whether there + * is any alpha or transparency in the image and simply cancel the +@@ -1190,10 +1225,10 @@ + int input_has_transparency = png_ptr->num_trans > 0; + + /* If no alpha we can optimize. */ +- if (!input_has_alpha) ++ if (input_has_alpha == 0) + { + /* Any alpha means background and associative alpha processing is +- * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA ++ * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ + # ifdef PNG_READ_ALPHA_MODE_SUPPORTED +@@ -1201,7 +1236,7 @@ + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + # endif + +- if (!input_has_transparency) ++ if (input_has_transparency == 0) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +@@ -1214,67 +1249,58 @@ + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ +- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && +- (png_ptr->transformations & PNG_EXPAND) && +- !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ++ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && ++ (png_ptr->transformations & PNG_EXPAND) != 0 && ++ (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + /* i.e., GRAY or GRAY_ALPHA */ + { + { + /* Expand background and tRNS chunks */ ++ int gray = png_ptr->background.gray; ++ int trans_gray = png_ptr->trans_color.gray; ++ + switch (png_ptr->bit_depth) + { + case 1: +- png_ptr->background.gray *= (png_uint_16)0xff; +- png_ptr->background.red = png_ptr->background.green +- = png_ptr->background.blue = png_ptr->background.gray; +- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) +- { +- png_ptr->trans_color.gray *= (png_uint_16)0xff; +- png_ptr->trans_color.red = png_ptr->trans_color.green +- = png_ptr->trans_color.blue = png_ptr->trans_color.gray; +- } ++ gray *= 0xff; ++ trans_gray *= 0xff; + break; + + case 2: +- png_ptr->background.gray *= (png_uint_16)0x55; +- png_ptr->background.red = png_ptr->background.green +- = png_ptr->background.blue = png_ptr->background.gray; +- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) +- { +- png_ptr->trans_color.gray *= (png_uint_16)0x55; +- png_ptr->trans_color.red = png_ptr->trans_color.green +- = png_ptr->trans_color.blue = png_ptr->trans_color.gray; +- } ++ gray *= 0x55; ++ trans_gray *= 0x55; + break; + + case 4: +- png_ptr->background.gray *= (png_uint_16)0x11; +- png_ptr->background.red = png_ptr->background.green +- = png_ptr->background.blue = png_ptr->background.gray; +- if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) +- { +- png_ptr->trans_color.gray *= (png_uint_16)0x11; +- png_ptr->trans_color.red = png_ptr->trans_color.green +- = png_ptr->trans_color.blue = png_ptr->trans_color.gray; +- } ++ gray *= 0x11; ++ trans_gray *= 0x11; + break; + + default: + + case 8: ++ /* FALL THROUGH (Already 8 bits) */ + + case 16: +- png_ptr->background.red = png_ptr->background.green +- = png_ptr->background.blue = png_ptr->background.gray; ++ /* Already a full 16 bits */ + break; + } ++ ++ png_ptr->background.red = png_ptr->background.green = ++ png_ptr->background.blue = (png_uint_16)gray; ++ ++ if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) ++ { ++ png_ptr->trans_color.red = png_ptr->trans_color.green = ++ png_ptr->trans_color.blue = (png_uint_16)trans_gray; ++ } + } + } /* background expand and (therefore) no alpha association. */ +-#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ ++#endif /* READ_EXPAND && READ_BACKGROUND */ + } + + void /* PRIVATE */ +-png_init_read_transformations(png_structp png_ptr) ++png_init_read_transformations(png_structrp png_ptr) + { + png_debug(1, "in png_init_read_transformations"); + +@@ -1299,17 +1325,17 @@ + */ + int gamma_correction = 0; + +- if (png_ptr->gamma != 0) /* has been set */ ++ if (png_ptr->colorspace.gamma != 0) /* has been set */ + { + if (png_ptr->screen_gamma != 0) /* screen set too */ +- gamma_correction = png_gamma_threshold(png_ptr->gamma, ++ gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, + png_ptr->screen_gamma); + + else + /* Assume the output matches the input; a long time default behavior + * of libpng, although the standard has nothing to say about this. + */ +- png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma); ++ png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); + } + + else if (png_ptr->screen_gamma != 0) +@@ -1318,7 +1344,7 @@ + * png_set_alpha_mode (even if the alpha handling mode isn't required + * or isn't changed from the default.) + */ +- png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma); ++ png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); + + else /* neither are set */ + /* Just in case the following prevents any processing - file and screen +@@ -1326,7 +1352,10 @@ + * third gamma value other than png_set_background with 'UNIQUE', and, + * prior to 1.5.4 + */ +- png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1; ++ png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; ++ ++ /* We have a gamma value now. */ ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + + /* Now turn the gamma transformation on or off as appropriate. Notice + * that PNG_GAMMA just refers to the file->screen correction. Alpha +@@ -1336,7 +1365,7 @@ + * the code immediately below if the transform can be handled outside the + * row loop. + */ +- if (gamma_correction) ++ if (gamma_correction != 0) + png_ptr->transformations |= PNG_GAMMA; + + else +@@ -1345,7 +1374,7 @@ + #endif + + /* Certain transformations have the effect of preventing other +- * transformations that happen afterward in png_do_read_transformations, ++ * transformations that happen afterward in png_do_read_transformations; + * resolve the interdependencies here. From the code of + * png_do_read_transformations the order is: + * +@@ -1363,19 +1392,19 @@ + * 12) PNG_EXPAND_16 + * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY + * 14) PNG_INVERT_MONO +- * 15) PNG_SHIFT +- * 16) PNG_PACK +- * 17) PNG_BGR +- * 18) PNG_PACKSWAP +- * 19) PNG_FILLER (includes PNG_ADD_ALPHA) +- * 20) PNG_INVERT_ALPHA ++ * 15) PNG_INVERT_ALPHA ++ * 16) PNG_SHIFT ++ * 17) PNG_PACK ++ * 18) PNG_BGR ++ * 19) PNG_PACKSWAP ++ * 20) PNG_FILLER (includes PNG_ADD_ALPHA) + * 21) PNG_SWAP_ALPHA + * 22) PNG_SWAP_BYTES + * 23) PNG_USER_TRANSFORM [must be last] + */ + #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +- if ((png_ptr->transformations & PNG_STRIP_ALPHA) && +- !(png_ptr->transformations & PNG_COMPOSE)) ++ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && ++ (png_ptr->transformations & PNG_COMPOSE) == 0) + { + /* Stripping the alpha channel happens immediately after the 'expand' + * transformations, before all other transformation, so it cancels out +@@ -1401,16 +1430,23 @@ + /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA + * settings will have no effect. + */ +- if (!png_gamma_significant(png_ptr->screen_gamma)) ++ if (png_gamma_significant(png_ptr->screen_gamma) == 0) + { + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + } + #endif + +-#if defined(PNG_READ_EXPAND_SUPPORTED) && \ +- defined(PNG_READ_BACKGROUND_SUPPORTED) && \ +- defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) ++#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED ++ /* Make sure the coefficients for the rgb to gray conversion are set ++ * appropriately. ++ */ ++ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) ++ png_colorspace_set_rgb_coefficients(png_ptr); ++#endif ++ ++#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED ++#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* Detect gray background and attempt to enable optimization for + * gray --> RGB case. + * +@@ -1426,23 +1462,23 @@ + * png_set_background, along with the bit depth, then the code has a record + * of exactly what color space the background is currently in. + */ +- if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) ++ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) + { + /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if +- * the file was greyscale the background value is gray. ++ * the file was grayscale the background value is gray. + */ +- if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ++ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + } + +- else if (png_ptr->transformations & PNG_COMPOSE) ++ else if ((png_ptr->transformations & PNG_COMPOSE) != 0) + { + /* PNG_COMPOSE: png_set_background was called with need_expand false, + * so the color is in the color space of the output or png_set_alpha_mode + * was called and the color is black. Ignore RGB_TO_GRAY because that + * happens before GRAY_TO_RGB. + */ +- if (png_ptr->transformations & PNG_GRAY_TO_RGB) ++ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) + { + if (png_ptr->background.red == png_ptr->background.green && + png_ptr->background.red == png_ptr->background.blue) +@@ -1452,7 +1488,8 @@ + } + } + } +-#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ ++#endif /* READ_EXPAND && READ_BACKGROUND */ ++#endif /* READ_GRAY_TO_RGB */ + + /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations + * can be performed directly on the palette, and some (such as rgb to gray) +@@ -1473,10 +1510,10 @@ + + #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_EXPAND_16_SUPPORTED) +- if ((png_ptr->transformations & PNG_EXPAND_16) && +- (png_ptr->transformations & PNG_COMPOSE) && +- !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && +- png_ptr->bit_depth != 16) ++ if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && ++ (png_ptr->transformations & PNG_COMPOSE) != 0 && ++ (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && ++ png_ptr->bit_depth != 16) + { + /* TODO: fix this. Because the expand_16 operation is after the compose + * handling the background color must be 8, not 16, bits deep, but the +@@ -1488,14 +1525,36 @@ + * NOTE: this discards the low 16 bits of the user supplied background + * color, but until expand_16 works properly there is no choice! + */ +-# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16)) ++# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) + CHOP(png_ptr->background.red); + CHOP(png_ptr->background.green); + CHOP(png_ptr->background.blue); + CHOP(png_ptr->background.gray); + # undef CHOP + } +-#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ ++#endif /* READ_BACKGROUND && READ_EXPAND_16 */ ++ ++#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ ++ (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ ++ defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) ++ if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && ++ (png_ptr->transformations & PNG_COMPOSE) != 0 && ++ (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && ++ png_ptr->bit_depth == 16) ++ { ++ /* On the other hand, if a 16-bit file is to be reduced to 8-bits per ++ * component this will also happen after PNG_COMPOSE and so the background ++ * color must be pre-expanded here. ++ * ++ * TODO: fix this too. ++ */ ++ png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); ++ png_ptr->background.green = ++ (png_uint_16)(png_ptr->background.green * 257); ++ png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); ++ png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); ++ } ++#endif + + /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the + * background support (see the comments in scripts/pnglibconf.dfa), this +@@ -1524,27 +1583,36 @@ + * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the + * tables. + */ +- if ((png_ptr->transformations & PNG_GAMMA) +- || ((png_ptr->transformations & PNG_RGB_TO_GRAY) +- && (png_gamma_significant(png_ptr->gamma) || +- png_gamma_significant(png_ptr->screen_gamma))) +- || ((png_ptr->transformations & PNG_COMPOSE) +- && (png_gamma_significant(png_ptr->gamma) +- || png_gamma_significant(png_ptr->screen_gamma) ++ if ((png_ptr->transformations & PNG_GAMMA) != 0 || ++ ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && ++ (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || ++ png_gamma_significant(png_ptr->screen_gamma) != 0)) || ++ ((png_ptr->transformations & PNG_COMPOSE) != 0 && ++ (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || ++ png_gamma_significant(png_ptr->screen_gamma) != 0 + # ifdef PNG_READ_BACKGROUND_SUPPORTED +- || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE +- && png_gamma_significant(png_ptr->background_gamma)) ++ || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && ++ png_gamma_significant(png_ptr->background_gamma) != 0) + # endif +- )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) +- && png_gamma_significant(png_ptr->screen_gamma)) +- ) ++ )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && ++ png_gamma_significant(png_ptr->screen_gamma) != 0)) + { + png_build_gamma_table(png_ptr, png_ptr->bit_depth); + + #ifdef PNG_READ_BACKGROUND_SUPPORTED +- if (png_ptr->transformations & PNG_COMPOSE) ++ if ((png_ptr->transformations & PNG_COMPOSE) != 0) + { +- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ++ /* Issue a warning about this combination: because RGB_TO_GRAY is ++ * optimized to do the gamma transform if present yet do_background has ++ * to do the same thing if both options are set a ++ * double-gamma-correction happens. This is true in all versions of ++ * libpng to date. ++ */ ++ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) ++ png_warning(png_ptr, ++ "libpng does not support gamma+background+rgb_to_gray"); ++ ++ if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) + { + /* We don't get to here unless there is a tRNS chunk with non-opaque + * entries - see the checking code at the start of this function. +@@ -1576,8 +1644,8 @@ + break; + + case PNG_BACKGROUND_GAMMA_FILE: +- g = png_reciprocal(png_ptr->gamma); +- gs = png_reciprocal2(png_ptr->gamma, ++ g = png_reciprocal(png_ptr->colorspace.gamma); ++ gs = png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma); + break; + +@@ -1592,7 +1660,7 @@ + break; + } + +- if (png_gamma_significant(gs)) ++ if (png_gamma_significant(gs) != 0) + { + back.red = png_gamma_8bit_correct(png_ptr->background.red, + gs); +@@ -1609,7 +1677,7 @@ + back.blue = (png_byte)png_ptr->background.blue; + } + +- if (png_gamma_significant(g)) ++ if (png_gamma_significant(g) != 0) + { + back_1.red = png_gamma_8bit_correct(png_ptr->background.red, + g); +@@ -1663,7 +1731,7 @@ + + /* Prevent the transformations being done again. + * +- * NOTE: this is highly dubious; it zaps the transformations in ++ * NOTE: this is highly dubious; it removes the transformations in + * place. This seems inconsistent with the general treatment of the + * transformations elsewhere. + */ +@@ -1673,8 +1741,9 @@ + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ + else /* color_type != PNG_COLOR_TYPE_PALETTE */ + { +- png_fixed_point g = PNG_FP_1; +- png_fixed_point gs = PNG_FP_1; ++ int gs_sig, g_sig; ++ png_fixed_point g = PNG_FP_1; /* Correction to linear */ ++ png_fixed_point gs = PNG_FP_1; /* Correction to screen */ + + switch (png_ptr->background_gamma_type) + { +@@ -1684,8 +1753,9 @@ + break; + + case PNG_BACKGROUND_GAMMA_FILE: +- g = png_reciprocal(png_ptr->gamma); +- gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); ++ g = png_reciprocal(png_ptr->colorspace.gamma); ++ gs = png_reciprocal2(png_ptr->colorspace.gamma, ++ png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: +@@ -1698,34 +1768,45 @@ + png_error(png_ptr, "invalid background gamma type"); + } + +- png_ptr->background_1.gray = png_gamma_correct(png_ptr, +- png_ptr->background.gray, g); +- +- png_ptr->background.gray = png_gamma_correct(png_ptr, +- png_ptr->background.gray, gs); ++ g_sig = png_gamma_significant(g); ++ gs_sig = png_gamma_significant(gs); ++ ++ if (g_sig != 0) ++ png_ptr->background_1.gray = png_gamma_correct(png_ptr, ++ png_ptr->background.gray, g); ++ ++ if (gs_sig != 0) ++ png_ptr->background.gray = png_gamma_correct(png_ptr, ++ png_ptr->background.gray, gs); + + if ((png_ptr->background.red != png_ptr->background.green) || + (png_ptr->background.red != png_ptr->background.blue) || + (png_ptr->background.red != png_ptr->background.gray)) + { + /* RGB or RGBA with color background */ +- png_ptr->background_1.red = png_gamma_correct(png_ptr, +- png_ptr->background.red, g); +- +- png_ptr->background_1.green = png_gamma_correct(png_ptr, +- png_ptr->background.green, g); +- +- png_ptr->background_1.blue = png_gamma_correct(png_ptr, +- png_ptr->background.blue, g); +- +- png_ptr->background.red = png_gamma_correct(png_ptr, +- png_ptr->background.red, gs); +- +- png_ptr->background.green = png_gamma_correct(png_ptr, +- png_ptr->background.green, gs); +- +- png_ptr->background.blue = png_gamma_correct(png_ptr, +- png_ptr->background.blue, gs); ++ if (g_sig != 0) ++ { ++ png_ptr->background_1.red = png_gamma_correct(png_ptr, ++ png_ptr->background.red, g); ++ ++ png_ptr->background_1.green = png_gamma_correct(png_ptr, ++ png_ptr->background.green, g); ++ ++ png_ptr->background_1.blue = png_gamma_correct(png_ptr, ++ png_ptr->background.blue, g); ++ } ++ ++ if (gs_sig != 0) ++ { ++ png_ptr->background.red = png_gamma_correct(png_ptr, ++ png_ptr->background.red, gs); ++ ++ png_ptr->background.green = png_gamma_correct(png_ptr, ++ png_ptr->background.green, gs); ++ ++ png_ptr->background.blue = png_gamma_correct(png_ptr, ++ png_ptr->background.blue, gs); ++ } + } + + else +@@ -1737,20 +1818,29 @@ + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + } ++ ++ /* The background is now in screen gamma: */ ++ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; + } /* color_type != PNG_COLOR_TYPE_PALETTE */ + }/* png_ptr->transformations & PNG_BACKGROUND */ + + else + /* Transformation does not include PNG_BACKGROUND */ +-#endif /* PNG_READ_BACKGROUND_SUPPORTED */ +- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ++#endif /* READ_BACKGROUND */ ++ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ++#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED ++ /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ ++ && ((png_ptr->transformations & PNG_EXPAND) == 0 || ++ (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) ++#endif ++ ) + { + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + +- /*NOTE: there are other transformations that should probably be in here +- * too. ++ /* NOTE: there are other transformations that should probably be in ++ * here too. + */ + for (i = 0; i < num_palette; i++) + { +@@ -1766,11 +1856,11 @@ + #ifdef PNG_READ_BACKGROUND_SUPPORTED + else + #endif +-#endif /* PNG_READ_GAMMA_SUPPORTED */ ++#endif /* READ_GAMMA */ + + #ifdef PNG_READ_BACKGROUND_SUPPORTED + /* No GAMMA transformation (see the hanging else 4 lines above) */ +- if ((png_ptr->transformations & PNG_COMPOSE) && ++ if ((png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; +@@ -1805,35 +1895,53 @@ + + png_ptr->transformations &= ~PNG_COMPOSE; + } +-#endif /* PNG_READ_BACKGROUND_SUPPORTED */ ++#endif /* READ_BACKGROUND */ + + #ifdef PNG_READ_SHIFT_SUPPORTED +- if ((png_ptr->transformations & PNG_SHIFT) && ++ if ((png_ptr->transformations & PNG_SHIFT) != 0 && ++ (png_ptr->transformations & PNG_EXPAND) == 0 && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { +- png_uint_16 i; +- png_uint_16 istop = png_ptr->num_palette; +- int sr = 8 - png_ptr->sig_bit.red; +- int sg = 8 - png_ptr->sig_bit.green; +- int sb = 8 - png_ptr->sig_bit.blue; +- +- if (sr < 0 || sr > 8) +- sr = 0; +- +- if (sg < 0 || sg > 8) +- sg = 0; +- +- if (sb < 0 || sb > 8) +- sb = 0; +- +- for (i = 0; i < istop; i++) +- { +- png_ptr->palette[i].red >>= sr; +- png_ptr->palette[i].green >>= sg; +- png_ptr->palette[i].blue >>= sb; +- } ++ int i; ++ int istop = png_ptr->num_palette; ++ int shift = 8 - png_ptr->sig_bit.red; ++ ++ png_ptr->transformations &= ~PNG_SHIFT; ++ ++ /* significant bits can be in the range 1 to 7 for a meaninful result, if ++ * the number of significant bits is 0 then no shift is done (this is an ++ * error condition which is silently ignored.) ++ */ ++ if (shift > 0 && shift < 8) ++ for (i=0; i<istop; ++i) ++ { ++ int component = png_ptr->palette[i].red; ++ ++ component >>= shift; ++ png_ptr->palette[i].red = (png_byte)component; ++ } ++ ++ shift = 8 - png_ptr->sig_bit.green; ++ if (shift > 0 && shift < 8) ++ for (i=0; i<istop; ++i) ++ { ++ int component = png_ptr->palette[i].green; ++ ++ component >>= shift; ++ png_ptr->palette[i].green = (png_byte)component; ++ } ++ ++ shift = 8 - png_ptr->sig_bit.blue; ++ if (shift > 0 && shift < 8) ++ for (i=0; i<istop; ++i) ++ { ++ int component = png_ptr->palette[i].blue; ++ ++ component >>= shift; ++ png_ptr->palette[i].blue = (png_byte)component; ++ } + } +-#endif /* PNG_READ_SHIFT_SUPPORTED */ ++#endif /* READ_SHIFT */ + } + + /* Modify the info structure to reflect the transformations. The +@@ -1841,12 +1949,12 @@ + * assuming the transformations result in valid PNG data. + */ + void /* PRIVATE */ +-png_read_transform_info(png_structp png_ptr, png_infop info_ptr) ++png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) + { + png_debug(1, "in png_read_transform_info"); + + #ifdef PNG_READ_EXPAND_SUPPORTED +- if (png_ptr->transformations & PNG_EXPAND) ++ if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { +@@ -1868,9 +1976,9 @@ + } + else + { +- if (png_ptr->num_trans) ++ if (png_ptr->num_trans != 0) + { +- if (png_ptr->transformations & PNG_EXPAND_tRNS) ++ if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } + if (info_ptr->bit_depth < 8) +@@ -1886,7 +1994,7 @@ + /* The following is almost certainly wrong unless the background value is in + * the screen space! + */ +- if (png_ptr->transformations & PNG_COMPOSE) ++ if ((png_ptr->transformations & PNG_COMPOSE) != 0) + info_ptr->background = png_ptr->background; + #endif + +@@ -1895,20 +2003,24 @@ + * however it seems that the code in png_init_read_transformations, which has + * been called before this from png_read_update_info->png_read_start_row + * sometimes does the gamma transform and cancels the flag. ++ * ++ * TODO: this looks wrong; the info_ptr should end up with a gamma equal to ++ * the screen_gamma value. The following probably results in weirdness if ++ * the info_ptr is used by the app after the rows have been read. + */ +- info_ptr->gamma = png_ptr->gamma; ++ info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; + #endif + + if (info_ptr->bit_depth == 16) + { + # ifdef PNG_READ_16BIT_SUPPORTED + # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +- if (png_ptr->transformations & PNG_SCALE_16_TO_8) ++ if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) + info_ptr->bit_depth = 8; + # endif + + # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +- if (png_ptr->transformations & PNG_16_TO_8) ++ if ((png_ptr->transformations & PNG_16_TO_8) != 0) + info_ptr->bit_depth = 8; + # endif + +@@ -1926,7 +2038,7 @@ + info_ptr->bit_depth = 8; + # else + +-# if PNG_READ_SCALE_16_TO_8_SUPPORTED ++# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_ptr->transformations |= PNG_SCALE_16_TO_8; + info_ptr->bit_depth = 8; + # else +@@ -1934,25 +2046,27 @@ + CONFIGURATION ERROR: you must enable at least one 16 to 8 method + # endif + # endif +-#endif /* !READ_16BIT_SUPPORTED */ ++#endif /* !READ_16BIT */ + } + + #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +- if (png_ptr->transformations & PNG_GRAY_TO_RGB) +- info_ptr->color_type |= PNG_COLOR_MASK_COLOR; ++ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) ++ info_ptr->color_type = (png_byte)(info_ptr->color_type | ++ PNG_COLOR_MASK_COLOR); + #endif + + #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +- if (png_ptr->transformations & PNG_RGB_TO_GRAY) +- info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; ++ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) ++ info_ptr->color_type = (png_byte)(info_ptr->color_type & ++ ~PNG_COLOR_MASK_COLOR); + #endif + + #ifdef PNG_READ_QUANTIZE_SUPPORTED +- if (png_ptr->transformations & PNG_QUANTIZE) ++ if ((png_ptr->transformations & PNG_QUANTIZE) != 0) + { + if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && +- png_ptr->palette_lookup && info_ptr->bit_depth == 8) ++ png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) + { + info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; + } +@@ -1960,54 +2074,57 @@ + #endif + + #ifdef PNG_READ_EXPAND_16_SUPPORTED +- if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && +- info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) ++ if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && ++ info_ptr->bit_depth == 8 && ++ info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + info_ptr->bit_depth = 16; + } + #endif + + #ifdef PNG_READ_PACK_SUPPORTED +- if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) ++ if ((png_ptr->transformations & PNG_PACK) != 0 && ++ (info_ptr->bit_depth < 8)) + info_ptr->bit_depth = 8; + #endif + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + +- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) ++ else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + info_ptr->channels = 3; + + else + info_ptr->channels = 1; + + #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +- if (png_ptr->transformations & PNG_STRIP_ALPHA) ++ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) + { +- info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; ++ info_ptr->color_type = (png_byte)(info_ptr->color_type & ++ ~PNG_COLOR_MASK_ALPHA); + info_ptr->num_trans = 0; + } + #endif + +- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) ++ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) + info_ptr->channels++; + + #ifdef PNG_READ_FILLER_SUPPORTED + /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ +- if ((png_ptr->transformations & PNG_FILLER) && +- ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || +- (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) ++ if ((png_ptr->transformations & PNG_FILLER) != 0 && ++ (info_ptr->color_type == PNG_COLOR_TYPE_RGB || ++ info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) + { + info_ptr->channels++; + /* If adding a true alpha channel not just filler */ +- if (png_ptr->transformations & PNG_ADD_ALPHA) ++ if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } + #endif + + #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ + defined(PNG_READ_USER_TRANSFORM_SUPPORTED) +- if (png_ptr->transformations & PNG_USER_TRANSFORM) ++ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + { + if (info_ptr->bit_depth < png_ptr->user_transform_depth) + info_ptr->bit_depth = png_ptr->user_transform_depth; +@@ -2031,291 +2148,11 @@ + png_ptr->info_rowbytes = info_ptr->rowbytes; + + #ifndef PNG_READ_EXPAND_SUPPORTED +- if (png_ptr) ++ if (png_ptr != NULL) + return; + #endif + } + +-/* Transform the row. The order of transformations is significant, +- * and is very touchy. If you add a transformation, take care to +- * decide how it fits in with the other transformations here. +- */ +-void /* PRIVATE */ +-png_do_read_transformations(png_structp png_ptr) +-{ +- png_debug(1, "in png_do_read_transformations"); +- +- if (png_ptr->row_buf == NULL) +- { +- /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this +- * error is incredibly rare and incredibly easy to debug without this +- * information. +- */ +- png_error(png_ptr, "NULL row buffer"); +- } +- +- /* The following is debugging; prior to 1.5.4 the code was never compiled in; +- * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro +- * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for +- * selected new APIs to ensure that there is no API change. +- */ +- if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && +- !(png_ptr->flags & PNG_FLAG_ROW_INIT)) +- { +- /* Application has failed to call either png_read_start_image() or +- * png_read_update_info() after setting transforms that expand pixels. +- * This check added to libpng-1.2.19 (but not enabled until 1.5.4). +- */ +- png_error(png_ptr, "Uninitialized row"); +- } +- +-#ifdef PNG_READ_EXPAND_SUPPORTED +- if (png_ptr->transformations & PNG_EXPAND) +- { +- if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) +- { +- png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, +- png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); +- } +- +- else +- { +- if (png_ptr->num_trans && +- (png_ptr->transformations & PNG_EXPAND_tRNS)) +- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, +- &(png_ptr->trans_color)); +- +- else +- png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, +- NULL); +- } +- } +-#endif +- +-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +- if ((png_ptr->transformations & PNG_STRIP_ALPHA) && +- !(png_ptr->transformations & PNG_COMPOSE) && +- (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || +- png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) +- png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, +- 0 /* at_start == false, because SWAP_ALPHA happens later */); +-#endif +- +-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +- if (png_ptr->transformations & PNG_RGB_TO_GRAY) +- { +- int rgb_error = +- png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), +- png_ptr->row_buf + 1); +- +- if (rgb_error) +- { +- png_ptr->rgb_to_gray_status=1; +- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == +- PNG_RGB_TO_GRAY_WARN) +- png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); +- +- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == +- PNG_RGB_TO_GRAY_ERR) +- png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); +- } +- } +-#endif +- +-/* From Andreas Dilger e-mail to png-implement, 26 March 1998: +- * +- * In most cases, the "simple transparency" should be done prior to doing +- * gray-to-RGB, or you will have to test 3x as many bytes to check if a +- * pixel is transparent. You would also need to make sure that the +- * transparency information is upgraded to RGB. +- * +- * To summarize, the current flow is: +- * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite +- * with background "in place" if transparent, +- * convert to RGB if necessary +- * - Gray + alpha -> composite with gray background and remove alpha bytes, +- * convert to RGB if necessary +- * +- * To support RGB backgrounds for gray images we need: +- * - Gray + simple transparency -> convert to RGB + simple transparency, +- * compare 3 or 6 bytes and composite with +- * background "in place" if transparent +- * (3x compare/pixel compared to doing +- * composite with gray bkgrnd) +- * - Gray + alpha -> convert to RGB + alpha, composite with background and +- * remove alpha bytes (3x float +- * operations/pixel compared with composite +- * on gray background) +- * +- * Greg's change will do this. The reason it wasn't done before is for +- * performance, as this increases the per-pixel operations. If we would check +- * in advance if the background was gray or RGB, and position the gray-to-RGB +- * transform appropriately, then it would save a lot of work/time. +- */ +- +-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +- /* If gray -> RGB, do so now only if background is non-gray; else do later +- * for performance reasons +- */ +- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && +- !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) +- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ +- (defined PNG_READ_ALPHA_MODE_SUPPORTED) +- if (png_ptr->transformations & PNG_COMPOSE) +- png_do_compose(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); +-#endif +- +-#ifdef PNG_READ_GAMMA_SUPPORTED +- if ((png_ptr->transformations & PNG_GAMMA) && +-#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ +- (defined PNG_READ_ALPHA_MODE_SUPPORTED) +- !((png_ptr->transformations & PNG_COMPOSE) && +- ((png_ptr->num_trans != 0) || +- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && +-#endif +- (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) +- png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); +-#endif +- +-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +- if ((png_ptr->transformations & PNG_STRIP_ALPHA) && +- (png_ptr->transformations & PNG_COMPOSE) && +- (png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || +- png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) +- png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, +- 0 /* at_start == false, because SWAP_ALPHA happens later */); +-#endif +- +-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +- if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && +- (png_ptr->row_info.color_type & PNG_COLOR_MASK_ALPHA)) +- png_do_encode_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); +-#endif +- +-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +- if (png_ptr->transformations & PNG_SCALE_16_TO_8) +- png_do_scale_16_to_8(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +- /* There is no harm in doing both of these because only one has any effect, +- * by putting the 'scale' option first if the app asks for scale (either by +- * calling the API or in a TRANSFORM flag) this is what happens. +- */ +- if (png_ptr->transformations & PNG_16_TO_8) +- png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_QUANTIZE_SUPPORTED +- if (png_ptr->transformations & PNG_QUANTIZE) +- { +- png_do_quantize(&(png_ptr->row_info), png_ptr->row_buf + 1, +- png_ptr->palette_lookup, png_ptr->quantize_index); +- +- if (png_ptr->row_info.rowbytes == 0) +- png_error(png_ptr, "png_do_quantize returned rowbytes=0"); +- } +-#endif /* PNG_READ_QUANTIZE_SUPPORTED */ +- +-#ifdef PNG_READ_EXPAND_16_SUPPORTED +- /* Do the expansion now, after all the arithmetic has been done. Notice +- * that previous transformations can handle the PNG_EXPAND_16 flag if this +- * is efficient (particularly true in the case of gamma correction, where +- * better accuracy results faster!) +- */ +- if (png_ptr->transformations & PNG_EXPAND_16) +- png_do_expand_16(&png_ptr->row_info, png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +- /*NOTE: moved here in 1.5.4 (from much later in this list.) */ +- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && +- (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) +- png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_INVERT_SUPPORTED +- if (png_ptr->transformations & PNG_INVERT_MONO) +- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_SHIFT_SUPPORTED +- if (png_ptr->transformations & PNG_SHIFT) +- png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, +- &(png_ptr->shift)); +-#endif +- +-#ifdef PNG_READ_PACK_SUPPORTED +- if (png_ptr->transformations & PNG_PACK) +- png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_BGR_SUPPORTED +- if (png_ptr->transformations & PNG_BGR) +- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_PACKSWAP_SUPPORTED +- if (png_ptr->transformations & PNG_PACKSWAP) +- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_FILLER_SUPPORTED +- if (png_ptr->transformations & PNG_FILLER) +- png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, +- (png_uint_32)png_ptr->filler, png_ptr->flags); +-#endif +- +-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +- if (png_ptr->transformations & PNG_INVERT_ALPHA) +- png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +- if (png_ptr->transformations & PNG_SWAP_ALPHA) +- png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_READ_16BIT_SUPPORTED +-#ifdef PNG_READ_SWAP_SUPPORTED +- if (png_ptr->transformations & PNG_SWAP_BYTES) +- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +-#endif +- +-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +- if (png_ptr->transformations & PNG_USER_TRANSFORM) +- { +- if (png_ptr->read_user_transform_fn != NULL) +- (*(png_ptr->read_user_transform_fn)) /* User read transform function */ +- (png_ptr, /* png_ptr */ +- &(png_ptr->row_info), /* row_info: */ +- /* png_uint_32 width; width of row */ +- /* png_size_t rowbytes; number of bytes in row */ +- /* png_byte color_type; color type of pixels */ +- /* png_byte bit_depth; bit depth of samples */ +- /* png_byte channels; number of channels (1-4) */ +- /* png_byte pixel_depth; bits per pixel (depth*channels) */ +- png_ptr->row_buf + 1); /* start of pixel data for row */ +-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +- if (png_ptr->user_transform_depth) +- png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; +- +- if (png_ptr->user_transform_channels) +- png_ptr->row_info.channels = png_ptr->user_transform_channels; +-#endif +- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * +- png_ptr->row_info.channels); +- +- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, +- png_ptr->row_info.width); +- } +-#endif +-} +- + #ifdef PNG_READ_PACK_SUPPORTED + /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, + * without changing the actual values. Thus, if you had a row with +@@ -2323,7 +2160,7 @@ + * the numbers 0 or 1. If you would rather they contain 0 and 255, use + * png_do_shift() after this. + */ +-void /* PRIVATE */ ++static void + png_do_unpack(png_row_infop row_info, png_bytep row) + { + png_debug(1, "in png_do_unpack"); +@@ -2421,109 +2258,132 @@ + * a row of bit depth 8, but only 5 are significant, this will shift + * the values back to 0 through 31. + */ +-void /* PRIVATE */ ++static void + png_do_unshift(png_row_infop row_info, png_bytep row, + png_const_color_8p sig_bits) + { ++ int color_type; ++ + png_debug(1, "in png_do_unshift"); + +- if ( +- row_info->color_type != PNG_COLOR_TYPE_PALETTE) ++ /* The palette case has already been handled in the _init routine. */ ++ color_type = row_info->color_type; ++ ++ if (color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift[4]; + int channels = 0; +- int c; +- png_uint_16 value = 0; +- png_uint_32 row_width = row_info->width; +- +- if (row_info->color_type & PNG_COLOR_MASK_COLOR) ++ int bit_depth = row_info->bit_depth; ++ ++ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { +- shift[channels++] = row_info->bit_depth - sig_bits->red; +- shift[channels++] = row_info->bit_depth - sig_bits->green; +- shift[channels++] = row_info->bit_depth - sig_bits->blue; ++ shift[channels++] = bit_depth - sig_bits->red; ++ shift[channels++] = bit_depth - sig_bits->green; ++ shift[channels++] = bit_depth - sig_bits->blue; + } + + else + { +- shift[channels++] = row_info->bit_depth - sig_bits->gray; ++ shift[channels++] = bit_depth - sig_bits->gray; + } + +- if (row_info->color_type & PNG_COLOR_MASK_ALPHA) ++ if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) + { +- shift[channels++] = row_info->bit_depth - sig_bits->alpha; ++ shift[channels++] = bit_depth - sig_bits->alpha; + } + +- for (c = 0; c < channels; c++) + { +- if (shift[c] <= 0) +- shift[c] = 0; +- +- else +- value = 1; ++ int c, have_shift; ++ ++ for (c = have_shift = 0; c < channels; ++c) ++ { ++ /* A shift of more than the bit depth is an error condition but it ++ * gets ignored here. ++ */ ++ if (shift[c] <= 0 || shift[c] >= bit_depth) ++ shift[c] = 0; ++ ++ else ++ have_shift = 1; ++ } ++ ++ if (have_shift == 0) ++ return; + } + +- if (!value) +- return; +- +- switch (row_info->bit_depth) ++ switch (bit_depth) + { + default: ++ /* Must be 1bpp gray: should not be here! */ ++ /* NOTREACHED */ + break; + + case 2: ++ /* Must be 2bpp gray */ ++ /* assert(channels == 1 && shift[0] == 1) */ + { +- png_bytep bp; +- png_size_t i; +- png_size_t istop = row_info->rowbytes; +- +- for (bp = row, i = 0; i < istop; i++) ++ png_bytep bp = row; ++ png_bytep bp_end = bp + row_info->rowbytes; ++ ++ while (bp < bp_end) + { +- *bp >>= 1; +- *bp++ &= 0x55; ++ int b = (*bp >> 1) & 0x55; ++ *bp++ = (png_byte)b; + } + break; + } + + case 4: ++ /* Must be 4bpp gray */ ++ /* assert(channels == 1) */ + { + png_bytep bp = row; +- png_size_t i; +- png_size_t istop = row_info->rowbytes; +- png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | +- (png_byte)((int)0xf >> shift[0])); +- +- for (i = 0; i < istop; i++) ++ png_bytep bp_end = bp + row_info->rowbytes; ++ int gray_shift = shift[0]; ++ int mask = 0xf >> gray_shift; ++ ++ mask |= mask << 4; ++ ++ while (bp < bp_end) + { +- *bp >>= shift[0]; +- *bp++ &= mask; ++ int b = (*bp >> gray_shift) & mask; ++ *bp++ = (png_byte)b; + } + break; + } + + case 8: ++ /* Single byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; +- png_uint_32 i; +- png_uint_32 istop = row_width * channels; +- +- for (i = 0; i < istop; i++) ++ png_bytep bp_end = bp + row_info->rowbytes; ++ int channel = 0; ++ ++ while (bp < bp_end) + { +- *bp++ >>= shift[i%channels]; ++ int b = *bp >> shift[channel]; ++ if (++channel >= channels) ++ channel = 0; ++ *bp++ = (png_byte)b; + } + break; + } + + #ifdef PNG_READ_16BIT_SUPPORTED + case 16: ++ /* Double byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; +- png_uint_32 i; +- png_uint_32 istop = channels * row_width; +- +- for (i = 0; i < istop; i++) ++ png_bytep bp_end = bp + row_info->rowbytes; ++ int channel = 0; ++ ++ while (bp < bp_end) + { +- value = (png_uint_16)((*bp << 8) + *(bp + 1)); +- value >>= shift[i%channels]; ++ int value = (bp[0] << 8) + bp[1]; ++ ++ value >>= shift[channel]; ++ if (++channel >= channels) ++ channel = 0; + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)(value & 0xff); + } +@@ -2537,7 +2397,7 @@ + + #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + /* Scale rows of bit depth 16 down to 8 accurately */ +-void /* PRIVATE */ ++static void + png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) + { + png_debug(1, "in png_do_scale_16_to_8"); +@@ -2545,7 +2405,7 @@ + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ +- png_bytep dp = row; /* destinaton */ ++ png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) +@@ -2595,7 +2455,7 @@ + #endif + + #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +-void /* PRIVATE */ ++static void + /* Simply discard the low byte. This was the default behavior prior + * to libpng-1.5.4. + */ +@@ -2606,7 +2466,7 @@ + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ +- png_bytep dp = row; /* destinaton */ ++ png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) +@@ -2623,7 +2483,7 @@ + #endif + + #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +-void /* PRIVATE */ ++static void + png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) + { + png_debug(1, "in png_do_read_swap_alpha"); +@@ -2720,7 +2580,7 @@ + #endif + + #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +-void /* PRIVATE */ ++static void + png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) + { + png_uint_32 row_width; +@@ -2822,7 +2682,7 @@ + + #ifdef PNG_READ_FILLER_SUPPORTED + /* Add filler channel if we have RGB color */ +-void /* PRIVATE */ ++static void + png_do_read_filler(png_row_infop row_info, png_bytep row, + png_uint_32 filler, png_uint_32 flags) + { +@@ -2841,7 +2701,7 @@ + { + if (row_info->bit_depth == 8) + { +- if (flags & PNG_FLAG_FILLER_AFTER) ++ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from G to GX */ + png_bytep sp = row + (png_size_t)row_width; +@@ -2876,7 +2736,7 @@ + #ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { +- if (flags & PNG_FLAG_FILLER_AFTER) ++ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from GG to GGXX */ + png_bytep sp = row + (png_size_t)row_width * 2; +@@ -2918,7 +2778,7 @@ + { + if (row_info->bit_depth == 8) + { +- if (flags & PNG_FLAG_FILLER_AFTER) ++ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from RGB to RGBX */ + png_bytep sp = row + (png_size_t)row_width * 3; +@@ -2957,7 +2817,7 @@ + #ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { +- if (flags & PNG_FLAG_FILLER_AFTER) ++ if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from RRGGBB to RRGGBBXX */ + png_bytep sp = row + (png_size_t)row_width * 6; +@@ -3009,7 +2869,7 @@ + + #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* Expand grayscale files to RGB, with or without alpha */ +-void /* PRIVATE */ ++static void + png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) + { + png_uint_32 i; +@@ -3018,7 +2878,7 @@ + png_debug(1, "in png_do_gray_to_rgb"); + + if (row_info->bit_depth >= 8 && +- !(row_info->color_type & PNG_COLOR_MASK_COLOR)) ++ (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { +@@ -3086,7 +2946,7 @@ + } + } + } +- row_info->channels += (png_byte)2; ++ row_info->channels = (png_byte)(row_info->channels + 2); + row_info->color_type |= PNG_COLOR_MASK_COLOR; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); +@@ -3097,269 +2957,242 @@ + + #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Reduce RGB files to grayscale, with or without alpha +- * using the equation given in Poynton's ColorFAQ at +- * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008) +- * New link: +- * <http://www.poynton.com/notes/colour_and_gamma/> ++ * using the equation given in Poynton's ColorFAQ of 1998-01-04 at ++ * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but ++ * versions dated 1998 through November 2002 have been archived at ++ * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ ++ * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) + * Charles Poynton poynton at poynton.com + * + * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + * +- * We approximate this with +- * +- * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B +- * + * which can be expressed with integers as + * + * Y = (6969 * R + 23434 * G + 2365 * B)/32768 + * +- * The calculation is to be done in a linear colorspace. ++ * Poynton's current link (as of January 2003 through July 2011): ++ * <http://www.poynton.com/notes/colour_and_gamma/> ++ * has changed the numbers slightly: + * +- * Other integer coefficents can be used via png_set_rgb_to_gray(). ++ * Y = 0.2126*R + 0.7152*G + 0.0722*B ++ * ++ * which can be expressed with integers as ++ * ++ * Y = (6966 * R + 23436 * G + 2366 * B)/32768 ++ * ++ * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 ++ * end point chromaticities and the D65 white point. Depending on the ++ * precision used for the D65 white point this produces a variety of different ++ * numbers, however if the four decimal place value used in ITU-R Rec 709 is ++ * used (0.3127,0.3290) the Y calculation would be: ++ * ++ * Y = (6968 * R + 23435 * G + 2366 * B)/32768 ++ * ++ * While this is correct the rounding results in an overflow for white, because ++ * the sum of the rounded coefficients is 32769, not 32768. Consequently ++ * libpng uses, instead, the closest non-overflowing approximation: ++ * ++ * Y = (6968 * R + 23434 * G + 2366 * B)/32768 ++ * ++ * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk ++ * (including an sRGB chunk) then the chromaticities are used to calculate the ++ * coefficients. See the chunk handling in pngrutil.c for more information. ++ * ++ * In all cases the calculation is to be done in a linear colorspace. If no ++ * gamma information is available to correct the encoding of the original RGB ++ * values this results in an implicit assumption that the original PNG RGB ++ * values were linear. ++ * ++ * Other integer coefficents can be used via png_set_rgb_to_gray(). Because ++ * the API takes just red and green coefficients the blue coefficient is ++ * calculated to make the sum 32768. This will result in different rounding ++ * to that used above. + */ +-int /* PRIVATE */ +-png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) ++static int ++png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) + + { +- png_uint_32 i; +- +- png_uint_32 row_width = row_info->width; + int rgb_error = 0; + + png_debug(1, "in png_do_rgb_to_gray"); + +- if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && +- (row_info->color_type & PNG_COLOR_MASK_COLOR)) ++ if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && ++ (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { +- png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; +- png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; +- png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; +- +- if (row_info->color_type == PNG_COLOR_TYPE_RGB) ++ PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; ++ PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; ++ PNG_CONST png_uint_32 bc = 32768 - rc - gc; ++ PNG_CONST png_uint_32 row_width = row_info->width; ++ PNG_CONST int have_alpha = ++ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; ++ ++ if (row_info->bit_depth == 8) + { +- if (row_info->bit_depth == 8) ++#ifdef PNG_READ_GAMMA_SUPPORTED ++ /* Notice that gamma to/from 1 are not necessarily inverses (if ++ * there is an overall gamma correction). Prior to 1.5.5 this code ++ * checked the linearized values for equality; this doesn't match ++ * the documentation, the original values must be checked. ++ */ ++ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { +-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) ++ png_bytep sp = row; ++ png_bytep dp = row; ++ png_uint_32 i; ++ ++ for (i = 0; i < row_width; i++) + { +- png_bytep sp = row; +- png_bytep dp = row; +- +- for (i = 0; i < row_width; i++) ++ png_byte red = *(sp++); ++ png_byte green = *(sp++); ++ png_byte blue = *(sp++); ++ ++ if (red != green || red != blue) + { +- png_byte red = png_ptr->gamma_to_1[*(sp++)]; +- png_byte green = png_ptr->gamma_to_1[*(sp++)]; +- png_byte blue = png_ptr->gamma_to_1[*(sp++)]; +- +- if (red != green || red != blue) +- { +- rgb_error |= 1; +- *(dp++) = png_ptr->gamma_from_1[ +- (rc*red + gc*green + bc*blue)>>15]; +- } ++ red = png_ptr->gamma_to_1[red]; ++ green = png_ptr->gamma_to_1[green]; ++ blue = png_ptr->gamma_to_1[blue]; ++ ++ rgb_error |= 1; ++ *(dp++) = png_ptr->gamma_from_1[ ++ (rc*red + gc*green + bc*blue + 16384)>>15]; ++ } ++ ++ else ++ { ++ /* If there is no overall correction the table will not be ++ * set. ++ */ ++ if (png_ptr->gamma_table != NULL) ++ red = png_ptr->gamma_table[red]; ++ ++ *(dp++) = red; ++ } ++ ++ if (have_alpha != 0) ++ *(dp++) = *(sp++); ++ } ++ } ++ else ++#endif ++ { ++ png_bytep sp = row; ++ png_bytep dp = row; ++ png_uint_32 i; ++ ++ for (i = 0; i < row_width; i++) ++ { ++ png_byte red = *(sp++); ++ png_byte green = *(sp++); ++ png_byte blue = *(sp++); ++ ++ if (red != green || red != blue) ++ { ++ rgb_error |= 1; ++ /* NOTE: this is the historical approach which simply ++ * truncates the results. ++ */ ++ *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); ++ } ++ ++ else ++ *(dp++) = red; ++ ++ if (have_alpha != 0) ++ *(dp++) = *(sp++); ++ } ++ } ++ } ++ ++ else /* RGB bit_depth == 16 */ ++ { ++#ifdef PNG_READ_GAMMA_SUPPORTED ++ if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) ++ { ++ png_bytep sp = row; ++ png_bytep dp = row; ++ png_uint_32 i; ++ ++ for (i = 0; i < row_width; i++) ++ { ++ png_uint_16 red, green, blue, w; ++ ++ red = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; ++ green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; ++ blue = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; ++ ++ if (red == green && red == blue) ++ { ++ if (png_ptr->gamma_16_table != NULL) ++ w = png_ptr->gamma_16_table[(red & 0xff) ++ >> png_ptr->gamma_shift][red >> 8]; + + else +- *(dp++) = *(sp - 1); ++ w = red; + } +- } +- else +-#endif +- { +- png_bytep sp = row; +- png_bytep dp = row; +- for (i = 0; i < row_width; i++) ++ ++ else + { +- png_byte red = *(sp++); +- png_byte green = *(sp++); +- png_byte blue = *(sp++); +- +- if (red != green || red != blue) +- { +- rgb_error |= 1; +- *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); +- } +- +- else +- *(dp++) = *(sp - 1); ++ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) ++ >> png_ptr->gamma_shift][red>>8]; ++ png_uint_16 green_1 = ++ png_ptr->gamma_16_to_1[(green&0xff) >> ++ png_ptr->gamma_shift][green>>8]; ++ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) ++ >> png_ptr->gamma_shift][blue>>8]; ++ png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 ++ + bc*blue_1 + 16384)>>15); ++ w = png_ptr->gamma_16_from_1[(gray16&0xff) >> ++ png_ptr->gamma_shift][gray16 >> 8]; ++ rgb_error |= 1; ++ } ++ ++ *(dp++) = (png_byte)((w>>8) & 0xff); ++ *(dp++) = (png_byte)(w & 0xff); ++ ++ if (have_alpha != 0) ++ { ++ *(dp++) = *(sp++); ++ *(dp++) = *(sp++); + } + } + } +- +- else /* RGB bit_depth == 16 */ ++ else ++#endif + { +-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +- if (png_ptr->gamma_16_to_1 != NULL && +- png_ptr->gamma_16_from_1 != NULL) ++ png_bytep sp = row; ++ png_bytep dp = row; ++ png_uint_32 i; ++ ++ for (i = 0; i < row_width; i++) + { +- png_bytep sp = row; +- png_bytep dp = row; +- for (i = 0; i < row_width; i++) ++ png_uint_16 red, green, blue, gray16; ++ ++ red = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; ++ green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; ++ blue = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2; ++ ++ if (red != green || red != blue) ++ rgb_error |= 1; ++ ++ /* From 1.5.5 in the 16 bit case do the accurate conversion even ++ * in the 'fast' case - this is because this is where the code ++ * ends up when handling linear 16 bit data. ++ */ ++ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> ++ 15); ++ *(dp++) = (png_byte)((gray16 >> 8) & 0xff); ++ *(dp++) = (png_byte)(gray16 & 0xff); ++ ++ if (have_alpha != 0) + { +- png_uint_16 red, green, blue, w; +- +- red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- +- if (red == green && red == blue) +- w = red; +- +- else +- { +- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) +- >> png_ptr->gamma_shift][red>>8]; +- png_uint_16 green_1 = +- png_ptr->gamma_16_to_1[(green&0xff) >> +- png_ptr->gamma_shift][green>>8]; +- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) +- >> png_ptr->gamma_shift][blue>>8]; +- png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 +- + bc*blue_1)>>15); +- w = png_ptr->gamma_16_from_1[(gray16&0xff) >> +- png_ptr->gamma_shift][gray16 >> 8]; +- rgb_error |= 1; +- } +- +- *(dp++) = (png_byte)((w>>8) & 0xff); +- *(dp++) = (png_byte)(w & 0xff); +- } +- } +- else +-#endif +- { +- png_bytep sp = row; +- png_bytep dp = row; +- for (i = 0; i < row_width; i++) +- { +- png_uint_16 red, green, blue, gray16; +- +- red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- +- if (red != green || red != blue) +- rgb_error |= 1; +- +- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); +- *(dp++) = (png_byte)((gray16>>8) & 0xff); +- *(dp++) = (png_byte)(gray16 & 0xff); +- } +- } +- } +- } +- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) +- { +- if (row_info->bit_depth == 8) +- { +-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +- if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) +- { +- png_bytep sp = row; +- png_bytep dp = row; +- for (i = 0; i < row_width; i++) +- { +- png_byte red = png_ptr->gamma_to_1[*(sp++)]; +- png_byte green = png_ptr->gamma_to_1[*(sp++)]; +- png_byte blue = png_ptr->gamma_to_1[*(sp++)]; +- +- if (red != green || red != blue) +- rgb_error |= 1; +- +- *(dp++) = png_ptr->gamma_from_1 +- [(rc*red + gc*green + bc*blue)>>15]; +- +- *(dp++) = *(sp++); /* alpha */ +- } +- } +- else +-#endif +- { +- png_bytep sp = row; +- png_bytep dp = row; +- for (i = 0; i < row_width; i++) +- { +- png_byte red = *(sp++); +- png_byte green = *(sp++); +- png_byte blue = *(sp++); +- if (red != green || red != blue) +- rgb_error |= 1; +- +- *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); +- *(dp++) = *(sp++); /* alpha */ +- } +- } +- } +- else /* RGBA bit_depth == 16 */ +- { +-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +- if (png_ptr->gamma_16_to_1 != NULL && +- png_ptr->gamma_16_from_1 != NULL) +- { +- png_bytep sp = row; +- png_bytep dp = row; +- for (i = 0; i < row_width; i++) +- { +- png_uint_16 red, green, blue, w; +- +- red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; +- +- if (red == green && red == blue) +- w = red; +- +- else +- { +- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> +- png_ptr->gamma_shift][red>>8]; +- +- png_uint_16 green_1 = +- png_ptr->gamma_16_to_1[(green&0xff) >> +- png_ptr->gamma_shift][green>>8]; +- +- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> +- png_ptr->gamma_shift][blue>>8]; +- +- png_uint_16 gray16 = (png_uint_16)((rc * red_1 +- + gc * green_1 + bc * blue_1)>>15); +- +- w = png_ptr->gamma_16_from_1[(gray16&0xff) >> +- png_ptr->gamma_shift][gray16 >> 8]; +- +- rgb_error |= 1; +- } +- +- *(dp++) = (png_byte)((w>>8) & 0xff); +- *(dp++) = (png_byte)(w & 0xff); +- *(dp++) = *(sp++); /* alpha */ + *(dp++) = *(sp++); +- } +- } +- else +-#endif +- { +- png_bytep sp = row; +- png_bytep dp = row; +- for (i = 0; i < row_width; i++) +- { +- png_uint_16 red, green, blue, gray16; +- red = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; +- green = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; +- blue = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; +- +- if (red != green || red != blue) +- rgb_error |= 1; +- +- gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); +- *(dp++) = (png_byte)((gray16>>8) & 0xff); +- *(dp++) = (png_byte)(gray16 & 0xff); +- *(dp++) = *(sp++); /* alpha */ + *(dp++) = *(sp++); + } + } + } + } +- row_info->channels -= 2; ++ ++ row_info->channels = (png_byte)(row_info->channels - 2); + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_COLOR); + row_info->pixel_depth = (png_byte)(row_info->channels * +@@ -3369,73 +3202,15 @@ + return rgb_error; + } + #endif +-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ +- +-#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +-/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth +- * large of png_color. This lets grayscale images be treated as +- * paletted. Most useful for gamma correction and simplification +- * of code. This API is not used internally. +- */ +-void PNGAPI +-png_build_grayscale_palette(int bit_depth, png_colorp palette) +-{ +- int num_palette; +- int color_inc; +- int i; +- int v; +- +- png_debug(1, "in png_do_build_grayscale_palette"); +- +- if (palette == NULL) +- return; +- +- switch (bit_depth) +- { +- case 1: +- num_palette = 2; +- color_inc = 0xff; +- break; +- +- case 2: +- num_palette = 4; +- color_inc = 0x55; +- break; +- +- case 4: +- num_palette = 16; +- color_inc = 0x11; +- break; +- +- case 8: +- num_palette = 256; +- color_inc = 1; +- break; +- +- default: +- num_palette = 0; +- color_inc = 0; +- break; +- } +- +- for (i = 0, v = 0; i < num_palette; i++, v += color_inc) +- { +- palette[i].red = (png_byte)v; +- palette[i].green = (png_byte)v; +- palette[i].blue = (png_byte)v; +- } +-} +-#endif +- +- +-#ifdef PNG_READ_TRANSFORMS_SUPPORTED +-#ifdef PNG_READ_BACKGROUND_SUPPORTED ++ ++#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ ++ defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* Replace any alpha or transparency with the supplied background color. + * "background" is already in the screen gamma, while "background_1" is + * at a gamma of 1.0. Paletted files have already been taken care of. + */ +-void /* PRIVATE */ +-png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) ++static void ++png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) + { + #ifdef PNG_READ_GAMMA_SUPPORTED + png_const_bytep gamma_table = png_ptr->gamma_table; +@@ -3445,12 +3220,12 @@ + png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; + png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; + int gamma_shift = png_ptr->gamma_shift; ++ int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; + #endif + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; +- int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; + int shift; + + png_debug(1, "in png_do_compose"); +@@ -3471,11 +3246,12 @@ + if ((png_uint_16)((*sp >> shift) & 0x01) + == png_ptr->trans_color.gray) + { +- *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); +- *sp |= (png_byte)(png_ptr->background.gray << shift); ++ unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); ++ tmp |= png_ptr->background.gray << shift; ++ *sp = (png_byte)(tmp & 0xff); + } + +- if (!shift) ++ if (shift == 0) + { + shift = 7; + sp++; +@@ -3499,20 +3275,22 @@ + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) + { +- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); +- *sp |= (png_byte)(png_ptr->background.gray << shift); ++ unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); ++ tmp |= png_ptr->background.gray << shift; ++ *sp = (png_byte)(tmp & 0xff); + } + + else + { +- png_byte p = (png_byte)((*sp >> shift) & 0x03); +- png_byte g = (png_byte)((gamma_table [p | (p << 2) | +- (p << 4) | (p << 6)] >> 6) & 0x03); +- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); +- *sp |= (png_byte)(g << shift); ++ unsigned int p = (*sp >> shift) & 0x03; ++ unsigned int g = (gamma_table [p | (p << 2) | ++ (p << 4) | (p << 6)] >> 6) & 0x03; ++ unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); ++ tmp |= g << shift; ++ *sp = (png_byte)(tmp & 0xff); + } + +- if (!shift) ++ if (shift == 0) + { + shift = 6; + sp++; +@@ -3533,11 +3311,12 @@ + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) + { +- *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); +- *sp |= (png_byte)(png_ptr->background.gray << shift); ++ unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); ++ tmp |= png_ptr->background.gray << shift; ++ *sp = (png_byte)(tmp & 0xff); + } + +- if (!shift) ++ if (shift == 0) + { + shift = 6; + sp++; +@@ -3562,20 +3341,22 @@ + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { +- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); +- *sp |= (png_byte)(png_ptr->background.gray << shift); ++ unsigned int tmp = *sp & (0xf0f >> (4 - shift)); ++ tmp |= png_ptr->background.gray << shift; ++ *sp = (png_byte)(tmp & 0xff); + } + + else + { +- png_byte p = (png_byte)((*sp >> shift) & 0x0f); +- png_byte g = (png_byte)((gamma_table[p | +- (p << 4)] >> 4) & 0x0f); +- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); +- *sp |= (png_byte)(g << shift); ++ unsigned int p = (*sp >> shift) & 0x0f; ++ unsigned int g = (gamma_table[p | (p << 4)] >> 4) & ++ 0x0f; ++ unsigned int tmp = *sp & (0xf0f >> (4 - shift)); ++ tmp |= g << shift; ++ *sp = (png_byte)(tmp & 0xff); + } + +- if (!shift) ++ if (shift == 0) + { + shift = 4; + sp++; +@@ -3596,11 +3377,12 @@ + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { +- *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); +- *sp |= (png_byte)(png_ptr->background.gray << shift); ++ unsigned int tmp = *sp & (0xf0f >> (4 - shift)); ++ tmp |= png_ptr->background.gray << shift; ++ *sp = (png_byte)(tmp & 0xff); + } + +- if (!shift) ++ if (shift == 0) + { + shift = 4; + sp++; +@@ -3656,8 +3438,10 @@ + if (v == png_ptr->trans_color.gray) + { + /* Background is already in screen gamma */ +- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); +- *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); ++ *sp = (png_byte)((png_ptr->background.gray >> 8) ++ & 0xff); ++ *(sp + 1) = (png_byte)(png_ptr->background.gray ++ & 0xff); + } + + else +@@ -3680,8 +3464,10 @@ + + if (v == png_ptr->trans_color.gray) + { +- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); +- *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); ++ *sp = (png_byte)((png_ptr->background.gray >> 8) ++ & 0xff); ++ *(sp + 1) = (png_byte)(png_ptr->background.gray ++ & 0xff); + } + } + } +@@ -3761,9 +3547,12 @@ + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); +- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); +- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); +- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); ++ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) ++ & 0xff); ++ *(sp + 3) = (png_byte)(png_ptr->background.green ++ & 0xff); ++ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) ++ & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + +@@ -3804,9 +3593,12 @@ + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); +- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); +- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); +- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); ++ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) ++ & 0xff); ++ *(sp + 3) = (png_byte)(png_ptr->background.green ++ & 0xff); ++ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) ++ & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + } +@@ -3843,7 +3635,7 @@ + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.gray); +- if (!optimize) ++ if (optimize == 0) + w = gamma_from_1[w]; + *sp = w; + } +@@ -3861,7 +3653,7 @@ + *sp = (png_byte)png_ptr->background.gray; + + else if (a < 0xff) +- png_composite(*sp, *sp, a, png_ptr->background_1.gray); ++ png_composite(*sp, *sp, a, png_ptr->background.gray); + } + } + } +@@ -3889,7 +3681,8 @@ + else if (a == 0) + { + /* Background is already in screen gamma */ +- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); ++ *sp = (png_byte)((png_ptr->background.gray >> 8) ++ & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + +@@ -3899,7 +3692,7 @@ + + g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(v, g, a, png_ptr->background_1.gray); +- if (optimize) ++ if (optimize != 0) + w = v; + else + w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; +@@ -3919,7 +3712,8 @@ + + if (a == 0) + { +- *sp = (png_byte)((png_ptr->background.gray >> 8) & 0xff); ++ *sp = (png_byte)((png_ptr->background.gray >> 8) ++ & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + +@@ -3928,7 +3722,7 @@ + png_uint_16 g, v; + + g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); +- png_composite_16(v, g, a, png_ptr->background_1.gray); ++ png_composite_16(v, g, a, png_ptr->background.gray); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } +@@ -3972,17 +3766,17 @@ + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.red); +- if (!optimize) w = gamma_from_1[w]; ++ if (optimize == 0) w = gamma_from_1[w]; + *sp = w; + + v = gamma_to_1[*(sp + 1)]; + png_composite(w, v, a, png_ptr->background_1.green); +- if (!optimize) w = gamma_from_1[w]; ++ if (optimize == 0) w = gamma_from_1[w]; + *(sp + 1) = w; + + v = gamma_to_1[*(sp + 2)]; + png_composite(w, v, a, png_ptr->background_1.blue); +- if (!optimize) w = gamma_from_1[w]; ++ if (optimize == 0) w = gamma_from_1[w]; + *(sp + 2) = w; + } + } +@@ -4049,9 +3843,12 @@ + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); +- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); +- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); +- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); ++ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) ++ & 0xff); ++ *(sp + 3) = (png_byte)(png_ptr->background.green ++ & 0xff); ++ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) ++ & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + +@@ -4061,23 +3858,26 @@ + + v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(w, v, a, png_ptr->background_1.red); +- if (!optimize) +- w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; ++ if (optimize == 0) ++ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> ++ 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + png_composite_16(w, v, a, png_ptr->background_1.green); +- if (!optimize) +- w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; ++ if (optimize == 0) ++ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> ++ 8]; + + *(sp + 2) = (png_byte)((w >> 8) & 0xff); + *(sp + 3) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + png_composite_16(w, v, a, png_ptr->background_1.blue); +- if (!optimize) +- w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; ++ if (optimize == 0) ++ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> ++ 8]; + + *(sp + 4) = (png_byte)((w >> 8) & 0xff); + *(sp + 5) = (png_byte)(w & 0xff); +@@ -4098,9 +3898,12 @@ + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); +- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) & 0xff); +- *(sp + 3) = (png_byte)(png_ptr->background.green & 0xff); +- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) & 0xff); ++ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) ++ & 0xff); ++ *(sp + 3) = (png_byte)(png_ptr->background.green ++ & 0xff); ++ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) ++ & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + +@@ -4137,7 +3940,7 @@ + } + } + } +-#endif ++#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ + + #ifdef PNG_READ_GAMMA_SUPPORTED + /* Gamma correct the image, avoiding the alpha channel. Make sure +@@ -4146,8 +3949,8 @@ + * is 16, use gamma_16_table and gamma_shift. Build these with + * build_gamma_table(). + */ +-void /* PRIVATE */ +-png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) ++static void ++png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) + { + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; +@@ -4347,14 +4150,14 @@ + * linear.) Called only with color types that have an alpha channel. Needs the + * from_1 tables. + */ +-void /* PRIVATE */ +-png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) ++static void ++png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) + { + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_encode_alpha"); + +- if (row_info->color_type & PNG_COLOR_MASK_ALPHA) ++ if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + if (row_info->bit_depth == 8) + { +@@ -4413,7 +4216,7 @@ + /* Expands a palette row to an RGB or RGBA row depending + * upon whether you supply trans and num_trans. + */ +-void /* PRIVATE */ ++static void + png_do_expand_palette(png_row_infop row_info, png_bytep row, + png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) + { +@@ -4566,7 +4369,7 @@ + /* If the bit depth < 8, it is expanded to 8. Also, if the already + * expanded transparency value is supplied, an alpha channel is built. + */ +-void /* PRIVATE */ ++static void + png_do_expand(png_row_infop row_info, png_bytep row, + png_const_color_16p trans_color) + { +@@ -4580,7 +4383,7 @@ + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { +- png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0); ++ unsigned int gray = trans_color != NULL ? trans_color->gray : 0; + + if (row_info->bit_depth < 8) + { +@@ -4588,7 +4391,7 @@ + { + case 1: + { +- gray = (png_uint_16)((gray & 0x01) * 0xff); ++ gray = (gray & 0x01) * 0xff; + sp = row + (png_size_t)((row_width - 1) >> 3); + dp = row + (png_size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); +@@ -4616,7 +4419,7 @@ + + case 2: + { +- gray = (png_uint_16)((gray & 0x03) * 0x55); ++ gray = (gray & 0x03) * 0x55; + sp = row + (png_size_t)((row_width - 1) >> 2); + dp = row + (png_size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); +@@ -4641,7 +4444,7 @@ + + case 4: + { +- gray = (png_uint_16)((gray & 0x0f) * 0x11); ++ gray = (gray & 0x0f) * 0x11; + sp = row + (png_size_t)((row_width - 1) >> 1); + dp = row + (png_size_t)row_width - 1; + shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); +@@ -4694,8 +4497,8 @@ + + else if (row_info->bit_depth == 16) + { +- png_byte gray_high = (png_byte)((gray >> 8) & 0xff); +- png_byte gray_low = (png_byte)(gray & 0xff); ++ unsigned int gray_high = (gray >> 8) & 0xff; ++ unsigned int gray_low = gray & 0xff; + sp = row + row_info->rowbytes - 1; + dp = row + (row_info->rowbytes << 1) - 1; + for (i = 0; i < row_width; i++) +@@ -4724,7 +4527,8 @@ + row_width); + } + } +- else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) ++ else if (row_info->color_type == PNG_COLOR_TYPE_RGB && ++ trans_color != NULL) + { + if (row_info->bit_depth == 8) + { +@@ -4793,10 +4597,10 @@ + #endif + + #ifdef PNG_READ_EXPAND_16_SUPPORTED +-/* If the bit depth is 8 and the colour type is not a palette type expand the ++/* If the bit depth is 8 and the color type is not a palette type expand the + * whole row to 16 bits. Has no effect otherwise. + */ +-void /* PRIVATE */ ++static void + png_do_expand_16(png_row_infop row_info, png_bytep row) + { + if (row_info->bit_depth == 8 && +@@ -4824,7 +4628,7 @@ + #endif + + #ifdef PNG_READ_QUANTIZE_SUPPORTED +-void /* PRIVATE */ ++static void + png_do_quantize(png_row_infop row_info, png_bytep row, + png_const_bytep palette_lookup, png_const_bytep quantize_lookup) + { +@@ -4915,70 +4719,304 @@ + } + } + } +-#endif /* PNG_READ_QUANTIZE_SUPPORTED */ +-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ +- +-#ifdef PNG_MNG_FEATURES_SUPPORTED +-/* Undoes intrapixel differencing */ ++#endif /* READ_QUANTIZE */ ++ ++/* Transform the row. The order of transformations is significant, ++ * and is very touchy. If you add a transformation, take care to ++ * decide how it fits in with the other transformations here. ++ */ + void /* PRIVATE */ +-png_do_read_intrapixel(png_row_infop row_info, png_bytep row) ++png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) + { +- png_debug(1, "in png_do_read_intrapixel"); +- +- if ( +- (row_info->color_type & PNG_COLOR_MASK_COLOR)) ++ png_debug(1, "in png_do_read_transformations"); ++ ++ if (png_ptr->row_buf == NULL) + { +- int bytes_per_pixel; +- png_uint_32 row_width = row_info->width; +- +- if (row_info->bit_depth == 8) ++ /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this ++ * error is incredibly rare and incredibly easy to debug without this ++ * information. ++ */ ++ png_error(png_ptr, "NULL row buffer"); ++ } ++ ++ /* The following is debugging; prior to 1.5.4 the code was never compiled in; ++ * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro ++ * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for ++ * all transformations, however in practice the ROW_INIT always gets done on ++ * demand, if necessary. ++ */ ++ if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && ++ (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) ++ { ++ /* Application has failed to call either png_read_start_image() or ++ * png_read_update_info() after setting transforms that expand pixels. ++ * This check added to libpng-1.2.19 (but not enabled until 1.5.4). ++ */ ++ png_error(png_ptr, "Uninitialized row"); ++ } ++ ++#ifdef PNG_READ_EXPAND_SUPPORTED ++ if ((png_ptr->transformations & PNG_EXPAND) != 0) ++ { ++ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { +- png_bytep rp; +- png_uint_32 i; +- +- if (row_info->color_type == PNG_COLOR_TYPE_RGB) +- bytes_per_pixel = 3; +- +- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) +- bytes_per_pixel = 4; ++ png_do_expand_palette(row_info, png_ptr->row_buf + 1, ++ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); ++ } ++ ++ else ++ { ++ if (png_ptr->num_trans != 0 && ++ (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) ++ png_do_expand(row_info, png_ptr->row_buf + 1, ++ &(png_ptr->trans_color)); + + else +- return; +- +- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) +- { +- *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); +- *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); +- } +- } +- else if (row_info->bit_depth == 16) +- { +- png_bytep rp; +- png_uint_32 i; +- +- if (row_info->color_type == PNG_COLOR_TYPE_RGB) +- bytes_per_pixel = 6; +- +- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) +- bytes_per_pixel = 8; +- +- else +- return; +- +- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) +- { +- png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); +- png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); +- png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); +- png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL); +- png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL); +- *(rp ) = (png_byte)((red >> 8) & 0xff); +- *(rp + 1) = (png_byte)(red & 0xff); +- *(rp + 4) = (png_byte)((blue >> 8) & 0xff); +- *(rp + 5) = (png_byte)(blue & 0xff); +- } ++ png_do_expand(row_info, png_ptr->row_buf + 1, ++ NULL); + } + } ++#endif ++ ++#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED ++ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && ++ (png_ptr->transformations & PNG_COMPOSE) == 0 && ++ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || ++ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) ++ png_do_strip_channel(row_info, png_ptr->row_buf + 1, ++ 0 /* at_start == false, because SWAP_ALPHA happens later */); ++#endif ++ ++#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED ++ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) ++ { ++ int rgb_error = ++ png_do_rgb_to_gray(png_ptr, row_info, ++ png_ptr->row_buf + 1); ++ ++ if (rgb_error != 0) ++ { ++ png_ptr->rgb_to_gray_status=1; ++ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == ++ PNG_RGB_TO_GRAY_WARN) ++ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); ++ ++ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == ++ PNG_RGB_TO_GRAY_ERR) ++ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); ++ } ++ } ++#endif ++ ++/* From Andreas Dilger e-mail to png-implement, 26 March 1998: ++ * ++ * In most cases, the "simple transparency" should be done prior to doing ++ * gray-to-RGB, or you will have to test 3x as many bytes to check if a ++ * pixel is transparent. You would also need to make sure that the ++ * transparency information is upgraded to RGB. ++ * ++ * To summarize, the current flow is: ++ * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite ++ * with background "in place" if transparent, ++ * convert to RGB if necessary ++ * - Gray + alpha -> composite with gray background and remove alpha bytes, ++ * convert to RGB if necessary ++ * ++ * To support RGB backgrounds for gray images we need: ++ * - Gray + simple transparency -> convert to RGB + simple transparency, ++ * compare 3 or 6 bytes and composite with ++ * background "in place" if transparent ++ * (3x compare/pixel compared to doing ++ * composite with gray bkgrnd) ++ * - Gray + alpha -> convert to RGB + alpha, composite with background and ++ * remove alpha bytes (3x float ++ * operations/pixel compared with composite ++ * on gray background) ++ * ++ * Greg's change will do this. The reason it wasn't done before is for ++ * performance, as this increases the per-pixel operations. If we would check ++ * in advance if the background was gray or RGB, and position the gray-to-RGB ++ * transform appropriately, then it would save a lot of work/time. ++ */ ++ ++#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED ++ /* If gray -> RGB, do so now only if background is non-gray; else do later ++ * for performance reasons ++ */ ++ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && ++ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) ++ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ ++ defined(PNG_READ_ALPHA_MODE_SUPPORTED) ++ if ((png_ptr->transformations & PNG_COMPOSE) != 0) ++ png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); ++#endif ++ ++#ifdef PNG_READ_GAMMA_SUPPORTED ++ if ((png_ptr->transformations & PNG_GAMMA) != 0 && ++#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED ++ /* Because RGB_TO_GRAY does the gamma transform. */ ++ (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && ++#endif ++#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ ++ defined(PNG_READ_ALPHA_MODE_SUPPORTED) ++ /* Because PNG_COMPOSE does the gamma transform if there is something to ++ * do (if there is an alpha channel or transparency.) ++ */ ++ !((png_ptr->transformations & PNG_COMPOSE) && ++ ((png_ptr->num_trans != 0) || ++ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && ++#endif ++ /* Because png_init_read_transformations transforms the palette, unless ++ * RGB_TO_GRAY will do the transform. ++ */ ++ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) ++ png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); ++#endif ++ ++#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED ++ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && ++ (png_ptr->transformations & PNG_COMPOSE) != 0 && ++ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || ++ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) ++ png_do_strip_channel(row_info, png_ptr->row_buf + 1, ++ 0 /* at_start == false, because SWAP_ALPHA happens later */); ++#endif ++ ++#ifdef PNG_READ_ALPHA_MODE_SUPPORTED ++ if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && ++ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) ++ png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); ++#endif ++ ++#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED ++ if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) ++ png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED ++ /* There is no harm in doing both of these because only one has any effect, ++ * by putting the 'scale' option first if the app asks for scale (either by ++ * calling the API or in a TRANSFORM flag) this is what happens. ++ */ ++ if ((png_ptr->transformations & PNG_16_TO_8) != 0) ++ png_do_chop(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_QUANTIZE_SUPPORTED ++ if ((png_ptr->transformations & PNG_QUANTIZE) != 0) ++ { ++ png_do_quantize(row_info, png_ptr->row_buf + 1, ++ png_ptr->palette_lookup, png_ptr->quantize_index); ++ ++ if (row_info->rowbytes == 0) ++ png_error(png_ptr, "png_do_quantize returned rowbytes=0"); ++ } ++#endif /* READ_QUANTIZE */ ++ ++#ifdef PNG_READ_EXPAND_16_SUPPORTED ++ /* Do the expansion now, after all the arithmetic has been done. Notice ++ * that previous transformations can handle the PNG_EXPAND_16 flag if this ++ * is efficient (particularly true in the case of gamma correction, where ++ * better accuracy results faster!) ++ */ ++ if ((png_ptr->transformations & PNG_EXPAND_16) != 0) ++ png_do_expand_16(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED ++ /* NOTE: moved here in 1.5.4 (from much later in this list.) */ ++ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && ++ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) ++ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_INVERT_SUPPORTED ++ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) ++ png_do_invert(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED ++ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) ++ png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_SHIFT_SUPPORTED ++ if ((png_ptr->transformations & PNG_SHIFT) != 0) ++ png_do_unshift(row_info, png_ptr->row_buf + 1, ++ &(png_ptr->shift)); ++#endif ++ ++#ifdef PNG_READ_PACK_SUPPORTED ++ if ((png_ptr->transformations & PNG_PACK) != 0) ++ png_do_unpack(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED ++ /* Added at libpng-1.5.10 */ ++ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && ++ png_ptr->num_palette_max >= 0) ++ png_do_check_palette_indexes(png_ptr, row_info); ++#endif ++ ++#ifdef PNG_READ_BGR_SUPPORTED ++ if ((png_ptr->transformations & PNG_BGR) != 0) ++ png_do_bgr(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_PACKSWAP_SUPPORTED ++ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) ++ png_do_packswap(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_FILLER_SUPPORTED ++ if ((png_ptr->transformations & PNG_FILLER) != 0) ++ png_do_read_filler(row_info, png_ptr->row_buf + 1, ++ (png_uint_32)png_ptr->filler, png_ptr->flags); ++#endif ++ ++#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED ++ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) ++ png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_READ_16BIT_SUPPORTED ++#ifdef PNG_READ_SWAP_SUPPORTED ++ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) ++ png_do_swap(row_info, png_ptr->row_buf + 1); ++#endif ++#endif ++ ++#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED ++ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) ++ { ++ if (png_ptr->read_user_transform_fn != NULL) ++ (*(png_ptr->read_user_transform_fn)) /* User read transform function */ ++ (png_ptr, /* png_ptr */ ++ row_info, /* row_info: */ ++ /* png_uint_32 width; width of row */ ++ /* png_size_t rowbytes; number of bytes in row */ ++ /* png_byte color_type; color type of pixels */ ++ /* png_byte bit_depth; bit depth of samples */ ++ /* png_byte channels; number of channels (1-4) */ ++ /* png_byte pixel_depth; bits per pixel (depth*channels) */ ++ png_ptr->row_buf + 1); /* start of pixel data for row */ ++#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED ++ if (png_ptr->user_transform_depth != 0) ++ row_info->bit_depth = png_ptr->user_transform_depth; ++ ++ if (png_ptr->user_transform_channels != 0) ++ row_info->channels = png_ptr->user_transform_channels; ++#endif ++ row_info->pixel_depth = (png_byte)(row_info->bit_depth * ++ row_info->channels); ++ ++ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); ++ } ++#endif + } +-#endif /* PNG_MNG_FEATURES_SUPPORTED */ +-#endif /* PNG_READ_SUPPORTED */ ++ ++#endif /* READ_TRANSFORMS */ ++#endif /* READ */ +--- ./jdk/src/share/native/sun/awt/libpng/pngrutil.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngrutil.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -46,10 +46,8 @@ + + #ifdef PNG_READ_SUPPORTED + +-#define png_strtod(p,a,b) strtod(a,b) +- + png_uint_32 PNGAPI +-png_get_uint_31(png_structp png_ptr, png_const_bytep buf) ++png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) + { + png_uint_32 uval = png_get_uint_32(buf); + +@@ -68,7 +66,7 @@ + #define PNG_FIXED_ERROR (-1) + + static png_fixed_point /* PRIVATE */ +-png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) ++png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) + { + png_uint_32 uval = png_get_uint_32(buf); + +@@ -115,10 +113,10 @@ + png_get_int_32)(png_const_bytep buf) + { + png_uint_32 uval = png_get_uint_32(buf); +- if ((uval & 0x80000000L) == 0) /* non-negative */ ++ if ((uval & 0x80000000) == 0) /* non-negative */ + return uval; + +- uval = (uval ^ 0xffffffffL) + 1; /* 2's complement: -x = ~x+1 */ ++ uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ + return -(png_int_32)uval; + } + +@@ -126,7 +124,7 @@ + png_uint_16 (PNGAPI + png_get_uint_16)(png_const_bytep buf) + { +- /* ANSI-C requires an int value to accommodate at least 16 bits so this ++ /* ANSI-C requires an int value to accomodate at least 16 bits so this + * works and allows the compiler not to worry about possible narrowing + * on 32 bit systems. (Pre-ANSI systems did not make integers smaller + * than 16 bits either.) +@@ -138,11 +136,11 @@ + return (png_uint_16)val; + } + +-#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ ++#endif /* READ_INT_FUNCTIONS */ + + /* Read and check the PNG file signature */ + void /* PRIVATE */ +-png_read_sig(png_structp png_ptr, png_infop info_ptr) ++png_read_sig(png_structrp png_ptr, png_inforp info_ptr) + { + png_size_t num_checked, num_to_check; + +@@ -161,7 +159,7 @@ + png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); + png_ptr->sig_bytes = 8; + +- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) ++ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) +@@ -177,7 +175,7 @@ + * Put the type name into png_ptr->chunk_name, and return the length. + */ + png_uint_32 /* PRIVATE */ +-png_read_chunk_header(png_structp png_ptr) ++png_read_chunk_header(png_structrp png_ptr) + { + png_byte buf[8]; + png_uint_32 length; +@@ -193,14 +191,14 @@ + length = png_get_uint_31(png_ptr, buf); + + /* Put the chunk name into png_ptr->chunk_name. */ +- png_memcpy(png_ptr->chunk_name, buf + 4, 4); +- +- png_debug2(0, "Reading %s chunk, length = %u", +- png_ptr->chunk_name, length); ++ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); ++ ++ png_debug2(0, "Reading %lx chunk, length = %lu", ++ (unsigned long)png_ptr->chunk_name, (unsigned long)length); + + /* Reset the crc and run it over the chunk name. */ + png_reset_crc(png_ptr); +- png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); ++ png_calculate_crc(png_ptr, buf + 4, 4); + + /* Check to see if chunk name is valid. */ + png_check_chunk_name(png_ptr, png_ptr->chunk_name); +@@ -214,7 +212,7 @@ + + /* Read data, and (optionally) run it through the CRC. */ + void /* PRIVATE */ +-png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) ++png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) + { + if (png_ptr == NULL) + return; +@@ -224,41 +222,40 @@ + } + + /* Optionally skip data and then check the CRC. Depending on whether we +- * are reading a ancillary or critical chunk, and how the program has set ++ * are reading an ancillary or critical chunk, and how the program has set + * things up, we may calculate the CRC on the data and print a message. + * Returns '1' if there was a CRC error, '0' otherwise. + */ + int /* PRIVATE */ +-png_crc_finish(png_structp png_ptr, png_uint_32 skip) ++png_crc_finish(png_structrp png_ptr, png_uint_32 skip) + { +- png_size_t i; +- png_size_t istop = png_ptr->zbuf_size; +- +- for (i = (png_size_t)skip; i > istop; i -= istop) ++ /* The size of the local buffer for inflate is a good guess as to a ++ * reasonable size to use for buffering reads from the application. ++ */ ++ while (skip > 0) + { +- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); ++ png_uint_32 len; ++ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; ++ ++ len = (sizeof tmpbuf); ++ if (len > skip) ++ len = skip; ++ skip -= len; ++ ++ png_crc_read(png_ptr, tmpbuf, len); + } + +- if (i) ++ if (png_crc_error(png_ptr) != 0) + { +- png_crc_read(png_ptr, png_ptr->zbuf, i); +- } +- +- if (png_crc_error(png_ptr)) +- { +- if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ +- !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || +- (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ +- (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) ++ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? ++ (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : ++ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) + { + png_chunk_warning(png_ptr, "CRC error"); + } + + else +- { +- png_chunk_benign_error(png_ptr, "CRC error"); +- return (0); +- } ++ png_chunk_error(png_ptr, "CRC error"); + + return (1); + } +@@ -270,22 +267,22 @@ + * the data it has read thus far. + */ + int /* PRIVATE */ +-png_crc_error(png_structp png_ptr) ++png_crc_error(png_structrp png_ptr) + { + png_byte crc_bytes[4]; + png_uint_32 crc; + int need_crc = 1; + +- if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ ++ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + +- else /* critical */ ++ else /* critical */ + { +- if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) ++ if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) + need_crc = 0; + } + +@@ -296,7 +293,7 @@ + /* The chunk CRC must be serialized in a single I/O call. */ + png_read_data(png_ptr, crc_bytes, 4); + +- if (need_crc) ++ if (need_crc != 0) + { + crc = png_get_uint_32(crc_bytes); + return ((int)(crc != png_ptr->crc)); +@@ -306,252 +303,522 @@ + return (0); + } + ++#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ ++ defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ ++ defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ ++ defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) ++/* Manage the read buffer; this simply reallocates the buffer if it is not small ++ * enough (or if it is not allocated). The routine returns a pointer to the ++ * buffer; if an error occurs and 'warn' is set the routine returns NULL, else ++ * it will call png_error (via png_malloc) on failure. (warn == 2 means ++ * 'silent'). ++ */ ++static png_bytep ++png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) ++{ ++ png_bytep buffer = png_ptr->read_buffer; ++ ++ if (buffer != NULL && new_size > png_ptr->read_buffer_size) ++ { ++ png_ptr->read_buffer = NULL; ++ png_ptr->read_buffer = NULL; ++ png_ptr->read_buffer_size = 0; ++ png_free(png_ptr, buffer); ++ buffer = NULL; ++ } ++ ++ if (buffer == NULL) ++ { ++ buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); ++ ++ if (buffer != NULL) ++ { ++ png_ptr->read_buffer = buffer; ++ png_ptr->read_buffer_size = new_size; ++ } ++ ++ else if (warn < 2) /* else silent */ ++ { ++ if (warn != 0) ++ png_chunk_warning(png_ptr, "insufficient memory to read chunk"); ++ ++ else ++ png_chunk_error(png_ptr, "insufficient memory to read chunk"); ++ } ++ } ++ ++ return buffer; ++} ++#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ ++ ++/* png_inflate_claim: claim the zstream for some nefarious purpose that involves ++ * decompression. Returns Z_OK on success, else a zlib error code. It checks ++ * the owner but, in final release builds, just issues a warning if some other ++ * chunk apparently owns the stream. Prior to release it does a png_error. ++ */ ++static int ++png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) ++{ ++ if (png_ptr->zowner != 0) ++ { ++ char msg[64]; ++ ++ PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); ++ /* So the message that results is "<chunk> using zstream"; this is an ++ * internal error, but is very useful for debugging. i18n requirements ++ * are minimal. ++ */ ++ (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); ++#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC ++ png_chunk_warning(png_ptr, msg); ++ png_ptr->zowner = 0; ++#else ++ png_chunk_error(png_ptr, msg); ++#endif ++ } ++ ++ /* Implementation note: unlike 'png_deflate_claim' this internal function ++ * does not take the size of the data as an argument. Some efficiency could ++ * be gained by using this when it is known *if* the zlib stream itself does ++ * not record the number; however, this is an illusion: the original writer ++ * of the PNG may have selected a lower window size, and we really must ++ * follow that because, for systems with with limited capabilities, we ++ * would otherwise reject the application's attempts to use a smaller window ++ * size (zlib doesn't have an interface to say "this or lower"!). ++ * ++ * inflateReset2 was added to zlib 1.2.4; before this the window could not be ++ * reset, therefore it is necessary to always allocate the maximum window ++ * size with earlier zlibs just in case later compressed chunks need it. ++ */ ++ { ++ int ret; /* zlib return code */ ++#if PNG_ZLIB_VERNUM >= 0x1240 ++ ++# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) ++ int window_bits; ++ ++ if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == ++ PNG_OPTION_ON) ++ window_bits = 15; ++ ++ else ++ window_bits = 0; ++# else ++# define window_bits 0 ++# endif ++#endif ++ ++ /* Set this for safety, just in case the previous owner left pointers to ++ * memory allocations. ++ */ ++ png_ptr->zstream.next_in = NULL; ++ png_ptr->zstream.avail_in = 0; ++ png_ptr->zstream.next_out = NULL; ++ png_ptr->zstream.avail_out = 0; ++ ++ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) ++ { ++#if PNG_ZLIB_VERNUM < 0x1240 ++ ret = inflateReset(&png_ptr->zstream); ++#else ++ ret = inflateReset2(&png_ptr->zstream, window_bits); ++#endif ++ } ++ ++ else ++ { ++#if PNG_ZLIB_VERNUM < 0x1240 ++ ret = inflateInit(&png_ptr->zstream); ++#else ++ ret = inflateInit2(&png_ptr->zstream, window_bits); ++#endif ++ ++ if (ret == Z_OK) ++ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; ++ } ++ ++ if (ret == Z_OK) ++ png_ptr->zowner = owner; ++ ++ else ++ png_zstream_error(png_ptr, ret); ++ ++ return ret; ++ } ++ ++#ifdef window_bits ++# undef window_bits ++#endif ++} ++ + #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED +-static png_size_t +-png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, +- png_bytep output, png_size_t output_size) ++/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to ++ * allow the caller to do multiple calls if required. If the 'finish' flag is ++ * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must ++ * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and ++ * Z_OK or Z_STREAM_END will be returned on success. ++ * ++ * The input and output sizes are updated to the actual amounts of data consumed ++ * or written, not the amount available (as in a z_stream). The data pointers ++ * are not changed, so the next input is (data+input_size) and the next ++ * available output is (output+output_size). ++ */ ++static int ++png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, ++ /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, ++ /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) + { +- png_size_t count = 0; +- +- /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't +- * even necessarily handle 65536 bytes) because the type uInt is "16 bits or +- * more". Consequently it is necessary to chunk the input to zlib. This +- * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value +- * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a +- * lower value in pngpriv.h and this may sometimes have a performance +- * advantage, because it forces access of the input data to be separated from +- * at least some of the use by some period of time. +- */ +- png_ptr->zstream.next_in = data; +- /* avail_in is set below from 'size' */ +- png_ptr->zstream.avail_in = 0; +- +- while (1) ++ if (png_ptr->zowner == owner) /* Else not claimed */ + { +- int ret, avail; +- +- /* The setting of 'avail_in' used to be outside the loop, by setting it +- * inside it is possible to chunk the input to zlib and simply rely on +- * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o +- * data to be passed through zlib at the unavoidable cost of requiring a +- * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX +- * input bytes. ++ int ret; ++ png_alloc_size_t avail_out = *output_size_ptr; ++ png_uint_32 avail_in = *input_size_ptr; ++ ++ /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it ++ * can't even necessarily handle 65536 bytes) because the type uInt is ++ * "16 bits or more". Consequently it is necessary to chunk the input to ++ * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the ++ * maximum value that can be stored in a uInt.) It is possible to set ++ * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have ++ * a performance advantage, because it reduces the amount of data accessed ++ * at each step and that may give the OS more time to page it in. + */ +- if (png_ptr->zstream.avail_in == 0 && size > 0) ++ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); ++ /* avail_in and avail_out are set below from 'size' */ ++ png_ptr->zstream.avail_in = 0; ++ png_ptr->zstream.avail_out = 0; ++ ++ /* Read directly into the output if it is available (this is set to ++ * a local buffer below if output is NULL). ++ */ ++ if (output != NULL) ++ png_ptr->zstream.next_out = output; ++ ++ do + { +- if (size <= ZLIB_IO_MAX) ++ uInt avail; ++ Byte local_buffer[PNG_INFLATE_BUF_SIZE]; ++ ++ /* zlib INPUT BUFFER */ ++ /* The setting of 'avail_in' used to be outside the loop; by setting it ++ * inside it is possible to chunk the input to zlib and simply rely on ++ * zlib to advance the 'next_in' pointer. This allows arbitrary ++ * amounts of data to be passed through zlib at the unavoidable cost of ++ * requiring a window save (memcpy of up to 32768 output bytes) ++ * every ZLIB_IO_MAX input bytes. ++ */ ++ avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ ++ ++ avail = ZLIB_IO_MAX; ++ ++ if (avail_in < avail) ++ avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ ++ ++ avail_in -= avail; ++ png_ptr->zstream.avail_in = avail; ++ ++ /* zlib OUTPUT BUFFER */ ++ avail_out += png_ptr->zstream.avail_out; /* not written last time */ ++ ++ avail = ZLIB_IO_MAX; /* maximum zlib can process */ ++ ++ if (output == NULL) + { +- /* The value is less than ZLIB_IO_MAX so the cast is safe: */ +- png_ptr->zstream.avail_in = (uInt)size; +- size = 0; ++ /* Reset the output buffer each time round if output is NULL and ++ * make available the full buffer, up to 'remaining_space' ++ */ ++ png_ptr->zstream.next_out = local_buffer; ++ if ((sizeof local_buffer) < avail) ++ avail = (sizeof local_buffer); + } + +- else +- { +- png_ptr->zstream.avail_in = ZLIB_IO_MAX; +- size -= ZLIB_IO_MAX; +- } +- } +- +- /* Reset the output buffer each time round - we empty it +- * after every inflate call. ++ if (avail_out < avail) ++ avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ ++ ++ png_ptr->zstream.avail_out = avail; ++ avail_out -= avail; ++ ++ /* zlib inflate call */ ++ /* In fact 'avail_out' may be 0 at this point, that happens at the end ++ * of the read when the final LZ end code was not passed at the end of ++ * the previous chunk of input data. Tell zlib if we have reached the ++ * end of the output buffer. ++ */ ++ ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : ++ (finish ? Z_FINISH : Z_SYNC_FLUSH)); ++ } while (ret == Z_OK); ++ ++ /* For safety kill the local buffer pointer now */ ++ if (output == NULL) ++ png_ptr->zstream.next_out = NULL; ++ ++ /* Claw back the 'size' and 'remaining_space' byte counts. */ ++ avail_in += png_ptr->zstream.avail_in; ++ avail_out += png_ptr->zstream.avail_out; ++ ++ /* Update the input and output sizes; the updated values are the amount ++ * consumed or written, effectively the inverse of what zlib uses. + */ +- png_ptr->zstream.next_out = png_ptr->zbuf; +- png_ptr->zstream.avail_out = png_ptr->zbuf_size; +- +- ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); +- avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; +- +- /* First copy/count any new output - but only if we didn't +- * get an error code. ++ if (avail_out > 0) ++ *output_size_ptr -= avail_out; ++ ++ if (avail_in > 0) ++ *input_size_ptr -= avail_in; ++ ++ /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ ++ png_zstream_error(png_ptr, ret); ++ return ret; ++ } ++ ++ else ++ { ++ /* This is a bad internal error. The recovery assigns to the zstream msg ++ * pointer, which is not owned by the caller, but this is safe; it's only ++ * used on errors! + */ +- if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) +- { +- png_size_t space = avail; /* > 0, see above */ +- +- if (output != 0 && output_size > count) +- { +- png_size_t copy = output_size - count; +- +- if (space < copy) +- copy = space; +- +- png_memcpy(output + count, png_ptr->zbuf, copy); +- } +- count += space; +- } +- +- if (ret == Z_OK) +- continue; +- +- /* Termination conditions - always reset the zstream, it +- * must be left in inflateInit state. +- */ +- png_ptr->zstream.avail_in = 0; +- inflateReset(&png_ptr->zstream); +- +- if (ret == Z_STREAM_END) +- return count; /* NOTE: may be zero. */ +- +- /* Now handle the error codes - the API always returns 0 +- * and the error message is dumped into the uncompressed +- * buffer if available. +- */ +-# ifdef PNG_WARNINGS_SUPPORTED +- { +- png_const_charp msg; +- +- if (png_ptr->zstream.msg != 0) +- msg = png_ptr->zstream.msg; +- +- else switch (ret) +- { +- case Z_BUF_ERROR: +- msg = "Buffer error in compressed datastream"; +- break; +- +- case Z_DATA_ERROR: +- msg = "Data error in compressed datastream"; +- break; +- +- default: +- msg = "Incomplete compressed datastream"; +- break; +- } +- +- png_chunk_warning(png_ptr, msg); +- } +-# endif +- +- /* 0 means an error - notice that this code simply ignores +- * zero length compressed chunks as a result. +- */ +- return 0; ++ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); ++ return Z_STREAM_ERROR; + } + } + + /* +- * Decompress trailing data in a chunk. The assumption is that chunkdata ++ * Decompress trailing data in a chunk. The assumption is that read_buffer + * points at an allocated area holding the contents of a chunk with a + * trailing compressed part. What we get back is an allocated area + * holding the original prefix part and an uncompressed version of the + * trailing part (the malloc area passed in is freed). + */ ++static int ++png_decompress_chunk(png_structrp png_ptr, ++ png_uint_32 chunklength, png_uint_32 prefix_size, ++ png_alloc_size_t *newlength /* must be initialized to the maximum! */, ++ int terminate /*add a '\0' to the end of the uncompressed data*/) ++{ ++ /* TODO: implement different limits for different types of chunk. ++ * ++ * The caller supplies *newlength set to the maximum length of the ++ * uncompressed data, but this routine allocates space for the prefix and ++ * maybe a '\0' terminator too. We have to assume that 'prefix_size' is ++ * limited only by the maximum chunk size. ++ */ ++ png_alloc_size_t limit = PNG_SIZE_MAX; ++ ++# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED ++ if (png_ptr->user_chunk_malloc_max > 0 && ++ png_ptr->user_chunk_malloc_max < limit) ++ limit = png_ptr->user_chunk_malloc_max; ++# elif PNG_USER_CHUNK_MALLOC_MAX > 0 ++ if (PNG_USER_CHUNK_MALLOC_MAX < limit) ++ limit = PNG_USER_CHUNK_MALLOC_MAX; ++# endif ++ ++ if (limit >= prefix_size + (terminate != 0)) ++ { ++ int ret; ++ ++ limit -= prefix_size + (terminate != 0); ++ ++ if (limit < *newlength) ++ *newlength = limit; ++ ++ /* Now try to claim the stream. */ ++ ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); ++ ++ if (ret == Z_OK) ++ { ++ png_uint_32 lzsize = chunklength - prefix_size; ++ ++ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, ++ /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, ++ /* output: */ NULL, newlength); ++ ++ if (ret == Z_STREAM_END) ++ { ++ /* Use 'inflateReset' here, not 'inflateReset2' because this ++ * preserves the previously decided window size (otherwise it would ++ * be necessary to store the previous window size.) In practice ++ * this doesn't matter anyway, because png_inflate will call inflate ++ * with Z_FINISH in almost all cases, so the window will not be ++ * maintained. ++ */ ++ if (inflateReset(&png_ptr->zstream) == Z_OK) ++ { ++ /* Because of the limit checks above we know that the new, ++ * expanded, size will fit in a size_t (let alone an ++ * png_alloc_size_t). Use png_malloc_base here to avoid an ++ * extra OOM message. ++ */ ++ png_alloc_size_t new_size = *newlength; ++ png_alloc_size_t buffer_size = prefix_size + new_size + ++ (terminate != 0); ++ png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, ++ buffer_size)); ++ ++ if (text != NULL) ++ { ++ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, ++ png_ptr->read_buffer + prefix_size, &lzsize, ++ text + prefix_size, newlength); ++ ++ if (ret == Z_STREAM_END) ++ { ++ if (new_size == *newlength) ++ { ++ if (terminate != 0) ++ text[prefix_size + *newlength] = 0; ++ ++ if (prefix_size > 0) ++ memcpy(text, png_ptr->read_buffer, prefix_size); ++ ++ { ++ png_bytep old_ptr = png_ptr->read_buffer; ++ ++ png_ptr->read_buffer = text; ++ png_ptr->read_buffer_size = buffer_size; ++ text = old_ptr; /* freed below */ ++ } ++ } ++ ++ else ++ { ++ /* The size changed on the second read, there can be no ++ * guarantee that anything is correct at this point. ++ * The 'msg' pointer has been set to "unexpected end of ++ * LZ stream", which is fine, but return an error code ++ * that the caller won't accept. ++ */ ++ ret = PNG_UNEXPECTED_ZLIB_RETURN; ++ } ++ } ++ ++ else if (ret == Z_OK) ++ ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ ++ ++ /* Free the text pointer (this is the old read_buffer on ++ * success) ++ */ ++ png_free(png_ptr, text); ++ text = NULL; ++ ++ /* This really is very benign, but it's still an error because ++ * the extra space may otherwise be used as a Trojan Horse. ++ */ ++ if (ret == Z_STREAM_END && ++ chunklength - prefix_size != lzsize) ++ png_chunk_benign_error(png_ptr, "extra compressed data"); ++ } ++ ++ else ++ { ++ /* Out of memory allocating the buffer */ ++ ret = Z_MEM_ERROR; ++ png_zstream_error(png_ptr, Z_MEM_ERROR); ++ } ++ } ++ ++ else ++ { ++ /* inflateReset failed, store the error message */ ++ png_zstream_error(png_ptr, ret); ++ ++ if (ret == Z_STREAM_END) ++ ret = PNG_UNEXPECTED_ZLIB_RETURN; ++ } ++ } ++ ++ else if (ret == Z_OK) ++ ret = PNG_UNEXPECTED_ZLIB_RETURN; ++ ++ /* Release the claimed stream */ ++ png_ptr->zowner = 0; ++ } ++ ++ else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ ++ ret = PNG_UNEXPECTED_ZLIB_RETURN; ++ ++ return ret; ++ } ++ ++ else ++ { ++ /* Application/configuration limits exceeded */ ++ png_zstream_error(png_ptr, Z_MEM_ERROR); ++ return Z_MEM_ERROR; ++ } ++} ++#endif /* READ_COMPRESSED_TEXT */ ++ ++#ifdef PNG_READ_iCCP_SUPPORTED ++/* Perform a partial read and decompress, producing 'avail_out' bytes and ++ * reading from the current chunk as required. ++ */ ++static int ++png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, ++ png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, ++ int finish) ++{ ++ if (png_ptr->zowner == png_ptr->chunk_name) ++ { ++ int ret; ++ ++ /* next_in and avail_in must have been initialized by the caller. */ ++ png_ptr->zstream.next_out = next_out; ++ png_ptr->zstream.avail_out = 0; /* set in the loop */ ++ ++ do ++ { ++ if (png_ptr->zstream.avail_in == 0) ++ { ++ if (read_size > *chunk_bytes) ++ read_size = (uInt)*chunk_bytes; ++ *chunk_bytes -= read_size; ++ ++ if (read_size > 0) ++ png_crc_read(png_ptr, read_buffer, read_size); ++ ++ png_ptr->zstream.next_in = read_buffer; ++ png_ptr->zstream.avail_in = read_size; ++ } ++ ++ if (png_ptr->zstream.avail_out == 0) ++ { ++ uInt avail = ZLIB_IO_MAX; ++ if (avail > *out_size) ++ avail = (uInt)*out_size; ++ *out_size -= avail; ++ ++ png_ptr->zstream.avail_out = avail; ++ } ++ ++ /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all ++ * the available output is produced; this allows reading of truncated ++ * streams. ++ */ ++ ret = inflate(&png_ptr->zstream, ++ *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); ++ } ++ while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); ++ ++ *out_size += png_ptr->zstream.avail_out; ++ png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ ++ ++ /* Ensure the error message pointer is always set: */ ++ png_zstream_error(png_ptr, ret); ++ return ret; ++ } ++ ++ else ++ { ++ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); ++ return Z_STREAM_ERROR; ++ } ++} ++#endif ++ ++/* Read and check the IDHR chunk */ ++ + void /* PRIVATE */ +-png_decompress_chunk(png_structp png_ptr, int comp_type, +- png_size_t chunklength, +- png_size_t prefix_size, png_size_t *newlength) +-{ +- /* The caller should guarantee this */ +- if (prefix_size > chunklength) +- { +- /* The recovery is to delete the chunk. */ +- png_warning(png_ptr, "invalid chunklength"); +- prefix_size = 0; /* To delete everything */ +- } +- +- else if (comp_type == PNG_COMPRESSION_TYPE_BASE) +- { +- png_size_t expanded_size = png_inflate(png_ptr, +- (png_bytep)(png_ptr->chunkdata + prefix_size), +- chunklength - prefix_size, +- 0, /* output */ +- 0); /* output size */ +- +- /* Now check the limits on this chunk - if the limit fails the +- * compressed data will be removed, the prefix will remain. +- */ +-#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +- if (png_ptr->user_chunk_malloc_max && +- (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) +-#else +-# ifdef PNG_USER_CHUNK_MALLOC_MAX +- if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && +- prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) +-# endif +-#endif +- png_warning(png_ptr, "Exceeded size limit while expanding chunk"); +- +- /* If the size is zero either there was an error and a message +- * has already been output (warning) or the size really is zero +- * and we have nothing to do - the code will exit through the +- * error case below. +- */ +-#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ +- defined(PNG_USER_CHUNK_MALLOC_MAX) +- else if (expanded_size > 0) +-#else +- if (expanded_size > 0) +-#endif +- { +- /* Success (maybe) - really uncompress the chunk. */ +- png_size_t new_size = 0; +- png_charp text = png_malloc_warn(png_ptr, +- prefix_size + expanded_size + 1); +- +- if (text != NULL) +- { +- png_memcpy(text, png_ptr->chunkdata, prefix_size); +- new_size = png_inflate(png_ptr, +- (png_bytep)(png_ptr->chunkdata + prefix_size), +- chunklength - prefix_size, +- (png_bytep)(text + prefix_size), expanded_size); +- text[prefix_size + expanded_size] = 0; /* just in case */ +- +- if (new_size == expanded_size) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = text; +- *newlength = prefix_size + expanded_size; +- return; /* The success return! */ +- } +- +- png_warning(png_ptr, "png_inflate logic error"); +- png_free(png_ptr, text); +- } +- +- else +- png_warning(png_ptr, "Not enough memory to decompress chunk"); +- } +- } +- +- else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ +- { +- PNG_WARNING_PARAMETERS(p) +- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type); +- png_formatted_warning(png_ptr, p, "Unknown zTXt compression type @1"); +- +- /* The recovery is to simply drop the data. */ +- } +- +- /* Generic error return - leave the prefix, delete the compressed +- * data, reallocate the chunkdata to remove the potentially large +- * amount of compressed data. +- */ +- { +- png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); +- +- if (text != NULL) +- { +- if (prefix_size > 0) +- png_memcpy(text, png_ptr->chunkdata, prefix_size); +- +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = text; +- +- /* This is an extra zero in the 'uncompressed' part. */ +- *(png_ptr->chunkdata + prefix_size) = 0x00; +- } +- /* Ignore a malloc error here - it is safe. */ +- } +- +- *newlength = prefix_size; +-} +-#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ +- +-/* Read and check the IDHR chunk */ +-void /* PRIVATE */ +-png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_byte buf[13]; + png_uint_32 width, height; +@@ -560,12 +827,12 @@ + + png_debug(1, "in png_handle_IHDR"); + +- if (png_ptr->mode & PNG_HAVE_IHDR) +- png_error(png_ptr, "Out of place IHDR"); ++ if ((png_ptr->mode & PNG_HAVE_IHDR) != 0) ++ png_chunk_error(png_ptr, "out of place"); + + /* Check the length */ + if (length != 13) +- png_error(png_ptr, "Invalid IHDR chunk"); ++ png_chunk_error(png_ptr, "invalid"); + + png_ptr->mode |= PNG_HAVE_IHDR; + +@@ -614,8 +881,7 @@ + } + + /* Set up other useful info */ +- png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * +- png_ptr->channels); ++ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); + png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); + png_debug1(3, "channels = %d", png_ptr->channels); +@@ -626,7 +892,7 @@ + + /* Read and check the palette */ + void /* PRIVATE */ +-png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_color palette[PNG_MAX_PALETTE_LENGTH]; + int num, i; +@@ -636,26 +902,33 @@ + + png_debug(1, "in png_handle_PLTE"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before PLTE"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ /* Moved to before the 'after IDAT' check below because otherwise duplicate ++ * PLTE chunks are potentially ignored (the spec says there shall not be more ++ * than one PLTE, the error is not treated as benign, so this check trumps ++ * the requirement that PLTE appears before IDAT.) ++ */ ++ else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) ++ png_chunk_error(png_ptr, "duplicate"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { +- png_warning(png_ptr, "Invalid PLTE after IDAT"); ++ /* This is benign because the non-benign error happened before, when an ++ * IDAT was encountered in a color-mapped image with no PLTE. ++ */ + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- else if (png_ptr->mode & PNG_HAVE_PLTE) +- png_error(png_ptr, "Duplicate PLTE chunk"); +- + png_ptr->mode |= PNG_HAVE_PLTE; + +- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) ++ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + { +- png_warning(png_ptr, +- "Ignoring PLTE chunk in grayscale PNG"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); + return; + } + +@@ -669,19 +942,18 @@ + + if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) + { ++ png_crc_finish(png_ptr, length); ++ + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) +- { +- png_warning(png_ptr, "Invalid palette chunk"); +- png_crc_finish(png_ptr, length); +- return; +- } ++ png_chunk_benign_error(png_ptr, "invalid"); + + else +- { +- png_error(png_ptr, "Invalid palette chunk"); +- } ++ png_chunk_error(png_ptr, "invalid"); ++ ++ return; + } + ++ /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ + num = (int)length / 3; + + #ifdef PNG_POINTER_INDEXING_SUPPORTED +@@ -720,214 +992,196 @@ + } + + #ifndef PNG_READ_OPT_PLTE_SUPPORTED +- else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ ++ else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */ + { + /* If we don't want to use the data from an ancillary chunk, + * we have two options: an error abort, or a warning and we + * ignore the data in this chunk (which should be OK, since + * it's considered ancillary for a RGB or RGBA image). ++ * ++ * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the ++ * chunk type to determine whether to check the ancillary or the critical ++ * flags. + */ +- if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) ++ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0) + { +- if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) +- { +- png_chunk_benign_error(png_ptr, "CRC error"); +- } ++ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0) ++ return; + + else +- { +- png_chunk_warning(png_ptr, "CRC error"); +- return; +- } ++ png_chunk_error(png_ptr, "CRC error"); + } + + /* Otherwise, we (optionally) emit a warning and use the chunk. */ +- else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) +- { ++ else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0) + png_chunk_warning(png_ptr, "CRC error"); +- } + } + #endif + ++ /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its ++ * own copy of the palette. This has the side effect that when png_start_row ++ * is called (this happens after any call to png_read_update_info) the ++ * info_ptr palette gets changed. This is extremely unexpected and ++ * confusing. ++ * ++ * Fix this by not sharing the palette in this way. ++ */ + png_set_PLTE(png_ptr, info_ptr, palette, num); + ++ /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before ++ * IDAT. Prior to 1.6.0 this was not checked; instead the code merely ++ * checked the apparent validity of a tRNS chunk inserted before PLTE on a ++ * palette PNG. 1.6.0 attempts to rigorously follow the standard and ++ * therefore does a benign error if the erroneous condition is detected *and* ++ * cancels the tRNS if the benign error returns. The alternative is to ++ * amend the standard since it would be rather hypocritical of the standards ++ * maintainers to ignore it. ++ */ + #ifdef PNG_READ_tRNS_SUPPORTED +- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ++ if (png_ptr->num_trans > 0 || ++ (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) + { +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) +- { +- if (png_ptr->num_trans > (png_uint_16)num) +- { +- png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); +- png_ptr->num_trans = (png_uint_16)num; +- } +- +- if (info_ptr->num_trans > (png_uint_16)num) +- { +- png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); +- info_ptr->num_trans = (png_uint_16)num; +- } +- } ++ /* Cancel this because otherwise it would be used if the transforms ++ * require it. Don't cancel the 'valid' flag because this would prevent ++ * detection of duplicate chunks. ++ */ ++ png_ptr->num_trans = 0; ++ ++ if (info_ptr != NULL) ++ info_ptr->num_trans = 0; ++ ++ png_chunk_benign_error(png_ptr, "tRNS must be after"); + } + #endif + ++#ifdef PNG_READ_hIST_SUPPORTED ++ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) ++ png_chunk_benign_error(png_ptr, "hIST must be after"); ++#endif ++ ++#ifdef PNG_READ_bKGD_SUPPORTED ++ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) ++ png_chunk_benign_error(png_ptr, "bKGD must be after"); ++#endif + } + + void /* PRIVATE */ +-png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_debug(1, "in png_handle_IEND"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) +- { +- png_error(png_ptr, "No image in file"); +- } ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 || ++ (png_ptr->mode & PNG_HAVE_IDAT) == 0) ++ png_chunk_error(png_ptr, "out of place"); + + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); + ++ png_crc_finish(png_ptr, length); ++ + if (length != 0) +- { +- png_warning(png_ptr, "Incorrect IEND chunk length"); +- } +- +- png_crc_finish(png_ptr, length); +- +- PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ ++ png_chunk_benign_error(png_ptr, "invalid"); ++ ++ PNG_UNUSED(info_ptr) + } + + #ifdef PNG_READ_gAMA_SUPPORTED + void /* PRIVATE */ +-png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_fixed_point igamma; + png_byte buf[4]; + + png_debug(1, "in png_handle_gAMA"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before gAMA"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) + { +- png_warning(png_ptr, "Invalid gAMA after IDAT"); ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); ++ return; ++ } ++ ++ if (length != 4) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); ++ return; ++ } ++ ++ png_crc_read(png_ptr, buf, 4); ++ ++ if (png_crc_finish(png_ptr, 0) != 0) ++ return; ++ ++ igamma = png_get_fixed_point(NULL, buf); ++ ++ png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); ++ png_colorspace_sync(png_ptr, info_ptr); ++} ++#endif ++ ++#ifdef PNG_READ_sBIT_SUPPORTED ++void /* PRIVATE */ ++png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) ++{ ++ unsigned int truelen, i; ++ png_byte sample_depth; ++ png_byte buf[4]; ++ ++ png_debug(1, "in png_handle_sBIT"); ++ ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); ++ return; ++ } ++ ++ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); ++ return; ++ } ++ ++ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ++ { ++ truelen = 3; ++ sample_depth = 8; ++ } ++ ++ else ++ { ++ truelen = png_ptr->channels; ++ sample_depth = png_ptr->bit_depth; ++ } ++ ++ if (length != truelen || length > 4) ++ { ++ png_chunk_benign_error(png_ptr, "invalid"); + png_crc_finish(png_ptr, length); + return; + } + +- else if (png_ptr->mode & PNG_HAVE_PLTE) +- /* Should be an error, but we can cope with it */ +- png_warning(png_ptr, "Out of place gAMA chunk"); +- +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) +-#ifdef PNG_READ_sRGB_SUPPORTED +- && !(info_ptr->valid & PNG_INFO_sRGB) +-#endif +- ) +- { +- png_warning(png_ptr, "Duplicate gAMA chunk"); +- png_crc_finish(png_ptr, length); ++ buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; ++ png_crc_read(png_ptr, buf, truelen); ++ ++ if (png_crc_finish(png_ptr, 0) != 0) + return; +- } +- +- if (length != 4) +- { +- png_warning(png_ptr, "Incorrect gAMA chunk length"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- png_crc_read(png_ptr, buf, 4); +- +- if (png_crc_finish(png_ptr, 0)) +- return; +- +- igamma = png_get_fixed_point(NULL, buf); +- +- /* Check for zero gamma or an error. */ +- if (igamma <= 0) +- { +- png_warning(png_ptr, +- "Ignoring gAMA chunk with out of range gamma"); +- +- return; +- } +- +-# ifdef PNG_READ_sRGB_SUPPORTED +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) +- { +- if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) ++ ++ for (i=0; i<truelen; ++i) ++ if (buf[i] == 0 || buf[i] > sample_depth) + { +- PNG_WARNING_PARAMETERS(p) +- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); +- png_formatted_warning(png_ptr, p, +- "Ignoring incorrect gAMA value @1 when sRGB is also present"); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } +- } +-# endif /* PNG_READ_sRGB_SUPPORTED */ +- +-# ifdef PNG_READ_GAMMA_SUPPORTED +- /* Gamma correction on read is supported. */ +- png_ptr->gamma = igamma; +-# endif +- /* And set the 'info' structure members. */ +- png_set_gAMA_fixed(png_ptr, info_ptr, igamma); +-} +-#endif +- +-#ifdef PNG_READ_sBIT_SUPPORTED +-void /* PRIVATE */ +-png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +-{ +- png_size_t truelen; +- png_byte buf[4]; +- +- png_debug(1, "in png_handle_sBIT"); +- +- buf[0] = buf[1] = buf[2] = buf[3] = 0; +- +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before sBIT"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) +- { +- png_warning(png_ptr, "Invalid sBIT after IDAT"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- else if (png_ptr->mode & PNG_HAVE_PLTE) +- { +- /* Should be an error, but we can cope with it */ +- png_warning(png_ptr, "Out of place sBIT chunk"); +- } +- +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) +- { +- png_warning(png_ptr, "Duplicate sBIT chunk"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +- truelen = 3; +- +- else +- truelen = (png_size_t)png_ptr->channels; +- +- if (length != truelen || length > 4) +- { +- png_warning(png_ptr, "Incorrect sBIT chunk length"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- png_crc_read(png_ptr, buf, truelen); +- +- if (png_crc_finish(png_ptr, 0)) +- return; +- +- if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) ++ ++ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[1]; +@@ -950,377 +1204,416 @@ + + #ifdef PNG_READ_cHRM_SUPPORTED + void /* PRIVATE */ +-png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_byte buf[32]; +- png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, +- y_blue; ++ png_xy xy; + + png_debug(1, "in png_handle_cHRM"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before cHRM"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) + { +- png_warning(png_ptr, "Invalid cHRM after IDAT"); ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); ++ return; ++ } ++ ++ if (length != 32) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); ++ return; ++ } ++ ++ png_crc_read(png_ptr, buf, 32); ++ ++ if (png_crc_finish(png_ptr, 0) != 0) ++ return; ++ ++ xy.whitex = png_get_fixed_point(NULL, buf); ++ xy.whitey = png_get_fixed_point(NULL, buf + 4); ++ xy.redx = png_get_fixed_point(NULL, buf + 8); ++ xy.redy = png_get_fixed_point(NULL, buf + 12); ++ xy.greenx = png_get_fixed_point(NULL, buf + 16); ++ xy.greeny = png_get_fixed_point(NULL, buf + 20); ++ xy.bluex = png_get_fixed_point(NULL, buf + 24); ++ xy.bluey = png_get_fixed_point(NULL, buf + 28); ++ ++ if (xy.whitex == PNG_FIXED_ERROR || ++ xy.whitey == PNG_FIXED_ERROR || ++ xy.redx == PNG_FIXED_ERROR || ++ xy.redy == PNG_FIXED_ERROR || ++ xy.greenx == PNG_FIXED_ERROR || ++ xy.greeny == PNG_FIXED_ERROR || ++ xy.bluex == PNG_FIXED_ERROR || ++ xy.bluey == PNG_FIXED_ERROR) ++ { ++ png_chunk_benign_error(png_ptr, "invalid values"); ++ return; ++ } ++ ++ /* If a colorspace error has already been output skip this chunk */ ++ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) ++ return; ++ ++ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0) ++ { ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; ++ png_colorspace_sync(png_ptr, info_ptr); ++ png_chunk_benign_error(png_ptr, "duplicate"); ++ return; ++ } ++ ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; ++ (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, ++ 1/*prefer cHRM values*/); ++ png_colorspace_sync(png_ptr, info_ptr); ++} ++#endif ++ ++#ifdef PNG_READ_sRGB_SUPPORTED ++void /* PRIVATE */ ++png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) ++{ ++ png_byte intent; ++ ++ png_debug(1, "in png_handle_sRGB"); ++ ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); ++ return; ++ } ++ ++ if (length != 1) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); ++ return; ++ } ++ ++ png_crc_read(png_ptr, &intent, 1); ++ ++ if (png_crc_finish(png_ptr, 0) != 0) ++ return; ++ ++ /* If a colorspace error has already been output skip this chunk */ ++ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) ++ return; ++ ++ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect ++ * this. ++ */ ++ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0) ++ { ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; ++ png_colorspace_sync(png_ptr, info_ptr); ++ png_chunk_benign_error(png_ptr, "too many profiles"); ++ return; ++ } ++ ++ (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); ++ png_colorspace_sync(png_ptr, info_ptr); ++} ++#endif /* READ_sRGB */ ++ ++#ifdef PNG_READ_iCCP_SUPPORTED ++void /* PRIVATE */ ++png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) ++/* Note: this does not properly handle profiles that are > 64K under DOS */ ++{ ++ png_const_charp errmsg = NULL; /* error message output, or no error */ ++ int finished = 0; /* crc checked */ ++ ++ png_debug(1, "in png_handle_iCCP"); ++ ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); ++ return; ++ } ++ ++ /* Consistent with all the above colorspace handling an obviously *invalid* ++ * chunk is just ignored, so does not invalidate the color space. An ++ * alternative is to set the 'invalid' flags at the start of this routine ++ * and only clear them in they were not set before and all the tests pass. ++ * The minimum 'deflate' stream is assumed to be just the 2 byte header and ++ * 4 byte checksum. The keyword must be at least one character and there is ++ * a terminator (0) byte and the compression method. ++ */ ++ if (length < 9) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "too short"); ++ return; ++ } ++ ++ /* If a colorspace error has already been output skip this chunk */ ++ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) ++ { + png_crc_finish(png_ptr, length); + return; + } + +- else if (png_ptr->mode & PNG_HAVE_PLTE) +- /* Should be an error, but we can cope with it */ +- png_warning(png_ptr, "Missing PLTE before cHRM"); +- +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) +-# ifdef PNG_READ_sRGB_SUPPORTED +- && !(info_ptr->valid & PNG_INFO_sRGB) +-# endif +- ) ++ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect ++ * this. ++ */ ++ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) + { +- png_warning(png_ptr, "Duplicate cHRM chunk"); ++ uInt read_length, keyword_length; ++ char keyword[81]; ++ ++ /* Find the keyword; the keyword plus separator and compression method ++ * bytes can be at most 81 characters long. ++ */ ++ read_length = 81; /* maximum */ ++ if (read_length > length) ++ read_length = (uInt)length; ++ ++ png_crc_read(png_ptr, (png_bytep)keyword, read_length); ++ length -= read_length; ++ ++ keyword_length = 0; ++ while (keyword_length < 80 && keyword_length < read_length && ++ keyword[keyword_length] != 0) ++ ++keyword_length; ++ ++ /* TODO: make the keyword checking common */ ++ if (keyword_length >= 1 && keyword_length <= 79) ++ { ++ /* We only understand '0' compression - deflate - so if we get a ++ * different value we can't safely decode the chunk. ++ */ ++ if (keyword_length+1 < read_length && ++ keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) ++ { ++ read_length -= keyword_length+2; ++ ++ if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) ++ { ++ Byte profile_header[132]; ++ Byte local_buffer[PNG_INFLATE_BUF_SIZE]; ++ png_alloc_size_t size = (sizeof profile_header); ++ ++ png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); ++ png_ptr->zstream.avail_in = read_length; ++ (void)png_inflate_read(png_ptr, local_buffer, ++ (sizeof local_buffer), &length, profile_header, &size, ++ 0/*finish: don't, because the output is too small*/); ++ ++ if (size == 0) ++ { ++ /* We have the ICC profile header; do the basic header checks. ++ */ ++ const png_uint_32 profile_length = ++ png_get_uint_32(profile_header); ++ ++ if (png_icc_check_length(png_ptr, &png_ptr->colorspace, ++ keyword, profile_length) != 0) ++ { ++ /* The length is apparently ok, so we can check the 132 ++ * byte header. ++ */ ++ if (png_icc_check_header(png_ptr, &png_ptr->colorspace, ++ keyword, profile_length, profile_header, ++ png_ptr->color_type) != 0) ++ { ++ /* Now read the tag table; a variable size buffer is ++ * needed at this point, allocate one for the whole ++ * profile. The header check has already validated ++ * that none of these stuff will overflow. ++ */ ++ const png_uint_32 tag_count = png_get_uint_32( ++ profile_header+128); ++ png_bytep profile = png_read_buffer(png_ptr, ++ profile_length, 2/*silent*/); ++ ++ if (profile != NULL) ++ { ++ memcpy(profile, profile_header, ++ (sizeof profile_header)); ++ ++ size = 12 * tag_count; ++ ++ (void)png_inflate_read(png_ptr, local_buffer, ++ (sizeof local_buffer), &length, ++ profile + (sizeof profile_header), &size, 0); ++ ++ /* Still expect a buffer error because we expect ++ * there to be some tag data! ++ */ ++ if (size == 0) ++ { ++ if (png_icc_check_tag_table(png_ptr, ++ &png_ptr->colorspace, keyword, profile_length, ++ profile) != 0) ++ { ++ /* The profile has been validated for basic ++ * security issues, so read the whole thing in. ++ */ ++ size = profile_length - (sizeof profile_header) ++ - 12 * tag_count; ++ ++ (void)png_inflate_read(png_ptr, local_buffer, ++ (sizeof local_buffer), &length, ++ profile + (sizeof profile_header) + ++ 12 * tag_count, &size, 1/*finish*/); ++ ++ if (length > 0 && !(png_ptr->flags & ++ PNG_FLAG_BENIGN_ERRORS_WARN)) ++ errmsg = "extra compressed data"; ++ ++ /* But otherwise allow extra data: */ ++ else if (size == 0) ++ { ++ if (length > 0) ++ { ++ /* This can be handled completely, so ++ * keep going. ++ */ ++ png_chunk_warning(png_ptr, ++ "extra compressed data"); ++ } ++ ++ png_crc_finish(png_ptr, length); ++ finished = 1; ++ ++# ifdef PNG_sRGB_SUPPORTED ++ /* Check for a match against sRGB */ ++ png_icc_set_sRGB(png_ptr, ++ &png_ptr->colorspace, profile, ++ png_ptr->zstream.adler); ++# endif ++ ++ /* Steal the profile for info_ptr. */ ++ if (info_ptr != NULL) ++ { ++ png_free_data(png_ptr, info_ptr, ++ PNG_FREE_ICCP, 0); ++ ++ info_ptr->iccp_name = png_voidcast(char*, ++ png_malloc_base(png_ptr, ++ keyword_length+1)); ++ if (info_ptr->iccp_name != NULL) ++ { ++ memcpy(info_ptr->iccp_name, keyword, ++ keyword_length+1); ++ info_ptr->iccp_proflen = ++ profile_length; ++ info_ptr->iccp_profile = profile; ++ png_ptr->read_buffer = NULL; /*steal*/ ++ info_ptr->free_me |= PNG_FREE_ICCP; ++ info_ptr->valid |= PNG_INFO_iCCP; ++ } ++ ++ else ++ { ++ png_ptr->colorspace.flags |= ++ PNG_COLORSPACE_INVALID; ++ errmsg = "out of memory"; ++ } ++ } ++ ++ /* else the profile remains in the read ++ * buffer which gets reused for subsequent ++ * chunks. ++ */ ++ ++ if (info_ptr != NULL) ++ png_colorspace_sync(png_ptr, info_ptr); ++ ++ if (errmsg == NULL) ++ { ++ png_ptr->zowner = 0; ++ return; ++ } ++ } ++ ++ else if (size > 0) ++ errmsg = "truncated"; ++ ++ else ++ errmsg = png_ptr->zstream.msg; ++ } ++ ++ /* else png_icc_check_tag_table output an error */ ++ } ++ ++ else /* profile truncated */ ++ errmsg = png_ptr->zstream.msg; ++ } ++ ++ else ++ errmsg = "out of memory"; ++ } ++ ++ /* else png_icc_check_header output an error */ ++ } ++ ++ /* else png_icc_check_length output an error */ ++ } ++ ++ else /* profile truncated */ ++ errmsg = png_ptr->zstream.msg; ++ ++ /* Release the stream */ ++ png_ptr->zowner = 0; ++ } ++ ++ else /* png_inflate_claim failed */ ++ errmsg = png_ptr->zstream.msg; ++ } ++ ++ else ++ errmsg = "bad compression method"; /* or missing */ ++ } ++ ++ else ++ errmsg = "bad keyword"; ++ } ++ ++ else ++ errmsg = "too many profiles"; ++ ++ /* Failure: the reason is in 'errmsg' */ ++ if (finished == 0) + png_crc_finish(png_ptr, length); +- return; +- } +- +- if (length != 32) +- { +- png_warning(png_ptr, "Incorrect cHRM chunk length"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- png_crc_read(png_ptr, buf, 32); +- +- if (png_crc_finish(png_ptr, 0)) +- return; +- +- x_white = png_get_fixed_point(NULL, buf); +- y_white = png_get_fixed_point(NULL, buf + 4); +- x_red = png_get_fixed_point(NULL, buf + 8); +- y_red = png_get_fixed_point(NULL, buf + 12); +- x_green = png_get_fixed_point(NULL, buf + 16); +- y_green = png_get_fixed_point(NULL, buf + 20); +- x_blue = png_get_fixed_point(NULL, buf + 24); +- y_blue = png_get_fixed_point(NULL, buf + 28); +- +- if (x_white == PNG_FIXED_ERROR || +- y_white == PNG_FIXED_ERROR || +- x_red == PNG_FIXED_ERROR || +- y_red == PNG_FIXED_ERROR || +- x_green == PNG_FIXED_ERROR || +- y_green == PNG_FIXED_ERROR || +- x_blue == PNG_FIXED_ERROR || +- y_blue == PNG_FIXED_ERROR) +- { +- png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); +- return; +- } +- +-#ifdef PNG_READ_sRGB_SUPPORTED +- if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) +- { +- if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || +- PNG_OUT_OF_RANGE(y_white, 32900, 1000) || +- PNG_OUT_OF_RANGE(x_red, 64000L, 1000) || +- PNG_OUT_OF_RANGE(y_red, 33000, 1000) || +- PNG_OUT_OF_RANGE(x_green, 30000, 1000) || +- PNG_OUT_OF_RANGE(y_green, 60000L, 1000) || +- PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || +- PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) +- { +- PNG_WARNING_PARAMETERS(p) +- +- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white); +- png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white); +- png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red); +- png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red); +- png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green); +- png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green); +- png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue); +- png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue); +- +- png_formatted_warning(png_ptr, p, +- "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) " +- "when sRGB is also present"); +- } +- return; +- } +-#endif /* PNG_READ_sRGB_SUPPORTED */ +- +-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +- /* Store the _white values as default coefficients for the rgb to gray +- * operation if it is supported. +- */ +- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) +- { +- /* png_set_background has not been called, the coefficients must be in +- * range for the following to work without overflow. +- */ +- if (y_red <= (1<<17) && y_green <= (1<<17) && y_blue <= (1<<17)) +- { +- /* The y values are chromaticities: Y/X+Y+Z, the weights for the gray +- * transformation are simply the normalized Y values for red, green and +- * blue scaled by 32768. +- */ +- png_uint_32 w = y_red + y_green + y_blue; +- +- png_ptr->rgb_to_gray_red_coeff = (png_uint_16)(((png_uint_32)y_red * +- 32768)/w); +- png_ptr->rgb_to_gray_green_coeff = (png_uint_16)(((png_uint_32)y_green +- * 32768)/w); +- png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(((png_uint_32)y_blue * +- 32768)/w); +- } +- } +-#endif +- +- png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, +- x_green, y_green, x_blue, y_blue); ++ ++ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; ++ png_colorspace_sync(png_ptr, info_ptr); ++ if (errmsg != NULL) /* else already output */ ++ png_chunk_benign_error(png_ptr, errmsg); + } +-#endif +- +-#ifdef PNG_READ_sRGB_SUPPORTED ++#endif /* READ_iCCP */ ++ ++#ifdef PNG_READ_sPLT_SUPPORTED + void /* PRIVATE */ +-png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +-{ +- int intent; +- png_byte buf[1]; +- +- png_debug(1, "in png_handle_sRGB"); +- +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before sRGB"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) +- { +- png_warning(png_ptr, "Invalid sRGB after IDAT"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- else if (png_ptr->mode & PNG_HAVE_PLTE) +- /* Should be an error, but we can cope with it */ +- png_warning(png_ptr, "Out of place sRGB chunk"); +- +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) +- { +- png_warning(png_ptr, "Duplicate sRGB chunk"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- if (length != 1) +- { +- png_warning(png_ptr, "Incorrect sRGB chunk length"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- png_crc_read(png_ptr, buf, 1); +- +- if (png_crc_finish(png_ptr, 0)) +- return; +- +- intent = buf[0]; +- +- /* Check for bad intent */ +- if (intent >= PNG_sRGB_INTENT_LAST) +- { +- png_warning(png_ptr, "Unknown sRGB intent"); +- return; +- } +- +-#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) +- { +- if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500)) +- { +- PNG_WARNING_PARAMETERS(p) +- +- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, +- info_ptr->gamma); +- +- png_formatted_warning(png_ptr, p, +- "Ignoring incorrect gAMA value @1 when sRGB is also present"); +- } +- } +-#endif /* PNG_READ_gAMA_SUPPORTED */ +- +-#ifdef PNG_READ_cHRM_SUPPORTED +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) +- if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || +- PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || +- PNG_OUT_OF_RANGE(info_ptr->x_red, 64000L, 1000) || +- PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || +- PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || +- PNG_OUT_OF_RANGE(info_ptr->y_green, 60000L, 1000) || +- PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || +- PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) +- { +- png_warning(png_ptr, +- "Ignoring incorrect cHRM value when sRGB is also present"); +- } +-#endif /* PNG_READ_cHRM_SUPPORTED */ +- +- png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); +-} +-#endif /* PNG_READ_sRGB_SUPPORTED */ +- +-#ifdef PNG_READ_iCCP_SUPPORTED +-void /* PRIVATE */ +-png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + /* Note: this does not properly handle chunks that are > 64K under DOS */ + { +- png_byte compression_type; +- png_bytep pC; +- png_charp profile; +- png_uint_32 skip = 0; +- png_uint_32 profile_size; +- png_alloc_size_t profile_length; +- png_size_t slength, prefix_length, data_length; +- +- png_debug(1, "in png_handle_iCCP"); +- +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before iCCP"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) +- { +- png_warning(png_ptr, "Invalid iCCP after IDAT"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- else if (png_ptr->mode & PNG_HAVE_PLTE) +- /* Should be an error, but we can cope with it */ +- png_warning(png_ptr, "Out of place iCCP chunk"); +- +- if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) +- { +- png_warning(png_ptr, "Duplicate iCCP chunk"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +-#ifdef PNG_MAX_MALLOC_64K +- if (length > (png_uint_32)65535L) +- { +- png_warning(png_ptr, "iCCP chunk too large to fit in memory"); +- skip = length - (png_uint_32)65535L; +- length = (png_uint_32)65535L; +- } +-#endif +- +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); +- slength = (png_size_t)length; +- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); +- +- if (png_crc_finish(png_ptr, skip)) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- png_ptr->chunkdata[slength] = 0x00; +- +- for (profile = png_ptr->chunkdata; *profile; profile++) +- /* Empty loop to find end of name */ ; +- +- ++profile; +- +- /* There should be at least one zero (the compression type byte) +- * following the separator, and we should be on it +- */ +- if (profile >= png_ptr->chunkdata + slength - 1) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- png_warning(png_ptr, "Malformed iCCP chunk"); +- return; +- } +- +- /* Compression_type should always be zero */ +- compression_type = *profile++; +- +- if (compression_type) +- { +- png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); +- compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 +- wrote nonzero) */ +- } +- +- prefix_length = profile - png_ptr->chunkdata; +- png_decompress_chunk(png_ptr, compression_type, +- slength, prefix_length, &data_length); +- +- profile_length = data_length - prefix_length; +- +- if (prefix_length > data_length || profile_length < 4) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- png_warning(png_ptr, "Profile size field missing from iCCP chunk"); +- return; +- } +- +- /* Check the profile_size recorded in the first 32 bits of the ICC profile */ +- pC = (png_bytep)(png_ptr->chunkdata + prefix_length); +- profile_size = ((*(pC )) << 24) | +- ((*(pC + 1)) << 16) | +- ((*(pC + 2)) << 8) | +- ((*(pC + 3)) ); +- +- /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, +- * because profile_size is a 32 bit value. +- */ +- if (profile_size < profile_length) +- profile_length = profile_size; +- +- /* And the following guarantees that profile_size == profile_length. */ +- if (profile_size > profile_length) +- { +- PNG_WARNING_PARAMETERS(p) +- +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- +- png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size); +- png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length); +- png_formatted_warning(png_ptr, p, +- "Ignoring iCCP chunk with declared size = @1 and actual length = @2"); +- return; +- } +- +- png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, +- compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, +- profile_size); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +-} +-#endif /* PNG_READ_iCCP_SUPPORTED */ +- +-#ifdef PNG_READ_sPLT_SUPPORTED +-void /* PRIVATE */ +-png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +-/* Note: this does not properly handle chunks that are > 64K under DOS */ +-{ +- png_bytep entry_start; ++ png_bytep entry_start, buffer; + png_sPLT_t new_palette; + png_sPLT_entryp pp; + png_uint_32 data_length; + int entry_size, i; + png_uint_32 skip = 0; +- png_size_t slength; + png_uint_32 dl; + png_size_t max_dl; + + png_debug(1, "in png_handle_sPLT"); + + #ifdef PNG_USER_LIMITS_SUPPORTED +- + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) +@@ -1338,55 +1631,53 @@ + } + #endif + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before sPLT"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { +- png_warning(png_ptr, "Invalid sPLT after IDAT"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + + #ifdef PNG_MAX_MALLOC_64K +- if (length > (png_uint_32)65535L) ++ if (length > 65535U) + { +- png_warning(png_ptr, "sPLT chunk too large to fit in memory"); +- skip = length - (png_uint_32)65535L; +- length = (png_uint_32)65535L; ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "too large to fit in memory"); ++ return; + } + #endif + +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); ++ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); ++ if (buffer == NULL) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of memory"); ++ return; ++ } ++ + + /* WARNING: this may break if size_t is less than 32 bits; it is assumed + * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a + * potential breakage point if the types in pngconf.h aren't exactly right. + */ +- slength = (png_size_t)length; +- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); +- +- if (png_crc_finish(png_ptr, skip)) ++ png_crc_read(png_ptr, buffer, length); ++ ++ if (png_crc_finish(png_ptr, skip) != 0) ++ return; ++ ++ buffer[length] = 0; ++ ++ for (entry_start = buffer; *entry_start; entry_start++) ++ /* Empty loop to find end of name */ ; ++ ++ ++entry_start; ++ ++ /* A sample depth should follow the separator, and we should be on it */ ++ if (entry_start > buffer + length - 2) + { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- png_ptr->chunkdata[slength] = 0x00; +- +- for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; +- entry_start++) +- /* Empty loop to find end of name */ ; +- +- ++entry_start; +- +- /* A sample depth should follow the separator, and we should be on it */ +- if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; + png_warning(png_ptr, "malformed sPLT chunk"); + return; + } +@@ -1394,23 +1685,19 @@ + new_palette.depth = *entry_start++; + entry_size = (new_palette.depth == 8 ? 6 : 10); + /* This must fit in a png_uint_32 because it is derived from the original +- * chunk data length (and use 'length', not 'slength' here for clarity - +- * they are guaranteed to be the same, see the tests above.) ++ * chunk data length. + */ +- data_length = length - (png_uint_32)(entry_start - +- (png_bytep)png_ptr->chunkdata); ++ data_length = length - (png_uint_32)(entry_start - buffer); + + /* Integrity-check the data length */ +- if (data_length % entry_size) ++ if ((data_length % entry_size) != 0) + { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; + png_warning(png_ptr, "sPLT chunk has bad length"); + return; + } + + dl = (png_int_32)(data_length / entry_size); +- max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); ++ max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); + + if (dl > max_dl) + { +@@ -1421,7 +1708,7 @@ + new_palette.nentries = (png_int_32)(data_length / entry_size); + + new_palette.entries = (png_sPLT_entryp)png_malloc_warn( +- png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); ++ png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry))); + + if (new_palette.entries == NULL) + { +@@ -1479,38 +1766,36 @@ + #endif + + /* Discard all chunk data except the name and stash that */ +- new_palette.name = png_ptr->chunkdata; ++ new_palette.name = (png_charp)buffer; + + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); + +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; + png_free(png_ptr, new_palette.entries); + } +-#endif /* PNG_READ_sPLT_SUPPORTED */ ++#endif /* READ_sPLT */ + + #ifdef PNG_READ_tRNS_SUPPORTED + void /* PRIVATE */ +-png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_tRNS"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before tRNS"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { +- png_warning(png_ptr, "Invalid tRNS after IDAT"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) + { +- png_warning(png_ptr, "Duplicate tRNS chunk"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + +@@ -1520,8 +1805,8 @@ + + if (length != 2) + { +- png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + +@@ -1536,12 +1821,12 @@ + + if (length != 6) + { +- png_warning(png_ptr, "Incorrect tRNS chunk length"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + +- png_crc_read(png_ptr, buf, (png_size_t)length); ++ png_crc_read(png_ptr, buf, length); + png_ptr->num_trans = 1; + png_ptr->trans_color.red = png_get_uint_16(buf); + png_ptr->trans_color.green = png_get_uint_16(buf + 2); +@@ -1550,44 +1835,43 @@ + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { +- if (!(png_ptr->mode & PNG_HAVE_PLTE)) ++ if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) + { +- /* Should be an error, but we can cope with it. */ +- png_warning(png_ptr, "Missing PLTE before tRNS"); +- } +- +- if (length > (png_uint_32)png_ptr->num_palette || +- length > PNG_MAX_PALETTE_LENGTH) +- { +- png_warning(png_ptr, "Incorrect tRNS chunk length"); ++ /* TODO: is this actually an error in the ISO spec? */ + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- if (length == 0) ++ if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH || ++ length == 0) + { +- png_warning(png_ptr, "Zero length tRNS chunk"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + +- png_crc_read(png_ptr, readbuf, (png_size_t)length); ++ png_crc_read(png_ptr, readbuf, length); + png_ptr->num_trans = (png_uint_16)length; + } + + else + { +- png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid with alpha channel"); + return; + } + +- if (png_crc_finish(png_ptr, 0)) ++ if (png_crc_finish(png_ptr, 0) != 0) + { + png_ptr->num_trans = 0; + return; + } + ++ /* TODO: this is a horrible side effect in the palette case because the ++ * png_struct ends up with a pointer to the tRNS buffer owned by the ++ * png_info. Fix this. ++ */ + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, + &(png_ptr->trans_color)); + } +@@ -1595,58 +1879,52 @@ + + #ifdef PNG_READ_bKGD_SUPPORTED + void /* PRIVATE */ +-png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { +- png_size_t truelen; ++ unsigned int truelen; + png_byte buf[6]; + png_color_16 background; + + png_debug(1, "in png_handle_bKGD"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before bKGD"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || ++ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && ++ (png_ptr->mode & PNG_HAVE_PLTE) == 0)) + { +- png_warning(png_ptr, "Invalid bKGD after IDAT"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && +- !(png_ptr->mode & PNG_HAVE_PLTE)) ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) + { +- png_warning(png_ptr, "Missing PLTE before bKGD"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) ++ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ++ truelen = 1; ++ ++ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) ++ truelen = 6; ++ ++ else ++ truelen = 2; ++ ++ if (length != truelen) + { +- png_warning(png_ptr, "Duplicate bKGD chunk"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + +- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +- truelen = 1; +- +- else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) +- truelen = 6; +- +- else +- truelen = 2; +- +- if (length != truelen) +- { +- png_warning(png_ptr, "Incorrect bKGD chunk length"); +- png_crc_finish(png_ptr, length); +- return; +- } +- + png_crc_read(png_ptr, buf, truelen); + +- if (png_crc_finish(png_ptr, 0)) ++ if (png_crc_finish(png_ptr, 0) != 0) + return; + + /* We convert the index value into RGB components so that we can allow +@@ -1658,11 +1936,11 @@ + { + background.index = buf[0]; + +- if (info_ptr && info_ptr->num_palette) ++ if (info_ptr != NULL && info_ptr->num_palette != 0) + { + if (buf[0] >= info_ptr->num_palette) + { +- png_warning(png_ptr, "Incorrect bKGD chunk index value"); ++ png_chunk_benign_error(png_ptr, "invalid index"); + return; + } + +@@ -1677,7 +1955,7 @@ + background.gray = 0; + } + +- else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ ++ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ + { + background.index = 0; + background.red = +@@ -1701,44 +1979,37 @@ + + #ifdef PNG_READ_hIST_SUPPORTED + void /* PRIVATE */ +-png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + unsigned int num, i; + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_hIST"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before hIST"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || ++ (png_ptr->mode & PNG_HAVE_PLTE) == 0) + { +- png_warning(png_ptr, "Invalid hIST after IDAT"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- else if (!(png_ptr->mode & PNG_HAVE_PLTE)) ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) + { +- png_warning(png_ptr, "Missing PLTE before hIST"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) ++ num = length / 2 ; ++ ++ if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH) + { +- png_warning(png_ptr, "Duplicate hIST chunk"); + png_crc_finish(png_ptr, length); +- return; +- } +- +- num = length / 2 ; +- +- if (num != (unsigned int)png_ptr->num_palette || num > +- (unsigned int)PNG_MAX_PALETTE_LENGTH) +- { +- png_warning(png_ptr, "Incorrect hIST chunk length"); +- png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + +@@ -1750,7 +2021,7 @@ + readbuf[i] = png_get_uint_16(buf); + } + +- if (png_crc_finish(png_ptr, 0)) ++ if (png_crc_finish(png_ptr, 0) != 0) + return; + + png_set_hIST(png_ptr, info_ptr, readbuf); +@@ -1759,7 +2030,7 @@ + + #ifdef PNG_READ_pHYs_SUPPORTED + void /* PRIVATE */ +-png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_byte buf[9]; + png_uint_32 res_x, res_y; +@@ -1767,33 +2038,33 @@ + + png_debug(1, "in png_handle_pHYs"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before pHYs"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { +- png_warning(png_ptr, "Invalid pHYs after IDAT"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) + { +- png_warning(png_ptr, "Duplicate pHYs chunk"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + if (length != 9) + { +- png_warning(png_ptr, "Incorrect pHYs chunk length"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, buf, 9); + +- if (png_crc_finish(png_ptr, 0)) ++ if (png_crc_finish(png_ptr, 0) != 0) + return; + + res_x = png_get_uint_32(buf); +@@ -1805,7 +2076,7 @@ + + #ifdef PNG_READ_oFFs_SUPPORTED + void /* PRIVATE */ +-png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_byte buf[9]; + png_int_32 offset_x, offset_y; +@@ -1813,33 +2084,33 @@ + + png_debug(1, "in png_handle_oFFs"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before oFFs"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { +- png_warning(png_ptr, "Invalid oFFs after IDAT"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) + { +- png_warning(png_ptr, "Duplicate oFFs chunk"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + if (length != 9) + { +- png_warning(png_ptr, "Incorrect oFFs chunk length"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, buf, 9); + +- if (png_crc_finish(png_ptr, 0)) ++ if (png_crc_finish(png_ptr, 0) != 0) + return; + + offset_x = png_get_int_32(buf); +@@ -1852,71 +2123,64 @@ + #ifdef PNG_READ_pCAL_SUPPORTED + /* Read the pCAL chunk (described in the PNG Extensions document) */ + void /* PRIVATE */ +-png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_int_32 X0, X1; + png_byte type, nparams; +- png_charp buf, units, endptr; ++ png_bytep buffer, buf, units, endptr; + png_charpp params; +- png_size_t slength; + int i; + + png_debug(1, "in png_handle_pCAL"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before pCAL"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { +- png_warning(png_ptr, "Invalid pCAL after IDAT"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); + return; + } + +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0) + { +- png_warning(png_ptr, "Duplicate pCAL chunk"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + + png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", + length + 1); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); +- +- if (png_ptr->chunkdata == NULL) ++ ++ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); ++ ++ if (buffer == NULL) + { +- png_warning(png_ptr, "No memory for pCAL purpose"); ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + +- slength = (png_size_t)length; +- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); +- +- if (png_crc_finish(png_ptr, 0)) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; ++ png_crc_read(png_ptr, buffer, length); ++ ++ if (png_crc_finish(png_ptr, 0) != 0) + return; +- } +- +- png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ ++ ++ buffer[length] = 0; /* Null terminate the last string */ + + png_debug(3, "Finding end of pCAL purpose string"); +- for (buf = png_ptr->chunkdata; *buf; buf++) ++ for (buf = buffer; *buf; buf++) + /* Empty loop */ ; + +- endptr = png_ptr->chunkdata + slength; ++ endptr = buffer + length; + + /* We need to have at least 12 bytes after the purpose string + * in order to get the parameter information. + */ + if (endptr <= buf + 12) + { +- png_warning(png_ptr, "Invalid pCAL data"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + +@@ -1936,15 +2200,13 @@ + (type == PNG_EQUATION_ARBITRARY && nparams != 3) || + (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) + { +- png_warning(png_ptr, "Invalid pCAL parameters for equation type"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; ++ png_chunk_benign_error(png_ptr, "invalid parameter count"); + return; + } + + else if (type >= PNG_EQUATION_LAST) + { +- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); ++ png_chunk_benign_error(png_ptr, "unrecognized equation type"); + } + + for (buf = units; *buf; buf++) +@@ -1952,43 +2214,37 @@ + + png_debug(3, "Allocating pCAL parameters array"); + +- params = (png_charpp)png_malloc_warn(png_ptr, +- (png_size_t)(nparams * png_sizeof(png_charp))); ++ params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, ++ nparams * (sizeof (png_charp)))); + + if (params == NULL) + { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- png_warning(png_ptr, "No memory for pCAL params"); ++ png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + + /* Get pointers to the start of each parameter string. */ +- for (i = 0; i < (int)nparams; i++) ++ for (i = 0; i < nparams; i++) + { + buf++; /* Skip the null string terminator from previous parameter. */ + + png_debug1(3, "Reading pCAL parameter %d", i); + +- for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) ++ for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) + /* Empty loop to move past each parameter string */ ; + + /* Make sure we haven't run out of data yet */ + if (buf > endptr) + { +- png_warning(png_ptr, "Invalid pCAL data"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; + png_free(png_ptr, params); ++ png_chunk_benign_error(png_ptr, "invalid data"); + return; + } + } + +- png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, +- units, params); +- +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; ++ png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, ++ (png_charp)units, params); ++ + png_free(png_ptr, params); + } + #endif +@@ -1996,67 +2252,61 @@ + #ifdef PNG_READ_sCAL_SUPPORTED + /* Read the sCAL chunk */ + void /* PRIVATE */ +-png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { +- png_size_t slength, i; ++ png_bytep buffer; ++ png_size_t i; + int state; + + png_debug(1, "in png_handle_sCAL"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before sCAL"); +- +- else if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { +- png_warning(png_ptr, "Invalid sCAL after IDAT"); ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of place"); ++ return; ++ } ++ ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); ++ return; ++ } ++ ++ /* Need unit type, width, \0, height: minimum 4 bytes */ ++ else if (length < 4) ++ { ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); ++ return; ++ } ++ ++ png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", ++ length + 1); ++ ++ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); ++ ++ if (buffer == NULL) ++ { ++ png_chunk_benign_error(png_ptr, "out of memory"); + png_crc_finish(png_ptr, length); + return; + } + +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) ++ png_crc_read(png_ptr, buffer, length); ++ buffer[length] = 0; /* Null terminate the last string */ ++ ++ if (png_crc_finish(png_ptr, 0) != 0) ++ return; ++ ++ /* Validate the unit. */ ++ if (buffer[0] != 1 && buffer[0] != 2) + { +- png_warning(png_ptr, "Duplicate sCAL chunk"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- /* Need unit type, width, \0, height: minimum 4 bytes */ +- else if (length < 4) +- { +- png_warning(png_ptr, "sCAL chunk too short"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", +- length + 1); +- +- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); +- +- if (png_ptr->chunkdata == NULL) +- { +- png_warning(png_ptr, "Out of memory while processing sCAL chunk"); +- png_crc_finish(png_ptr, length); +- return; +- } +- +- slength = (png_size_t)length; +- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); +- png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ +- +- if (png_crc_finish(png_ptr, 0)) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- /* Validate the unit. */ +- if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) +- { +- png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; ++ png_chunk_benign_error(png_ptr, "invalid unit"); + return; + } + +@@ -2066,70 +2316,65 @@ + i = 1; + state = 0; + +- if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || +- i >= slength || png_ptr->chunkdata[i++] != 0) +- png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); +- +- else if (!PNG_FP_IS_POSITIVE(state)) +- png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width"); ++ if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 || ++ i >= length || buffer[i++] != 0) ++ png_chunk_benign_error(png_ptr, "bad width format"); ++ ++ else if (PNG_FP_IS_POSITIVE(state) == 0) ++ png_chunk_benign_error(png_ptr, "non-positive width"); + + else + { + png_size_t heighti = i; + + state = 0; +- if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || +- i != slength) +- png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); +- +- else if (!PNG_FP_IS_POSITIVE(state)) +- png_warning(png_ptr, +- "Invalid sCAL chunk ignored: non-positive height"); ++ if (png_check_fp_number((png_const_charp)buffer, length, ++ &state, &i) == 0 || i != length) ++ png_chunk_benign_error(png_ptr, "bad height format"); ++ ++ else if (PNG_FP_IS_POSITIVE(state) == 0) ++ png_chunk_benign_error(png_ptr, "non-positive height"); + + else + /* This is the (only) success case. */ +- png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], +- png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); ++ png_set_sCAL_s(png_ptr, info_ptr, buffer[0], ++ (png_charp)buffer+1, (png_charp)buffer+heighti); + } +- +- /* Clean up - just free the temporarily allocated buffer. */ +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; + } + #endif + + #ifdef PNG_READ_tIME_SUPPORTED + void /* PRIVATE */ +-png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { + png_byte buf[7]; + png_time mod_time; + + png_debug(1, "in png_handle_tIME"); + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Out of place tIME chunk"); +- +- else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0) + { +- png_warning(png_ptr, "Duplicate tIME chunk"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "duplicate"); + return; + } + +- if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + png_ptr->mode |= PNG_AFTER_IDAT; + + if (length != 7) + { +- png_warning(png_ptr, "Incorrect tIME chunk length"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "invalid"); + return; + } + + png_crc_read(png_ptr, buf, 7); + +- if (png_crc_finish(png_ptr, 0)) ++ if (png_crc_finish(png_ptr, 0) != 0) + return; + + mod_time.second = buf[6]; +@@ -2146,14 +2391,13 @@ + #ifdef PNG_READ_tEXt_SUPPORTED + /* Note: this does not properly handle chunks that are > 64K under DOS */ + void /* PRIVATE */ +-png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { +- png_textp text_ptr; ++ png_text text_info; ++ png_bytep buffer; + png_charp key; + png_charp text; + png_uint_32 skip = 0; +- png_size_t slength; +- int ret; + + png_debug(1, "in png_handle_tEXt"); + +@@ -2168,84 +2412,59 @@ + + if (--png_ptr->user_chunk_cache_max == 1) + { +- png_warning(png_ptr, "No space in chunk cache for tEXt"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "no space in chunk cache"); + return; + } + } + #endif + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before tEXt"); +- +- if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + png_ptr->mode |= PNG_AFTER_IDAT; + + #ifdef PNG_MAX_MALLOC_64K +- if (length > (png_uint_32)65535L) ++ if (length > 65535U) + { +- png_warning(png_ptr, "tEXt chunk too large to fit in memory"); +- skip = length - (png_uint_32)65535L; +- length = (png_uint_32)65535L; ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "too large to fit in memory"); ++ return; + } + #endif + +- png_free(png_ptr, png_ptr->chunkdata); +- +- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); +- +- if (png_ptr->chunkdata == NULL) ++ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); ++ ++ if (buffer == NULL) + { +- png_warning(png_ptr, "No memory to process text chunk"); ++ png_chunk_benign_error(png_ptr, "out of memory"); + return; + } + +- slength = (png_size_t)length; +- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); +- +- if (png_crc_finish(png_ptr, skip)) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; ++ png_crc_read(png_ptr, buffer, length); ++ ++ if (png_crc_finish(png_ptr, skip) != 0) + return; +- } +- +- key = png_ptr->chunkdata; +- +- key[slength] = 0x00; ++ ++ key = (png_charp)buffer; ++ key[length] = 0; + + for (text = key; *text; text++) + /* Empty loop to find end of key */ ; + +- if (text != key + slength) ++ if (text != key + length) + text++; + +- text_ptr = (png_textp)png_malloc_warn(png_ptr, +- png_sizeof(png_text)); +- +- if (text_ptr == NULL) +- { +- png_warning(png_ptr, "Not enough memory to process text chunk"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; +- text_ptr->key = key; +- text_ptr->lang = NULL; +- text_ptr->lang_key = NULL; +- text_ptr->itxt_length = 0; +- text_ptr->text = text; +- text_ptr->text_length = png_strlen(text); +- +- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); +- +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- png_free(png_ptr, text_ptr); +- +- if (ret) ++ text_info.compression = PNG_TEXT_COMPRESSION_NONE; ++ text_info.key = key; ++ text_info.lang = NULL; ++ text_info.lang_key = NULL; ++ text_info.itxt_length = 0; ++ text_info.text = text; ++ text_info.text_length = strlen(text); ++ ++ if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0) + png_warning(png_ptr, "Insufficient memory to process text chunk"); + } + #endif +@@ -2253,13 +2472,11 @@ + #ifdef PNG_READ_zTXt_SUPPORTED + /* Note: this does not correctly handle chunks that are > 64K under DOS */ + void /* PRIVATE */ +-png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { +- png_textp text_ptr; +- png_charp text; +- int comp_type; +- int ret; +- png_size_t slength, prefix_len, data_len; ++ png_const_charp errmsg = NULL; ++ png_bytep buffer; ++ png_uint_32 keyword_length; + + png_debug(1, "in png_handle_zTXt"); + +@@ -2274,123 +2491,101 @@ + + if (--png_ptr->user_chunk_cache_max == 1) + { +- png_warning(png_ptr, "No space in chunk cache for zTXt"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "no space in chunk cache"); + return; + } + } + #endif + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before zTXt"); +- +- if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + png_ptr->mode |= PNG_AFTER_IDAT; + +-#ifdef PNG_MAX_MALLOC_64K +- /* We will no doubt have problems with chunks even half this size, but +- * there is no hard and fast rule to tell us where to stop. +- */ +- if (length > (png_uint_32)65535L) ++ buffer = png_read_buffer(png_ptr, length, 2/*silent*/); ++ ++ if (buffer == NULL) + { +- png_warning(png_ptr, "zTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of memory"); + return; + } +-#endif +- +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); +- +- if (png_ptr->chunkdata == NULL) +- { +- png_warning(png_ptr, "Out of memory processing zTXt chunk"); ++ ++ png_crc_read(png_ptr, buffer, length); ++ ++ if (png_crc_finish(png_ptr, 0) != 0) + return; +- } +- +- slength = (png_size_t)length; +- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); +- +- if (png_crc_finish(png_ptr, 0)) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- png_ptr->chunkdata[slength] = 0x00; +- +- for (text = png_ptr->chunkdata; *text; text++) +- /* Empty loop */ ; +- +- /* zTXt must have some text after the chunkdataword */ +- if (text >= png_ptr->chunkdata + slength - 2) +- { +- png_warning(png_ptr, "Truncated zTXt chunk"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } ++ ++ /* TODO: also check that the keyword contents match the spec! */ ++ for (keyword_length = 0; ++ keyword_length < length && buffer[keyword_length] != 0; ++ ++keyword_length) ++ /* Empty loop to find end of name */ ; ++ ++ if (keyword_length > 79 || keyword_length < 1) ++ errmsg = "bad keyword"; ++ ++ /* zTXt must have some LZ data after the keyword, although it may expand to ++ * zero bytes; we need a '\0' at the end of the keyword, the compression type ++ * then the LZ data: ++ */ ++ else if (keyword_length + 3 > length) ++ errmsg = "truncated"; ++ ++ else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) ++ errmsg = "unknown compression type"; + + else + { +- comp_type = *(++text); +- +- if (comp_type != PNG_TEXT_COMPRESSION_zTXt) +- { +- png_warning(png_ptr, "Unknown compression type in zTXt chunk"); +- comp_type = PNG_TEXT_COMPRESSION_zTXt; +- } +- +- text++; /* Skip the compression_method byte */ ++ png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; ++ ++ /* TODO: at present png_decompress_chunk imposes a single application ++ * level memory limit, this should be split to different values for iCCP ++ * and text chunks. ++ */ ++ if (png_decompress_chunk(png_ptr, length, keyword_length+2, ++ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) ++ { ++ png_text text; ++ ++ /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except ++ * for the extra compression type byte and the fact that it isn't ++ * necessarily '\0' terminated. ++ */ ++ buffer = png_ptr->read_buffer; ++ buffer[uncompressed_length+(keyword_length+2)] = 0; ++ ++ text.compression = PNG_TEXT_COMPRESSION_zTXt; ++ text.key = (png_charp)buffer; ++ text.text = (png_charp)(buffer + keyword_length+2); ++ text.text_length = uncompressed_length; ++ text.itxt_length = 0; ++ text.lang = NULL; ++ text.lang_key = NULL; ++ ++ if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) ++ errmsg = "insufficient memory"; ++ } ++ ++ else ++ errmsg = png_ptr->zstream.msg; + } + +- prefix_len = text - png_ptr->chunkdata; +- +- png_decompress_chunk(png_ptr, comp_type, +- (png_size_t)length, prefix_len, &data_len); +- +- text_ptr = (png_textp)png_malloc_warn(png_ptr, +- png_sizeof(png_text)); +- +- if (text_ptr == NULL) +- { +- png_warning(png_ptr, "Not enough memory to process zTXt chunk"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- text_ptr->compression = comp_type; +- text_ptr->key = png_ptr->chunkdata; +- text_ptr->lang = NULL; +- text_ptr->lang_key = NULL; +- text_ptr->itxt_length = 0; +- text_ptr->text = png_ptr->chunkdata + prefix_len; +- text_ptr->text_length = data_len; +- +- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); +- +- png_free(png_ptr, text_ptr); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- +- if (ret) +- png_error(png_ptr, "Insufficient memory to store zTXt chunk"); ++ if (errmsg != NULL) ++ png_chunk_benign_error(png_ptr, errmsg); + } + #endif + + #ifdef PNG_READ_iTXt_SUPPORTED + /* Note: this does not correctly handle chunks that are > 64K under DOS */ + void /* PRIVATE */ +-png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) + { +- png_textp text_ptr; +- png_charp key, lang, text, lang_key; +- int comp_flag; +- int comp_type = 0; +- int ret; +- png_size_t slength, prefix_len, data_len; ++ png_const_charp errmsg = NULL; ++ png_bytep buffer; ++ png_uint_32 prefix_length; + + png_debug(1, "in png_handle_iTXt"); + +@@ -2405,274 +2600,393 @@ + + if (--png_ptr->user_chunk_cache_max == 1) + { +- png_warning(png_ptr, "No space in chunk cache for iTXt"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "no space in chunk cache"); + return; + } + } + #endif + +- if (!(png_ptr->mode & PNG_HAVE_IHDR)) +- png_error(png_ptr, "Missing IHDR before iTXt"); +- +- if (png_ptr->mode & PNG_HAVE_IDAT) ++ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) ++ png_chunk_error(png_ptr, "missing IHDR"); ++ ++ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + png_ptr->mode |= PNG_AFTER_IDAT; + +-#ifdef PNG_MAX_MALLOC_64K +- /* We will no doubt have problems with chunks even half this size, but +- * there is no hard and fast rule to tell us where to stop. +- */ +- if (length > (png_uint_32)65535L) ++ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); ++ ++ if (buffer == NULL) + { +- png_warning(png_ptr, "iTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "out of memory"); + return; + } +-#endif +- +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); +- +- if (png_ptr->chunkdata == NULL) ++ ++ png_crc_read(png_ptr, buffer, length); ++ ++ if (png_crc_finish(png_ptr, 0) != 0) ++ return; ++ ++ /* First the keyword. */ ++ for (prefix_length=0; ++ prefix_length < length && buffer[prefix_length] != 0; ++ ++prefix_length) ++ /* Empty loop */ ; ++ ++ /* Perform a basic check on the keyword length here. */ ++ if (prefix_length > 79 || prefix_length < 1) ++ errmsg = "bad keyword"; ++ ++ /* Expect keyword, compression flag, compression type, language, translated ++ * keyword (both may be empty but are 0 terminated) then the text, which may ++ * be empty. ++ */ ++ else if (prefix_length + 5 > length) ++ errmsg = "truncated"; ++ ++ else if (buffer[prefix_length+1] == 0 || ++ (buffer[prefix_length+1] == 1 && ++ buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) + { +- png_warning(png_ptr, "No memory to process iTXt chunk"); +- return; ++ int compressed = buffer[prefix_length+1] != 0; ++ png_uint_32 language_offset, translated_keyword_offset; ++ png_alloc_size_t uncompressed_length = 0; ++ ++ /* Now the language tag */ ++ prefix_length += 3; ++ language_offset = prefix_length; ++ ++ for (; prefix_length < length && buffer[prefix_length] != 0; ++ ++prefix_length) ++ /* Empty loop */ ; ++ ++ /* WARNING: the length may be invalid here, this is checked below. */ ++ translated_keyword_offset = ++prefix_length; ++ ++ for (; prefix_length < length && buffer[prefix_length] != 0; ++ ++prefix_length) ++ /* Empty loop */ ; ++ ++ /* prefix_length should now be at the trailing '\0' of the translated ++ * keyword, but it may already be over the end. None of this arithmetic ++ * can overflow because chunks are at most 2^31 bytes long, but on 16-bit ++ * systems the available allocation may overflow. ++ */ ++ ++prefix_length; ++ ++ if (compressed == 0 && prefix_length <= length) ++ uncompressed_length = length - prefix_length; ++ ++ else if (compressed != 0 && prefix_length < length) ++ { ++ uncompressed_length = PNG_SIZE_MAX; ++ ++ /* TODO: at present png_decompress_chunk imposes a single application ++ * level memory limit, this should be split to different values for ++ * iCCP and text chunks. ++ */ ++ if (png_decompress_chunk(png_ptr, length, prefix_length, ++ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) ++ buffer = png_ptr->read_buffer; ++ ++ else ++ errmsg = png_ptr->zstream.msg; ++ } ++ ++ else ++ errmsg = "truncated"; ++ ++ if (errmsg == NULL) ++ { ++ png_text text; ++ ++ buffer[uncompressed_length+prefix_length] = 0; ++ ++ if (compressed == 0) ++ text.compression = PNG_ITXT_COMPRESSION_NONE; ++ ++ else ++ text.compression = PNG_ITXT_COMPRESSION_zTXt; ++ ++ text.key = (png_charp)buffer; ++ text.lang = (png_charp)buffer + language_offset; ++ text.lang_key = (png_charp)buffer + translated_keyword_offset; ++ text.text = (png_charp)buffer + prefix_length; ++ text.text_length = 0; ++ text.itxt_length = uncompressed_length; ++ ++ if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) ++ errmsg = "insufficient memory"; ++ } + } + +- slength = (png_size_t)length; +- png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); +- +- if (png_crc_finish(png_ptr, 0)) +- { +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- png_ptr->chunkdata[slength] = 0x00; +- +- for (lang = png_ptr->chunkdata; *lang; lang++) +- /* Empty loop */ ; +- +- lang++; /* Skip NUL separator */ +- +- /* iTXt must have a language tag (possibly empty), two compression bytes, +- * translated keyword (possibly empty), and possibly some text after the +- * keyword +- */ +- +- if (lang >= png_ptr->chunkdata + slength - 3) +- { +- png_warning(png_ptr, "Truncated iTXt chunk"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- + else +- { +- comp_flag = *lang++; +- comp_type = *lang++; +- } +- +- for (lang_key = lang; *lang_key; lang_key++) +- /* Empty loop */ ; +- +- lang_key++; /* Skip NUL separator */ +- +- if (lang_key >= png_ptr->chunkdata + slength) +- { +- png_warning(png_ptr, "Truncated iTXt chunk"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- for (text = lang_key; *text; text++) +- /* Empty loop */ ; +- +- text++; /* Skip NUL separator */ +- +- if (text >= png_ptr->chunkdata + slength) +- { +- png_warning(png_ptr, "Malformed iTXt chunk"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- prefix_len = text - png_ptr->chunkdata; +- +- key=png_ptr->chunkdata; +- +- if (comp_flag) +- png_decompress_chunk(png_ptr, comp_type, +- (size_t)length, prefix_len, &data_len); +- +- else +- data_len = png_strlen(png_ptr->chunkdata + prefix_len); +- +- text_ptr = (png_textp)png_malloc_warn(png_ptr, +- png_sizeof(png_text)); +- +- if (text_ptr == NULL) +- { +- png_warning(png_ptr, "Not enough memory to process iTXt chunk"); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- return; +- } +- +- text_ptr->compression = (int)comp_flag + 1; +- text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); +- text_ptr->lang = png_ptr->chunkdata + (lang - key); +- text_ptr->itxt_length = data_len; +- text_ptr->text_length = 0; +- text_ptr->key = png_ptr->chunkdata; +- text_ptr->text = png_ptr->chunkdata + prefix_len; +- +- ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); +- +- png_free(png_ptr, text_ptr); +- png_free(png_ptr, png_ptr->chunkdata); +- png_ptr->chunkdata = NULL; +- +- if (ret) +- png_error(png_ptr, "Insufficient memory to store iTXt chunk"); ++ errmsg = "bad compression info"; ++ ++ if (errmsg != NULL) ++ png_chunk_benign_error(png_ptr, errmsg); + } + #endif + +-/* This function is called when we haven't found a handler for a +- * chunk. If there isn't a problem with the chunk itself (ie bad +- * chunk name, CRC, or a critical chunk), the chunk is silently ignored +- * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which +- * case it will be saved away to be written out later. +- */ +-void /* PRIVATE */ +-png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) ++#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED ++/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ ++static int ++png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) + { +- png_uint_32 skip = 0; +- +- png_debug(1, "in png_handle_unknown"); +- +-#ifdef PNG_USER_LIMITS_SUPPORTED +- if (png_ptr->user_chunk_cache_max != 0) ++ png_alloc_size_t limit = PNG_SIZE_MAX; ++ ++ if (png_ptr->unknown_chunk.data != NULL) + { +- if (png_ptr->user_chunk_cache_max == 1) +- { +- png_crc_finish(png_ptr, length); +- return; +- } +- +- if (--png_ptr->user_chunk_cache_max == 1) +- { +- png_warning(png_ptr, "No space in chunk cache for unknown chunk"); +- png_crc_finish(png_ptr, length); +- return; +- } +- } +-#endif +- +- if (png_ptr->mode & PNG_HAVE_IDAT) +- { +- PNG_IDAT; +- +- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ +- png_ptr->mode |= PNG_AFTER_IDAT; +- } +- +- if (!(png_ptr->chunk_name[0] & 0x20)) +- { +-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != +- PNG_HANDLE_CHUNK_ALWAYS +-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +- && png_ptr->read_user_chunk_fn == NULL +-#endif +- ) +-#endif +- png_chunk_error(png_ptr, "unknown critical chunk"); +- } +- +-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +- if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) +-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +- || (png_ptr->read_user_chunk_fn != NULL) +-#endif +- ) +- { +-#ifdef PNG_MAX_MALLOC_64K +- if (length > (png_uint_32)65535L) +- { +- png_warning(png_ptr, "unknown chunk too large to fit in memory"); +- skip = length - (png_uint_32)65535L; +- length = (png_uint_32)65535L; +- } +-#endif +- +- png_memcpy((png_charp)png_ptr->unknown_chunk.name, +- (png_charp)png_ptr->chunk_name, +- png_sizeof(png_ptr->unknown_chunk.name)); +- +- png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] +- = '\0'; +- +- png_ptr->unknown_chunk.size = (png_size_t)length; +- +- if (length == 0) +- png_ptr->unknown_chunk.data = NULL; +- +- else +- { +- png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); +- png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); +- } +- +-#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +- if (png_ptr->read_user_chunk_fn != NULL) +- { +- /* Callback to user unknown chunk handler */ +- int ret; +- +- ret = (*(png_ptr->read_user_chunk_fn)) +- (png_ptr, &png_ptr->unknown_chunk); +- +- if (ret < 0) +- png_chunk_error(png_ptr, "error in user chunk"); +- +- if (ret == 0) +- { +- if (!(png_ptr->chunk_name[0] & 0x20)) +- { +-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +- if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != +- PNG_HANDLE_CHUNK_ALWAYS) +-#endif +- png_chunk_error(png_ptr, "unknown critical chunk"); +- } +- +- png_set_unknown_chunks(png_ptr, info_ptr, +- &png_ptr->unknown_chunk, 1); +- } +- } +- +- else +-#endif +- png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); +- + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + ++# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED ++ if (png_ptr->user_chunk_malloc_max > 0 && ++ png_ptr->user_chunk_malloc_max < limit) ++ limit = png_ptr->user_chunk_malloc_max; ++ ++# elif PNG_USER_CHUNK_MALLOC_MAX > 0 ++ if (PNG_USER_CHUNK_MALLOC_MAX < limit) ++ limit = PNG_USER_CHUNK_MALLOC_MAX; ++# endif ++ ++ if (length <= limit) ++ { ++ PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); ++ /* The following is safe because of the PNG_SIZE_MAX init above */ ++ png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/; ++ /* 'mode' is a flag array, only the bottom four bits matter here */ ++ png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; ++ ++ if (length == 0) ++ png_ptr->unknown_chunk.data = NULL; ++ ++ else ++ { ++ /* Do a 'warn' here - it is handled below. */ ++ png_ptr->unknown_chunk.data = png_voidcast(png_bytep, ++ png_malloc_warn(png_ptr, length)); ++ } ++ } ++ ++ if (png_ptr->unknown_chunk.data == NULL && length > 0) ++ { ++ /* This is benign because we clean up correctly */ ++ png_crc_finish(png_ptr, length); ++ png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); ++ return 0; ++ } ++ + else +-#endif +- skip = length; +- +- png_crc_finish(png_ptr, skip); +- +-#ifndef PNG_READ_USER_CHUNKS_SUPPORTED +- PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ +-#endif ++ { ++ if (length > 0) ++ png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); ++ png_crc_finish(png_ptr, 0); ++ return 1; ++ } ++} ++#endif /* READ_UNKNOWN_CHUNKS */ ++ ++/* Handle an unknown, or known but disabled, chunk */ ++void /* PRIVATE */ ++png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, ++ png_uint_32 length, int keep) ++{ ++ int handled = 0; /* the chunk was handled */ ++ ++ png_debug(1, "in png_handle_unknown"); ++ ++#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED ++ /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing ++ * the bug which meant that setting a non-default behavior for a specific ++ * chunk would be ignored (the default was always used unless a user ++ * callback was installed). ++ * ++ * 'keep' is the value from the png_chunk_unknown_handling, the setting for ++ * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it ++ * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. ++ * This is just an optimization to avoid multiple calls to the lookup ++ * function. ++ */ ++# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED ++# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++ keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); ++# endif ++# endif ++ ++ /* One of the following methods will read the chunk or skip it (at least one ++ * of these is always defined because this is the only way to switch on ++ * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ++ */ ++# ifdef PNG_READ_USER_CHUNKS_SUPPORTED ++ /* The user callback takes precedence over the chunk keep value, but the ++ * keep value is still required to validate a save of a critical chunk. ++ */ ++ if (png_ptr->read_user_chunk_fn != NULL) ++ { ++ if (png_cache_unknown_chunk(png_ptr, length) != 0) ++ { ++ /* Callback to user unknown chunk handler */ ++ int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, ++ &png_ptr->unknown_chunk); ++ ++ /* ret is: ++ * negative: An error occured, png_chunk_error will be called. ++ * zero: The chunk was not handled, the chunk will be discarded ++ * unless png_set_keep_unknown_chunks has been used to set ++ * a 'keep' behavior for this particular chunk, in which ++ * case that will be used. A critical chunk will cause an ++ * error at this point unless it is to be saved. ++ * positive: The chunk was handled, libpng will ignore/discard it. ++ */ ++ if (ret < 0) ++ png_chunk_error(png_ptr, "error in user chunk"); ++ ++ else if (ret == 0) ++ { ++ /* If the keep value is 'default' or 'never' override it, but ++ * still error out on critical chunks unless the keep value is ++ * 'always' While this is weird it is the behavior in 1.4.12. ++ * A possible improvement would be to obey the value set for the ++ * chunk, but this would be an API change that would probably ++ * damage some applications. ++ * ++ * The png_app_warning below catches the case that matters, where ++ * the application has not set specific save or ignore for this ++ * chunk or global save or ignore. ++ */ ++ if (keep < PNG_HANDLE_CHUNK_IF_SAFE) ++ { ++# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++ if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) ++ { ++ png_chunk_warning(png_ptr, "Saving unknown chunk:"); ++ png_app_warning(png_ptr, ++ "forcing save of an unhandled chunk;" ++ " please call png_set_keep_unknown_chunks"); ++ /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ ++ } ++# endif ++ keep = PNG_HANDLE_CHUNK_IF_SAFE; ++ } ++ } ++ ++ else /* chunk was handled */ ++ { ++ handled = 1; ++ /* Critical chunks can be safely discarded at this point. */ ++ keep = PNG_HANDLE_CHUNK_NEVER; ++ } ++ } ++ ++ else ++ keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ ++ } ++ ++ else ++ /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ ++# endif /* READ_USER_CHUNKS */ ++ ++# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED ++ { ++ /* keep is currently just the per-chunk setting, if there was no ++ * setting change it to the global default now (not that this may ++ * still be AS_DEFAULT) then obtain the cache of the chunk if required, ++ * if not simply skip the chunk. ++ */ ++ if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) ++ keep = png_ptr->unknown_default; ++ ++ if (keep == PNG_HANDLE_CHUNK_ALWAYS || ++ (keep == PNG_HANDLE_CHUNK_IF_SAFE && ++ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) ++ { ++ if (png_cache_unknown_chunk(png_ptr, length) == 0) ++ keep = PNG_HANDLE_CHUNK_NEVER; ++ } ++ ++ else ++ png_crc_finish(png_ptr, length); ++ } ++# else ++# ifndef PNG_READ_USER_CHUNKS_SUPPORTED ++# error no method to support READ_UNKNOWN_CHUNKS ++# endif ++ ++ { ++ /* If here there is no read callback pointer set and no support is ++ * compiled in to just save the unknown chunks, so simply skip this ++ * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then ++ * the app has erroneously asked for unknown chunk saving when there ++ * is no support. ++ */ ++ if (keep > PNG_HANDLE_CHUNK_NEVER) ++ png_app_error(png_ptr, "no unknown chunk support available"); ++ ++ png_crc_finish(png_ptr, length); ++ } ++# endif ++ ++# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED ++ /* Now store the chunk in the chunk list if appropriate, and if the limits ++ * permit it. ++ */ ++ if (keep == PNG_HANDLE_CHUNK_ALWAYS || ++ (keep == PNG_HANDLE_CHUNK_IF_SAFE && ++ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) ++ { ++# ifdef PNG_USER_LIMITS_SUPPORTED ++ switch (png_ptr->user_chunk_cache_max) ++ { ++ case 2: ++ png_ptr->user_chunk_cache_max = 1; ++ png_chunk_benign_error(png_ptr, "no space in chunk cache"); ++ /* FALL THROUGH */ ++ case 1: ++ /* NOTE: prior to 1.6.0 this case resulted in an unknown critical ++ * chunk being skipped, now there will be a hard error below. ++ */ ++ break; ++ ++ default: /* not at limit */ ++ --(png_ptr->user_chunk_cache_max); ++ /* FALL THROUGH */ ++ case 0: /* no limit */ ++# endif /* USER_LIMITS */ ++ /* Here when the limit isn't reached or when limits are compiled ++ * out; store the chunk. ++ */ ++ png_set_unknown_chunks(png_ptr, info_ptr, ++ &png_ptr->unknown_chunk, 1); ++ handled = 1; ++# ifdef PNG_USER_LIMITS_SUPPORTED ++ break; ++ } ++# endif ++ } ++# else /* no store support: the chunk must be handled by the user callback */ ++ PNG_UNUSED(info_ptr) ++# endif ++ ++ /* Regardless of the error handling below the cached data (if any) can be ++ * freed now. Notice that the data is not freed if there is a png_error, but ++ * it will be freed by destroy_read_struct. ++ */ ++ if (png_ptr->unknown_chunk.data != NULL) ++ png_free(png_ptr, png_ptr->unknown_chunk.data); ++ png_ptr->unknown_chunk.data = NULL; ++ ++#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ ++ /* There is no support to read an unknown chunk, so just skip it. */ ++ png_crc_finish(png_ptr, length); ++ PNG_UNUSED(info_ptr) ++ PNG_UNUSED(keep) ++#endif /* !READ_UNKNOWN_CHUNKS */ ++ ++ /* Check for unhandled critical chunks */ ++ if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) ++ png_chunk_error(png_ptr, "unhandled critical chunk"); + } + + /* This function is called to verify that a chunk name is valid. +@@ -2682,267 +2996,527 @@ + * the chunk name itself is valid. + */ + +-#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) ++/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: ++ * ++ * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) ++ */ + + void /* PRIVATE */ +-png_check_chunk_name(png_structp png_ptr, png_const_bytep chunk_name) ++png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name) + { ++ int i; ++ + png_debug(1, "in png_check_chunk_name"); +- if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || +- isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) ++ ++ for (i=1; i<=4; ++i) + { +- png_chunk_error(png_ptr, "invalid chunk type"); ++ int c = chunk_name & 0xff; ++ ++ if (c < 65 || c > 122 || (c > 90 && c < 97)) ++ png_chunk_error(png_ptr, "invalid chunk type"); ++ ++ chunk_name >>= 8; + } + } + +-/* Combines the row recently read in with the existing pixels in the +- * row. This routine takes care of alpha and transparency if requested. +- * This routine also handles the two methods of progressive display +- * of interlaced images, depending on the mask value. +- * The mask value describes which pixels are to be combined with +- * the row. The pattern always repeats every 8 pixels, so just 8 +- * bits are needed. A one indicates the pixel is to be combined, +- * a zero indicates the pixel is to be skipped. This is in addition +- * to any alpha or transparency value associated with the pixel. If +- * you want all pixels to be combined, pass 0xff (255) in mask. ++/* Combines the row recently read in with the existing pixels in the row. This ++ * routine takes care of alpha and transparency if requested. This routine also ++ * handles the two methods of progressive display of interlaced images, ++ * depending on the 'display' value; if 'display' is true then the whole row ++ * (dp) is filled from the start by replicating the available pixels. If ++ * 'display' is false only those pixels present in the pass are filled in. + */ +- + void /* PRIVATE */ +-png_combine_row(png_structp png_ptr, png_bytep row, int mask) ++png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) + { ++ unsigned int pixel_depth = png_ptr->transformed_pixel_depth; ++ png_const_bytep sp = png_ptr->row_buf + 1; ++ png_alloc_size_t row_width = png_ptr->width; ++ unsigned int pass = png_ptr->pass; ++ png_bytep end_ptr = 0; ++ png_byte end_byte = 0; ++ unsigned int end_mask; ++ + png_debug(1, "in png_combine_row"); + +- /* Added in 1.5.4: the row_info should match the information returned by any +- * call to png_read_update_info at this point. Do not continue if we got ++ /* Added in 1.5.6: it should not be possible to enter this routine until at ++ * least one row has been read from the PNG data and transformed. ++ */ ++ if (pixel_depth == 0) ++ png_error(png_ptr, "internal row logic error"); ++ ++ /* Added in 1.5.4: the pixel depth should match the information returned by ++ * any call to png_read_update_info at this point. Do not continue if we got + * this wrong. + */ + if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != +- PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)) ++ PNG_ROWBYTES(pixel_depth, row_width)) + png_error(png_ptr, "internal row size calculation error"); + +- if (mask == 0xff) ++ /* Don't expect this to ever happen: */ ++ if (row_width == 0) ++ png_error(png_ptr, "internal row width error"); ++ ++ /* Preserve the last byte in cases where only part of it will be overwritten, ++ * the multiply below may overflow, we don't care because ANSI-C guarantees ++ * we get the low bits. ++ */ ++ end_mask = (pixel_depth * row_width) & 7; ++ if (end_mask != 0) + { +- png_memcpy(row, png_ptr->row_buf + 1, +- PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); ++ /* end_ptr == NULL is a flag to say do nothing */ ++ end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; ++ end_byte = *end_ptr; ++# ifdef PNG_READ_PACKSWAP_SUPPORTED ++ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) ++ /* little-endian byte */ ++ end_mask = 0xff << end_mask; ++ ++ else /* big-endian byte */ ++# endif ++ end_mask = 0xff >> end_mask; ++ /* end_mask is now the bits to *keep* from the destination row */ + } + +- else ++ /* For non-interlaced images this reduces to a memcpy(). A memcpy() ++ * will also happen if interlacing isn't supported or if the application ++ * does not call png_set_interlace_handling(). In the latter cases the ++ * caller just gets a sequence of the unexpanded rows from each interlace ++ * pass. ++ */ ++#ifdef PNG_READ_INTERLACING_SUPPORTED ++ if (png_ptr->interlaced != 0 && ++ (png_ptr->transformations & PNG_INTERLACE) != 0 && ++ pass < 6 && (display == 0 || ++ /* The following copies everything for 'display' on passes 0, 2 and 4. */ ++ (display == 1 && (pass & 1) != 0))) + { +- switch (png_ptr->row_info.pixel_depth) ++ /* Narrow images may have no bits in a pass; the caller should handle ++ * this, but this test is cheap: ++ */ ++ if (row_width <= PNG_PASS_START_COL(pass)) ++ return; ++ ++ if (pixel_depth < 8) + { +- case 1: ++ /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit ++ * into 32 bits, then a single loop over the bytes using the four byte ++ * values in the 32-bit mask can be used. For the 'display' option the ++ * expanded mask may also not require any masking within a byte. To ++ * make this work the PACKSWAP option must be taken into account - it ++ * simply requires the pixels to be reversed in each byte. ++ * ++ * The 'regular' case requires a mask for each of the first 6 passes, ++ * the 'display' case does a copy for the even passes in the range ++ * 0..6. This has already been handled in the test above. ++ * ++ * The masks are arranged as four bytes with the first byte to use in ++ * the lowest bits (little-endian) regardless of the order (PACKSWAP or ++ * not) of the pixels in each byte. ++ * ++ * NOTE: the whole of this logic depends on the caller of this function ++ * only calling it on rows appropriate to the pass. This function only ++ * understands the 'x' logic; the 'y' logic is handled by the caller. ++ * ++ * The following defines allow generation of compile time constant bit ++ * masks for each pixel depth and each possibility of swapped or not ++ * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, ++ * is in the range 0..7; and the result is 1 if the pixel is to be ++ * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' ++ * for the block method. ++ * ++ * With some compilers a compile time expression of the general form: ++ * ++ * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) ++ * ++ * Produces warnings with values of 'shift' in the range 33 to 63 ++ * because the right hand side of the ?: expression is evaluated by ++ * the compiler even though it isn't used. Microsoft Visual C (various ++ * versions) and the Intel C compiler are known to do this. To avoid ++ * this the following macros are used in 1.5.6. This is a temporary ++ * solution to avoid destabilizing the code during the release process. ++ */ ++# if PNG_USE_COMPILE_TIME_MASKS ++# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) ++# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) ++# else ++# define PNG_LSR(x,s) ((x)>>(s)) ++# define PNG_LSL(x,s) ((x)<<(s)) ++# endif ++# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ ++ PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) ++# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ ++ PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) ++ ++ /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is ++ * little endian - the first pixel is at bit 0 - however the extra ++ * parameter 's' can be set to cause the mask position to be swapped ++ * within each byte, to match the PNG format. This is done by XOR of ++ * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. ++ */ ++# define PIXEL_MASK(p,x,d,s) \ ++ (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) ++ ++ /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. ++ */ ++# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) ++# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) ++ ++ /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp ++ * cases the result needs replicating, for the 4-bpp case the above ++ * generates a full 32 bits. ++ */ ++# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) ++ ++# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ ++ S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ ++ S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) ++ ++# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ ++ B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ ++ B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) ++ ++#if PNG_USE_COMPILE_TIME_MASKS ++ /* Utility macros to construct all the masks for a depth/swap ++ * combination. The 's' parameter says whether the format is PNG ++ * (big endian bytes) or not. Only the three odd-numbered passes are ++ * required for the display/block algorithm. ++ */ ++# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ ++ S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } ++ ++# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) } ++ ++# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) ++ ++ /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and ++ * then pass: ++ */ ++ static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = + { +- png_bytep sp = png_ptr->row_buf + 1; +- png_bytep dp = row; +- int s_inc, s_start, s_end; +- int m = 0x80; +- int shift; +- png_uint_32 i; +- png_uint_32 row_width = png_ptr->width; +- +-#ifdef PNG_READ_PACKSWAP_SUPPORTED +- if (png_ptr->transformations & PNG_PACKSWAP) ++ /* Little-endian byte masks for PACKSWAP */ ++ { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, ++ /* Normal (big-endian byte) masks - PNG format */ ++ { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } ++ }; ++ ++ /* display_mask has only three entries for the odd passes, so index by ++ * pass>>1. ++ */ ++ static PNG_CONST png_uint_32 display_mask[2][3][3] = ++ { ++ /* Little-endian byte masks for PACKSWAP */ ++ { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, ++ /* Normal (big-endian byte) masks - PNG format */ ++ { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } ++ }; ++ ++# define MASK(pass,depth,display,png)\ ++ ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ ++ row_mask[png][DEPTH_INDEX(depth)][pass]) ++ ++#else /* !PNG_USE_COMPILE_TIME_MASKS */ ++ /* This is the runtime alternative: it seems unlikely that this will ++ * ever be either smaller or faster than the compile time approach. ++ */ ++# define MASK(pass,depth,display,png)\ ++ ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) ++#endif /* !USE_COMPILE_TIME_MASKS */ ++ ++ /* Use the appropriate mask to copy the required bits. In some cases ++ * the byte mask will be 0 or 0xff; optimize these cases. row_width is ++ * the number of pixels, but the code copies bytes, so it is necessary ++ * to special case the end. ++ */ ++ png_uint_32 pixels_per_byte = 8 / pixel_depth; ++ png_uint_32 mask; ++ ++# ifdef PNG_READ_PACKSWAP_SUPPORTED ++ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) ++ mask = MASK(pass, pixel_depth, display, 0); ++ ++ else ++# endif ++ mask = MASK(pass, pixel_depth, display, 1); ++ ++ for (;;) ++ { ++ png_uint_32 m; ++ ++ /* It doesn't matter in the following if png_uint_32 has more than ++ * 32 bits because the high bits always match those in m<<24; it is, ++ * however, essential to use OR here, not +, because of this. ++ */ ++ m = mask; ++ mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ ++ m &= 0xff; ++ ++ if (m != 0) /* something to copy */ + { +- s_start = 0; +- s_end = 7; +- s_inc = 1; ++ if (m != 0xff) ++ *dp = (png_byte)((*dp & ~m) | (*sp & m)); ++ else ++ *dp = *sp; + } + +- else +-#endif +- { +- s_start = 7; +- s_end = 0; +- s_inc = -1; +- } +- +- shift = s_start; +- +- for (i = 0; i < row_width; i++) +- { +- if (m & mask) +- { +- int value; +- +- value = (*sp >> shift) & 0x01; +- *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); +- *dp |= (png_byte)(value << shift); +- } +- +- if (shift == s_end) +- { +- shift = s_start; +- sp++; +- dp++; +- } +- +- else +- shift += s_inc; +- +- if (m == 1) +- m = 0x80; +- +- else +- m >>= 1; +- } +- break; +- } +- +- case 2: +- { +- png_bytep sp = png_ptr->row_buf + 1; +- png_bytep dp = row; +- int s_start, s_end, s_inc; +- int m = 0x80; +- int shift; +- png_uint_32 i; +- png_uint_32 row_width = png_ptr->width; +- int value; +- +-#ifdef PNG_READ_PACKSWAP_SUPPORTED +- if (png_ptr->transformations & PNG_PACKSWAP) +- { +- s_start = 0; +- s_end = 6; +- s_inc = 2; +- } +- +- else +-#endif +- { +- s_start = 6; +- s_end = 0; +- s_inc = -2; +- } +- +- shift = s_start; +- +- for (i = 0; i < row_width; i++) +- { +- if (m & mask) +- { +- value = (*sp >> shift) & 0x03; +- *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); +- *dp |= (png_byte)(value << shift); +- } +- +- if (shift == s_end) +- { +- shift = s_start; +- sp++; +- dp++; +- } +- +- else +- shift += s_inc; +- +- if (m == 1) +- m = 0x80; +- +- else +- m >>= 1; +- } +- break; +- } +- +- case 4: +- { +- png_bytep sp = png_ptr->row_buf + 1; +- png_bytep dp = row; +- int s_start, s_end, s_inc; +- int m = 0x80; +- int shift; +- png_uint_32 i; +- png_uint_32 row_width = png_ptr->width; +- int value; +- +-#ifdef PNG_READ_PACKSWAP_SUPPORTED +- if (png_ptr->transformations & PNG_PACKSWAP) +- { +- s_start = 0; +- s_end = 4; +- s_inc = 4; +- } +- +- else +-#endif +- { +- s_start = 4; +- s_end = 0; +- s_inc = -4; +- } +- shift = s_start; +- +- for (i = 0; i < row_width; i++) +- { +- if (m & mask) +- { +- value = (*sp >> shift) & 0xf; +- *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); +- *dp |= (png_byte)(value << shift); +- } +- +- if (shift == s_end) +- { +- shift = s_start; +- sp++; +- dp++; +- } +- +- else +- shift += s_inc; +- +- if (m == 1) +- m = 0x80; +- +- else +- m >>= 1; +- } +- break; +- } +- +- default: +- { +- png_bytep sp = png_ptr->row_buf + 1; +- png_bytep dp = row; +- png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); +- png_uint_32 i; +- png_uint_32 row_width = png_ptr->width; +- png_byte m = 0x80; +- +- for (i = 0; i < row_width; i++) +- { +- if (m & mask) +- { +- png_memcpy(dp, sp, pixel_bytes); +- } +- +- sp += pixel_bytes; +- dp += pixel_bytes; +- +- if (m == 1) +- m = 0x80; +- +- else +- m >>= 1; +- } +- break; ++ /* NOTE: this may overwrite the last byte with garbage if the image ++ * is not an exact number of bytes wide; libpng has always done ++ * this. ++ */ ++ if (row_width <= pixels_per_byte) ++ break; /* May need to restore part of the last byte */ ++ ++ row_width -= pixels_per_byte; ++ ++dp; ++ ++sp; + } + } ++ ++ else /* pixel_depth >= 8 */ ++ { ++ unsigned int bytes_to_copy, bytes_to_jump; ++ ++ /* Validate the depth - it must be a multiple of 8 */ ++ if (pixel_depth & 7) ++ png_error(png_ptr, "invalid user transform pixel depth"); ++ ++ pixel_depth >>= 3; /* now in bytes */ ++ row_width *= pixel_depth; ++ ++ /* Regardless of pass number the Adam 7 interlace always results in a ++ * fixed number of pixels to copy then to skip. There may be a ++ * different number of pixels to skip at the start though. ++ */ ++ { ++ unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; ++ ++ row_width -= offset; ++ dp += offset; ++ sp += offset; ++ } ++ ++ /* Work out the bytes to copy. */ ++ if (display != 0) ++ { ++ /* When doing the 'block' algorithm the pixel in the pass gets ++ * replicated to adjacent pixels. This is why the even (0,2,4,6) ++ * passes are skipped above - the entire expanded row is copied. ++ */ ++ bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; ++ ++ /* But don't allow this number to exceed the actual row width. */ ++ if (bytes_to_copy > row_width) ++ bytes_to_copy = (unsigned int)/*SAFE*/row_width; ++ } ++ ++ else /* normal row; Adam7 only ever gives us one pixel to copy. */ ++ bytes_to_copy = pixel_depth; ++ ++ /* In Adam7 there is a constant offset between where the pixels go. */ ++ bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; ++ ++ /* And simply copy these bytes. Some optimization is possible here, ++ * depending on the value of 'bytes_to_copy'. Special case the low ++ * byte counts, which we know to be frequent. ++ * ++ * Notice that these cases all 'return' rather than 'break' - this ++ * avoids an unnecessary test on whether to restore the last byte ++ * below. ++ */ ++ switch (bytes_to_copy) ++ { ++ case 1: ++ for (;;) ++ { ++ *dp = *sp; ++ ++ if (row_width <= bytes_to_jump) ++ return; ++ ++ dp += bytes_to_jump; ++ sp += bytes_to_jump; ++ row_width -= bytes_to_jump; ++ } ++ ++ case 2: ++ /* There is a possibility of a partial copy at the end here; this ++ * slows the code down somewhat. ++ */ ++ do ++ { ++ dp[0] = sp[0], dp[1] = sp[1]; ++ ++ if (row_width <= bytes_to_jump) ++ return; ++ ++ sp += bytes_to_jump; ++ dp += bytes_to_jump; ++ row_width -= bytes_to_jump; ++ } ++ while (row_width > 1); ++ ++ /* And there can only be one byte left at this point: */ ++ *dp = *sp; ++ return; ++ ++ case 3: ++ /* This can only be the RGB case, so each copy is exactly one ++ * pixel and it is not necessary to check for a partial copy. ++ */ ++ for (;;) ++ { ++ dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; ++ ++ if (row_width <= bytes_to_jump) ++ return; ++ ++ sp += bytes_to_jump; ++ dp += bytes_to_jump; ++ row_width -= bytes_to_jump; ++ } ++ ++ default: ++#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE ++ /* Check for double byte alignment and, if possible, use a ++ * 16-bit copy. Don't attempt this for narrow images - ones that ++ * are less than an interlace panel wide. Don't attempt it for ++ * wide bytes_to_copy either - use the memcpy there. ++ */ ++ if (bytes_to_copy < 16 /*else use memcpy*/ && ++ png_isaligned(dp, png_uint_16) && ++ png_isaligned(sp, png_uint_16) && ++ bytes_to_copy % (sizeof (png_uint_16)) == 0 && ++ bytes_to_jump % (sizeof (png_uint_16)) == 0) ++ { ++ /* Everything is aligned for png_uint_16 copies, but try for ++ * png_uint_32 first. ++ */ ++ if (png_isaligned(dp, png_uint_32) != 0 && ++ png_isaligned(sp, png_uint_32) != 0 && ++ bytes_to_copy % (sizeof (png_uint_32)) == 0 && ++ bytes_to_jump % (sizeof (png_uint_32)) == 0) ++ { ++ png_uint_32p dp32 = png_aligncast(png_uint_32p,dp); ++ png_const_uint_32p sp32 = png_aligncastconst( ++ png_const_uint_32p, sp); ++ size_t skip = (bytes_to_jump-bytes_to_copy) / ++ (sizeof (png_uint_32)); ++ ++ do ++ { ++ size_t c = bytes_to_copy; ++ do ++ { ++ *dp32++ = *sp32++; ++ c -= (sizeof (png_uint_32)); ++ } ++ while (c > 0); ++ ++ if (row_width <= bytes_to_jump) ++ return; ++ ++ dp32 += skip; ++ sp32 += skip; ++ row_width -= bytes_to_jump; ++ } ++ while (bytes_to_copy <= row_width); ++ ++ /* Get to here when the row_width truncates the final copy. ++ * There will be 1-3 bytes left to copy, so don't try the ++ * 16-bit loop below. ++ */ ++ dp = (png_bytep)dp32; ++ sp = (png_const_bytep)sp32; ++ do ++ *dp++ = *sp++; ++ while (--row_width > 0); ++ return; ++ } ++ ++ /* Else do it in 16-bit quantities, but only if the size is ++ * not too large. ++ */ ++ else ++ { ++ png_uint_16p dp16 = png_aligncast(png_uint_16p, dp); ++ png_const_uint_16p sp16 = png_aligncastconst( ++ png_const_uint_16p, sp); ++ size_t skip = (bytes_to_jump-bytes_to_copy) / ++ (sizeof (png_uint_16)); ++ ++ do ++ { ++ size_t c = bytes_to_copy; ++ do ++ { ++ *dp16++ = *sp16++; ++ c -= (sizeof (png_uint_16)); ++ } ++ while (c > 0); ++ ++ if (row_width <= bytes_to_jump) ++ return; ++ ++ dp16 += skip; ++ sp16 += skip; ++ row_width -= bytes_to_jump; ++ } ++ while (bytes_to_copy <= row_width); ++ ++ /* End of row - 1 byte left, bytes_to_copy > row_width: */ ++ dp = (png_bytep)dp16; ++ sp = (png_const_bytep)sp16; ++ do ++ *dp++ = *sp++; ++ while (--row_width > 0); ++ return; ++ } ++ } ++#endif /* ALIGN_TYPE code */ ++ ++ /* The true default - use a memcpy: */ ++ for (;;) ++ { ++ memcpy(dp, sp, bytes_to_copy); ++ ++ if (row_width <= bytes_to_jump) ++ return; ++ ++ sp += bytes_to_jump; ++ dp += bytes_to_jump; ++ row_width -= bytes_to_jump; ++ if (bytes_to_copy > row_width) ++ bytes_to_copy = (unsigned int)/*SAFE*/row_width; ++ } ++ } ++ ++ /* NOT REACHED*/ ++ } /* pixel_depth >= 8 */ ++ ++ /* Here if pixel_depth < 8 to check 'end_ptr' below. */ + } ++ else ++#endif /* READ_INTERLACING */ ++ ++ /* If here then the switch above wasn't used so just memcpy the whole row ++ * from the temporary row buffer (notice that this overwrites the end of the ++ * destination row if it is a partial byte.) ++ */ ++ memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); ++ ++ /* Restore the overwritten bits from the last byte if necessary. */ ++ if (end_ptr != NULL) ++ *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); + } + + #ifdef PNG_READ_INTERLACING_SUPPORTED + void /* PRIVATE */ +-png_do_read_interlace(png_structp png_ptr) ++png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, ++ png_uint_32 transformations /* Because these may affect the byte layout */) + { +- png_row_infop row_info = &(png_ptr->row_info); +- png_bytep row = png_ptr->row_buf + 1; +- int pass = png_ptr->pass; +- png_uint_32 transformations = png_ptr->transformations; + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Offset to next interlace block */ +- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + png_debug(1, "in png_do_read_interlace"); + if (row != NULL && row_info != NULL) +@@ -2965,7 +3539,7 @@ + int j; + + #ifdef PNG_READ_PACKSWAP_SUPPORTED +- if (transformations & PNG_PACKSWAP) ++ if ((transformations & PNG_PACKSWAP) != 0) + { + sshift = (int)((row_info->width + 7) & 0x07); + dshift = (int)((final_width + 7) & 0x07); +@@ -2989,8 +3563,9 @@ + v = (png_byte)((*sp >> sshift) & 0x01); + for (j = 0; j < jstop; j++) + { +- *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); +- *dp |= (png_byte)(v << dshift); ++ unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); ++ tmp |= v << dshift; ++ *dp = (png_byte)(tmp & 0xff); + + if (dshift == s_end) + { +@@ -3024,7 +3599,7 @@ + png_uint_32 i; + + #ifdef PNG_READ_PACKSWAP_SUPPORTED +- if (transformations & PNG_PACKSWAP) ++ if ((transformations & PNG_PACKSWAP) != 0) + { + sshift = (int)(((row_info->width + 3) & 0x03) << 1); + dshift = (int)(((final_width + 3) & 0x03) << 1); +@@ -3051,8 +3626,9 @@ + v = (png_byte)((*sp >> sshift) & 0x03); + for (j = 0; j < jstop; j++) + { +- *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); +- *dp |= (png_byte)(v << dshift); ++ unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); ++ tmp |= v << dshift; ++ *dp = (png_byte)(tmp & 0xff); + + if (dshift == s_end) + { +@@ -3086,7 +3662,7 @@ + int jstop = png_pass_inc[pass]; + + #ifdef PNG_READ_PACKSWAP_SUPPORTED +- if (transformations & PNG_PACKSWAP) ++ if ((transformations & PNG_PACKSWAP) != 0) + { + sshift = (int)(((row_info->width + 1) & 0x01) << 2); + dshift = (int)(((final_width + 1) & 0x01) << 2); +@@ -3107,13 +3683,14 @@ + + for (i = 0; i < row_info->width; i++) + { +- png_byte v = (png_byte)((*sp >> sshift) & 0xf); ++ png_byte v = (png_byte)((*sp >> sshift) & 0x0f); + int j; + + for (j = 0; j < jstop; j++) + { +- *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); +- *dp |= (png_byte)(v << dshift); ++ unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); ++ tmp |= v << dshift; ++ *dp = (png_byte)(tmp & 0xff); + + if (dshift == s_end) + { +@@ -3136,6 +3713,7 @@ + } + break; + } ++ + default: + { + png_size_t pixel_bytes = (row_info->pixel_depth >> 3); +@@ -3150,14 +3728,14 @@ + + for (i = 0; i < row_info->width; i++) + { +- png_byte v[8]; ++ png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */ + int j; + +- png_memcpy(v, sp, pixel_bytes); ++ memcpy(v, sp, pixel_bytes); + + for (j = 0; j < jstop; j++) + { +- png_memcpy(dp, v, pixel_bytes); ++ memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + +@@ -3166,6 +3744,7 @@ + break; + } + } ++ + row_info->width = final_width; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); + } +@@ -3173,167 +3752,427 @@ + PNG_UNUSED(transformations) /* Silence compiler warning */ + #endif + } +-#endif /* PNG_READ_INTERLACING_SUPPORTED */ ++#endif /* READ_INTERLACING */ ++ ++static void ++png_read_filter_row_sub(png_row_infop row_info, png_bytep row, ++ png_const_bytep prev_row) ++{ ++ png_size_t i; ++ png_size_t istop = row_info->rowbytes; ++ unsigned int bpp = (row_info->pixel_depth + 7) >> 3; ++ png_bytep rp = row + bpp; ++ ++ PNG_UNUSED(prev_row) ++ ++ for (i = bpp; i < istop; i++) ++ { ++ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); ++ rp++; ++ } ++} ++ ++static void ++png_read_filter_row_up(png_row_infop row_info, png_bytep row, ++ png_const_bytep prev_row) ++{ ++ png_size_t i; ++ png_size_t istop = row_info->rowbytes; ++ png_bytep rp = row; ++ png_const_bytep pp = prev_row; ++ ++ for (i = 0; i < istop; i++) ++ { ++ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); ++ rp++; ++ } ++} ++ ++static void ++png_read_filter_row_avg(png_row_infop row_info, png_bytep row, ++ png_const_bytep prev_row) ++{ ++ png_size_t i; ++ png_bytep rp = row; ++ png_const_bytep pp = prev_row; ++ unsigned int bpp = (row_info->pixel_depth + 7) >> 3; ++ png_size_t istop = row_info->rowbytes - bpp; ++ ++ for (i = 0; i < bpp; i++) ++ { ++ *rp = (png_byte)(((int)(*rp) + ++ ((int)(*pp++) / 2 )) & 0xff); ++ ++ rp++; ++ } ++ ++ for (i = 0; i < istop; i++) ++ { ++ *rp = (png_byte)(((int)(*rp) + ++ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); ++ ++ rp++; ++ } ++} ++ ++static void ++png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, ++ png_const_bytep prev_row) ++{ ++ png_bytep rp_end = row + row_info->rowbytes; ++ int a, c; ++ ++ /* First pixel/byte */ ++ c = *prev_row++; ++ a = *row + c; ++ *row++ = (png_byte)a; ++ ++ /* Remainder */ ++ while (row < rp_end) ++ { ++ int b, pa, pb, pc, p; ++ ++ a &= 0xff; /* From previous iteration or start */ ++ b = *prev_row++; ++ ++ p = b - c; ++ pc = a - c; ++ ++# ifdef PNG_USE_ABS ++ pa = abs(p); ++ pb = abs(pc); ++ pc = abs(p + pc); ++# else ++ pa = p < 0 ? -p : p; ++ pb = pc < 0 ? -pc : pc; ++ pc = (p + pc) < 0 ? -(p + pc) : p + pc; ++# endif ++ ++ /* Find the best predictor, the least of pa, pb, pc favoring the earlier ++ * ones in the case of a tie. ++ */ ++ if (pb < pa) pa = pb, a = b; ++ if (pc < pa) a = c; ++ ++ /* Calculate the current pixel in a, and move the previous row pixel to c ++ * for the next time round the loop ++ */ ++ c = b; ++ a += *row; ++ *row++ = (png_byte)a; ++ } ++} ++ ++static void ++png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, ++ png_const_bytep prev_row) ++{ ++ int bpp = (row_info->pixel_depth + 7) >> 3; ++ png_bytep rp_end = row + bpp; ++ ++ /* Process the first pixel in the row completely (this is the same as 'up' ++ * because there is only one candidate predictor for the first row). ++ */ ++ while (row < rp_end) ++ { ++ int a = *row + *prev_row++; ++ *row++ = (png_byte)a; ++ } ++ ++ /* Remainder */ ++ rp_end += row_info->rowbytes - bpp; ++ ++ while (row < rp_end) ++ { ++ int a, b, c, pa, pb, pc, p; ++ ++ c = *(prev_row - bpp); ++ a = *(row - bpp); ++ b = *prev_row++; ++ ++ p = b - c; ++ pc = a - c; ++ ++# ifdef PNG_USE_ABS ++ pa = abs(p); ++ pb = abs(pc); ++ pc = abs(p + pc); ++# else ++ pa = p < 0 ? -p : p; ++ pb = pc < 0 ? -pc : pc; ++ pc = (p + pc) < 0 ? -(p + pc) : p + pc; ++# endif ++ ++ if (pb < pa) pa = pb, a = b; ++ if (pc < pa) a = c; ++ ++ a += *row; ++ *row++ = (png_byte)a; ++ } ++} ++ ++static void ++png_init_filter_functions(png_structrp pp) ++ /* This function is called once for every PNG image (except for PNG images ++ * that only use PNG_FILTER_VALUE_NONE for all rows) to set the ++ * implementations required to reverse the filtering of PNG rows. Reversing ++ * the filter is the first transformation performed on the row data. It is ++ * performed in place, therefore an implementation can be selected based on ++ * the image pixel format. If the implementation depends on image width then ++ * take care to ensure that it works correctly if the image is interlaced - ++ * interlacing causes the actual row width to vary. ++ */ ++{ ++ unsigned int bpp = (pp->pixel_depth + 7) >> 3; ++ ++ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; ++ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; ++ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; ++ if (bpp == 1) ++ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = ++ png_read_filter_row_paeth_1byte_pixel; ++ else ++ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = ++ png_read_filter_row_paeth_multibyte_pixel; ++ ++#ifdef PNG_FILTER_OPTIMIZATIONS ++ /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to ++ * call to install hardware optimizations for the above functions; simply ++ * replace whatever elements of the pp->read_filter[] array with a hardware ++ * specific (or, for that matter, generic) optimization. ++ * ++ * To see an example of this examine what configure.ac does when ++ * --enable-arm-neon is specified on the command line. ++ */ ++ PNG_FILTER_OPTIMIZATIONS(pp, bpp); ++#endif ++} + + void /* PRIVATE */ +-png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, +- png_const_bytep prev_row, int filter) ++png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, ++ png_const_bytep prev_row, int filter) + { +- png_debug(1, "in png_read_filter_row"); +- png_debug2(2, "row = %u, filter = %d", png_ptr->row_number, filter); +- switch (filter) ++ /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define ++ * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic ++ * implementations. See png_init_filter_functions above. ++ */ ++ if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) + { +- case PNG_FILTER_VALUE_NONE: +- break; +- +- case PNG_FILTER_VALUE_SUB: ++ if (pp->read_filter[0] == NULL) ++ png_init_filter_functions(pp); ++ ++ pp->read_filter[filter-1](row_info, row, prev_row); ++ } ++} ++ ++#ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++void /* PRIVATE */ ++png_read_IDAT_data(png_structrp png_ptr, png_bytep output, ++ png_alloc_size_t avail_out) ++{ ++ /* Loop reading IDATs and decompressing the result into output[avail_out] */ ++ png_ptr->zstream.next_out = output; ++ png_ptr->zstream.avail_out = 0; /* safety: set below */ ++ ++ if (output == NULL) ++ avail_out = 0; ++ ++ do ++ { ++ int ret; ++ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; ++ ++ if (png_ptr->zstream.avail_in == 0) + { +- png_size_t i; +- png_size_t istop = row_info->rowbytes; +- unsigned int bpp = (row_info->pixel_depth + 7) >> 3; +- png_bytep rp = row + bpp; +- png_bytep lp = row; +- +- for (i = bpp; i < istop; i++) ++ uInt avail_in; ++ png_bytep buffer; ++ ++ while (png_ptr->idat_size == 0) + { +- *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); +- rp++; ++ png_crc_finish(png_ptr, 0); ++ ++ png_ptr->idat_size = png_read_chunk_header(png_ptr); ++ /* This is an error even in the 'check' case because the code just ++ * consumed a non-IDAT header. ++ */ ++ if (png_ptr->chunk_name != png_IDAT) ++ png_error(png_ptr, "Not enough image data"); + } ++ ++ avail_in = png_ptr->IDAT_read_size; ++ ++ if (avail_in > png_ptr->idat_size) ++ avail_in = (uInt)png_ptr->idat_size; ++ ++ /* A PNG with a gradually increasing IDAT size will defeat this attempt ++ * to minimize memory usage by causing lots of re-allocs, but ++ * realistically doing IDAT_read_size re-allocs is not likely to be a ++ * big problem. ++ */ ++ buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); ++ ++ png_crc_read(png_ptr, buffer, avail_in); ++ png_ptr->idat_size -= avail_in; ++ ++ png_ptr->zstream.next_in = buffer; ++ png_ptr->zstream.avail_in = avail_in; ++ } ++ ++ /* And set up the output side. */ ++ if (output != NULL) /* standard read */ ++ { ++ uInt out = ZLIB_IO_MAX; ++ ++ if (out > avail_out) ++ out = (uInt)avail_out; ++ ++ avail_out -= out; ++ png_ptr->zstream.avail_out = out; ++ } ++ ++ else /* after last row, checking for end */ ++ { ++ png_ptr->zstream.next_out = tmpbuf; ++ png_ptr->zstream.avail_out = (sizeof tmpbuf); ++ } ++ ++ /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the ++ * process. If the LZ stream is truncated the sequential reader will ++ * terminally damage the stream, above, by reading the chunk header of the ++ * following chunk (it then exits with png_error). ++ * ++ * TODO: deal more elegantly with truncated IDAT lists. ++ */ ++ ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); ++ ++ /* Take the unconsumed output back. */ ++ if (output != NULL) ++ avail_out += png_ptr->zstream.avail_out; ++ ++ else /* avail_out counts the extra bytes */ ++ avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; ++ ++ png_ptr->zstream.avail_out = 0; ++ ++ if (ret == Z_STREAM_END) ++ { ++ /* Do this for safety; we won't read any more into this row. */ ++ png_ptr->zstream.next_out = NULL; ++ ++ png_ptr->mode |= PNG_AFTER_IDAT; ++ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; ++ ++ if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) ++ png_chunk_benign_error(png_ptr, "Extra compressed data"); + break; + } +- case PNG_FILTER_VALUE_UP: ++ ++ if (ret != Z_OK) + { +- png_size_t i; +- png_size_t istop = row_info->rowbytes; +- png_bytep rp = row; +- png_const_bytep pp = prev_row; +- +- for (i = 0; i < istop; i++) ++ png_zstream_error(png_ptr, ret); ++ ++ if (output != NULL) ++ png_chunk_error(png_ptr, png_ptr->zstream.msg); ++ ++ else /* checking */ + { +- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); +- rp++; ++ png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); ++ return; + } +- break; + } +- case PNG_FILTER_VALUE_AVG: +- { +- png_size_t i; +- png_bytep rp = row; +- png_const_bytep pp = prev_row; +- png_bytep lp = row; +- unsigned int bpp = (row_info->pixel_depth + 7) >> 3; +- png_size_t istop = row_info->rowbytes - bpp; +- +- for (i = 0; i < bpp; i++) +- { +- *rp = (png_byte)(((int)(*rp) + +- ((int)(*pp++) / 2 )) & 0xff); +- +- rp++; +- } +- +- for (i = 0; i < istop; i++) +- { +- *rp = (png_byte)(((int)(*rp) + +- (int)(*pp++ + *lp++) / 2 ) & 0xff); +- +- rp++; +- } +- break; +- } +- case PNG_FILTER_VALUE_PAETH: +- { +- png_size_t i; +- png_bytep rp = row; +- png_const_bytep pp = prev_row; +- png_bytep lp = row; +- png_const_bytep cp = prev_row; +- unsigned int bpp = (row_info->pixel_depth + 7) >> 3; +- png_size_t istop=row_info->rowbytes - bpp; +- +- for (i = 0; i < bpp; i++) +- { +- *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); +- rp++; +- } +- +- for (i = 0; i < istop; i++) /* Use leftover rp,pp */ +- { +- int a, b, c, pa, pb, pc, p; +- +- a = *lp++; +- b = *pp++; +- c = *cp++; +- +- p = b - c; +- pc = a - c; +- +-#ifdef PNG_USE_ABS +- pa = abs(p); +- pb = abs(pc); +- pc = abs(p + pc); +-#else +- pa = p < 0 ? -p : p; +- pb = pc < 0 ? -pc : pc; +- pc = (p + pc) < 0 ? -(p + pc) : p + pc; +-#endif +- +- /* +- if (pa <= pb && pa <= pc) +- p = a; +- +- else if (pb <= pc) +- p = b; +- +- else +- p = c; +- */ +- +- p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; +- +- *rp = (png_byte)(((int)(*rp) + p) & 0xff); +- rp++; +- } +- break; +- } +- default: +- png_error(png_ptr, "Ignoring bad adaptive filter type"); +- /*NOT REACHED */ +- break; ++ } while (avail_out > 0); ++ ++ if (avail_out > 0) ++ { ++ /* The stream ended before the image; this is the same as too few IDATs so ++ * should be handled the same way. ++ */ ++ if (output != NULL) ++ png_error(png_ptr, "Not enough image data"); ++ ++ else /* the deflate stream contained extra data */ ++ png_chunk_benign_error(png_ptr, "Too much image data"); + } + } + +-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED + void /* PRIVATE */ +-png_read_finish_row(png_structp png_ptr) ++png_read_finish_IDAT(png_structrp png_ptr) + { +-#ifdef PNG_READ_INTERLACING_SUPPORTED ++ /* We don't need any more data and the stream should have ended, however the ++ * LZ end code may actually not have been processed. In this case we must ++ * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk ++ * may still remain to be consumed. ++ */ ++ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) ++ { ++ /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in ++ * the compressed stream, but the stream may be damaged too, so even after ++ * this call we may need to terminate the zstream ownership. ++ */ ++ png_read_IDAT_data(png_ptr, NULL, 0); ++ png_ptr->zstream.next_out = NULL; /* safety */ ++ ++ /* Now clear everything out for safety; the following may not have been ++ * done. ++ */ ++ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) ++ { ++ png_ptr->mode |= PNG_AFTER_IDAT; ++ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; ++ } ++ } ++ ++ /* If the zstream has not been released do it now *and* terminate the reading ++ * of the final IDAT chunk. ++ */ ++ if (png_ptr->zowner == png_IDAT) ++ { ++ /* Always do this; the pointers otherwise point into the read buffer. */ ++ png_ptr->zstream.next_in = NULL; ++ png_ptr->zstream.avail_in = 0; ++ ++ /* Now we no longer own the zstream. */ ++ png_ptr->zowner = 0; ++ ++ /* The slightly weird semantics of the sequential IDAT reading is that we ++ * are always in or at the end of an IDAT chunk, so we always need to do a ++ * crc_finish here. If idat_size is non-zero we also need to read the ++ * spurious bytes at the end of the chunk now. ++ */ ++ (void)png_crc_finish(png_ptr, png_ptr->idat_size); ++ } ++} ++ ++void /* PRIVATE */ ++png_read_finish_row(png_structrp png_ptr) ++{ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ +- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; ++ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ +- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ +- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; ++ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ +- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +-#endif /* PNG_READ_INTERLACING_SUPPORTED */ ++ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + + png_debug(1, "in png_read_finish_row"); + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + +-#ifdef PNG_READ_INTERLACING_SUPPORTED +- if (png_ptr->interlaced) ++ if (png_ptr->interlaced != 0) + { + png_ptr->row_number = 0; + +- png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); ++ /* TO DO: don't do this if prev_row isn't needed (requires ++ * read-ahead of the next row's filter byte. ++ */ ++ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + do + { +@@ -3347,7 +4186,7 @@ + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + +- if (!(png_ptr->transformations & PNG_INTERLACE)) ++ if ((png_ptr->transformations & PNG_INTERLACE) == 0) + { + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - +@@ -3363,108 +4202,40 @@ + if (png_ptr->pass < 7) + return; + } +-#endif /* PNG_READ_INTERLACING_SUPPORTED */ +- +- if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) +- { +- PNG_IDAT; +- char extra; +- int ret; +- +- png_ptr->zstream.next_out = (Byte *)&extra; +- png_ptr->zstream.avail_out = (uInt)1; +- +- for (;;) +- { +- if (!(png_ptr->zstream.avail_in)) +- { +- while (!png_ptr->idat_size) +- { +- png_crc_finish(png_ptr, 0); +- png_ptr->idat_size = png_read_chunk_header(png_ptr); +- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) +- png_error(png_ptr, "Not enough image data"); +- } +- +- png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; +- png_ptr->zstream.next_in = png_ptr->zbuf; +- +- if (png_ptr->zbuf_size > png_ptr->idat_size) +- png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; +- +- png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); +- png_ptr->idat_size -= png_ptr->zstream.avail_in; +- } +- +- ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); +- +- if (ret == Z_STREAM_END) +- { +- if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || +- png_ptr->idat_size) +- png_warning(png_ptr, "Extra compressed data"); +- +- png_ptr->mode |= PNG_AFTER_IDAT; +- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; +- break; +- } +- +- if (ret != Z_OK) +- png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : +- "Decompression Error"); +- +- if (!(png_ptr->zstream.avail_out)) +- { +- png_warning(png_ptr, "Extra compressed data"); +- png_ptr->mode |= PNG_AFTER_IDAT; +- png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; +- break; +- } +- +- } +- png_ptr->zstream.avail_out = 0; +- } +- +- if (png_ptr->idat_size || png_ptr->zstream.avail_in) +- png_warning(png_ptr, "Extra compression data"); +- +- inflateReset(&png_ptr->zstream); +- +- png_ptr->mode |= PNG_AFTER_IDAT; ++ ++ /* Here after at the end of the last row of the last pass. */ ++ png_read_finish_IDAT(png_ptr); + } +-#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ ++#endif /* SEQUENTIAL_READ */ + + void /* PRIVATE */ +-png_read_start_row(png_structp png_ptr) ++png_read_start_row(png_structrp png_ptr) + { +-#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ +- PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; ++ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ +- PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ +- PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; ++ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ +- PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +-#endif ++ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + + int max_pixel_depth; + png_size_t row_bytes; + + png_debug(1, "in png_read_start_row"); +- png_ptr->zstream.avail_in = 0; ++ + #ifdef PNG_READ_TRANSFORMS_SUPPORTED + png_init_read_transformations(png_ptr); + #endif +-#ifdef PNG_READ_INTERLACING_SUPPORTED +- if (png_ptr->interlaced) ++ if (png_ptr->interlaced != 0) + { +- if (!(png_ptr->transformations & PNG_INTERLACE)) ++ if ((png_ptr->transformations & PNG_INTERLACE) == 0) + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + +@@ -3478,7 +4249,6 @@ + } + + else +-#endif /* PNG_READ_INTERLACING_SUPPORTED */ + { + png_ptr->num_rows = png_ptr->height; + png_ptr->iwidth = png_ptr->width; +@@ -3486,17 +4256,27 @@ + + max_pixel_depth = png_ptr->pixel_depth; + ++ /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of ++ * calculations to calculate the final pixel depth, then ++ * png_do_read_transforms actually does the transforms. This means that the ++ * code which effectively calculates this value is actually repeated in three ++ * separate places. They must all match. Innocent changes to the order of ++ * transformations can and will break libpng in a way that causes memory ++ * overwrites. ++ * ++ * TODO: fix this. ++ */ + #ifdef PNG_READ_PACK_SUPPORTED +- if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) ++ if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8) + max_pixel_depth = 8; + #endif + + #ifdef PNG_READ_EXPAND_SUPPORTED +- if (png_ptr->transformations & PNG_EXPAND) ++ if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { +- if (png_ptr->num_trans) ++ if (png_ptr->num_trans != 0) + max_pixel_depth = 32; + + else +@@ -3508,13 +4288,13 @@ + if (max_pixel_depth < 8) + max_pixel_depth = 8; + +- if (png_ptr->num_trans) ++ if (png_ptr->num_trans != 0) + max_pixel_depth *= 2; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { +- if (png_ptr->num_trans) ++ if (png_ptr->num_trans != 0) + { + max_pixel_depth *= 4; + max_pixel_depth /= 3; +@@ -3524,13 +4304,13 @@ + #endif + + #ifdef PNG_READ_EXPAND_16_SUPPORTED +- if (png_ptr->transformations & PNG_EXPAND_16) ++ if ((png_ptr->transformations & PNG_EXPAND_16) != 0) + { + # ifdef PNG_READ_EXPAND_SUPPORTED + /* In fact it is an error if it isn't supported, but checking is + * the safe way. + */ +- if (png_ptr->transformations & PNG_EXPAND) ++ if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (png_ptr->bit_depth < 16) + max_pixel_depth *= 2; +@@ -3542,12 +4322,9 @@ + #endif + + #ifdef PNG_READ_FILLER_SUPPORTED +- if (png_ptr->transformations & (PNG_FILLER)) ++ if ((png_ptr->transformations & (PNG_FILLER)) != 0) + { +- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +- max_pixel_depth = 32; +- +- else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) ++ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth <= 8) + max_pixel_depth = 16; +@@ -3556,7 +4333,8 @@ + max_pixel_depth = 32; + } + +- else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) ++ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || ++ png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (max_pixel_depth <= 32) + max_pixel_depth = 32; +@@ -3568,14 +4346,15 @@ + #endif + + #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +- if (png_ptr->transformations & PNG_GRAY_TO_RGB) ++ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) + { + if ( + #ifdef PNG_READ_EXPAND_SUPPORTED +- (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || ++ (png_ptr->num_trans != 0 && ++ (png_ptr->transformations & PNG_EXPAND) != 0) || + #endif + #ifdef PNG_READ_FILLER_SUPPORTED +- (png_ptr->transformations & (PNG_FILLER)) || ++ (png_ptr->transformations & (PNG_FILLER)) != 0 || + #endif + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { +@@ -3608,16 +4387,22 @@ + + #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ + defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) +- if (png_ptr->transformations & PNG_USER_TRANSFORM) ++ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + { +- int user_pixel_depth = png_ptr->user_transform_depth* ++ int user_pixel_depth = png_ptr->user_transform_depth * + png_ptr->user_transform_channels; + + if (user_pixel_depth > max_pixel_depth) +- max_pixel_depth=user_pixel_depth; ++ max_pixel_depth = user_pixel_depth; + } + #endif + ++ /* This value is stored in png_struct and double checked in the row read ++ * code. ++ */ ++ png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; ++ png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ ++ + /* Align the width on the next larger 8 pixels. Mainly used + * for interlacing + */ +@@ -3636,28 +4421,39 @@ + if (row_bytes + 48 > png_ptr->old_big_row_buf_size) + { + png_free(png_ptr, png_ptr->big_row_buf); +- +- if (png_ptr->interlaced) ++ png_free(png_ptr, png_ptr->big_prev_row); ++ ++ if (png_ptr->interlaced != 0) + png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, + row_bytes + 48); + + else +- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, +- row_bytes + 48); +- +- png_ptr->old_big_row_buf_size = row_bytes + 48; ++ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); ++ ++ png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + + #ifdef PNG_ALIGNED_MEMORY_SUPPORTED + /* Use 16-byte aligned memory for row_buf with at least 16 bytes +- * of padding before and after row_buf. ++ * of padding before and after row_buf; treat prev_row similarly. ++ * NOTE: the alignment is to the start of the pixels, one beyond the start ++ * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this ++ * was incorrect; the filter byte was aligned, which had the exact ++ * opposite effect of that intended. + */ +- png_ptr->row_buf = png_ptr->big_row_buf + 32 - +- (((png_alloc_size_t)png_ptr->big_row_buf + 15) & 0x0F); +- +- png_ptr->old_big_row_buf_size = row_bytes + 48; ++ { ++ png_bytep temp = png_ptr->big_row_buf + 32; ++ int extra = (int)((temp - (png_bytep)0) & 0x0f); ++ png_ptr->row_buf = temp - extra - 1/*filter byte*/; ++ ++ temp = png_ptr->big_prev_row + 32; ++ extra = (int)((temp - (png_bytep)0) & 0x0f); ++ png_ptr->prev_row = temp - extra - 1/*filter byte*/; ++ } ++ + #else +- /* Use 32 bytes of padding before and 16 bytes after row_buf. */ +- png_ptr->row_buf = png_ptr->big_row_buf + 32; ++ /* Use 31 bytes of padding before and 17 bytes after row_buf. */ ++ png_ptr->row_buf = png_ptr->big_row_buf + 31; ++ png_ptr->prev_row = png_ptr->big_prev_row + 31; + #endif + png_ptr->old_big_row_buf_size = row_bytes + 48; + } +@@ -3670,16 +4466,7 @@ + if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) + png_error(png_ptr, "Row has too many bytes to allocate in memory"); + +- if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size) +- { +- png_free(png_ptr, png_ptr->prev_row); +- +- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); +- +- png_ptr->old_prev_row_size = png_ptr->rowbytes + 1; +- } +- +- png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); ++ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + png_debug1(3, "width = %u,", png_ptr->width); + png_debug1(3, "height = %u,", png_ptr->height); +@@ -3689,6 +4476,27 @@ + png_debug1(3, "irowbytes = %lu", + (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); + ++ /* The sequential reader needs a buffer for IDAT, but the progressive reader ++ * does not, so free the read buffer now regardless; the sequential reader ++ * reallocates it on demand. ++ */ ++ if (png_ptr->read_buffer != 0) ++ { ++ png_bytep buffer = png_ptr->read_buffer; ++ ++ png_ptr->read_buffer_size = 0; ++ png_ptr->read_buffer = NULL; ++ png_free(png_ptr, buffer); ++ } ++ ++ /* Finally claim the zstream for the inflate of the IDAT data, use the bits ++ * value from the stream (note that this will result in a fatal error if the ++ * IDAT stream has a bogus deflate header window_bits value, but this should ++ * not be happening any longer!) ++ */ ++ if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) ++ png_error(png_ptr, png_ptr->zstream.msg); ++ + png_ptr->flags |= PNG_FLAG_ROW_INIT; + } +-#endif /* PNG_READ_SUPPORTED */ ++#endif /* READ */ +--- ./jdk/src/share/native/sun/awt/libpng/pngset.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngset.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -50,51 +50,84 @@ + + #ifdef PNG_bKGD_SUPPORTED + void PNGAPI +-png_set_bKGD(png_structp png_ptr, png_infop info_ptr, ++png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_16p background) + { + png_debug1(1, "in %s storage function", "bKGD"); + +- if (png_ptr == NULL || info_ptr == NULL) ++ if (png_ptr == NULL || info_ptr == NULL || background == NULL) + return; + +- png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); ++ info_ptr->background = *background; + info_ptr->valid |= PNG_INFO_bKGD; + } + #endif + + #ifdef PNG_cHRM_SUPPORTED + void PNGFAPI +-png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, ++png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, + png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y) + { ++ png_xy xy; ++ + png_debug1(1, "in %s storage function", "cHRM fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +-# ifdef PNG_CHECK_cHRM_SUPPORTED +- if (png_check_cHRM_fixed(png_ptr, +- white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) +-# endif +- { +- info_ptr->x_white = white_x; +- info_ptr->y_white = white_y; +- info_ptr->x_red = red_x; +- info_ptr->y_red = red_y; +- info_ptr->x_green = green_x; +- info_ptr->y_green = green_y; +- info_ptr->x_blue = blue_x; +- info_ptr->y_blue = blue_y; +- info_ptr->valid |= PNG_INFO_cHRM; +- } ++ xy.redx = red_x; ++ xy.redy = red_y; ++ xy.greenx = green_x; ++ xy.greeny = green_y; ++ xy.bluex = blue_x; ++ xy.bluey = blue_y; ++ xy.whitex = white_x; ++ xy.whitey = white_y; ++ ++ if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, ++ 2/* override with app values*/) != 0) ++ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; ++ ++ png_colorspace_sync_info(png_ptr, info_ptr); ++} ++ ++void PNGFAPI ++png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, ++ png_fixed_point int_red_X, png_fixed_point int_red_Y, ++ png_fixed_point int_red_Z, png_fixed_point int_green_X, ++ png_fixed_point int_green_Y, png_fixed_point int_green_Z, ++ png_fixed_point int_blue_X, png_fixed_point int_blue_Y, ++ png_fixed_point int_blue_Z) ++{ ++ png_XYZ XYZ; ++ ++ png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); ++ ++ if (png_ptr == NULL || info_ptr == NULL) ++ return; ++ ++ XYZ.red_X = int_red_X; ++ XYZ.red_Y = int_red_Y; ++ XYZ.red_Z = int_red_Z; ++ XYZ.green_X = int_green_X; ++ XYZ.green_Y = int_green_Y; ++ XYZ.green_Z = int_green_Z; ++ XYZ.blue_X = int_blue_X; ++ XYZ.blue_Y = int_blue_Y; ++ XYZ.blue_Z = int_blue_Z; ++ ++ if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, ++ &XYZ, 2) != 0) ++ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; ++ ++ png_colorspace_sync_info(png_ptr, info_ptr); + } + + # ifdef PNG_FLOATING_POINT_SUPPORTED + void PNGAPI +-png_set_cHRM(png_structp png_ptr, png_infop info_ptr, ++png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y) + { +@@ -108,41 +141,44 @@ + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); + } +-# endif /* PNG_FLOATING_POINT_SUPPORTED */ + +-#endif /* PNG_cHRM_SUPPORTED */ ++void PNGAPI ++png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, ++ double red_Y, double red_Z, double green_X, double green_Y, double green_Z, ++ double blue_X, double blue_Y, double blue_Z) ++{ ++ png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, ++ png_fixed(png_ptr, red_X, "cHRM Red X"), ++ png_fixed(png_ptr, red_Y, "cHRM Red Y"), ++ png_fixed(png_ptr, red_Z, "cHRM Red Z"), ++ png_fixed(png_ptr, green_X, "cHRM Red X"), ++ png_fixed(png_ptr, green_Y, "cHRM Red Y"), ++ png_fixed(png_ptr, green_Z, "cHRM Red Z"), ++ png_fixed(png_ptr, blue_X, "cHRM Red X"), ++ png_fixed(png_ptr, blue_Y, "cHRM Red Y"), ++ png_fixed(png_ptr, blue_Z, "cHRM Red Z")); ++} ++# endif /* FLOATING_POINT */ ++ ++#endif /* cHRM */ + + #ifdef PNG_gAMA_SUPPORTED + void PNGFAPI +-png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point +- file_gamma) ++png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, ++ png_fixed_point file_gamma) + { + png_debug1(1, "in %s storage function", "gAMA"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +- /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't +- * occur. Since the fixed point representation is assymetrical it is +- * possible for 1/gamma to overflow the limit of 21474 and this means the +- * gamma value must be at least 5/100000 and hence at most 20000.0. For +- * safety the limits here are a little narrower. The values are 0.00016 to +- * 6250.0, which are truely ridiculous gammma values (and will produce +- * displays that are all black or all white.) +- */ +- if (file_gamma < 16 || file_gamma > 625000000) +- png_warning(png_ptr, "Out of range gamma value ignored"); +- +- else +- { +- info_ptr->gamma = file_gamma; +- info_ptr->valid |= PNG_INFO_gAMA; +- } ++ png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); ++ png_colorspace_sync_info(png_ptr, info_ptr); + } + + # ifdef PNG_FLOATING_POINT_SUPPORTED + void PNGAPI +-png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) ++png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) + { + png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, + "png_set_gAMA")); +@@ -152,7 +188,8 @@ + + #ifdef PNG_hIST_SUPPORTED + void PNGAPI +-png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) ++png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, ++ png_const_uint_16p hist) + { + int i; + +@@ -175,26 +212,26 @@ + /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in + * version 1.2.1 + */ +- png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, +- PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); ++ info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, ++ PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); + +- if (png_ptr->hist == NULL) ++ if (info_ptr->hist == NULL) + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data"); + return; + } + ++ info_ptr->free_me |= PNG_FREE_HIST; ++ + for (i = 0; i < info_ptr->num_palette; i++) +- png_ptr->hist[i] = hist[i]; ++ info_ptr->hist[i] = hist[i]; + +- info_ptr->hist = png_ptr->hist; + info_ptr->valid |= PNG_INFO_hIST; +- info_ptr->free_me |= PNG_FREE_HIST; + } + #endif + + void PNGAPI +-png_set_IHDR(png_structp png_ptr, png_infop info_ptr, ++png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +@@ -219,32 +256,23 @@ + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + +- else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) ++ else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + info_ptr->channels = 3; + + else + info_ptr->channels = 1; + +- if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) ++ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) + info_ptr->channels++; + + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); + +- /* Check for potential overflow */ +- if (width > +- (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */ +- - 48 /* bigrowbuf hack */ +- - 1 /* filter byte */ +- - 7*8 /* rounding of width to multiple of 8 pixels */ +- - 8) /* extra max_pixel_depth pad */ +- info_ptr->rowbytes = 0; +- else +- info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); ++ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); + } + + #ifdef PNG_oFFs_SUPPORTED + void PNGAPI +-png_set_oFFs(png_structp png_ptr, png_infop info_ptr, ++png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type) + { + png_debug1(1, "in %s storage function", "oFFs"); +@@ -261,7 +289,7 @@ + + #ifdef PNG_pCAL_SUPPORTED + void PNGAPI +-png_set_pCAL(png_structp png_ptr, png_infop info_ptr, ++png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params) + { +@@ -270,10 +298,11 @@ + + png_debug1(1, "in %s storage function", "pCAL"); + +- if (png_ptr == NULL || info_ptr == NULL) ++ if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL ++ || (nparams > 0 && params == NULL)) + return; + +- length = png_strlen(purpose) + 1; ++ length = strlen(purpose) + 1; + png_debug1(3, "allocating purpose for info (%lu bytes)", + (unsigned long)length); + +@@ -283,12 +312,19 @@ + if (type < 0 || type > 3) + png_error(png_ptr, "Invalid pCAL equation type"); + ++ if (nparams < 0 || nparams > 255) ++ png_error(png_ptr, "Invalid pCAL parameter count"); ++ + /* Validate params[nparams] */ + for (i=0; i<nparams; ++i) +- if (!png_check_fp_string(params[i], png_strlen(params[i]))) ++ { ++ if (params[i] == NULL || ++ !png_check_fp_string(params[i], strlen(params[i]))) + png_error(png_ptr, "Invalid format for pCAL parameter"); ++ } + +- info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); ++ info_ptr->pcal_purpose = png_voidcast(png_charp, ++ png_malloc_warn(png_ptr, length)); + + if (info_ptr->pcal_purpose == NULL) + { +@@ -296,7 +332,7 @@ + return; + } + +- png_memcpy(info_ptr->pcal_purpose, purpose, length); ++ memcpy(info_ptr->pcal_purpose, purpose, length); + + png_debug(3, "storing X0, X1, type, and nparams in info"); + info_ptr->pcal_X0 = X0; +@@ -304,11 +340,12 @@ + info_ptr->pcal_type = (png_byte)type; + info_ptr->pcal_nparams = (png_byte)nparams; + +- length = png_strlen(units) + 1; ++ length = strlen(units) + 1; + png_debug1(3, "allocating units for info (%lu bytes)", + (unsigned long)length); + +- info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); ++ info_ptr->pcal_units = png_voidcast(png_charp, ++ png_malloc_warn(png_ptr, length)); + + if (info_ptr->pcal_units == NULL) + { +@@ -316,10 +353,10 @@ + return; + } + +- png_memcpy(info_ptr->pcal_units, units, length); ++ memcpy(info_ptr->pcal_units, units, length); + +- info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, +- (png_size_t)((nparams + 1) * png_sizeof(png_charp))); ++ info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, ++ (png_size_t)((nparams + 1) * (sizeof (png_charp))))); + + if (info_ptr->pcal_params == NULL) + { +@@ -327,11 +364,11 @@ + return; + } + +- png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); ++ memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); + + for (i = 0; i < nparams; i++) + { +- length = png_strlen(params[i]) + 1; ++ length = strlen(params[i]) + 1; + png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, + (unsigned long)length); + +@@ -343,7 +380,7 @@ + return; + } + +- png_memcpy(info_ptr->pcal_params[i], params[i], length); ++ memcpy(info_ptr->pcal_params[i], params[i], length); + } + + info_ptr->valid |= PNG_INFO_pCAL; +@@ -353,7 +390,7 @@ + + #ifdef PNG_sCAL_SUPPORTED + void PNGAPI +-png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, ++png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight) + { + png_size_t lengthw = 0, lengthh = 0; +@@ -369,11 +406,11 @@ + if (unit != 1 && unit != 2) + png_error(png_ptr, "Invalid sCAL unit"); + +- if (swidth == NULL || (lengthw = png_strlen(swidth)) == 0 || ++ if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || + swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) + png_error(png_ptr, "Invalid sCAL width"); + +- if (sheight == NULL || (lengthh = png_strlen(sheight)) == 0 || ++ if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || + sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) + png_error(png_ptr, "Invalid sCAL height"); + +@@ -383,7 +420,8 @@ + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); + +- info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); ++ info_ptr->scal_s_width = png_voidcast(png_charp, ++ png_malloc_warn(png_ptr, lengthw)); + + if (info_ptr->scal_s_width == NULL) + { +@@ -391,13 +429,14 @@ + return; + } + +- png_memcpy(info_ptr->scal_s_width, swidth, lengthw); ++ memcpy(info_ptr->scal_s_width, swidth, lengthw); + + ++lengthh; + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); + +- info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); ++ info_ptr->scal_s_height = png_voidcast(png_charp, ++ png_malloc_warn(png_ptr, lengthh)); + + if (info_ptr->scal_s_height == NULL) + { +@@ -408,7 +447,7 @@ + return; + } + +- png_memcpy(info_ptr->scal_s_height, sheight, lengthh); ++ memcpy(info_ptr->scal_s_height, sheight, lengthh); + + info_ptr->valid |= PNG_INFO_sCAL; + info_ptr->free_me |= PNG_FREE_SCAL; +@@ -416,8 +455,8 @@ + + # ifdef PNG_FLOATING_POINT_SUPPORTED + void PNGAPI +-png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, +- double height) ++png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, ++ double width, double height) + { + png_debug1(1, "in %s storage function", "sCAL"); + +@@ -434,9 +473,9 @@ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + +- png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, ++ png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, + PNG_sCAL_PRECISION); +- png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, ++ png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, + PNG_sCAL_PRECISION); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); +@@ -446,7 +485,7 @@ + + # ifdef PNG_FIXED_POINT_SUPPORTED + void PNGAPI +-png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, ++png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, + png_fixed_point width, png_fixed_point height) + { + png_debug1(1, "in %s storage function", "sCAL"); +@@ -464,8 +503,8 @@ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + +- png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); +- png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); ++ png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); ++ png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +@@ -475,7 +514,7 @@ + + #ifdef PNG_pHYs_SUPPORTED + void PNGAPI +-png_set_pHYs(png_structp png_ptr, png_infop info_ptr, ++png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type) + { + png_debug1(1, "in %s storage function", "pHYs"); +@@ -491,7 +530,7 @@ + #endif + + void PNGAPI +-png_set_PLTE(png_structp png_ptr, png_infop info_ptr, ++png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, + png_const_colorp palette, int num_palette) + { + +@@ -526,6 +565,9 @@ + /* It may not actually be necessary to set png_ptr->palette here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. ++ * ++ * 1.6.0: the above statement appears to be incorrect; something has to set ++ * the palette inside png_struct on read. + */ + png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); + +@@ -533,10 +575,11 @@ + * of num_palette entries, in case of an invalid PNG file that has + * too-large sample values. + */ +- png_ptr->palette = (png_colorp)png_calloc(png_ptr, +- PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); ++ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, ++ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); + +- png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); ++ if (num_palette > 0) ++ memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color))); + info_ptr->palette = png_ptr->palette; + info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; + +@@ -547,34 +590,34 @@ + + #ifdef PNG_sBIT_SUPPORTED + void PNGAPI +-png_set_sBIT(png_structp png_ptr, png_infop info_ptr, ++png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_8p sig_bit) + { + png_debug1(1, "in %s storage function", "sBIT"); + +- if (png_ptr == NULL || info_ptr == NULL) ++ if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) + return; + +- png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); ++ info_ptr->sig_bit = *sig_bit; + info_ptr->valid |= PNG_INFO_sBIT; + } + #endif + + #ifdef PNG_sRGB_SUPPORTED + void PNGAPI +-png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent) ++png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) + { + png_debug1(1, "in %s storage function", "sRGB"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +- info_ptr->srgb_intent = (png_byte)srgb_intent; +- info_ptr->valid |= PNG_INFO_sRGB; ++ (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); ++ png_colorspace_sync_info(png_ptr, info_ptr); + } + + void PNGAPI +-png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, ++png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, + int srgb_intent) + { + png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); +@@ -582,71 +625,87 @@ + if (png_ptr == NULL || info_ptr == NULL) + return; + +- png_set_sRGB(png_ptr, info_ptr, srgb_intent); ++ if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, ++ srgb_intent) != 0) ++ { ++ /* This causes the gAMA and cHRM to be written too */ ++ info_ptr->colorspace.flags |= ++ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; ++ } + +-# ifdef PNG_gAMA_SUPPORTED +- png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); +-# endif +- +-# ifdef PNG_cHRM_SUPPORTED +- png_set_cHRM_fixed(png_ptr, info_ptr, +- /* color x y */ +- /* white */ 31270L, 32900L, +- /* red */ 64000L, 33000L, +- /* green */ 30000L, 60000L, +- /* blue */ 15000L, 6000L +- ); +-# endif /* cHRM */ ++ png_colorspace_sync_info(png_ptr, info_ptr); + } + #endif /* sRGB */ + + + #ifdef PNG_iCCP_SUPPORTED + void PNGAPI +-png_set_iCCP(png_structp png_ptr, png_infop info_ptr, ++png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen) + { + png_charp new_iccp_name; + png_bytep new_iccp_profile; +- png_uint_32 length; ++ png_size_t length; + + png_debug1(1, "in %s storage function", "iCCP"); + + if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) + return; + +- length = png_strlen(name)+1; +- new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); ++ if (compression_type != PNG_COMPRESSION_TYPE_BASE) ++ png_app_error(png_ptr, "Invalid iCCP compression method"); ++ ++ /* Set the colorspace first because this validates the profile; do not ++ * override previously set app cHRM or gAMA here (because likely as not the ++ * application knows better than libpng what the correct values are.) Pass ++ * the info_ptr color_type field to png_colorspace_set_ICC because in the ++ * write case it has not yet been stored in png_ptr. ++ */ ++ { ++ int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, ++ proflen, profile, info_ptr->color_type); ++ ++ png_colorspace_sync_info(png_ptr, info_ptr); ++ ++ /* Don't do any of the copying if the profile was bad, or inconsistent. */ ++ if (result == 0) ++ return; ++ ++ /* But do write the gAMA and cHRM chunks from the profile. */ ++ info_ptr->colorspace.flags |= ++ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; ++ } ++ ++ length = strlen(name)+1; ++ new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); + + if (new_iccp_name == NULL) + { +- png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); ++ png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); + return; + } + +- png_memcpy(new_iccp_name, name, length); +- new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); ++ memcpy(new_iccp_name, name, length); ++ new_iccp_profile = png_voidcast(png_bytep, ++ png_malloc_warn(png_ptr, proflen)); + + if (new_iccp_profile == NULL) + { +- png_free (png_ptr, new_iccp_name); +- png_warning(png_ptr, ++ png_free(png_ptr, new_iccp_name); ++ new_iccp_name = NULL; ++ png_benign_error(png_ptr, + "Insufficient memory to process iCCP profile"); + return; + } + +- png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); ++ memcpy(new_iccp_profile, profile, proflen); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); + + info_ptr->iccp_proflen = proflen; + info_ptr->iccp_name = new_iccp_name; + info_ptr->iccp_profile = new_iccp_profile; +- /* Compression is always zero but is here so the API and info structure +- * does not have to change if we introduce multiple compression types +- */ +- info_ptr->iccp_compression = (png_byte)compression_type; + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; + } +@@ -654,74 +713,81 @@ + + #ifdef PNG_TEXT_SUPPORTED + void PNGAPI +-png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, +- int num_text) ++png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, ++ png_const_textp text_ptr, int num_text) + { + int ret; + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + +- if (ret) ++ if (ret != 0) + png_error(png_ptr, "Insufficient memory to store text"); + } + + int /* PRIVATE */ +-png_set_text_2(png_structp png_ptr, png_infop info_ptr, ++png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_textp text_ptr, int num_text) + { + int i; + +- png_debug1(1, "in %s storage function", ((png_ptr == NULL || +- png_ptr->chunk_name[0] == '\0') ? +- "text" : (png_const_charp)png_ptr->chunk_name)); ++ png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" : ++ (unsigned long)png_ptr->chunk_name); + +- if (png_ptr == NULL || info_ptr == NULL || num_text == 0) ++ if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) + return(0); + + /* Make sure we have enough space in the "text" array in info_struct +- * to hold all of the incoming text_ptr objects. ++ * to hold all of the incoming text_ptr objects. This compare can't overflow ++ * because max_text >= num_text (anyway, subtract of two positive integers ++ * can't overflow in any case.) + */ +- if (info_ptr->num_text + num_text > info_ptr->max_text) ++ if (num_text > info_ptr->max_text - info_ptr->num_text) + { +- if (info_ptr->text != NULL) ++ int old_num_text = info_ptr->num_text; ++ int max_text; ++ png_textp new_text = NULL; ++ ++ /* Calculate an appropriate max_text, checking for overflow. */ ++ max_text = old_num_text; ++ if (num_text <= INT_MAX - max_text) + { +- png_textp old_text; +- int old_max; ++ max_text += num_text; + +- old_max = info_ptr->max_text; +- info_ptr->max_text = info_ptr->num_text + num_text + 8; +- old_text = info_ptr->text; +- info_ptr->text = (png_textp)png_malloc_warn(png_ptr, +- (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); ++ /* Round up to a multiple of 8 */ ++ if (max_text < INT_MAX-8) ++ max_text = (max_text + 8) & ~0x7; + +- if (info_ptr->text == NULL) +- { +- png_free(png_ptr, old_text); +- return(1); +- } ++ else ++ max_text = INT_MAX; + +- png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * +- png_sizeof(png_text))); +- png_free(png_ptr, old_text); ++ /* Now allocate a new array and copy the old members in; this does all ++ * the overflow checks. ++ */ ++ new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, ++ info_ptr->text, old_num_text, max_text-old_num_text, ++ sizeof *new_text)); + } + +- else ++ if (new_text == NULL) + { +- info_ptr->max_text = num_text + 8; +- info_ptr->num_text = 0; +- info_ptr->text = (png_textp)png_malloc_warn(png_ptr, +- (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); +- if (info_ptr->text == NULL) +- return(1); +- info_ptr->free_me |= PNG_FREE_TEXT; ++ png_chunk_report(png_ptr, "too many text chunks", ++ PNG_CHUNK_WRITE_ERROR); ++ return 1; + } + +- png_debug1(3, "allocated %d entries for info_ptr->text", +- info_ptr->max_text); ++ png_free(png_ptr, info_ptr->text); ++ ++ info_ptr->text = new_text; ++ info_ptr->free_me |= PNG_FREE_TEXT; ++ info_ptr->max_text = max_text; ++ /* num_text is adjusted below as the entries are copied in */ ++ ++ png_debug1(3, "allocated %d entries for info_ptr->text", max_text); + } ++ + for (i = 0; i < num_text; i++) + { +- png_size_t text_length, key_len; +- png_size_t lang_len, lang_key_len; ++ size_t text_length, key_len; ++ size_t lang_len, lang_key_len; + png_textp textp = &(info_ptr->text[info_ptr->num_text]); + + if (text_ptr[i].key == NULL) +@@ -730,11 +796,12 @@ + if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || + text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) + { +- png_warning(png_ptr, "text compression mode is out of range"); ++ png_chunk_report(png_ptr, "text compression mode is out of range", ++ PNG_CHUNK_WRITE_ERROR); + continue; + } + +- key_len = png_strlen(text_ptr[i].key); ++ key_len = strlen(text_ptr[i].key); + + if (text_ptr[i].compression <= 0) + { +@@ -748,20 +815,21 @@ + /* Set iTXt data */ + + if (text_ptr[i].lang != NULL) +- lang_len = png_strlen(text_ptr[i].lang); ++ lang_len = strlen(text_ptr[i].lang); + + else + lang_len = 0; + + if (text_ptr[i].lang_key != NULL) +- lang_key_len = png_strlen(text_ptr[i].lang_key); ++ lang_key_len = strlen(text_ptr[i].lang_key); + + else + lang_key_len = 0; + } + # else /* PNG_iTXt_SUPPORTED */ + { +- png_warning(png_ptr, "iTXt chunk not supported"); ++ png_chunk_report(png_ptr, "iTXt chunk not supported", ++ PNG_CHUNK_WRITE_ERROR); + continue; + } + # endif +@@ -780,32 +848,35 @@ + + else + { +- text_length = png_strlen(text_ptr[i].text); ++ text_length = strlen(text_ptr[i].text); + textp->compression = text_ptr[i].compression; + } + +- textp->key = (png_charp)png_malloc_warn(png_ptr, +- (png_size_t) +- (key_len + text_length + lang_len + lang_key_len + 4)); ++ textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, ++ key_len + text_length + lang_len + lang_key_len + 4)); + + if (textp->key == NULL) +- return(1); ++ { ++ png_chunk_report(png_ptr, "text chunk: out of memory", ++ PNG_CHUNK_WRITE_ERROR); ++ return 1; ++ } + + png_debug2(2, "Allocated %lu bytes at %p in png_set_text", + (unsigned long)(png_uint_32) + (key_len + lang_len + lang_key_len + text_length + 4), + textp->key); + +- png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); ++ memcpy(textp->key, text_ptr[i].key, key_len); + *(textp->key + key_len) = '\0'; + + if (text_ptr[i].compression > 0) + { + textp->lang = textp->key + key_len + 1; +- png_memcpy(textp->lang, text_ptr[i].lang, lang_len); ++ memcpy(textp->lang, text_ptr[i].lang, lang_len); + *(textp->lang + lang_len) = '\0'; + textp->lang_key = textp->lang + lang_len + 1; +- png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); ++ memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); + *(textp->lang_key + lang_key_len) = '\0'; + textp->text = textp->lang_key + lang_key_len + 1; + } +@@ -817,9 +888,8 @@ + textp->text = textp->key + key_len + 1; + } + +- if (text_length) +- png_memcpy(textp->text, text_ptr[i].text, +- (png_size_t)(text_length)); ++ if (text_length != 0) ++ memcpy(textp->text, text_ptr[i].text, text_length); + + *(textp->text + text_length) = '\0'; + +@@ -840,28 +910,39 @@ + info_ptr->num_text++; + png_debug1(3, "transferred text chunk %d", info_ptr->num_text); + } ++ + return(0); + } + #endif + + #ifdef PNG_tIME_SUPPORTED + void PNGAPI +-png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) ++png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, ++ png_const_timep mod_time) + { + png_debug1(1, "in %s storage function", "tIME"); + +- if (png_ptr == NULL || info_ptr == NULL || +- (png_ptr->mode & PNG_WROTE_tIME)) ++ if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL || ++ (png_ptr->mode & PNG_WROTE_tIME) != 0) + return; + +- png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); ++ if (mod_time->month == 0 || mod_time->month > 12 || ++ mod_time->day == 0 || mod_time->day > 31 || ++ mod_time->hour > 23 || mod_time->minute > 59 || ++ mod_time->second > 60) ++ { ++ png_warning(png_ptr, "Ignoring invalid time value"); ++ return; ++ } ++ ++ info_ptr->mod_time = *mod_time; + info_ptr->valid |= PNG_INFO_tIME; + } + #endif + + #ifdef PNG_tRNS_SUPPORTED + void PNGAPI +-png_set_tRNS(png_structp png_ptr, png_infop info_ptr, ++png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, + png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) + { + png_debug1(1, "in %s storage function", "tRNS"); +@@ -874,16 +955,20 @@ + /* It may not actually be necessary to set png_ptr->trans_alpha here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. ++ * ++ * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively ++ * relies on png_set_tRNS storing the information in png_struct ++ * (otherwise it won't be there for the code in pngrtran.c). + */ + + png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); + + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ +- png_ptr->trans_alpha = info_ptr->trans_alpha = +- (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); ++ png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep, ++ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); + + if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) +- png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); ++ memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + } + + if (trans_color != NULL) +@@ -891,16 +976,15 @@ + int sample_max = (1 << info_ptr->bit_depth); + + if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && +- (int)trans_color->gray > sample_max) || ++ trans_color->gray > sample_max) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB && +- ((int)trans_color->red > sample_max || +- (int)trans_color->green > sample_max || +- (int)trans_color->blue > sample_max))) ++ (trans_color->red > sample_max || ++ trans_color->green > sample_max || ++ trans_color->blue > sample_max))) + png_warning(png_ptr, + "tRNS chunk has out-of-range samples for bit_depth"); + +- png_memcpy(&(info_ptr->trans_color), trans_color, +- png_sizeof(png_color_16)); ++ info_ptr->trans_color = *trans_color; + + if (num_trans == 0) + num_trans = 1; +@@ -918,8 +1002,8 @@ + + #ifdef PNG_sPLT_SUPPORTED + void PNGAPI +-png_set_sPLT(png_structp png_ptr, +- png_infop info_ptr, png_const_sPLT_tp entries, int nentries) ++png_set_sPLT(png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) + /* + * entries - array of png_sPLT_t structures + * to be added to the list of palettes +@@ -930,220 +1014,455 @@ + */ + { + png_sPLT_tp np; +- int i; + +- if (png_ptr == NULL || info_ptr == NULL) ++ if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) + return; + +- np = (png_sPLT_tp)png_malloc_warn(png_ptr, +- (info_ptr->splt_palettes_num + nentries) * +- (png_size_t)png_sizeof(png_sPLT_t)); ++ /* Use the internal realloc function, which checks for all the possible ++ * overflows. Notice that the parameters are (int) and (size_t) ++ */ ++ np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, ++ info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, ++ sizeof *np)); + + if (np == NULL) + { +- png_warning(png_ptr, "No memory for sPLT palettes"); ++ /* Out of memory or too many chunks */ ++ png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); + return; + } + +- png_memcpy(np, info_ptr->splt_palettes, +- info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); ++ png_free(png_ptr, info_ptr->splt_palettes); ++ info_ptr->splt_palettes = np; ++ info_ptr->free_me |= PNG_FREE_SPLT; + +- png_free(png_ptr, info_ptr->splt_palettes); +- info_ptr->splt_palettes=NULL; ++ np += info_ptr->splt_palettes_num; + +- for (i = 0; i < nentries; i++) ++ do + { +- png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; +- png_const_sPLT_tp from = entries + i; +- png_uint_32 length; ++ png_size_t length; + +- length = png_strlen(from->name) + 1; +- to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length); +- +- if (to->name == NULL) ++ /* Skip invalid input entries */ ++ if (entries->name == NULL || entries->entries == NULL) + { +- png_warning(png_ptr, +- "Out of memory while processing sPLT chunk"); ++ /* png_handle_sPLT doesn't do this, so this is an app error */ ++ png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); ++ /* Just skip the invalid entry */ + continue; + } + +- png_memcpy(to->name, from->name, length); +- to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, +- (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry))); ++ np->depth = entries->depth; + +- if (to->entries == NULL) ++ /* In the event of out-of-memory just return - there's no point keeping ++ * on trying to add sPLT chunks. ++ */ ++ length = strlen(entries->name) + 1; ++ np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); ++ ++ if (np->name == NULL) ++ break; ++ ++ memcpy(np->name, entries->name, length); ++ ++ /* IMPORTANT: we have memory now that won't get freed if something else ++ * goes wrong; this code must free it. png_malloc_array produces no ++ * warnings; use a png_chunk_report (below) if there is an error. ++ */ ++ np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, ++ entries->nentries, sizeof (png_sPLT_entry))); ++ ++ if (np->entries == NULL) + { +- png_warning(png_ptr, +- "Out of memory while processing sPLT chunk"); +- png_free(png_ptr, to->name); +- to->name = NULL; +- continue; ++ png_free(png_ptr, np->name); ++ np->name = NULL; ++ break; + } + +- png_memcpy(to->entries, from->entries, +- from->nentries * png_sizeof(png_sPLT_entry)); ++ np->nentries = entries->nentries; ++ /* This multiply can't overflow because png_malloc_array has already ++ * checked it when doing the allocation. ++ */ ++ memcpy(np->entries, entries->entries, ++ entries->nentries * sizeof (png_sPLT_entry)); + +- to->nentries = from->nentries; +- to->depth = from->depth; ++ /* Note that 'continue' skips the advance of the out pointer and out ++ * count, so an invalid entry is not added. ++ */ ++ info_ptr->valid |= PNG_INFO_sPLT; ++ ++(info_ptr->splt_palettes_num); ++ ++np; ++ } ++ while (++entries, --nentries); ++ ++ if (nentries > 0) ++ png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); ++} ++#endif /* sPLT */ ++ ++#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED ++static png_byte ++check_location(png_const_structrp png_ptr, int location) ++{ ++ location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); ++ ++ /* New in 1.6.0; copy the location and check it. This is an API ++ * change; previously the app had to use the ++ * png_set_unknown_chunk_location API below for each chunk. ++ */ ++ if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0) ++ { ++ /* Write struct, so unknown chunks come from the app */ ++ png_app_warning(png_ptr, ++ "png_set_unknown_chunks now expects a valid location"); ++ /* Use the old behavior */ ++ location = (png_byte)(png_ptr->mode & ++ (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); + } + +- info_ptr->splt_palettes = np; +- info_ptr->splt_palettes_num += nentries; +- info_ptr->valid |= PNG_INFO_sPLT; +- info_ptr->free_me |= PNG_FREE_SPLT; ++ /* This need not be an internal error - if the app calls ++ * png_set_unknown_chunks on a read pointer it must get the location right. ++ */ ++ if (location == 0) ++ png_error(png_ptr, "invalid location in png_set_unknown_chunks"); ++ ++ /* Now reduce the location to the top-most set bit by removing each least ++ * significant bit in turn. ++ */ ++ while (location != (location & -location)) ++ location &= ~(location & -location); ++ ++ /* The cast is safe because 'location' is a bit mask and only the low four ++ * bits are significant. ++ */ ++ return (png_byte)location; + } +-#endif /* PNG_sPLT_SUPPORTED */ + +-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + void PNGAPI +-png_set_unknown_chunks(png_structp png_ptr, +- png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) ++png_set_unknown_chunks(png_const_structrp png_ptr, ++ png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) + { + png_unknown_chunkp np; +- int i; + +- if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) ++ if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || ++ unknowns == NULL) + return; + +- np = (png_unknown_chunkp)png_malloc_warn(png_ptr, +- (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * +- png_sizeof(png_unknown_chunk)); ++ /* Check for the failure cases where support has been disabled at compile ++ * time. This code is hardly ever compiled - it's here because ++ * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this ++ * code) but may be meaningless if the read or write handling of unknown ++ * chunks is not compiled in. ++ */ ++# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ ++ defined(PNG_READ_SUPPORTED) ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) ++ { ++ png_app_error(png_ptr, "no unknown chunk support on read"); ++ return; ++ } ++# endif ++# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ ++ defined(PNG_WRITE_SUPPORTED) ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) ++ { ++ png_app_error(png_ptr, "no unknown chunk support on write"); ++ return; ++ } ++# endif ++ ++ /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that ++ * unknown critical chunks could be lost with just a warning resulting in ++ * undefined behavior. Now png_chunk_report is used to provide behavior ++ * appropriate to read or write. ++ */ ++ np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, ++ info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, ++ sizeof *np)); + + if (np == NULL) + { +- png_warning(png_ptr, +- "Out of memory while processing unknown chunk"); ++ png_chunk_report(png_ptr, "too many unknown chunks", ++ PNG_CHUNK_WRITE_ERROR); + return; + } + +- png_memcpy(np, info_ptr->unknown_chunks, +- (png_size_t)info_ptr->unknown_chunks_num * +- png_sizeof(png_unknown_chunk)); ++ png_free(png_ptr, info_ptr->unknown_chunks); ++ info_ptr->unknown_chunks = np; /* safe because it is initialized */ ++ info_ptr->free_me |= PNG_FREE_UNKN; + +- png_free(png_ptr, info_ptr->unknown_chunks); +- info_ptr->unknown_chunks = NULL; ++ np += info_ptr->unknown_chunks_num; + +- for (i = 0; i < num_unknowns; i++) ++ /* Increment unknown_chunks_num each time round the loop to protect the ++ * just-allocated chunk data. ++ */ ++ for (; num_unknowns > 0; --num_unknowns, ++unknowns) + { +- png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; +- png_const_unknown_chunkp from = unknowns + i; ++ memcpy(np->name, unknowns->name, (sizeof np->name)); ++ np->name[(sizeof np->name)-1] = '\0'; ++ np->location = check_location(png_ptr, unknowns->location); + +- png_memcpy(to->name, from->name, png_sizeof(from->name)); +- to->name[png_sizeof(to->name)-1] = '\0'; +- to->size = from->size; +- +- /* Note our location in the read or write sequence */ +- to->location = (png_byte)(png_ptr->mode & 0xff); +- +- if (from->size == 0) +- to->data=NULL; ++ if (unknowns->size == 0) ++ { ++ np->data = NULL; ++ np->size = 0; ++ } + + else + { +- to->data = (png_bytep)png_malloc_warn(png_ptr, +- (png_size_t)from->size); ++ np->data = png_voidcast(png_bytep, ++ png_malloc_base(png_ptr, unknowns->size)); + +- if (to->data == NULL) ++ if (np->data == NULL) + { +- png_warning(png_ptr, +- "Out of memory while processing unknown chunk"); +- to->size = 0; ++ png_chunk_report(png_ptr, "unknown chunk: out of memory", ++ PNG_CHUNK_WRITE_ERROR); ++ /* But just skip storing the unknown chunk */ ++ continue; + } + +- else +- png_memcpy(to->data, from->data, from->size); ++ memcpy(np->data, unknowns->data, unknowns->size); ++ np->size = unknowns->size; + } ++ ++ /* These increments are skipped on out-of-memory for the data - the ++ * unknown chunk entry gets overwritten if the png_chunk_report returns. ++ * This is correct in the read case (the chunk is just dropped.) ++ */ ++ ++np; ++ ++(info_ptr->unknown_chunks_num); + } +- +- info_ptr->unknown_chunks = np; +- info_ptr->unknown_chunks_num += num_unknowns; +- info_ptr->free_me |= PNG_FREE_UNKN; + } + + void PNGAPI +-png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, ++png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, + int chunk, int location) + { +- if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < +- info_ptr->unknown_chunks_num) +- info_ptr->unknown_chunks[chunk].location = (png_byte)location; ++ /* This API is pretty pointless in 1.6.0 because the location can be set ++ * before the call to png_set_unknown_chunks. ++ * ++ * TODO: add a png_app_warning in 1.7 ++ */ ++ if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && ++ chunk < info_ptr->unknown_chunks_num) ++ { ++ if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) ++ { ++ png_app_error(png_ptr, "invalid unknown chunk location"); ++ /* Fake out the pre 1.6.0 behavior: */ ++ if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */ ++ location = PNG_AFTER_IDAT; ++ ++ else ++ location = PNG_HAVE_IHDR; /* also undocumented */ ++ } ++ ++ info_ptr->unknown_chunks[chunk].location = ++ check_location(png_ptr, location); ++ } + } + #endif + + + #ifdef PNG_MNG_FEATURES_SUPPORTED + png_uint_32 PNGAPI +-png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) ++png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features) + { + png_debug(1, "in png_permit_mng_features"); + + if (png_ptr == NULL) +- return (png_uint_32)0; ++ return 0; + +- png_ptr->mng_features_permitted = +- (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); ++ png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; + +- return (png_uint_32)png_ptr->mng_features_permitted; ++ return png_ptr->mng_features_permitted; + } + #endif + + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED ++static unsigned int ++add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) ++{ ++ unsigned int i; ++ ++ /* Utility function: update the 'keep' state of a chunk if it is already in ++ * the list, otherwise add it to the list. ++ */ ++ for (i=0; i<count; ++i, list += 5) ++ { ++ if (memcmp(list, add, 4) == 0) ++ { ++ list[4] = (png_byte)keep; ++ return count; ++ } ++ } ++ ++ if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT) ++ { ++ ++count; ++ memcpy(list, add, 4); ++ list[4] = (png_byte)keep; ++ } ++ ++ return count; ++} ++ + void PNGAPI +-png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep +- chunk_list, int num_chunks) ++png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, ++ png_const_bytep chunk_list, int num_chunks_in) + { +- png_bytep new_list, p; +- int i, old_num_chunks; ++ png_bytep new_list; ++ unsigned int num_chunks, old_num_chunks; ++ + if (png_ptr == NULL) + return; + +- if (num_chunks == 0) ++ if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST) + { +- if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) +- png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; +- +- else +- png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; +- +- if (keep == PNG_HANDLE_CHUNK_ALWAYS) +- png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; +- +- else +- png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; +- ++ png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); + return; + } + +- if (chunk_list == NULL) +- return; ++ if (num_chunks_in <= 0) ++ { ++ png_ptr->unknown_default = keep; ++ ++ /* '0' means just set the flags, so stop here */ ++ if (num_chunks_in == 0) ++ return; ++ } ++ ++ if (num_chunks_in < 0) ++ { ++ /* Ignore all unknown chunks and all chunks recognized by ++ * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND ++ */ ++ static PNG_CONST png_byte chunks_to_ignore[] = { ++ 98, 75, 71, 68, '\0', /* bKGD */ ++ 99, 72, 82, 77, '\0', /* cHRM */ ++ 103, 65, 77, 65, '\0', /* gAMA */ ++ 104, 73, 83, 84, '\0', /* hIST */ ++ 105, 67, 67, 80, '\0', /* iCCP */ ++ 105, 84, 88, 116, '\0', /* iTXt */ ++ 111, 70, 70, 115, '\0', /* oFFs */ ++ 112, 67, 65, 76, '\0', /* pCAL */ ++ 112, 72, 89, 115, '\0', /* pHYs */ ++ 115, 66, 73, 84, '\0', /* sBIT */ ++ 115, 67, 65, 76, '\0', /* sCAL */ ++ 115, 80, 76, 84, '\0', /* sPLT */ ++ 115, 84, 69, 82, '\0', /* sTER */ ++ 115, 82, 71, 66, '\0', /* sRGB */ ++ 116, 69, 88, 116, '\0', /* tEXt */ ++ 116, 73, 77, 69, '\0', /* tIME */ ++ 122, 84, 88, 116, '\0' /* zTXt */ ++ }; ++ ++ chunk_list = chunks_to_ignore; ++ num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U; ++ } ++ ++ else /* num_chunks_in > 0 */ ++ { ++ if (chunk_list == NULL) ++ { ++ /* Prior to 1.6.0 this was silently ignored, now it is an app_error ++ * which can be switched off. ++ */ ++ png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); ++ return; ++ } ++ ++ num_chunks = num_chunks_in; ++ } + + old_num_chunks = png_ptr->num_chunk_list; +- new_list=(png_bytep)png_malloc(png_ptr, +- (png_size_t)(5*(num_chunks + old_num_chunks))); ++ if (png_ptr->chunk_list == NULL) ++ old_num_chunks = 0; + +- if (png_ptr->chunk_list != NULL) ++ /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. ++ */ ++ if (num_chunks + old_num_chunks > UINT_MAX/5) + { +- png_memcpy(new_list, png_ptr->chunk_list, +- (png_size_t)(5*old_num_chunks)); +- png_free(png_ptr, png_ptr->chunk_list); +- png_ptr->chunk_list=NULL; ++ png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); ++ return; + } + +- png_memcpy(new_list + 5*old_num_chunks, chunk_list, +- (png_size_t)(5*num_chunks)); ++ /* If these chunks are being reset to the default then no more memory is ++ * required because add_one_chunk above doesn't extend the list if the 'keep' ++ * parameter is the default. ++ */ ++ if (keep != 0) ++ { ++ new_list = png_voidcast(png_bytep, png_malloc(png_ptr, ++ 5 * (num_chunks + old_num_chunks))); + +- for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5) +- *p=(png_byte)keep; ++ if (old_num_chunks > 0) ++ memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); ++ } + +- png_ptr->num_chunk_list = old_num_chunks + num_chunks; +- png_ptr->chunk_list = new_list; +- png_ptr->free_me |= PNG_FREE_LIST; ++ else if (old_num_chunks > 0) ++ new_list = png_ptr->chunk_list; ++ ++ else ++ new_list = NULL; ++ ++ /* Add the new chunks together with each one's handling code. If the chunk ++ * already exists the code is updated, otherwise the chunk is added to the ++ * end. (In libpng 1.6.0 order no longer matters because this code enforces ++ * the earlier convention that the last setting is the one that is used.) ++ */ ++ if (new_list != NULL) ++ { ++ png_const_bytep inlist; ++ png_bytep outlist; ++ unsigned int i; ++ ++ for (i=0; i<num_chunks; ++i) ++ { ++ old_num_chunks = add_one_chunk(new_list, old_num_chunks, ++ chunk_list+5*i, keep); ++ } ++ ++ /* Now remove any spurious 'default' entries. */ ++ num_chunks = 0; ++ for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5) ++ { ++ if (inlist[4]) ++ { ++ if (outlist != inlist) ++ memcpy(outlist, inlist, 5); ++ outlist += 5; ++ ++num_chunks; ++ } ++ } ++ ++ /* This means the application has removed all the specialized handling. */ ++ if (num_chunks == 0) ++ { ++ if (png_ptr->chunk_list != new_list) ++ png_free(png_ptr, new_list); ++ ++ new_list = NULL; ++ } ++ } ++ ++ else ++ num_chunks = 0; ++ ++ png_ptr->num_chunk_list = num_chunks; ++ ++ if (png_ptr->chunk_list != new_list) ++ { ++ if (png_ptr->chunk_list != NULL) ++ png_free(png_ptr, png_ptr->chunk_list); ++ ++ png_ptr->chunk_list = new_list; ++ } + } + #endif + + #ifdef PNG_READ_USER_CHUNKS_SUPPORTED + void PNGAPI +-png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, ++png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr, + png_user_chunk_ptr read_user_chunk_fn) + { + png_debug(1, "in png_set_read_user_chunk_fn"); +@@ -1158,64 +1477,90 @@ + + #ifdef PNG_INFO_IMAGE_SUPPORTED + void PNGAPI +-png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) ++png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, ++ png_bytepp row_pointers) + { + png_debug1(1, "in %s storage function", "rows"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +- if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) ++ if (info_ptr->row_pointers != NULL && ++ (info_ptr->row_pointers != row_pointers)) + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + + info_ptr->row_pointers = row_pointers; + +- if (row_pointers) ++ if (row_pointers != NULL) + info_ptr->valid |= PNG_INFO_IDAT; + } + #endif + + void PNGAPI +-png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) ++png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) + { + if (png_ptr == NULL) + return; + +- png_free(png_ptr, png_ptr->zbuf); ++ if (size == 0 || size > PNG_UINT_31_MAX) ++ png_error(png_ptr, "invalid compression buffer size"); + +- if (size > ZLIB_IO_MAX) +- { +- png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); +- png_ptr->zbuf_size = ZLIB_IO_MAX; +- size = ZLIB_IO_MAX; /* must fit */ +- } ++# ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) ++ { ++ png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ ++ return; ++ } ++# endif + +- else +- png_ptr->zbuf_size = (uInt)size; ++# ifdef PNG_WRITE_SUPPORTED ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) ++ { ++ if (png_ptr->zowner != 0) ++ { ++ png_warning(png_ptr, ++ "Compression buffer size cannot be changed because it is in use"); ++ return; ++ } + +- png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); ++ if (size > ZLIB_IO_MAX) ++ { ++ png_warning(png_ptr, ++ "Compression buffer size limited to system maximum"); ++ size = ZLIB_IO_MAX; /* must fit */ ++ } + +- /* The following ensures a relatively safe failure if this gets called while +- * the buffer is actually in use. +- */ +- png_ptr->zstream.next_out = png_ptr->zbuf; +- png_ptr->zstream.avail_out = 0; +- png_ptr->zstream.avail_in = 0; ++ else if (size < 6) ++ { ++ /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH ++ * if this is permitted. ++ */ ++ png_warning(png_ptr, ++ "Compression buffer size cannot be reduced below 6"); ++ return; ++ } ++ ++ if (png_ptr->zbuffer_size != size) ++ { ++ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); ++ png_ptr->zbuffer_size = (uInt)size; ++ } ++ } ++# endif + } + + void PNGAPI +-png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) ++png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) + { +- if (png_ptr && info_ptr) ++ if (png_ptr != NULL && info_ptr != NULL) + info_ptr->valid &= ~mask; + } + + +- + #ifdef PNG_SET_USER_LIMITS_SUPPORTED + /* This function was added to libpng 1.2.6 */ + void PNGAPI +-png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, ++png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, + png_uint_32 user_height_max) + { + /* Images with dimensions larger than these limits will be +@@ -1231,35 +1576,64 @@ + + /* This function was added to libpng 1.4.0 */ + void PNGAPI +-png_set_chunk_cache_max (png_structp png_ptr, +- png_uint_32 user_chunk_cache_max) ++png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) + { +- if (png_ptr) ++ if (png_ptr != NULL) + png_ptr->user_chunk_cache_max = user_chunk_cache_max; + } + + /* This function was added to libpng 1.4.1 */ + void PNGAPI +-png_set_chunk_malloc_max (png_structp png_ptr, ++png_set_chunk_malloc_max (png_structrp png_ptr, + png_alloc_size_t user_chunk_malloc_max) + { +- if (png_ptr) ++ if (png_ptr != NULL) + png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; + } +-#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ ++#endif /* ?SET_USER_LIMITS */ + + + #ifdef PNG_BENIGN_ERRORS_SUPPORTED + void PNGAPI +-png_set_benign_errors(png_structp png_ptr, int allowed) ++png_set_benign_errors(png_structrp png_ptr, int allowed) + { + png_debug(1, "in png_set_benign_errors"); + +- if (allowed) +- png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; ++ /* If allowed is 1, png_benign_error() is treated as a warning. ++ * ++ * If allowed is 0, png_benign_error() is treated as an error (which ++ * is the default behavior if png_set_benign_errors() is not called). ++ */ ++ ++ if (allowed != 0) ++ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | ++ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; + + else +- png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; ++ png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | ++ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); + } +-#endif /* PNG_BENIGN_ERRORS_SUPPORTED */ +-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ ++#endif /* BENIGN_ERRORS */ ++ ++#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED ++ /* Whether to report invalid palette index; added at libng-1.5.10. ++ * It is possible for an indexed (color-type==3) PNG file to contain ++ * pixels with invalid (out-of-range) indexes if the PLTE chunk has ++ * fewer entries than the image's bit-depth would allow. We recover ++ * from this gracefully by filling any incomplete palette with zeros ++ * (opaque black). By default, when this occurs libpng will issue ++ * a benign error. This API can be used to override that behavior. ++ */ ++void PNGAPI ++png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) ++{ ++ png_debug(1, "in png_set_check_for_invalid_index"); ++ ++ if (allowed > 0) ++ png_ptr->num_palette_max = 0; ++ ++ else ++ png_ptr->num_palette_max = -1; ++} ++#endif ++#endif /* READ || WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pngstruct.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngstruct.h Thu Feb 05 13:00:26 2015 +0100 +@@ -29,11 +29,11 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +- * Last changed in libpng 1.5.4 [July 7, 2011] ++ * Last changed in libpng 1.6.1 [March 28, 2013] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer +@@ -52,13 +52,130 @@ + * in this structure and is required for decompressing the LZ compressed + * data in PNG files. + */ ++#ifndef ZLIB_CONST ++ /* We must ensure that zlib uses 'const' in declarations. */ ++# define ZLIB_CONST ++#endif + #include "zlib.h" ++#ifdef const ++ /* zlib.h sometimes #defines const to nothing, undo this. */ ++# undef const ++#endif ++ ++/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility ++ * with older builds. ++ */ ++#if ZLIB_VERNUM < 0x1260 ++# define PNGZ_MSG_CAST(s) png_constcast(char*,s) ++# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) ++#else ++# define PNGZ_MSG_CAST(s) (s) ++# define PNGZ_INPUT_CAST(b) (b) ++#endif ++ ++/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib ++ * can handle at once. This type need be no larger than 16 bits (so maximum of ++ * 65535), this define allows us to discover how big it is, but limited by the ++ * maximuum for png_size_t. The value can be overriden in a library build ++ * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably ++ * lower value (e.g. 255 works). A lower value may help memory usage (slightly) ++ * and may even improve performance on some systems (and degrade it on others.) ++ */ ++#ifndef ZLIB_IO_MAX ++# define ZLIB_IO_MAX ((uInt)-1) ++#endif ++ ++#ifdef PNG_WRITE_SUPPORTED ++/* The type of a compression buffer list used by the write code. */ ++typedef struct png_compression_buffer ++{ ++ struct png_compression_buffer *next; ++ png_byte output[1]; /* actually zbuf_size */ ++} png_compression_buffer, *png_compression_bufferp; ++ ++#define PNG_COMPRESSION_BUFFER_SIZE(pp)\ ++ (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size) ++#endif ++ ++/* Colorspace support; structures used in png_struct, png_info and in internal ++ * functions to hold and communicate information about the color space. ++ * ++ * PNG_COLORSPACE_SUPPORTED is only required if the application will perform ++ * colorspace corrections, otherwise all the colorspace information can be ++ * skipped and the size of libpng can be reduced (significantly) by compiling ++ * out the colorspace support. ++ */ ++#ifdef PNG_COLORSPACE_SUPPORTED ++/* The chromaticities of the red, green and blue colorants and the chromaticity ++ * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). ++ */ ++typedef struct png_xy ++{ ++ png_fixed_point redx, redy; ++ png_fixed_point greenx, greeny; ++ png_fixed_point bluex, bluey; ++ png_fixed_point whitex, whitey; ++} png_xy; ++ ++/* The same data as above but encoded as CIE XYZ values. When this data comes ++ * from chromaticities the sum of the Y values is assumed to be 1.0 ++ */ ++typedef struct png_XYZ ++{ ++ png_fixed_point red_X, red_Y, red_Z; ++ png_fixed_point green_X, green_Y, green_Z; ++ png_fixed_point blue_X, blue_Y, blue_Z; ++} png_XYZ; ++#endif /* COLORSPACE */ ++ ++#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) ++/* A colorspace is all the above plus, potentially, profile information, ++ * however at present libpng does not use the profile internally so it is only ++ * stored in the png_info struct (if iCCP is supported.) The rendering intent ++ * is retained here and is checked. ++ * ++ * The file gamma encoding information is also stored here and gamma correction ++ * is done by libpng, whereas color correction must currently be done by the ++ * application. ++ */ ++typedef struct png_colorspace ++{ ++#ifdef PNG_GAMMA_SUPPORTED ++ png_fixed_point gamma; /* File gamma */ ++#endif ++ ++#ifdef PNG_COLORSPACE_SUPPORTED ++ png_xy end_points_xy; /* End points as chromaticities */ ++ png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ ++ png_uint_16 rendering_intent; /* Rendering intent of a profile */ ++#endif ++ ++ /* Flags are always defined to simplify the code. */ ++ png_uint_16 flags; /* As defined below */ ++} png_colorspace, * PNG_RESTRICT png_colorspacerp; ++ ++typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; ++ ++/* General flags for the 'flags' field */ ++#define PNG_COLORSPACE_HAVE_GAMMA 0x0001 ++#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002 ++#define PNG_COLORSPACE_HAVE_INTENT 0x0004 ++#define PNG_COLORSPACE_FROM_gAMA 0x0008 ++#define PNG_COLORSPACE_FROM_cHRM 0x0010 ++#define PNG_COLORSPACE_FROM_sRGB 0x0020 ++#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 ++#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ ++#define PNG_COLORSPACE_INVALID 0x8000 ++#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) ++#endif /* COLORSPACE || GAMMA */ + + struct png_struct_def + { + #ifdef PNG_SETJMP_SUPPORTED +- jmp_buf longjmp_buffer; /* used in png_error */ ++ jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */ + png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ ++ jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ ++ size_t jmp_buf_size; /* size of the above, if allocated */ + #endif + png_error_ptr error_fn; /* function for printing errors and aborting */ + #ifdef PNG_WARNINGS_SUPPORTED +@@ -91,22 +208,12 @@ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + +- z_stream zstream; /* pointer to decompression structure (below) */ +- png_bytep zbuf; /* buffer for zlib */ +- uInt zbuf_size; /* size of zbuf (typically 65536) */ ++ png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ ++ z_stream zstream; /* decompression structure */ ++ + #ifdef PNG_WRITE_SUPPORTED +- +-/* Added in 1.5.4: state to keep track of whether the zstream has been +- * initialized and if so whether it is for IDAT or some other chunk. +- */ +-#define PNG_ZLIB_UNINITIALIZED 0 +-#define PNG_ZLIB_FOR_IDAT 1 +-#define PNG_ZLIB_FOR_TEXT 2 /* anything other than IDAT */ +-#define PNG_ZLIB_USE_MASK 3 /* bottom two bits */ +-#define PNG_ZLIB_IN_USE 4 /* a flag value */ +- +- png_uint_32 zlib_state; /* State of zlib initialization */ +-/* End of material added at libpng 1.5.4 */ ++ png_compression_bufferp zbuffer_list; /* Created on demand during write */ ++ uInt zbuffer_size; /* size of the actual buffer */ + + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ +@@ -115,8 +222,7 @@ + int zlib_strategy; /* holds zlib compression strategy */ + #endif + /* Added at libpng 1.5.4 */ +-#if defined(PNG_WRITE_COMPRESSED_TEXT_SUPPORTED) || \ +- defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED) ++#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + int zlib_text_level; /* holds zlib compression level */ + int zlib_text_method; /* holds zlib compression method */ + int zlib_text_window_bits; /* holds zlib compression window bits */ +@@ -124,6 +230,14 @@ + int zlib_text_strategy; /* holds zlib compression strategy */ + #endif + /* End of material added at libpng 1.5.4 */ ++/* Added at libpng 1.6.0 */ ++#ifdef PNG_WRITE_SUPPORTED ++ int zlib_set_level; /* Actual values set into the zstream on write */ ++ int zlib_set_method; ++ int zlib_set_window_bits; ++ int zlib_set_mem_level; ++ int zlib_set_strategy; ++#endif + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ +@@ -132,21 +246,32 @@ + png_size_t rowbytes; /* size of row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ +- png_bytep prev_row; /* buffer to save previous (unfiltered) row */ +- png_bytep row_buf; /* buffer to save current (unfiltered) row */ ++ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ ++ png_bytep prev_row; /* buffer to save previous (unfiltered) row. ++ * This is a pointer into big_prev_row ++ */ ++ png_bytep row_buf; /* buffer to save current (unfiltered) row. ++ * This is a pointer into big_row_buf ++ */ ++#ifdef PNG_WRITE_SUPPORTED + png_bytep sub_row; /* buffer to save "sub" row when filtering */ + png_bytep up_row; /* buffer to save "up" row when filtering */ + png_bytep avg_row; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ +- png_row_info row_info; /* used for transformation routines */ ++#endif + png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ ++ ++/* Added at libpng-1.5.10 */ ++#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED ++ int num_palette_max; /* maximum palette index found in IDAT */ ++#endif ++ + png_uint_16 num_trans; /* number of transparency values */ +- png_byte chunk_name[5]; /* null-terminated name of current chunk */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ +@@ -154,12 +279,17 @@ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ +- png_byte usr_bit_depth; /* bit depth of users row */ ++ png_byte usr_bit_depth; /* bit depth of users row: write only */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ +- png_byte usr_channels; /* channels at start of write */ ++#ifdef PNG_WRITE_SUPPORTED ++ png_byte usr_channels; /* channels at start of write: write only */ ++#endif + png_byte sig_bytes; /* magic bytes read/written from start of file */ +- ++ png_byte maximum_pixel_depth; ++ /* pixel depth used for the row buffers */ ++ png_byte transformed_pixel_depth; ++ /* pixel depth after read/write transforms */ + #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) + png_uint_16 filler; /* filler bytes for pixel expansion */ + #endif +@@ -172,7 +302,7 @@ + #ifdef PNG_READ_GAMMA_SUPPORTED + png_color_16 background_1; /* background normalized to gamma 1.0 */ + #endif +-#endif /* PNG_bKGD_SUPPORTED */ ++#endif /* bKGD */ + + #ifdef PNG_WRITE_FLUSH_SUPPORTED + png_flush_ptr output_flush_fn; /* Function for flushing output */ +@@ -180,19 +310,20 @@ + png_uint_32 flush_rows; /* number of rows written since last flush */ + #endif + +-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ++#ifdef PNG_READ_GAMMA_SUPPORTED + int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ +- png_fixed_point gamma; /* file gamma value */ + png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ +-#endif + +-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep gamma_table; /* gamma table for 8-bit depth files */ ++ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ ++#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ ++ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ ++ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ +- png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ ++#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ + #endif + + #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) +@@ -228,14 +359,7 @@ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ + +-# ifdef PNG_TEXT_SUPPORTED +- png_size_t current_text_size; /* current size of text input data */ +- png_size_t current_text_left; /* how much text left to read in input */ +- png_charp current_text; /* current text chunk buffer */ +- png_charp current_text_ptr; /* current location in current_text */ +-# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ +- +-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ ++#endif /* PROGRESSIVE_READ */ + + #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) + /* For the Borland special 64K segment handler */ +@@ -251,10 +375,6 @@ + png_bytep quantize_index; /* index translation for palette files */ + #endif + +-#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED) +- png_uint_16p hist; /* histogram */ +-#endif +- + #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ +@@ -265,9 +385,17 @@ + png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ + #endif + ++ /* Options */ ++#ifdef PNG_SET_OPTION_SUPPORTED ++ png_byte options; /* On/off state (up to 4 options) */ ++#endif ++ ++#if PNG_LIBPNG_VER < 10700 ++/* To do: remove this from libpng-1.7 */ + #ifdef PNG_TIME_RFC1123_SUPPORTED + char time_buffer[29]; /* String to hold RFC 1123 time text */ + #endif ++#endif + + /* New members added in libpng-1.0.6 */ + +@@ -275,27 +403,31 @@ + + #ifdef PNG_USER_CHUNKS_SUPPORTED + png_voidp user_chunk_ptr; ++#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ + #endif ++#endif + +-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +- int num_chunk_list; +- png_bytep chunk_list; ++#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++ int unknown_default; /* As PNG_HANDLE_* */ ++ unsigned int num_chunk_list; /* Number of entries in the list */ ++ png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name ++ * followed by a PNG_HANDLE_* byte */ + #endif + + /* New members added in libpng-1.0.3 */ + #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte rgb_to_gray_status; ++ /* Added in libpng 1.5.5 to record setting of coefficients: */ ++ png_byte rgb_to_gray_coefficients_set; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; +- png_uint_16 rgb_to_gray_blue_coeff; ++ /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ + #endif + + /* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +-#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ +- defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ +- defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) ++#if defined(PNG_MNG_FEATURES_SUPPORTED) + /* Changed from png_byte to png_uint_32 at version 1.2.0 */ + png_uint_32 mng_features_permitted; + #endif +@@ -345,21 +477,41 @@ + #endif + + /* New member added in libpng-1.0.25 and 1.2.17 */ +-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +- /* Storage for unknown chunk that the library doesn't recognize. */ ++#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED ++ /* Temporary storage for unknown chunk that the library doesn't recognize, ++ * used while reading the chunk. ++ */ + png_unknown_chunk unknown_chunk; + #endif + +-/* New members added in libpng-1.2.26 */ ++/* New member added in libpng-1.2.26 */ + png_size_t old_big_row_buf_size; +- png_size_t old_prev_row_size; + ++#ifdef PNG_READ_SUPPORTED + /* New member added in libpng-1.2.30 */ +- png_charp chunkdata; /* buffer for reading chunk data */ ++ png_bytep read_buffer; /* buffer for reading chunk data */ ++ png_alloc_size_t read_buffer_size; /* current size of the buffer */ ++#endif ++#ifdef PNG_SEQUENTIAL_READ_SUPPORTED ++ uInt IDAT_read_size; /* limit on read buffer size for IDAT */ ++#endif + + #ifdef PNG_IO_STATE_SUPPORTED + /* New member added in libpng-1.4.0 */ + png_uint_32 io_state; + #endif ++ ++/* New member added in libpng-1.5.6 */ ++ png_bytep big_prev_row; ++ ++/* New member added in libpng-1.5.7 */ ++ void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, ++ png_bytep row, png_const_bytep prev_row); ++ ++#ifdef PNG_READ_SUPPORTED ++#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) ++ png_colorspace colorspace; ++#endif ++#endif + }; + #endif /* PNGSTRUCT_H */ +--- ./jdk/src/share/native/sun/awt/libpng/pngtest.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngtest.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -61,16 +61,50 @@ + + #define _POSIX_SOURCE 1 + +-#include "zlib.h" ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++ ++/* Defined so I can write to a file on gui/windowing platforms */ ++/* #define STDERR stderr */ ++#define STDERR stdout /* For DOS */ ++ + #include "png.h" ++ ++/* Known chunks that exist in pngtest.png must be supported or pngtest will fail ++ * simply as a result of re-ordering them. This may be fixed in 1.7 ++ * ++ * pngtest allocates a single row buffer for each row and overwrites it, ++ * therefore if the write side doesn't support the writing of interlaced images ++ * nothing can be done for an interlaced image (and the code below will fail ++ * horribly trying to write extra data after writing garbage). ++ */ ++#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\ ++ defined PNG_READ_bKGD_SUPPORTED &&\ ++ defined PNG_READ_cHRM_SUPPORTED &&\ ++ defined PNG_READ_gAMA_SUPPORTED &&\ ++ defined PNG_READ_oFFs_SUPPORTED &&\ ++ defined PNG_READ_pCAL_SUPPORTED &&\ ++ defined PNG_READ_pHYs_SUPPORTED &&\ ++ defined PNG_READ_sBIT_SUPPORTED &&\ ++ defined PNG_READ_sCAL_SUPPORTED &&\ ++ defined PNG_READ_sRGB_SUPPORTED &&\ ++ defined PNG_READ_tEXt_SUPPORTED &&\ ++ defined PNG_READ_tIME_SUPPORTED &&\ ++ defined PNG_READ_zTXt_SUPPORTED &&\ ++ defined PNG_WRITE_INTERLACING_SUPPORTED ++ ++#ifdef PNG_ZLIB_HEADER ++# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ ++#else ++# include "zlib.h" ++#endif ++ + /* Copied from pngpriv.h but only used in error messages below. */ + #ifndef PNG_ZBUF_SIZE + # define PNG_ZBUF_SIZE 8192 + #endif +-# include <stdio.h> +-# include <stdlib.h> +-# include <string.h> +-# define FCLOSE(file) fclose(file) ++#define FCLOSE(file) fclose(file) + + #ifndef PNG_STDIO_SUPPORTED + typedef FILE * png_FILE_p; +@@ -95,17 +129,6 @@ + # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ + #endif + +-/* The code uses memcmp and memcpy on large objects (typically row pointers) so +- * it is necessary to do soemthing special on certain architectures, note that +- * the actual support for this was effectively removed in 1.4, so only the +- * memory remains in this program: +- */ +-#define CVT_PTR(ptr) (ptr) +-#define CVT_PTR_NOCHECK(ptr) (ptr) +-#define png_memcmp memcmp +-#define png_memcpy memcpy +-#define png_memset memset +- + /* Turn on CPU timing + #define PNGTEST_TIMING + */ +@@ -126,30 +149,34 @@ + #endif + + static int verbose = 0; +- +-int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); +- +-#ifdef __TURBOC__ +-#include <mem.h> +-#endif +- +-/* Defined so I can write to a file on gui/windowing platforms */ +-/* #define STDERR stderr */ +-#define STDERR stdout /* For DOS */ ++static int strict = 0; ++static int relaxed = 0; ++static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ ++static int error_count = 0; /* count calls to png_error */ ++static int warning_count = 0; /* count calls to png_warning */ + + /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ + #ifndef png_jmpbuf + # define png_jmpbuf(png_ptr) png_ptr->jmpbuf + #endif + ++/* Defines for unknown chunk handling if required. */ ++#ifndef PNG_HANDLE_CHUNK_ALWAYS ++# define PNG_HANDLE_CHUNK_ALWAYS 3 ++#endif ++#ifndef PNG_HANDLE_CHUNK_IF_SAFE ++# define PNG_HANDLE_CHUNK_IF_SAFE 2 ++#endif ++ ++/* Utility to save typing/errors, the argument must be a name */ ++#define MEMZERO(var) ((void)memset(&var, 0, sizeof var)) ++ + /* Example of using row callbacks to make a simple progress meter */ + static int status_pass = 1; + static int status_dots_requested = 0; + static int status_dots = 1; + +-void PNGCBAPI +-read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +-void PNGCBAPI ++static void PNGCBAPI + read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) + { + if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) +@@ -173,9 +200,8 @@ + fprintf(stdout, "r"); + } + +-void PNGCBAPI +-write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass); +-void PNGCBAPI ++#ifdef PNG_WRITE_SUPPORTED ++static void PNGCBAPI + write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) + { + if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) +@@ -183,6 +209,7 @@ + + fprintf(stdout, "w"); + } ++#endif + + + #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +@@ -191,9 +218,7 @@ + * 5 in case illegal filter values are present.) + */ + static png_uint_32 filters_used[256]; +-void PNGCBAPI +-count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data); +-void PNGCBAPI ++static void PNGCBAPI + count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) + { + if (png_ptr != NULL && row_info != NULL) +@@ -208,9 +233,7 @@ + + static png_uint_32 zero_samples; + +-void PNGCBAPI +-count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data); +-void PNGCBAPI ++static void PNGCBAPI + count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) + { + png_bytep dp = data; +@@ -288,7 +311,8 @@ + png_uint_32 n, nstop; + int channel; + int color_channels = row_info->channels; +- if (row_info->color_type > 3)color_channels--; ++ if (row_info->color_type > 3) ++ color_channels--; + + for (n = 0, nstop=row_info->width; n<nstop; n++) + { +@@ -315,9 +339,7 @@ + } + } + } +-#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */ +- +-static int wrote_question = 0; ++#endif /* WRITE_USER_TRANSFORM */ + + #ifndef PNG_STDIO_SUPPORTED + /* START of code to validate stdio-free compilation */ +@@ -366,12 +388,11 @@ + default: + err = 1; /* uninitialized */ + } +- if (err) ++ if (err != 0) + png_error(png_ptr, "Bad I/O state or buffer size"); + } + #endif + +-#ifndef USE_FAR_KEYWORD + static void PNGCBAPI + pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) + { +@@ -396,59 +417,6 @@ + pngtest_check_io_state(png_ptr, length, PNG_IO_READING); + #endif + } +-#else +-/* This is the model-independent version. Since the standard I/O library +- can't handle far buffers in the medium and small models, we have to copy +- the data. +-*/ +- +-#define NEAR_BUF_SIZE 1024 +-#define MIN(a,b) (a <= b ? a : b) +- +-static void PNGCBAPI +-pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +-{ +- png_size_t check; +- png_byte *n_data; +- png_FILE_p io_ptr; +- +- /* Check if data really is near. If so, use usual code. */ +- n_data = (png_byte *)CVT_PTR_NOCHECK(data); +- io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); +- if ((png_bytep)n_data == data) +- { +- check = fread(n_data, 1, length, io_ptr); +- } +- else +- { +- png_byte buf[NEAR_BUF_SIZE]; +- png_size_t read, remaining, err; +- check = 0; +- remaining = length; +- +- do +- { +- read = MIN(NEAR_BUF_SIZE, remaining); +- err = fread(buf, 1, 1, io_ptr); +- png_memcpy(data, buf, read); /* Copy far buffer to near buffer */ +- if (err != read) +- break; +- else +- check += err; +- data += read; +- remaining -= read; +- } +- while (remaining != 0); +- } +- +- if (check != length) +- png_error(png_ptr, "Read Error"); +- +-#ifdef PNG_IO_STATE_SUPPORTED +- pngtest_check_io_state(png_ptr, length, PNG_IO_READING); +-#endif +-} +-#endif /* USE_FAR_KEYWORD */ + + #ifdef PNG_WRITE_FLUSH_SUPPORTED + static void PNGCBAPI +@@ -464,7 +432,6 @@ + * write_data function and use it at run time with png_set_write_fn(), rather + * than changing the library. + */ +-#ifndef USE_FAR_KEYWORD + static void PNGCBAPI + pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) + { +@@ -481,81 +448,31 @@ + pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); + #endif + } +-#else +-/* This is the model-independent version. Since the standard I/O library +- can't handle far buffers in the medium and small models, we have to copy +- the data. +-*/ +- +-#define NEAR_BUF_SIZE 1024 +-#define MIN(a,b) (a <= b ? a : b) +- +-static void PNGCBAPI +-pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +-{ +- png_size_t check; +- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ +- png_FILE_p io_ptr; +- +- /* Check if data really is near. If so, use usual code. */ +- near_data = (png_byte *)CVT_PTR_NOCHECK(data); +- io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr)); +- +- if ((png_bytep)near_data == data) +- { +- check = fwrite(near_data, 1, length, io_ptr); +- } +- +- else +- { +- png_byte buf[NEAR_BUF_SIZE]; +- png_size_t written, remaining, err; +- check = 0; +- remaining = length; +- +- do +- { +- written = MIN(NEAR_BUF_SIZE, remaining); +- png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ +- err = fwrite(buf, 1, written, io_ptr); +- if (err != written) +- break; +- else +- check += err; +- data += written; +- remaining -= written; +- } +- while (remaining != 0); +- } +- +- if (check != length) +- { +- png_error(png_ptr, "Write Error"); +- } +- +-#ifdef PNG_IO_STATE_SUPPORTED +- pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); +-#endif +-} +-#endif /* USE_FAR_KEYWORD */ ++#endif /* !STDIO */ + + /* This function is called when there is a warning, but the library thinks + * it can continue anyway. Replacement functions don't have to do anything + * here if you don't want to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ ++typedef struct ++{ ++ PNG_CONST char *file_name; ++} pngtest_error_parameters; ++ + static void PNGCBAPI + pngtest_warning(png_structp png_ptr, png_const_charp message) + { + PNG_CONST char *name = "UNKNOWN (ERROR!)"; +- char *test; +- test = png_get_error_ptr(png_ptr); ++ pngtest_error_parameters *test = ++ (pngtest_error_parameters*)png_get_error_ptr(png_ptr); + +- if (test == NULL) +- fprintf(STDERR, "%s: libpng warning: %s\n", name, message); ++ ++warning_count; + +- else +- fprintf(STDERR, "%s: libpng warning: %s\n", test, message); ++ if (test != NULL && test->file_name != NULL) ++ name = test->file_name; ++ ++ fprintf(STDERR, "%s: libpng warning: %s\n", name, message); + } + + /* This is the default error handling function. Note that replacements for +@@ -566,12 +483,14 @@ + static void PNGCBAPI + pngtest_error(png_structp png_ptr, png_const_charp message) + { ++ ++error_count; ++ + pngtest_warning(png_ptr, message); + /* We can return because png_error calls the default handler, which is + * actually OK in this case. + */ + } +-#endif /* !PNG_STDIO_SUPPORTED */ ++ + /* END of code to validate stdio-free compilation */ + + /* START of code to validate memory allocation and deallocation */ +@@ -590,9 +509,9 @@ + { + png_alloc_size_t size; + png_voidp pointer; +- struct memory_information FAR *next; ++ struct memory_information *next; + } memory_information; +-typedef memory_information FAR *memory_infop; ++typedef memory_information *memory_infop; + + static memory_infop pinformation = NULL; + static int current_allocation = 0; +@@ -622,7 +541,7 @@ + memory_infop pinfo; + png_set_mem_fn(png_ptr, NULL, NULL, NULL); + pinfo = (memory_infop)png_malloc(png_ptr, +- png_sizeof(*pinfo)); ++ (sizeof *pinfo)); + pinfo->size = size; + current_allocation += size; + total_allocation += size; +@@ -648,9 +567,9 @@ + pinfo->next = pinformation; + pinformation = pinfo; + /* Make sure the caller isn't assuming zeroed memory. */ +- png_memset(pinfo->pointer, 0xdd, pinfo->size); ++ memset(pinfo->pointer, 0xdd, pinfo->size); + +- if (verbose) ++ if (verbose != 0) + printf("png_malloc %lu bytes at %p\n", (unsigned long)size, + pinfo->pointer); + +@@ -675,7 +594,7 @@ + + /* Unlink the element from the list. */ + { +- memory_infop FAR *ppinfo = &pinformation; ++ memory_infop *ppinfo = &pinformation; + + for (;;) + { +@@ -689,15 +608,16 @@ + fprintf(STDERR, "Duplicate free of memory\n"); + /* We must free the list element too, but first kill + the memory that is to be freed. */ +- png_memset(ptr, 0x55, pinfo->size); +- png_free_default(png_ptr, pinfo); ++ memset(ptr, 0x55, pinfo->size); ++ if (pinfo != NULL) ++ free(pinfo); + pinfo = NULL; + break; + } + + if (pinfo->next == NULL) + { +- fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); ++ fprintf(STDERR, "Pointer %p not found\n", ptr); + break; + } + +@@ -706,35 +626,84 @@ + } + + /* Finally free the data. */ +- if (verbose) ++ if (verbose != 0) + printf("Freeing %p\n", ptr); + +- png_free_default(png_ptr, ptr); ++ if (ptr != NULL) ++ free(ptr); + ptr = NULL; + } +-#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ ++#endif /* USER_MEM && DEBUG */ + /* END of code to test memory allocation/deallocation */ + + ++#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* Demonstration of user chunk support of the sTER and vpAg chunks */ +-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED + + /* (sTER is a public chunk not yet known by libpng. vpAg is a private + chunk used in ImageMagick to store "virtual page" size). */ + +-static png_uint_32 user_chunk_data[4]; ++static struct user_chunk_data ++{ ++ png_const_infop info_ptr; ++ png_uint_32 vpAg_width, vpAg_height; ++ png_byte vpAg_units; ++ png_byte sTER_mode; ++ int location[2]; ++} ++user_chunk_data; + +- /* 0: sTER mode + 1 +- * 1: vpAg width +- * 2: vpAg height +- * 3: vpAg units +- */ ++/* Used for location and order; zero means nothing. */ ++#define have_sTER 0x01 ++#define have_vpAg 0x02 ++#define before_PLTE 0x10 ++#define before_IDAT 0x20 ++#define after_IDAT 0x40 + +-static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, +- png_unknown_chunkp chunk) ++static void ++init_callback_info(png_const_infop info_ptr) + { +- png_uint_32 +- *my_user_chunk_data; ++ MEMZERO(user_chunk_data); ++ user_chunk_data.info_ptr = info_ptr; ++} ++ ++static int ++set_location(png_structp png_ptr, struct user_chunk_data *data, int what) ++{ ++ int location; ++ ++ if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0) ++ return 0; /* already have one of these */ ++ ++ /* Find where we are (the code below zeroes info_ptr to indicate that the ++ * chunks before the first IDAT have been read.) ++ */ ++ if (data->info_ptr == NULL) /* after IDAT */ ++ location = what | after_IDAT; ++ ++ else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0) ++ location = what | before_IDAT; ++ ++ else ++ location = what | before_PLTE; ++ ++ if (data->location[0] == 0) ++ data->location[0] = location; ++ ++ else ++ data->location[1] = location; ++ ++ return 1; /* handled */ ++} ++ ++static int PNGCBAPI ++read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) ++{ ++ struct user_chunk_data *my_user_chunk_data = ++ (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); ++ ++ if (my_user_chunk_data == NULL) ++ png_error(png_ptr, "lost user chunk pointer"); + + /* Return one of the following: + * return (-n); chunk had an error +@@ -759,9 +728,14 @@ + if (chunk->data[0] != 0 && chunk->data[0] != 1) + return (-1); /* Invalid mode */ + +- my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); +- my_user_chunk_data[0]=chunk->data[0]+1; +- return (1); ++ if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0) ++ { ++ my_user_chunk_data->sTER_mode=chunk->data[0]; ++ return (1); ++ } ++ ++ else ++ return (0); /* duplicate sTER - give it to libpng */ + } + + if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ +@@ -773,30 +747,126 @@ + if (chunk->size != 9) + return (-1); /* Error return */ + +- my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); ++ if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) ++ return (0); /* duplicate vpAg */ + +- my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data); +- my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4); +- my_user_chunk_data[3]=(png_uint_32)chunk->data[8]; ++ my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); ++ my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); ++ my_user_chunk_data->vpAg_units = chunk->data[8]; + + return (1); ++} + ++#ifdef PNG_WRITE_SUPPORTED ++static void ++write_sTER_chunk(png_structp write_ptr) ++{ ++ png_byte sTER[5] = {115, 84, 69, 82, '\0'}; ++ ++ if (verbose != 0) ++ fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode); ++ ++ png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1); + } ++ ++static void ++write_vpAg_chunk(png_structp write_ptr) ++{ ++ png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; ++ ++ png_byte vpag_chunk_data[9]; ++ ++ if (verbose != 0) ++ fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", ++ (unsigned long)user_chunk_data.vpAg_width, ++ (unsigned long)user_chunk_data.vpAg_height, ++ user_chunk_data.vpAg_units); ++ ++ png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); ++ png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); ++ vpag_chunk_data[8] = user_chunk_data.vpAg_units; ++ png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); ++} ++ ++static void ++write_chunks(png_structp write_ptr, int location) ++{ ++ int i; ++ ++ /* Notice that this preserves the original chunk order, however chunks ++ * intercepted by the callback will be written *after* chunks passed to ++ * libpng. This will actually reverse a pair of sTER chunks or a pair of ++ * vpAg chunks, resulting in an error later. This is not worth worrying ++ * about - the chunks should not be duplicated! ++ */ ++ for (i=0; i<2; ++i) ++ { ++ if (user_chunk_data.location[i] == (location | have_sTER)) ++ write_sTER_chunk(write_ptr); ++ ++ else if (user_chunk_data.location[i] == (location | have_vpAg)) ++ write_vpAg_chunk(write_ptr); ++ } ++} ++#endif /* WRITE */ ++#else /* !READ_USER_CHUNKS */ ++# define write_chunks(pp,loc) ((void)0) + #endif + /* END of code to demonstrate user chunk support */ + ++/* START of code to check that libpng has the required text support; this only ++ * checks for the write support because if read support is missing the chunk ++ * will simply not be reported back to pngtest. ++ */ ++#ifdef PNG_TEXT_SUPPORTED ++static void ++pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr, ++ int num_text) ++{ ++ while (num_text > 0) ++ { ++ switch (text_ptr[--num_text].compression) ++ { ++ case PNG_TEXT_COMPRESSION_NONE: ++ break; ++ ++ case PNG_TEXT_COMPRESSION_zTXt: ++# ifndef PNG_WRITE_zTXt_SUPPORTED ++ ++unsupported_chunks; ++# endif ++ break; ++ ++ case PNG_ITXT_COMPRESSION_NONE: ++ case PNG_ITXT_COMPRESSION_zTXt: ++# ifndef PNG_WRITE_iTXt_SUPPORTED ++ ++unsupported_chunks; ++# endif ++ break; ++ ++ default: ++ /* This is an error */ ++ png_error(png_ptr, "invalid text chunk compression field"); ++ break; ++ } ++ } ++} ++#endif ++/* END of code to check that libpng has the required text support */ ++ + /* Test one file */ +-int ++static int + test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) + { + static png_FILE_p fpin; + static png_FILE_p fpout; /* "static" prevents setjmp corruption */ ++ pngtest_error_parameters error_parameters; + png_structp read_ptr; + png_infop read_info_ptr, end_info_ptr; + #ifdef PNG_WRITE_SUPPORTED + png_structp write_ptr; + png_infop write_info_ptr; + png_infop write_end_info_ptr; ++ int interlace_preserved = 1; + #else + png_structp write_ptr = NULL; + png_infop write_info_ptr = NULL; +@@ -805,17 +875,11 @@ + png_bytep row_buf; + png_uint_32 y; + png_uint_32 width, height; +- int num_pass, pass; ++ int num_pass = 1, pass; + int bit_depth, color_type; +-#ifdef PNG_SETJMP_SUPPORTED +-#ifdef USE_FAR_KEYWORD +- jmp_buf tmp_jmpbuf; +-#endif +-#endif +- +- char inbuf[256], outbuf[256]; + + row_buf = NULL; ++ error_parameters.file_name = inname; + + if ((fpin = fopen(inname, "rb")) == NULL) + { +@@ -839,20 +903,9 @@ + read_ptr = + png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + #endif +-#ifndef PNG_STDIO_SUPPORTED +- png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, +- pngtest_warning); +-#endif ++ png_set_error_fn(read_ptr, &error_parameters, pngtest_error, ++ pngtest_warning); + +-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +- user_chunk_data[0] = 0; +- user_chunk_data[1] = 0; +- user_chunk_data[2] = 0; +- user_chunk_data[3] = 0; +- png_set_read_user_chunk_fn(read_ptr, user_chunk_data, +- read_user_chunk_callback); +- +-#endif + #ifdef PNG_WRITE_SUPPORTED + #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG + write_ptr = +@@ -862,10 +915,8 @@ + write_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + #endif +-#ifndef PNG_STDIO_SUPPORTED +- png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error, +- pngtest_warning); +-#endif ++ png_set_error_fn(write_ptr, &error_parameters, pngtest_error, ++ pngtest_warning); + #endif + pngtest_debug("Allocating read_info, write_info and end_info structures"); + read_info_ptr = png_create_info_struct(read_ptr); +@@ -875,13 +926,15 @@ + write_end_info_ptr = png_create_info_struct(write_ptr); + #endif + ++#ifdef PNG_READ_USER_CHUNKS_SUPPORTED ++ init_callback_info(read_info_ptr); ++ png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, ++ read_user_chunk_callback); ++#endif ++ + #ifdef PNG_SETJMP_SUPPORTED + pngtest_debug("Setting jmpbuf for read struct"); +-#ifdef USE_FAR_KEYWORD +- if (setjmp(tmp_jmpbuf)) +-#else + if (setjmp(png_jmpbuf(read_ptr))) +-#endif + { + fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); + png_free(read_ptr, row_buf); +@@ -895,18 +948,11 @@ + FCLOSE(fpout); + return (1); + } +-#ifdef USE_FAR_KEYWORD +- png_memcpy(png_jmpbuf(read_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +-#endif + + #ifdef PNG_WRITE_SUPPORTED + pngtest_debug("Setting jmpbuf for write struct"); +-#ifdef USE_FAR_KEYWORD + +- if (setjmp(tmp_jmpbuf)) +-#else + if (setjmp(png_jmpbuf(write_ptr))) +-#endif + { + fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); + png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); +@@ -918,12 +964,34 @@ + FCLOSE(fpout); + return (1); + } ++#endif ++#endif + +-#ifdef USE_FAR_KEYWORD +- png_memcpy(png_jmpbuf(write_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); ++ if (strict != 0) ++ { ++ /* Treat png_benign_error() as errors on read */ ++ png_set_benign_errors(read_ptr, 0); ++ ++#ifdef PNG_WRITE_SUPPORTED ++ /* Treat them as errors on write */ ++ png_set_benign_errors(write_ptr, 0); + #endif ++ ++ /* if strict is not set, then app warnings and errors are treated as ++ * warnings in release builds, but not in unstable builds; this can be ++ * changed with '--relaxed'. ++ */ ++ } ++ ++ else if (relaxed != 0) ++ { ++ /* Allow application (pngtest) errors and warnings to pass */ ++ png_set_benign_errors(read_ptr, 1); ++ ++#ifdef PNG_WRITE_SUPPORTED ++ png_set_benign_errors(write_ptr, 1); + #endif +-#endif ++ } + + pngtest_debug("Initializing input and output streams"); + #ifdef PNG_STDIO_SUPPORTED +@@ -943,14 +1011,6 @@ + # endif + #endif + +-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +- /* Normally one would use Z_DEFAULT_STRATEGY for text compression. +- * This is here just to make pngtest replicate the results from libpng +- * versions prior to 1.5.4, and to test this new API. +- */ +- png_set_text_compression_strategy(write_ptr, Z_FILTERED); +-#endif +- + if (status_dots_requested == 1) + { + #ifdef PNG_WRITE_SUPPORTED +@@ -982,36 +1042,65 @@ + png_set_write_user_transform_fn(write_ptr, count_zero_samples); + #endif + +-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +-# ifndef PNG_HANDLE_CHUNK_ALWAYS +-# define PNG_HANDLE_CHUNK_ALWAYS 3 +-# endif ++#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++ /* Preserve all the unknown chunks, if possible. If this is disabled then, ++ * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use ++ * libpng to *save* the unknown chunks on read (because we can't switch the ++ * save option on!) ++ * ++ * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all ++ * unknown chunks and write will write them all. ++ */ ++#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED + png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, + NULL, 0); + #endif + #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +-# ifndef PNG_HANDLE_CHUNK_IF_SAFE +-# define PNG_HANDLE_CHUNK_IF_SAFE 2 +-# endif +- png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE, ++ png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, + NULL, 0); + #endif ++#endif + + pngtest_debug("Reading info struct"); + png_read_info(read_ptr, read_info_ptr); + ++#ifdef PNG_READ_USER_CHUNKS_SUPPORTED ++ /* This is a bit of a hack; there is no obvious way in the callback function ++ * to determine that the chunks before the first IDAT have been read, so ++ * remove the info_ptr (which is only used to determine position relative to ++ * PLTE) here to indicate that we are after the IDAT. ++ */ ++ user_chunk_data.info_ptr = NULL; ++#endif ++ + pngtest_debug("Transferring info struct"); + { + int interlace_type, compression_type, filter_type; + + if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, +- &color_type, &interlace_type, &compression_type, &filter_type)) ++ &color_type, &interlace_type, &compression_type, &filter_type) != 0) + { + png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, +-#ifdef PNG_WRITE_INTERLACING_SUPPORTED + color_type, interlace_type, compression_type, filter_type); +-#else +- color_type, PNG_INTERLACE_NONE, compression_type, filter_type); ++#ifndef PNG_READ_INTERLACING_SUPPORTED ++ /* num_pass will not be set below, set it here if the image is ++ * interlaced: what happens is that write interlacing is *not* turned ++ * on an the partial interlaced rows are written directly. ++ */ ++ switch (interlace_type) ++ { ++ case PNG_INTERLACE_NONE: ++ num_pass = 1; ++ break; ++ ++ case PNG_INTERLACE_ADAM7: ++ num_pass = 7; ++ break; ++ ++ default: ++ png_error(read_ptr, "invalid interlace type"); ++ /*NOT REACHED*/ ++ } + #endif + } + } +@@ -1022,7 +1111,7 @@ + blue_y; + + if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, +- &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) ++ &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) + { + png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); +@@ -1033,7 +1122,7 @@ + { + png_fixed_point gamma; + +- if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) ++ if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) + png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); + } + #endif +@@ -1045,7 +1134,7 @@ + blue_y; + + if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, +- &red_y, &green_x, &green_y, &blue_x, &blue_y)) ++ &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) + { + png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, + red_y, green_x, green_y, blue_x, blue_y); +@@ -1056,7 +1145,7 @@ + { + double gamma; + +- if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) ++ if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) + png_set_gAMA(write_ptr, write_info_ptr, gamma); + } + #endif +@@ -1070,7 +1159,7 @@ + int compression_type; + + if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, +- &profile, &proflen)) ++ &profile, &proflen) != 0) + { + png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, + profile, proflen); +@@ -1081,7 +1170,7 @@ + { + int intent; + +- if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) ++ if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) + png_set_sRGB(write_ptr, write_info_ptr, intent); + } + #endif +@@ -1089,14 +1178,14 @@ + png_colorp palette; + int num_palette; + +- if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) ++ if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) + png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); + } + #ifdef PNG_bKGD_SUPPORTED + { + png_color_16p background; + +- if (png_get_bKGD(read_ptr, read_info_ptr, &background)) ++ if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) + { + png_set_bKGD(write_ptr, write_info_ptr, background); + } +@@ -1106,7 +1195,7 @@ + { + png_uint_16p hist; + +- if (png_get_hIST(read_ptr, read_info_ptr, &hist)) ++ if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) + png_set_hIST(write_ptr, write_info_ptr, hist); + } + #endif +@@ -1116,7 +1205,7 @@ + int unit_type; + + if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, +- &unit_type)) ++ &unit_type) != 0) + { + png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); + } +@@ -1130,7 +1219,7 @@ + int type, nparams; + + if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, +- &nparams, &units, ¶ms)) ++ &nparams, &units, ¶ms) != 0) + { + png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, + nparams, units, params); +@@ -1142,7 +1231,8 @@ + png_uint_32 res_x, res_y; + int unit_type; + +- if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) ++ if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, ++ &unit_type) != 0) + png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); + } + #endif +@@ -1150,18 +1240,19 @@ + { + png_color_8p sig_bit; + +- if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) ++ if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) + png_set_sBIT(write_ptr, write_info_ptr, sig_bit); + } + #endif + #ifdef PNG_sCAL_SUPPORTED +-#ifdef PNG_FLOATING_POINT_SUPPORTED ++#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ ++ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) + { + int unit; + double scal_width, scal_height; + + if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, +- &scal_height)) ++ &scal_height) != 0) + { + png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); + } +@@ -1173,7 +1264,7 @@ + png_charp scal_width, scal_height; + + if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, +- &scal_height)) ++ &scal_height) != 0) + { + png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, + scal_height); +@@ -1190,6 +1281,21 @@ + if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) + { + pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); ++ ++ pngtest_check_text_support(read_ptr, text_ptr, num_text); ++ ++ if (verbose != 0) ++ { ++ int i; ++ ++ printf("\n"); ++ for (i=0; i<num_text; i++) ++ { ++ printf(" Text compression[%d]=%d\n", ++ i, text_ptr[i].compression); ++ } ++ } ++ + png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); + } + } +@@ -1198,21 +1304,21 @@ + { + png_timep mod_time; + +- if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) ++ if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0) + { + png_set_tIME(write_ptr, write_info_ptr, mod_time); + #ifdef PNG_TIME_RFC1123_SUPPORTED +- /* We have to use png_memcpy instead of "=" because the string +- * pointed to by png_convert_to_rfc1123() gets free'ed before +- * we use it. +- */ +- png_memcpy(tIME_string, +- png_convert_to_rfc1123(read_ptr, mod_time), +- png_sizeof(tIME_string)); ++ if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) ++ tIME_string[(sizeof tIME_string) - 1] = '\0'; + +- tIME_string[png_sizeof(tIME_string) - 1] = '\0'; ++ else ++ { ++ strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string)); ++ tIME_string[(sizeof tIME_string) - 1] = '\0'; ++ } ++ + tIME_chunk_present++; +-#endif /* PNG_TIME_RFC1123_SUPPORTED */ ++#endif /* TIME_RFC1123 */ + } + } + #endif +@@ -1223,7 +1329,7 @@ + png_color_16p trans_color; + + if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, +- &trans_color)) ++ &trans_color) != 0) + { + int sample_max = (1 << bit_depth); + /* libpng doesn't reject a tRNS chunk with out-of-range samples */ +@@ -1244,18 +1350,22 @@ + int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, + &unknowns); + +- if (num_unknowns) ++ if (num_unknowns != 0) + { +- int i; + png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, + num_unknowns); ++#if PNG_LIBPNG_VER < 10600 + /* Copy the locations from the read_info_ptr. The automatically +- * generated locations in write_info_ptr are wrong because we +- * haven't written anything yet. ++ * generated locations in write_end_info_ptr are wrong prior to 1.6.0 ++ * because they are reset from the write pointer (removed in 1.6.0). + */ +- for (i = 0; i < num_unknowns; i++) +- png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, +- unknowns[i].location); ++ { ++ int i; ++ for (i = 0; i < num_unknowns; i++) ++ png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, ++ unknowns[i].location); ++ } ++#endif + } + } + #endif +@@ -1263,47 +1373,16 @@ + #ifdef PNG_WRITE_SUPPORTED + pngtest_debug("Writing info struct"); + +-/* If we wanted, we could write info in two steps: +- * png_write_info_before_PLTE(write_ptr, write_info_ptr); +- */ ++ /* Write the info in two steps so that if we write the 'unknown' chunks here ++ * they go to the correct place. ++ */ ++ png_write_info_before_PLTE(write_ptr, write_info_ptr); ++ ++ write_chunks(write_ptr, before_PLTE); /* before PLTE */ ++ + png_write_info(write_ptr, write_info_ptr); + +-#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +- if (user_chunk_data[0] != 0) +- { +- png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}; +- +- unsigned char +- ster_chunk_data[1]; +- +- if (verbose) +- fprintf(STDERR, "\n stereo mode = %lu\n", +- (unsigned long)(user_chunk_data[0] - 1)); +- +- ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1); +- png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1); +- } +- +- if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0) +- { +- png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'}; +- +- unsigned char +- vpag_chunk_data[9]; +- +- if (verbose) +- fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n", +- (unsigned long)user_chunk_data[1], +- (unsigned long)user_chunk_data[2], +- (unsigned long)user_chunk_data[3]); +- +- png_save_uint_32(vpag_chunk_data, user_chunk_data[1]); +- png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]); +- vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff); +- png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9); +- } +- +-#endif ++ write_chunks(write_ptr, before_IDAT); /* after PLTE */ + #endif + + #ifdef SINGLE_ROWBUF_ALLOC +@@ -1315,14 +1394,10 @@ + #endif /* SINGLE_ROWBUF_ALLOC */ + pngtest_debug("Writing row data"); + +-#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ +- defined(PNG_WRITE_INTERLACING_SUPPORTED) ++#ifdef PNG_READ_INTERLACING_SUPPORTED + num_pass = png_set_interlace_handling(read_ptr); +-# ifdef PNG_WRITE_SUPPORTED +- png_set_interlace_handling(write_ptr); +-# endif +-#else +- num_pass = 1; ++ if (png_set_interlace_handling(write_ptr) != num_pass) ++ png_error(write_ptr, "png_set_interlace_handling: inconsistent num_pass"); + #endif + + #ifdef PNGTEST_TIMING +@@ -1337,11 +1412,12 @@ + { + #ifndef SINGLE_ROWBUF_ALLOC + pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); ++ + row_buf = (png_bytep)png_malloc(read_ptr, + png_get_rowbytes(read_ptr, read_info_ptr)); + +- pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf, +- png_get_rowbytes(read_ptr, read_info_ptr)); ++ pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf, ++ (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); + + #endif /* !SINGLE_ROWBUF_ALLOC */ + png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); +@@ -1358,7 +1434,7 @@ + t_encode += (t_stop - t_start); + t_start = t_stop; + #endif +-#endif /* PNG_WRITE_SUPPORTED */ ++#endif /* WRITE */ + + #ifndef SINGLE_ROWBUF_ALLOC + pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); +@@ -1368,11 +1444,13 @@ + } + } + +-#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +- png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); +-#endif +-#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +- png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); ++#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED ++# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED ++ png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); ++# endif ++# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED ++ png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); ++# endif + #endif + + pngtest_debug("Reading and writing end_info data"); +@@ -1386,6 +1464,21 @@ + if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) + { + pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); ++ ++ pngtest_check_text_support(read_ptr, text_ptr, num_text); ++ ++ if (verbose != 0) ++ { ++ int i; ++ ++ printf("\n"); ++ for (i=0; i<num_text; i++) ++ { ++ printf(" Text compression[%d]=%d\n", ++ i, text_ptr[i].compression); ++ } ++ } ++ + png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); + } + } +@@ -1394,20 +1487,21 @@ + { + png_timep mod_time; + +- if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) ++ if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0) + { + png_set_tIME(write_ptr, write_end_info_ptr, mod_time); + #ifdef PNG_TIME_RFC1123_SUPPORTED +- /* We have to use png_memcpy instead of "=" because the string +- pointed to by png_convert_to_rfc1123() gets free'ed before +- we use it */ +- png_memcpy(tIME_string, +- png_convert_to_rfc1123(read_ptr, mod_time), +- png_sizeof(tIME_string)); ++ if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) ++ tIME_string[(sizeof tIME_string) - 1] = '\0'; + +- tIME_string[png_sizeof(tIME_string) - 1] = '\0'; ++ else ++ { ++ strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string); ++ tIME_string[(sizeof tIME_string)-1] = '\0'; ++ } ++ + tIME_chunk_present++; +-#endif /* PNG_TIME_RFC1123_SUPPORTED */ ++#endif /* TIME_RFC1123 */ + } + } + #endif +@@ -1417,27 +1511,48 @@ + int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, + &unknowns); + +- if (num_unknowns) ++ if (num_unknowns != 0) + { +- int i; + png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, + num_unknowns); ++#if PNG_LIBPNG_VER < 10600 + /* Copy the locations from the read_info_ptr. The automatically +- * generated locations in write_end_info_ptr are wrong because we +- * haven't written the end_info yet. ++ * generated locations in write_end_info_ptr are wrong prior to 1.6.0 ++ * because they are reset from the write pointer (removed in 1.6.0). + */ +- for (i = 0; i < num_unknowns; i++) +- png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, +- unknowns[i].location); ++ { ++ int i; ++ for (i = 0; i < num_unknowns; i++) ++ png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, ++ unknowns[i].location); ++ } ++#endif + } + } + #endif ++ + #ifdef PNG_WRITE_SUPPORTED ++#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED ++ /* Normally one would use Z_DEFAULT_STRATEGY for text compression. ++ * This is here just to make pngtest replicate the results from libpng ++ * versions prior to 1.5.4, and to test this new API. ++ */ ++ png_set_text_compression_strategy(write_ptr, Z_FILTERED); ++#endif ++ ++ /* When the unknown vpAg/sTER chunks are written by pngtest the only way to ++ * do it is to write them *before* calling png_write_end. When unknown ++ * chunks are written by libpng, however, they are written just before IEND. ++ * There seems to be no way round this, however vpAg/sTER are not expected ++ * after IDAT. ++ */ ++ write_chunks(write_ptr, after_IDAT); ++ + png_write_end(write_ptr, write_end_info_ptr); + #endif + + #ifdef PNG_EASY_ACCESS_SUPPORTED +- if (verbose) ++ if (verbose != 0) + { + png_uint_32 iwidth, iheight; + iwidth = png_get_image_width(write_ptr, write_info_ptr); +@@ -1466,6 +1581,40 @@ + FCLOSE(fpin); + FCLOSE(fpout); + ++ /* Summarize any warnings or errors and in 'strict' mode fail the test. ++ * Unsupported chunks can result in warnings, in that case ignore the strict ++ * setting, otherwise fail the test on warnings as well as errors. ++ */ ++ if (error_count > 0) ++ { ++ /* We don't really expect to get here because of the setjmp handling ++ * above, but this is safe. ++ */ ++ fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", ++ inname, error_count, warning_count); ++ ++ if (strict != 0) ++ return (1); ++ } ++ ++# ifdef PNG_WRITE_SUPPORTED ++ /* If there we no write support nothing was written! */ ++ else if (unsupported_chunks > 0) ++ { ++ fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", ++ inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); ++ } ++# endif ++ ++ else if (warning_count > 0) ++ { ++ fprintf(STDERR, "\n %s: %d libpng warnings found", ++ inname, warning_count); ++ ++ if (strict != 0) ++ return (1); ++ } ++ + pngtest_debug("Opening files for comparison"); + if ((fpin = fopen(inname, "rb")) == NULL) + { +@@ -1480,61 +1629,84 @@ + return (1); + } + +- for (;;) ++#ifdef PNG_WRITE_SUPPORTED /* else nothing was written */ ++ if (interlace_preserved != 0) /* else the files will be changed */ + { +- png_size_t num_in, num_out; ++ for (;;) ++ { ++ static int wrote_question = 0; ++ png_size_t num_in, num_out; ++ char inbuf[256], outbuf[256]; + +- num_in = fread(inbuf, 1, 1, fpin); +- num_out = fread(outbuf, 1, 1, fpout); ++ num_in = fread(inbuf, 1, sizeof inbuf, fpin); ++ num_out = fread(outbuf, 1, sizeof outbuf, fpout); + +- if (num_in != num_out) +- { +- fprintf(STDERR, "\nFiles %s and %s are of a different size\n", +- inname, outname); ++ if (num_in != num_out) ++ { ++ fprintf(STDERR, "\nFiles %s and %s are of a different size\n", ++ inname, outname); + +- if (wrote_question == 0) +- { +- fprintf(STDERR, ++ if (wrote_question == 0 && unsupported_chunks == 0) ++ { ++ fprintf(STDERR, + " Was %s written with the same maximum IDAT chunk size (%d bytes),", +- inname, PNG_ZBUF_SIZE); +- fprintf(STDERR, +- "\n filtering heuristic (libpng default), compression"); +- fprintf(STDERR, +- " level (zlib default),\n and zlib version (%s)?\n\n", +- ZLIB_VERSION); +- wrote_question = 1; ++ inname, PNG_ZBUF_SIZE); ++ fprintf(STDERR, ++ "\n filtering heuristic (libpng default), compression"); ++ fprintf(STDERR, ++ " level (zlib default),\n and zlib version (%s)?\n\n", ++ ZLIB_VERSION); ++ wrote_question = 1; ++ } ++ ++ FCLOSE(fpin); ++ FCLOSE(fpout); ++ ++ if (strict != 0 && unsupported_chunks == 0) ++ return (1); ++ ++ else ++ return (0); + } + +- FCLOSE(fpin); +- FCLOSE(fpout); +- return (0); +- } ++ if (num_in == 0) ++ break; + +- if (!num_in) +- break; ++ if (memcmp(inbuf, outbuf, num_in)) ++ { ++ fprintf(STDERR, "\nFiles %s and %s are different\n", inname, ++ outname); + +- if (png_memcmp(inbuf, outbuf, num_in)) +- { +- fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); ++ if (wrote_question == 0 && unsupported_chunks == 0) ++ { ++ fprintf(STDERR, ++ " Was %s written with the same maximum IDAT chunk size (%d bytes),", ++ inname, PNG_ZBUF_SIZE); ++ fprintf(STDERR, ++ "\n filtering heuristic (libpng default), compression"); ++ fprintf(STDERR, ++ " level (zlib default),\n and zlib version (%s)?\n\n", ++ ZLIB_VERSION); ++ wrote_question = 1; ++ } + +- if (wrote_question == 0) +- { +- fprintf(STDERR, +- " Was %s written with the same maximum IDAT chunk size (%d bytes),", +- inname, PNG_ZBUF_SIZE); +- fprintf(STDERR, +- "\n filtering heuristic (libpng default), compression"); +- fprintf(STDERR, +- " level (zlib default),\n and zlib version (%s)?\n\n", +- ZLIB_VERSION); +- wrote_question = 1; ++ FCLOSE(fpin); ++ FCLOSE(fpout); ++ ++ /* NOTE: the unsupported_chunks escape is permitted here because ++ * unsupported text chunk compression will result in the compression ++ * mode being changed (to NONE) yet, in the test case, the result ++ * can be exactly the same size! ++ */ ++ if (strict != 0 && unsupported_chunks == 0) ++ return (1); ++ ++ else ++ return (0); + } +- +- FCLOSE(fpin); +- FCLOSE(fpout); +- return (0); + } + } ++#endif /* WRITE */ + + FCLOSE(fpin); + FCLOSE(fpout); +@@ -1614,6 +1786,24 @@ + inname = argv[2]; + } + ++ else if (strcmp(argv[1], "--strict") == 0) ++ { ++ status_dots_requested = 0; ++ verbose = 1; ++ inname = argv[2]; ++ strict++; ++ relaxed = 0; ++ } ++ ++ else if (strcmp(argv[1], "--relaxed") == 0) ++ { ++ status_dots_requested = 0; ++ verbose = 1; ++ inname = argv[2]; ++ strict = 0; ++ relaxed++; ++ } ++ + else + { + inname = argv[1]; +@@ -1621,10 +1811,11 @@ + } + } + +- if (!multiple && argc == 3 + verbose) ++ if (multiple == 0 && argc == 3 + verbose) + outname = argv[2 + verbose]; + +- if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2)) ++ if ((multiple == 0 && argc > 3 + verbose) || ++ (multiple != 0 && argc < 2)) + { + fprintf(STDERR, + "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", +@@ -1636,7 +1827,7 @@ + exit(1); + } + +- if (multiple) ++ if (multiple != 0) + { + int i; + #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG +@@ -1646,6 +1837,9 @@ + { + int kerror; + fprintf(STDERR, "\n Testing %s:", argv[i]); ++#if PNG_DEBUG > 0 ++ fprintf(STDERR, "\n"); ++#endif + kerror = test_one_file(argv[i], outname); + if (kerror == 0) + { +@@ -1660,7 +1854,7 @@ + #endif + #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + for (k = 0; k<256; k++) +- if (filters_used[k]) ++ if (filters_used[k] != 0) + fprintf(STDERR, " Filter %d was used %lu times\n", + k, (unsigned long)filters_used[k]); + #endif +@@ -1669,7 +1863,7 @@ + fprintf(STDERR, " tIME = %s\n", tIME_string); + + tIME_chunk_present = 0; +-#endif /* PNG_TIME_RFC1123_SUPPORTED */ ++#endif /* TIME_RFC1123 */ + } + + else +@@ -1691,9 +1885,9 @@ + + while (pinfo != NULL) + { +- fprintf(STDERR, " %lu bytes at %x\n", ++ fprintf(STDERR, " %lu bytes at %p\n", + (unsigned long)pinfo->size, +- (unsigned int)pinfo->pointer); ++ pinfo->pointer); + pinfo = pinfo->next; + } + } +@@ -1727,7 +1921,12 @@ + status_dots_requested = 0; + + if (i == 0 || verbose == 1 || ierror != 0) ++ { + fprintf(STDERR, "\n Testing %s:", inname); ++#if PNG_DEBUG > 0 ++ fprintf(STDERR, "\n"); ++#endif ++ } + + kerror = test_one_file(inname, outname); + +@@ -1746,21 +1945,26 @@ + #endif + #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + for (k = 0; k<256; k++) +- if (filters_used[k]) ++ if (filters_used[k] != 0) + fprintf(STDERR, " Filter %d was used %lu times\n", + k, (unsigned long)filters_used[k]); + #endif + #ifdef PNG_TIME_RFC1123_SUPPORTED + if (tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n", tIME_string); +-#endif /* PNG_TIME_RFC1123_SUPPORTED */ ++#endif /* TIME_RFC1123 */ + } + } + + else + { + if (verbose == 0 && i != 2) ++ { + fprintf(STDERR, "\n Testing %s:", inname); ++#if PNG_DEBUG > 0 ++ fprintf(STDERR, "\n"); ++#endif ++ } + + fprintf(STDERR, " FAIL\n"); + ierror += kerror; +@@ -1779,8 +1983,8 @@ + + while (pinfo != NULL) + { +- fprintf(STDERR, " %lu bytes at %x\n", +- (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); ++ fprintf(STDERR, " %lu bytes at %p\n", ++ (unsigned long)pinfo->size, pinfo->pointer); + pinfo = pinfo->next; + } + } +@@ -1820,6 +2024,16 @@ + + return (int)(ierror != 0); + } ++#else ++int ++main(void) ++{ ++ fprintf(STDERR, ++ " test ignored because libpng was not built with read support\n"); ++ /* And skip this test */ ++ return PNG_LIBPNG_VER < 10600 ? 0 : 77; ++} ++#endif + + /* Generate a compiler error if there is an old png.h in the search path. */ +-typedef png_libpng_version_1_5_4 Your_png_h_is_not_version_1_5_4; ++typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16; +--- ./jdk/src/share/native/sun/awt/libpng/pngtrans.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngtrans.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -46,7 +46,7 @@ + #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) + /* Turn on BGR-to-RGB mapping */ + void PNGAPI +-png_set_bgr(png_structp png_ptr) ++png_set_bgr(png_structrp png_ptr) + { + png_debug(1, "in png_set_bgr"); + +@@ -60,7 +60,7 @@ + #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) + /* Turn on 16 bit byte swapping */ + void PNGAPI +-png_set_swap(png_structp png_ptr) ++png_set_swap(png_structrp png_ptr) + { + png_debug(1, "in png_set_swap"); + +@@ -75,7 +75,7 @@ + #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) + /* Turn on pixel packing */ + void PNGAPI +-png_set_packing(png_structp png_ptr) ++png_set_packing(png_structrp png_ptr) + { + png_debug(1, "in png_set_packing"); + +@@ -85,7 +85,9 @@ + if (png_ptr->bit_depth < 8) + { + png_ptr->transformations |= PNG_PACK; +- png_ptr->usr_bit_depth = 8; ++# ifdef PNG_WRITE_SUPPORTED ++ png_ptr->usr_bit_depth = 8; ++# endif + } + } + #endif +@@ -93,7 +95,7 @@ + #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) + /* Turn on packed pixel swapping */ + void PNGAPI +-png_set_packswap(png_structp png_ptr) ++png_set_packswap(png_structrp png_ptr) + { + png_debug(1, "in png_set_packswap"); + +@@ -107,7 +109,7 @@ + + #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + void PNGAPI +-png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) ++png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) + { + png_debug(1, "in png_set_shift"); + +@@ -122,11 +124,11 @@ + #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) + int PNGAPI +-png_set_interlace_handling(png_structp png_ptr) ++png_set_interlace_handling(png_structrp png_ptr) + { + png_debug(1, "in png_set_interlace handling"); + +- if (png_ptr && png_ptr->interlaced) ++ if (png_ptr != 0 && png_ptr->interlaced != 0) + { + png_ptr->transformations |= PNG_INTERLACE; + return (7); +@@ -143,44 +145,91 @@ + * that don't like bytes as parameters. + */ + void PNGAPI +-png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) ++png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) + { + png_debug(1, "in png_set_filler"); + + if (png_ptr == NULL) + return; + ++ /* In libpng 1.6 it is possible to determine whether this is a read or write ++ * operation and therefore to do more checking here for a valid call. ++ */ ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) ++ { ++# ifdef PNG_READ_FILLER_SUPPORTED ++ /* On read png_set_filler is always valid, regardless of the base PNG ++ * format, because other transformations can give a format where the ++ * filler code can execute (basically an 8 or 16-bit component RGB or G ++ * format.) ++ * ++ * NOTE: usr_channels is not used by the read code! (This has led to ++ * confusion in the past.) The filler is only used in the read code. ++ */ ++ png_ptr->filler = (png_uint_16)filler; ++# else ++ png_app_error(png_ptr, "png_set_filler not supported on read"); ++ PNG_UNUSED(filler) /* not used in the write case */ ++ return; ++# endif ++ } ++ ++ else /* write */ ++ { ++# ifdef PNG_WRITE_FILLER_SUPPORTED ++ /* On write the usr_channels parameter must be set correctly at the ++ * start to record the number of channels in the app-supplied data. ++ */ ++ switch (png_ptr->color_type) ++ { ++ case PNG_COLOR_TYPE_RGB: ++ png_ptr->usr_channels = 4; ++ break; ++ ++ case PNG_COLOR_TYPE_GRAY: ++ if (png_ptr->bit_depth >= 8) ++ { ++ png_ptr->usr_channels = 2; ++ break; ++ } ++ ++ else ++ { ++ /* There simply isn't any code in libpng to strip out bits ++ * from bytes when the components are less than a byte in ++ * size! ++ */ ++ png_app_error(png_ptr, ++ "png_set_filler is invalid for low bit depth gray output"); ++ return; ++ } ++ ++ default: ++ png_app_error(png_ptr, ++ "png_set_filler: inappropriate color type"); ++ return; ++ } ++# else ++ png_app_error(png_ptr, "png_set_filler not supported on write"); ++ return; ++# endif ++ } ++ ++ /* Here on success - libpng supports the operation, set the transformation ++ * and the flag to say where the filler channel is. ++ */ + png_ptr->transformations |= PNG_FILLER; +- png_ptr->filler = (png_uint_16)filler; + + if (filler_loc == PNG_FILLER_AFTER) + png_ptr->flags |= PNG_FLAG_FILLER_AFTER; + + else + png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; +- +- /* This should probably go in the "do_read_filler" routine. +- * I attempted to do that in libpng-1.0.1a but that caused problems +- * so I restored it in libpng-1.0.2a +- */ +- +- if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) +- { +- png_ptr->usr_channels = 4; +- } +- +- /* Also I added this in libpng-1.0.2a (what happens when we expand +- * a less-than-8-bit grayscale to GA?) */ +- +- if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) +- { +- png_ptr->usr_channels = 2; +- } + } + + /* Added to libpng-1.2.7 */ + void PNGAPI +-png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) ++png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) + { + png_debug(1, "in png_set_add_alpha"); + +@@ -188,7 +237,9 @@ + return; + + png_set_filler(png_ptr, filler, filler_loc); +- png_ptr->transformations |= PNG_ADD_ALPHA; ++ /* The above may fail to do anything. */ ++ if ((png_ptr->transformations & PNG_FILLER) != 0) ++ png_ptr->transformations |= PNG_ADD_ALPHA; + } + + #endif +@@ -196,7 +247,7 @@ + #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) + void PNGAPI +-png_set_swap_alpha(png_structp png_ptr) ++png_set_swap_alpha(png_structrp png_ptr) + { + png_debug(1, "in png_set_swap_alpha"); + +@@ -210,7 +261,7 @@ + #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) + void PNGAPI +-png_set_invert_alpha(png_structp png_ptr) ++png_set_invert_alpha(png_structrp png_ptr) + { + png_debug(1, "in png_set_invert_alpha"); + +@@ -223,7 +274,7 @@ + + #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) + void PNGAPI +-png_set_invert_mono(png_structp png_ptr) ++png_set_invert_mono(png_structrp png_ptr) + { + png_debug(1, "in png_set_invert_mono"); + +@@ -304,9 +355,16 @@ + + for (i = 0; i < istop; i++, rp += 2) + { ++#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED ++ /* Feature added to libpng-1.6.11 for testing purposes, not ++ * enabled by default. ++ */ ++ *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp); ++#else + png_byte t = *rp; + *rp = *(rp + 1); + *(rp + 1) = t; ++#endif + } + } + } +@@ -448,7 +506,7 @@ + *rp = table[*rp]; + } + } +-#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ ++#endif /* PACKSWAP || WRITE_PACKSWAP */ + + #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +@@ -480,7 +538,7 @@ + { + if (row_info->bit_depth == 8) + { +- if (at_start) /* Skip initial filler */ ++ if (at_start != 0) /* Skip initial filler */ + ++sp; + else /* Skip initial channel and, for sp, the filler */ + sp += 2, ++dp; +@@ -494,7 +552,7 @@ + + else if (row_info->bit_depth == 16) + { +- if (at_start) /* Skip initial filler */ ++ if (at_start != 0) /* Skip initial filler */ + sp += 2; + else /* Skip initial channel and, for sp, the filler */ + sp += 4, dp += 2; +@@ -520,7 +578,7 @@ + { + if (row_info->bit_depth == 8) + { +- if (at_start) /* Skip initial filler */ ++ if (at_start != 0) /* Skip initial filler */ + ++sp; + else /* Skip initial channels and, for sp, the filler */ + sp += 4, dp += 3; +@@ -534,7 +592,7 @@ + + else if (row_info->bit_depth == 16) + { +- if (at_start) /* Skip initial filler */ ++ if (at_start != 0) /* Skip initial filler */ + sp += 2; + else /* Skip initial channels and, for sp, the filler */ + sp += 8, dp += 6; +@@ -575,7 +633,7 @@ + { + png_debug(1, "in png_do_bgr"); + +- if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) ++ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) +@@ -645,19 +703,133 @@ + #endif + } + } +-#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ ++#endif /* READ_BGR || WRITE_BGR */ ++ ++#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ ++ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) ++/* Added at libpng-1.5.10 */ ++void /* PRIVATE */ ++png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) ++{ ++ if (png_ptr->num_palette < (1 << row_info->bit_depth) && ++ png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ ++ { ++ /* Calculations moved outside switch in an attempt to stop different ++ * compiler warnings. 'padding' is in *bits* within the last byte, it is ++ * an 'int' because pixel_depth becomes an 'int' in the expression below, ++ * and this calculation is used because it avoids warnings that other ++ * forms produced on either GCC or MSVC. ++ */ ++ int padding = (-row_info->pixel_depth * row_info->width) & 7; ++ png_bytep rp = png_ptr->row_buf + row_info->rowbytes; ++ ++ switch (row_info->bit_depth) ++ { ++ case 1: ++ { ++ /* in this case, all bytes must be 0 so we don't need ++ * to unpack the pixels except for the rightmost one. ++ */ ++ for (; rp > png_ptr->row_buf; rp--) ++ { ++ if (*rp >> padding != 0) ++ png_ptr->num_palette_max = 1; ++ padding = 0; ++ } ++ ++ break; ++ } ++ ++ case 2: ++ { ++ for (; rp > png_ptr->row_buf; rp--) ++ { ++ int i = ((*rp >> padding) & 0x03); ++ ++ if (i > png_ptr->num_palette_max) ++ png_ptr->num_palette_max = i; ++ ++ i = (((*rp >> padding) >> 2) & 0x03); ++ ++ if (i > png_ptr->num_palette_max) ++ png_ptr->num_palette_max = i; ++ ++ i = (((*rp >> padding) >> 4) & 0x03); ++ ++ if (i > png_ptr->num_palette_max) ++ png_ptr->num_palette_max = i; ++ ++ i = (((*rp >> padding) >> 6) & 0x03); ++ ++ if (i > png_ptr->num_palette_max) ++ png_ptr->num_palette_max = i; ++ ++ padding = 0; ++ } ++ ++ break; ++ } ++ ++ case 4: ++ { ++ for (; rp > png_ptr->row_buf; rp--) ++ { ++ int i = ((*rp >> padding) & 0x0f); ++ ++ if (i > png_ptr->num_palette_max) ++ png_ptr->num_palette_max = i; ++ ++ i = (((*rp >> padding) >> 4) & 0x0f); ++ ++ if (i > png_ptr->num_palette_max) ++ png_ptr->num_palette_max = i; ++ ++ padding = 0; ++ } ++ ++ break; ++ } ++ ++ case 8: ++ { ++ for (; rp > png_ptr->row_buf; rp--) ++ { ++ if (*rp > png_ptr->num_palette_max) ++ png_ptr->num_palette_max = (int) *rp; ++ } ++ ++ break; ++ } ++ ++ default: ++ break; ++ } ++ } ++} ++#endif /* CHECK_FOR_INVALID_INDEX */ + + #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + void PNGAPI +-png_set_user_transform_info(png_structp png_ptr, png_voidp ++png_set_user_transform_info(png_structrp png_ptr, png_voidp + user_transform_ptr, int user_transform_depth, int user_transform_channels) + { + png_debug(1, "in png_set_user_transform_info"); + + if (png_ptr == NULL) + return; ++ ++#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED ++ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && ++ (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) ++ { ++ png_app_error(png_ptr, ++ "info change after png_start_read_image or png_read_update_info"); ++ return; ++ } ++#endif ++ + png_ptr->user_transform_ptr = user_transform_ptr; + png_ptr->user_transform_depth = (png_byte)user_transform_depth; + png_ptr->user_transform_channels = (png_byte)user_transform_channels; +@@ -671,20 +843,20 @@ + */ + #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + png_voidp PNGAPI +-png_get_user_transform_ptr(png_const_structp png_ptr) ++png_get_user_transform_ptr(png_const_structrp png_ptr) + { + if (png_ptr == NULL) + return (NULL); + +- return ((png_voidp)png_ptr->user_transform_ptr); ++ return png_ptr->user_transform_ptr; + } + #endif + + #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED + png_uint_32 PNGAPI +-png_get_current_row_number(png_const_structp png_ptr) ++png_get_current_row_number(png_const_structrp png_ptr) + { +- /* See the comments in png.h - this is the sub-image row when reading and ++ /* See the comments in png.h - this is the sub-image row when reading an + * interlaced image. + */ + if (png_ptr != NULL) +@@ -694,13 +866,12 @@ + } + + png_byte PNGAPI +-png_get_current_pass_number(png_const_structp png_ptr) ++png_get_current_pass_number(png_const_structrp png_ptr) + { + if (png_ptr != NULL) + return png_ptr->pass; + return 8; /* invalid */ + } +-#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ +-#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || +- PNG_WRITE_USER_TRANSFORM_SUPPORTED */ +-#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ ++#endif /* USER_TRANSFORM_INFO */ ++#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */ ++#endif /* READ || WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pngwio.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngwio.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.0 [January 6, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -58,11 +58,12 @@ + */ + + void /* PRIVATE */ +-png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length) ++png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) + { + /* NOTE: write_data_fn must not change the buffer! */ + if (png_ptr->write_data_fn != NULL ) +- (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length); ++ (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), ++ length); + + else + png_error(png_ptr, "Call to NULL write function"); +@@ -74,7 +75,6 @@ + * write_data function and use it at run time with png_set_write_fn(), rather + * than changing the library. + */ +-#ifndef USE_FAR_KEYWORD + void PNGCBAPI + png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) + { +@@ -88,64 +88,6 @@ + if (check != length) + png_error(png_ptr, "Write Error"); + } +-#else +-/* This is the model-independent version. Since the standard I/O library +- * can't handle far buffers in the medium and small models, we have to copy +- * the data. +- */ +- +-#define NEAR_BUF_SIZE 1024 +-#define MIN(a,b) (a <= b ? a : b) +- +-void PNGCBAPI +-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +-{ +- png_uint_32 check; +- png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ +- png_FILE_p io_ptr; +- +- if (png_ptr == NULL) +- return; +- +- /* Check if data really is near. If so, use usual code. */ +- near_data = (png_byte *)CVT_PTR_NOCHECK(data); +- io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); +- +- if ((png_bytep)near_data == data) +- { +- check = fwrite(near_data, 1, length, io_ptr); +- } +- +- else +- { +- png_byte buf[NEAR_BUF_SIZE]; +- png_size_t written, remaining, err; +- check = 0; +- remaining = length; +- +- do +- { +- written = MIN(NEAR_BUF_SIZE, remaining); +- png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ +- err = fwrite(buf, 1, written, io_ptr); +- +- if (err != written) +- break; +- +- else +- check += err; +- +- data += written; +- remaining -= written; +- } +- while (remaining != 0); +- } +- +- if (check != length) +- png_error(png_ptr, "Write Error"); +-} +- +-#endif + #endif + + /* This function is called to output any data pending writing (normally +@@ -154,7 +96,7 @@ + */ + #ifdef PNG_WRITE_FLUSH_SUPPORTED + void /* PRIVATE */ +-png_flush(png_structp png_ptr) ++png_flush(png_structrp png_ptr) + { + if (png_ptr->output_flush_fn != NULL) + (*(png_ptr->output_flush_fn))(png_ptr); +@@ -169,7 +111,7 @@ + if (png_ptr == NULL) + return; + +- io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); ++ io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr)); + fflush(io_ptr); + } + # endif +@@ -205,7 +147,7 @@ + * *FILE structure. + */ + void PNGAPI +-png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, ++png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) + { + if (png_ptr == NULL) +@@ -235,8 +177,11 @@ + # else + png_ptr->output_flush_fn = output_flush_fn; + # endif +-#endif /* PNG_WRITE_FLUSH_SUPPORTED */ ++#else ++ PNG_UNUSED(output_flush_fn) ++#endif /* WRITE_FLUSH */ + ++#ifdef PNG_READ_SUPPORTED + /* It is an error to read while writing a png file */ + if (png_ptr->read_data_fn != NULL) + { +@@ -246,37 +191,6 @@ + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } ++#endif + } +- +-#ifdef USE_FAR_KEYWORD +-# ifdef _MSC_VER +-void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) +-{ +- void *near_ptr; +- void FAR *far_ptr; +- FP_OFF(near_ptr) = FP_OFF(ptr); +- far_ptr = (void FAR *)near_ptr; +- +- if (check != 0) +- if (FP_SEG(ptr) != FP_SEG(far_ptr)) +- png_error(png_ptr, "segment lost in conversion"); +- +- return(near_ptr); +-} +-# else +-void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) +-{ +- void *near_ptr; +- void FAR *far_ptr; +- near_ptr = (void FAR *)ptr; +- far_ptr = (void FAR *)near_ptr; +- +- if (check != 0) +- if (far_ptr != ptr) +- png_error(png_ptr, "segment lost in conversion"); +- +- return(near_ptr); +-} +-# endif +-#endif +-#endif /* PNG_WRITE_SUPPORTED */ ++#endif /* WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pngwrite.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngwrite.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -40,9 +40,65 @@ + */ + + #include "pngpriv.h" ++#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) ++# include <errno.h> ++#endif + + #ifdef PNG_WRITE_SUPPORTED + ++#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED ++/* Write out all the unknown chunks for the current given location */ ++static void ++write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, ++ unsigned int where) ++{ ++ if (info_ptr->unknown_chunks_num != 0) ++ { ++ png_const_unknown_chunkp up; ++ ++ png_debug(5, "writing extra chunks"); ++ ++ for (up = info_ptr->unknown_chunks; ++ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; ++ ++up) ++ if ((up->location & where) != 0) ++ { ++ /* If per-chunk unknown chunk handling is enabled use it, otherwise ++ * just write the chunks the application has set. ++ */ ++#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++ int keep = png_handle_as_unknown(png_ptr, up->name); ++ ++ /* NOTE: this code is radically different from the read side in the ++ * matter of handling an ancillary unknown chunk. In the read side ++ * the default behavior is to discard it, in the code below the default ++ * behavior is to write it. Critical chunks are, however, only ++ * written if explicitly listed or if the default is set to write all ++ * unknown chunks. ++ * ++ * The default handling is also slightly weird - it is not possible to ++ * stop the writing of all unsafe-to-copy chunks! ++ * ++ * TODO: REVIEW: this would seem to be a bug. ++ */ ++ if (keep != PNG_HANDLE_CHUNK_NEVER && ++ ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || ++ keep == PNG_HANDLE_CHUNK_ALWAYS || ++ (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && ++ png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) ++#endif ++ { ++ /* TODO: review, what is wrong with a zero length unknown chunk? */ ++ if (up->size == 0) ++ png_warning(png_ptr, "Writing zero-length unknown chunk"); ++ ++ png_write_chunk(png_ptr, up->name, up->data, up->size); ++ } ++ } ++ } ++} ++#endif /* WRITE_UNKNOWN_CHUNKS */ ++ + /* Writes all the PNG information. This is the suggested way to use the + * library. If you have a new chunk to add, make a function to write it, + * and put it in the correct location here. If you want the chunk written +@@ -53,21 +109,21 @@ + * them in png_write_end(), and compressing them. + */ + void PNGAPI +-png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) ++png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) + { + png_debug(1, "in png_write_info_before_PLTE"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) ++ if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) + { + /* Write PNG signature */ + png_write_sig(png_ptr); + + #ifdef PNG_MNG_FEATURES_SUPPORTED +- if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ +- (png_ptr->mng_features_permitted)) ++ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ ++ png_ptr->mng_features_permitted != 0) + { + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); + png_ptr->mng_features_permitted = 0; +@@ -79,75 +135,88 @@ + info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, + info_ptr->filter_type, + #ifdef PNG_WRITE_INTERLACING_SUPPORTED +- info_ptr->interlace_type); ++ info_ptr->interlace_type + #else +- 0); ++ 0 + #endif ++ ); ++ + /* The rest of these check to see if the valid field has the appropriate + * flag set, and if it does, writes the chunk. ++ * ++ * 1.6.0: COLORSPACE support controls the writing of these chunks too, and ++ * the chunks will be written if the WRITE routine is there and information ++ * is available in the COLORSPACE. (See png_colorspace_sync_info in png.c ++ * for where the valid flags get set.) ++ * ++ * Under certain circumstances the colorspace can be invalidated without ++ * syncing the info_struct 'valid' flags; this happens if libpng detects and ++ * error and calls png_error while the color space is being set, yet the ++ * application continues writing the PNG. So check the 'invalid' flag here ++ * too. + */ +-#ifdef PNG_WRITE_gAMA_SUPPORTED +- if (info_ptr->valid & PNG_INFO_gAMA) +- png_write_gAMA_fixed(png_ptr, info_ptr->gamma); +-#endif +-#ifdef PNG_WRITE_sRGB_SUPPORTED +- if (info_ptr->valid & PNG_INFO_sRGB) +- png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); ++#ifdef PNG_GAMMA_SUPPORTED ++# ifdef PNG_WRITE_gAMA_SUPPORTED ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 && ++ (info_ptr->valid & PNG_INFO_gAMA) != 0) ++ png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); ++# endif + #endif + +-#ifdef PNG_WRITE_iCCP_SUPPORTED +- if (info_ptr->valid & PNG_INFO_iCCP) +- png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, +- (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); +-#endif ++#ifdef PNG_COLORSPACE_SUPPORTED ++ /* Write only one of sRGB or an ICC profile. If a profile was supplied ++ * and it matches one of the known sRGB ones issue a warning. ++ */ ++# ifdef PNG_WRITE_iCCP_SUPPORTED ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && ++ (info_ptr->valid & PNG_INFO_iCCP) != 0) ++ { ++# ifdef PNG_WRITE_sRGB_SUPPORTED ++ if ((info_ptr->valid & PNG_INFO_sRGB) != 0) ++ png_app_warning(png_ptr, ++ "profile matches sRGB but writing iCCP instead"); ++# endif ++ ++ png_write_iCCP(png_ptr, info_ptr->iccp_name, ++ info_ptr->iccp_profile); ++ } ++# ifdef PNG_WRITE_sRGB_SUPPORTED ++ else ++# endif ++# endif ++ ++# ifdef PNG_WRITE_sRGB_SUPPORTED ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && ++ (info_ptr->valid & PNG_INFO_sRGB) != 0) ++ png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); ++# endif /* WRITE_sRGB */ ++#endif /* COLORSPACE */ ++ + #ifdef PNG_WRITE_sBIT_SUPPORTED +- if (info_ptr->valid & PNG_INFO_sBIT) ++ if ((info_ptr->valid & PNG_INFO_sBIT) != 0) + png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); + #endif +-#ifdef PNG_WRITE_cHRM_SUPPORTED +- if (info_ptr->valid & PNG_INFO_cHRM) +- png_write_cHRM_fixed(png_ptr, +- info_ptr->x_white, info_ptr->y_white, +- info_ptr->x_red, info_ptr->y_red, +- info_ptr->x_green, info_ptr->y_green, +- info_ptr->x_blue, info_ptr->y_blue); ++ ++#ifdef PNG_COLORSPACE_SUPPORTED ++# ifdef PNG_WRITE_cHRM_SUPPORTED ++ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && ++ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && ++ (info_ptr->valid & PNG_INFO_cHRM) != 0) ++ png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); ++# endif + #endif + + #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +- if (info_ptr->unknown_chunks_num) +- { +- png_unknown_chunk *up; ++ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); ++#endif + +- png_debug(5, "writing extra chunks"); +- +- for (up = info_ptr->unknown_chunks; +- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; +- up++) +- { +- int keep = png_handle_as_unknown(png_ptr, up->name); +- +- if (keep != PNG_HANDLE_CHUNK_NEVER && +- up->location && +- !(up->location & PNG_HAVE_PLTE) && +- !(up->location & PNG_HAVE_IDAT) && +- !(up->location & PNG_AFTER_IDAT) && +- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || +- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) +- { +- if (up->size == 0) +- png_warning(png_ptr, "Writing zero-length unknown chunk"); +- +- png_write_chunk(png_ptr, up->name, up->data, up->size); +- } +- } +- } +-#endif + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; + } + } + + void PNGAPI +-png_write_info(png_structp png_ptr, png_infop info_ptr) ++png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) + { + #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) + int i; +@@ -160,19 +229,19 @@ + + png_write_info_before_PLTE(png_ptr, info_ptr); + +- if (info_ptr->valid & PNG_INFO_PLTE) ++ if ((info_ptr->valid & PNG_INFO_PLTE) != 0) + png_write_PLTE(png_ptr, info_ptr->palette, + (png_uint_32)info_ptr->num_palette); + +- else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ++ else if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) !=0) + png_error(png_ptr, "Valid palette required for paletted images"); + + #ifdef PNG_WRITE_tRNS_SUPPORTED +- if (info_ptr->valid & PNG_INFO_tRNS) ++ if ((info_ptr->valid & PNG_INFO_tRNS) !=0) + { + #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + /* Invert the alpha channel (in tRNS) */ +- if ((png_ptr->transformations & PNG_INVERT_ALPHA) && ++ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 && + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + int j; +@@ -186,42 +255,42 @@ + } + #endif + #ifdef PNG_WRITE_bKGD_SUPPORTED +- if (info_ptr->valid & PNG_INFO_bKGD) ++ if ((info_ptr->valid & PNG_INFO_bKGD) != 0) + png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); + #endif + + #ifdef PNG_WRITE_hIST_SUPPORTED +- if (info_ptr->valid & PNG_INFO_hIST) ++ if ((info_ptr->valid & PNG_INFO_hIST) != 0) + png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); + #endif + + #ifdef PNG_WRITE_oFFs_SUPPORTED +- if (info_ptr->valid & PNG_INFO_oFFs) ++ if ((info_ptr->valid & PNG_INFO_oFFs) != 0) + png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, + info_ptr->offset_unit_type); + #endif + + #ifdef PNG_WRITE_pCAL_SUPPORTED +- if (info_ptr->valid & PNG_INFO_pCAL) ++ if ((info_ptr->valid & PNG_INFO_pCAL) != 0) + png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, + info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, + info_ptr->pcal_units, info_ptr->pcal_params); + #endif + + #ifdef PNG_WRITE_sCAL_SUPPORTED +- if (info_ptr->valid & PNG_INFO_sCAL) ++ if ((info_ptr->valid & PNG_INFO_sCAL) != 0) + png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_s_width, info_ptr->scal_s_height); + #endif /* sCAL */ + + #ifdef PNG_WRITE_pHYs_SUPPORTED +- if (info_ptr->valid & PNG_INFO_pHYs) ++ if ((info_ptr->valid & PNG_INFO_pHYs) != 0) + png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, + info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); + #endif /* pHYs */ + + #ifdef PNG_WRITE_tIME_SUPPORTED +- if (info_ptr->valid & PNG_INFO_tIME) ++ if ((info_ptr->valid & PNG_INFO_tIME) != 0) + { + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + png_ptr->mode |= PNG_WROTE_tIME; +@@ -229,7 +298,7 @@ + #endif /* tIME */ + + #ifdef PNG_WRITE_sPLT_SUPPORTED +- if (info_ptr->valid & PNG_INFO_sPLT) ++ if ((info_ptr->valid & PNG_INFO_sPLT) != 0) + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); + #endif /* sPLT */ +@@ -251,11 +320,14 @@ + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); ++ /* Mark this chunk as written */ ++ if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) ++ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; ++ else ++ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + #else +- png_warning(png_ptr, "Unable to write international text"); ++ png_warning(png_ptr, "Unable to write international text"); + #endif +- /* Mark this chunk as written */ +- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + + /* If we want a compressed text chunk */ +@@ -264,13 +336,12 @@ + #ifdef PNG_WRITE_zTXt_SUPPORTED + /* Write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, +- info_ptr->text[i].text, 0, +- info_ptr->text[i].compression); ++ info_ptr->text[i].text, info_ptr->text[i].compression); ++ /* Mark this chunk as written */ ++ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + #else + png_warning(png_ptr, "Unable to write compressed text"); + #endif +- /* Mark this chunk as written */ +- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) +@@ -291,29 +362,7 @@ + #endif /* tEXt */ + + #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +- if (info_ptr->unknown_chunks_num) +- { +- png_unknown_chunk *up; +- +- png_debug(5, "writing extra chunks"); +- +- for (up = info_ptr->unknown_chunks; +- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; +- up++) +- { +- int keep = png_handle_as_unknown(png_ptr, up->name); +- if (keep != PNG_HANDLE_CHUNK_NEVER && +- up->location && +- (up->location & PNG_HAVE_PLTE) && +- !(up->location & PNG_HAVE_IDAT) && +- !(up->location & PNG_AFTER_IDAT) && +- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || +- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) +- { +- png_write_chunk(png_ptr, up->name, up->data, up->size); +- } +- } +- } ++ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); + #endif + } + +@@ -323,16 +372,21 @@ + * comments, I suggest writing them here, and compressing them. + */ + void PNGAPI +-png_write_end(png_structp png_ptr, png_infop info_ptr) ++png_write_end(png_structrp png_ptr, png_inforp info_ptr) + { + png_debug(1, "in png_write_end"); + + if (png_ptr == NULL) + return; + +- if (!(png_ptr->mode & PNG_HAVE_IDAT)) ++ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) + png_error(png_ptr, "No IDATs written into file"); + ++#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED ++ if (png_ptr->num_palette_max > png_ptr->num_palette) ++ png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); ++#endif ++ + /* See if user wants us to write information chunks */ + if (info_ptr != NULL) + { +@@ -341,8 +395,8 @@ + #endif + #ifdef PNG_WRITE_tIME_SUPPORTED + /* Check to see if user has supplied a time chunk */ +- if ((info_ptr->valid & PNG_INFO_tIME) && +- !(png_ptr->mode & PNG_WROTE_tIME)) ++ if ((info_ptr->valid & PNG_INFO_tIME) != 0 && ++ (png_ptr->mode & PNG_WROTE_tIME) == 0) + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + + #endif +@@ -363,11 +417,14 @@ + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); ++ /* Mark this chunk as written */ ++ if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) ++ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; ++ else ++ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + #else + png_warning(png_ptr, "Unable to write international text"); + #endif +- /* Mark this chunk as written */ +- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + + else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) +@@ -375,13 +432,12 @@ + #ifdef PNG_WRITE_zTXt_SUPPORTED + /* Write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, +- info_ptr->text[i].text, 0, +- info_ptr->text[i].compression); ++ info_ptr->text[i].text, info_ptr->text[i].compression); ++ /* Mark this chunk as written */ ++ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + #else + png_warning(png_ptr, "Unable to write compressed text"); + #endif +- /* Mark this chunk as written */ +- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; + } + + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) +@@ -390,37 +446,16 @@ + /* Write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0); ++ /* Mark this chunk as written */ ++ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + #else + png_warning(png_ptr, "Unable to write uncompressed text"); + #endif +- +- /* Mark this chunk as written */ +- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } + } + #endif + #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +- if (info_ptr->unknown_chunks_num) +- { +- png_unknown_chunk *up; +- +- png_debug(5, "writing extra chunks"); +- +- for (up = info_ptr->unknown_chunks; +- up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; +- up++) +- { +- int keep = png_handle_as_unknown(png_ptr, up->name); +- if (keep != PNG_HANDLE_CHUNK_NEVER && +- up->location && +- (up->location & PNG_AFTER_IDAT) && +- ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || +- (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) +- { +- png_write_chunk(png_ptr, up->name, up->data, up->size); +- } +- } +- } ++ write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); + #endif + } + +@@ -428,6 +463,7 @@ + + /* Write end of PNG file */ + png_write_IEND(png_ptr); ++ + /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, + * and restored again in libpng-1.2.30, may cause some applications that + * do not set png_ptr->output_flush_fn to crash. If your application +@@ -443,9 +479,8 @@ + } + + #ifdef PNG_CONVERT_tIME_SUPPORTED +-/* "tm" structure is not supported on WindowsCE */ + void PNGAPI +-png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) ++png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) + { + png_debug(1, "in png_convert_from_struct_tm"); + +@@ -474,103 +509,75 @@ + png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) + { +-#ifdef PNG_USER_MEM_SUPPORTED +- return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, +- warn_fn, NULL, NULL, NULL)); ++#ifndef PNG_USER_MEM_SUPPORTED ++ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, ++ error_fn, warn_fn, NULL, NULL, NULL); ++#else ++ return png_create_write_struct_2(user_png_ver, error_ptr, error_fn, ++ warn_fn, NULL, NULL, NULL); + } + + /* Alternate initialize png_ptr structure, and allocate any memory needed */ +-static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ +- + PNG_FUNCTION(png_structp,PNGAPI + png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) + { +-#endif /* PNG_USER_MEM_SUPPORTED */ +- volatile int png_cleanup_needed = 0; +-#ifdef PNG_SETJMP_SUPPORTED +- volatile +-#endif +- png_structp png_ptr; +-#ifdef PNG_SETJMP_SUPPORTED +-#ifdef USE_FAR_KEYWORD +- jmp_buf tmp_jmpbuf; +-#endif ++ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, ++ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); ++#endif /* USER_MEM */ ++ if (png_ptr != NULL) ++ { ++ /* Set the zlib control values to defaults; they can be overridden by the ++ * application after the struct has been created. ++ */ ++ png_ptr->zbuffer_size = PNG_ZBUF_SIZE; ++ ++ /* The 'zlib_strategy' setting is irrelevant because png_default_claim in ++ * pngwutil.c defaults it according to whether or not filters will be ++ * used, and ignores this setting. ++ */ ++ png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; ++ png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; ++ png_ptr->zlib_mem_level = 8; ++ png_ptr->zlib_window_bits = 15; ++ png_ptr->zlib_method = 8; ++ ++#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED ++ png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; ++ png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; ++ png_ptr->zlib_text_mem_level = 8; ++ png_ptr->zlib_text_window_bits = 15; ++ png_ptr->zlib_text_method = 8; ++#endif /* WRITE_COMPRESSED_TEXT */ ++ ++ /* This is a highly dubious configuration option; by default it is off, ++ * but it may be appropriate for private builds that are testing ++ * extensions not conformant to the current specification, or of ++ * applications that must not fail to write at all costs! ++ */ ++#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED ++ /* In stable builds only warn if an application error can be completely ++ * handled. ++ */ ++ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + #endif + +- png_debug(1, "in png_create_write_struct"); +- +-#ifdef PNG_USER_MEM_SUPPORTED +- png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, +- (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); +-#else +- png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); +-#endif /* PNG_USER_MEM_SUPPORTED */ +- if (png_ptr == NULL) +- return (NULL); +- +- /* Added at libpng-1.2.6 */ +-#ifdef PNG_SET_USER_LIMITS_SUPPORTED +- png_ptr->user_width_max = PNG_USER_WIDTH_MAX; +- png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; ++ /* App warnings are warnings in release (or release candidate) builds but ++ * are errors during development. ++ */ ++#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC ++ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; + #endif + +-#ifdef PNG_SETJMP_SUPPORTED +-/* Applications that neglect to set up their own setjmp() and then +- encounter a png_error() will longjmp here. Since the jmpbuf is +- then meaningless we abort instead of returning. */ +-#ifdef USE_FAR_KEYWORD +- if (setjmp(tmp_jmpbuf)) +-#else +- if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ +-#endif +-#ifdef USE_FAR_KEYWORD +- png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); +-#endif +- PNG_ABORT(); +-#endif +- +-#ifdef PNG_USER_MEM_SUPPORTED +- png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); +-#endif /* PNG_USER_MEM_SUPPORTED */ +- png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); +- +- if (!png_user_version_check(png_ptr, user_png_ver)) +- png_cleanup_needed = 1; +- +- /* Initialize zbuf - compression buffer */ +- png_ptr->zbuf_size = PNG_ZBUF_SIZE; +- +- if (!png_cleanup_needed) +- { +- png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, +- png_ptr->zbuf_size); +- if (png_ptr->zbuf == NULL) +- png_cleanup_needed = 1; ++ /* TODO: delay this, it can be done in png_init_io() (if the app doesn't ++ * do it itself) avoiding setting the default function if it is not ++ * required. ++ */ ++ png_set_write_fn(png_ptr, NULL, NULL, NULL); + } + +- if (png_cleanup_needed) +- { +- /* Clean up PNG structure and deallocate any memory. */ +- png_free(png_ptr, png_ptr->zbuf); +- png_ptr->zbuf = NULL; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2((png_voidp)png_ptr, +- (png_free_ptr)free_fn, (png_voidp)mem_ptr); +-#else +- png_destroy_struct((png_voidp)png_ptr); +-#endif +- return (NULL); +- } +- +- png_set_write_fn(png_ptr, NULL, NULL, NULL); +- +-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +- png_reset_filter_heuristics(png_ptr); +-#endif +- +- return (png_ptr); ++ return png_ptr; + } + + +@@ -580,7 +587,7 @@ + * "write" the image seven times. + */ + void PNGAPI +-png_write_rows(png_structp png_ptr, png_bytepp row, ++png_write_rows(png_structrp png_ptr, png_bytepp row, + png_uint_32 num_rows) + { + png_uint_32 i; /* row counter */ +@@ -602,7 +609,7 @@ + * if you are writing an interlaced image. + */ + void PNGAPI +-png_write_image(png_structp png_ptr, png_bytepp image) ++png_write_image(png_structrp png_ptr, png_bytepp image) + { + png_uint_32 i; /* row index */ + int pass, num_pass; /* pass variables */ +@@ -632,10 +639,78 @@ + } + } + ++#ifdef PNG_MNG_FEATURES_SUPPORTED ++/* Performs intrapixel differencing */ ++static void ++png_do_write_intrapixel(png_row_infop row_info, png_bytep row) ++{ ++ png_debug(1, "in png_do_write_intrapixel"); ++ ++ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) ++ { ++ int bytes_per_pixel; ++ png_uint_32 row_width = row_info->width; ++ if (row_info->bit_depth == 8) ++ { ++ png_bytep rp; ++ png_uint_32 i; ++ ++ if (row_info->color_type == PNG_COLOR_TYPE_RGB) ++ bytes_per_pixel = 3; ++ ++ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) ++ bytes_per_pixel = 4; ++ ++ else ++ return; ++ ++ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) ++ { ++ *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); ++ *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); ++ } ++ } ++ ++#ifdef PNG_WRITE_16BIT_SUPPORTED ++ else if (row_info->bit_depth == 16) ++ { ++ png_bytep rp; ++ png_uint_32 i; ++ ++ if (row_info->color_type == PNG_COLOR_TYPE_RGB) ++ bytes_per_pixel = 6; ++ ++ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) ++ bytes_per_pixel = 8; ++ ++ else ++ return; ++ ++ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) ++ { ++ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); ++ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); ++ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); ++ png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); ++ png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); ++ *(rp ) = (png_byte)((red >> 8) & 0xff); ++ *(rp + 1) = (png_byte)(red & 0xff); ++ *(rp + 4) = (png_byte)((blue >> 8) & 0xff); ++ *(rp + 5) = (png_byte)(blue & 0xff); ++ } ++ } ++#endif /* WRITE_16BIT */ ++ } ++} ++#endif /* MNG_FEATURES */ ++ + /* Called by user to write a row of image data */ + void PNGAPI +-png_write_row(png_structp png_ptr, png_const_bytep row) ++png_write_row(png_structrp png_ptr, png_const_bytep row) + { ++ /* 1.5.6: moved from png_struct to be a local structure: */ ++ png_row_info row_info; ++ + if (png_ptr == NULL) + return; + +@@ -646,44 +721,44 @@ + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* Make sure we wrote the header info */ +- if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) ++ if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) + png_error(png_ptr, + "png_write_info was never called before png_write_row"); + + /* Check for transforms that have been set but were defined out */ + #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) +- if (png_ptr->transformations & PNG_INVERT_MONO) ++ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); + #endif + + #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) +- if (png_ptr->transformations & PNG_FILLER) ++ if ((png_ptr->transformations & PNG_FILLER) != 0) + png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); + #endif + #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ + defined(PNG_READ_PACKSWAP_SUPPORTED) +- if (png_ptr->transformations & PNG_PACKSWAP) ++ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_warning(png_ptr, + "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); + #endif + + #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) +- if (png_ptr->transformations & PNG_PACK) ++ if ((png_ptr->transformations & PNG_PACK) != 0) + png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); + #endif + + #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) +- if (png_ptr->transformations & PNG_SHIFT) ++ if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); + #endif + + #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) +- if (png_ptr->transformations & PNG_BGR) ++ if ((png_ptr->transformations & PNG_BGR) != 0) + png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); + #endif + + #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) +- if (png_ptr->transformations & PNG_SWAP_BYTES) ++ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); + #endif + +@@ -692,12 +767,13 @@ + + #ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced and not interested in row, return */ +- if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) ++ if (png_ptr->interlaced != 0 && ++ (png_ptr->transformations & PNG_INTERLACE) != 0) + { + switch (png_ptr->pass) + { + case 0: +- if (png_ptr->row_number & 0x07) ++ if ((png_ptr->row_number & 0x07) != 0) + { + png_write_finish_row(png_ptr); + return; +@@ -705,7 +781,7 @@ + break; + + case 1: +- if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) ++ if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5) + { + png_write_finish_row(png_ptr); + return; +@@ -721,7 +797,7 @@ + break; + + case 3: +- if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) ++ if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3) + { + png_write_finish_row(png_ptr); + return; +@@ -737,7 +813,7 @@ + break; + + case 5: +- if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) ++ if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2) + { + png_write_finish_row(png_ptr); + return; +@@ -745,7 +821,7 @@ + break; + + case 6: +- if (!(png_ptr->row_number & 0x01)) ++ if ((png_ptr->row_number & 0x01) == 0) + { + png_write_finish_row(png_ptr); + return; +@@ -759,36 +835,31 @@ + #endif + + /* Set up row info for transformations */ +- png_ptr->row_info.color_type = png_ptr->color_type; +- png_ptr->row_info.width = png_ptr->usr_width; +- png_ptr->row_info.channels = png_ptr->usr_channels; +- png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; +- png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * +- png_ptr->row_info.channels); ++ row_info.color_type = png_ptr->color_type; ++ row_info.width = png_ptr->usr_width; ++ row_info.channels = png_ptr->usr_channels; ++ row_info.bit_depth = png_ptr->usr_bit_depth; ++ row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); ++ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + +- png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, +- png_ptr->row_info.width); +- +- png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); +- png_debug1(3, "row_info->width = %u", png_ptr->row_info.width); +- png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); +- png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth); +- png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth); +- png_debug1(3, "row_info->rowbytes = %lu", +- (unsigned long)png_ptr->row_info.rowbytes); ++ png_debug1(3, "row_info->color_type = %d", row_info.color_type); ++ png_debug1(3, "row_info->width = %u", row_info.width); ++ png_debug1(3, "row_info->channels = %d", row_info.channels); ++ png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); ++ png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); ++ png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); + + /* Copy user's row into buffer, leaving room for filter byte. */ +- png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); ++ memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); + + #ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Handle interlacing */ + if (png_ptr->interlaced && png_ptr->pass < 6 && +- (png_ptr->transformations & PNG_INTERLACE)) ++ (png_ptr->transformations & PNG_INTERLACE) != 0) + { +- png_do_write_interlace(&(png_ptr->row_info), +- png_ptr->row_buf + 1, png_ptr->pass); ++ png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); + /* This should always get caught above, but still ... */ +- if (!(png_ptr->row_info.width)) ++ if (row_info.width == 0) + { + png_write_finish_row(png_ptr); + return; +@@ -798,10 +869,17 @@ + + #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED + /* Handle other transformations */ +- if (png_ptr->transformations) +- png_do_write_transformations(png_ptr); ++ if (png_ptr->transformations != 0) ++ png_do_write_transformations(png_ptr, &row_info); + #endif + ++ /* At this point the row_info pixel depth must match the 'transformed' depth, ++ * which is also the output depth. ++ */ ++ if (row_info.pixel_depth != png_ptr->pixel_depth || ++ row_info.pixel_depth != png_ptr->transformed_pixel_depth) ++ png_error(png_ptr, "internal write transform logic error"); ++ + #ifdef PNG_MNG_FEATURES_SUPPORTED + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and +@@ -812,16 +890,24 @@ + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ +- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && ++ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ +- png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); ++ png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); + } + #endif + ++/* Added at libpng-1.5.10 */ ++#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED ++ /* Check for out-of-range palette index */ ++ if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && ++ png_ptr->num_palette_max >= 0) ++ png_do_check_palette_indexes(png_ptr, &row_info); ++#endif ++ + /* Find a filter if necessary, filter the row and write it out. */ +- png_write_find_filter(png_ptr, &(png_ptr->row_info)); ++ png_write_find_filter(png_ptr, &row_info); + + if (png_ptr->write_row_fn != NULL) + (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +@@ -830,7 +916,7 @@ + #ifdef PNG_WRITE_FLUSH_SUPPORTED + /* Set the automatic flush interval or 0 to turn flushing off */ + void PNGAPI +-png_set_flush(png_structp png_ptr, int nrows) ++png_set_flush(png_structrp png_ptr, int nrows) + { + png_debug(1, "in png_set_flush"); + +@@ -842,10 +928,8 @@ + + /* Flush the current output buffers now */ + void PNGAPI +-png_write_flush(png_structp png_ptr) ++png_write_flush(png_structrp png_ptr) + { +- int wrote_IDAT; +- + png_debug(1, "in png_write_flush"); + + if (png_ptr == NULL) +@@ -855,146 +939,41 @@ + if (png_ptr->row_number >= png_ptr->num_rows) + return; + +- do +- { +- int ret; +- +- /* Compress the data */ +- ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); +- wrote_IDAT = 0; +- +- /* Check for compression errors */ +- if (ret != Z_OK) +- { +- if (png_ptr->zstream.msg != NULL) +- png_error(png_ptr, png_ptr->zstream.msg); +- +- else +- png_error(png_ptr, "zlib error"); +- } +- +- if (!(png_ptr->zstream.avail_out)) +- { +- /* Write the IDAT and reset the zlib output buffer */ +- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); +- wrote_IDAT = 1; +- } +- } while (wrote_IDAT == 1); +- +- /* If there is any data left to be output, write it into a new IDAT */ +- if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) +- { +- /* Write the IDAT and reset the zlib output buffer */ +- png_write_IDAT(png_ptr, png_ptr->zbuf, +- png_ptr->zbuf_size - png_ptr->zstream.avail_out); +- } ++ png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH); + png_ptr->flush_rows = 0; + png_flush(png_ptr); + } +-#endif /* PNG_WRITE_FLUSH_SUPPORTED */ ++#endif /* WRITE_FLUSH */ + +-/* Free all memory used by the write */ +-void PNGAPI +-png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +-{ +- png_structp png_ptr = NULL; +- png_infop info_ptr = NULL; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_free_ptr free_fn = NULL; +- png_voidp mem_ptr = NULL; ++#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED ++static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */ + #endif + +- png_debug(1, "in png_destroy_write_struct"); +- +- if (png_ptr_ptr != NULL) +- { +- png_ptr = *png_ptr_ptr; +-#ifdef PNG_USER_MEM_SUPPORTED +- free_fn = png_ptr->free_fn; +- mem_ptr = png_ptr->mem_ptr; +-#endif +- } +- +-#ifdef PNG_USER_MEM_SUPPORTED +- if (png_ptr != NULL) +- { +- free_fn = png_ptr->free_fn; +- mem_ptr = png_ptr->mem_ptr; +- } +-#endif +- +- if (info_ptr_ptr != NULL) +- info_ptr = *info_ptr_ptr; +- +- if (info_ptr != NULL) +- { +- if (png_ptr != NULL) +- { +- png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); +- +-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +- if (png_ptr->num_chunk_list) +- { +- png_free(png_ptr, png_ptr->chunk_list); +- png_ptr->num_chunk_list = 0; +- } +-#endif +- } +- +-#ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, +- (png_voidp)mem_ptr); +-#else +- png_destroy_struct((png_voidp)info_ptr); +-#endif +- *info_ptr_ptr = NULL; +- } +- +- if (png_ptr != NULL) +- { +- png_write_destroy(png_ptr); +-#ifdef PNG_USER_MEM_SUPPORTED +- png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, +- (png_voidp)mem_ptr); +-#else +- png_destroy_struct((png_voidp)png_ptr); +-#endif +- *png_ptr_ptr = NULL; +- } +-} +- +- +-/* Free any memory used in png_ptr struct (old method) */ +-void /* PRIVATE */ +-png_write_destroy(png_structp png_ptr) ++/* Free any memory used in png_ptr struct without freeing the struct itself. */ ++static void ++png_write_destroy(png_structrp png_ptr) + { +-#ifdef PNG_SETJMP_SUPPORTED +- jmp_buf tmp_jmp; /* Save jump buffer */ +-#endif +- png_error_ptr error_fn; +-#ifdef PNG_WARNINGS_SUPPORTED +- png_error_ptr warning_fn; +-#endif +- png_voidp error_ptr; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_free_ptr free_fn; +-#endif +- + png_debug(1, "in png_write_destroy"); + + /* Free any memory zlib uses */ +- if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) ++ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) + deflateEnd(&png_ptr->zstream); + + /* Free our memory. png_free checks NULL for us. */ +- png_free(png_ptr, png_ptr->zbuf); ++ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + png_free(png_ptr, png_ptr->row_buf); ++ png_ptr->row_buf = NULL; + #ifdef PNG_WRITE_FILTER_SUPPORTED + png_free(png_ptr, png_ptr->prev_row); + png_free(png_ptr, png_ptr->sub_row); + png_free(png_ptr, png_ptr->up_row); + png_free(png_ptr, png_ptr->avg_row); + png_free(png_ptr, png_ptr->paeth_row); ++ png_ptr->prev_row = NULL; ++ png_ptr->sub_row = NULL; ++ png_ptr->up_row = NULL; ++ png_ptr->avg_row = NULL; ++ png_ptr->paeth_row = NULL; + #endif + + #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +@@ -1002,41 +981,51 @@ + png_reset_filter_heuristics(png_ptr); + png_free(png_ptr, png_ptr->filter_costs); + png_free(png_ptr, png_ptr->inv_filter_costs); ++ png_ptr->filter_costs = NULL; ++ png_ptr->inv_filter_costs = NULL; + #endif + +-#ifdef PNG_SETJMP_SUPPORTED +- /* Reset structure */ +- png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); ++#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED ++ png_free(png_ptr, png_ptr->chunk_list); ++ png_ptr->chunk_list = NULL; + #endif + +- error_fn = png_ptr->error_fn; +-#ifdef PNG_WARNINGS_SUPPORTED +- warning_fn = png_ptr->warning_fn; +-#endif +- error_ptr = png_ptr->error_ptr; +-#ifdef PNG_USER_MEM_SUPPORTED +- free_fn = png_ptr->free_fn; +-#endif ++ /* The error handling and memory handling information is left intact at this ++ * point: the jmp_buf may still have to be freed. See png_destroy_png_struct ++ * for how this happens. ++ */ ++} + +- png_memset(png_ptr, 0, png_sizeof(png_struct)); ++/* Free all memory used by the write. ++ * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for ++ * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free ++ * the passed in info_structs but it would quietly fail to free any of the data ++ * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it ++ * has no png_ptr.) ++ */ ++void PNGAPI ++png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) ++{ ++ png_debug(1, "in png_destroy_write_struct"); + +- png_ptr->error_fn = error_fn; +-#ifdef PNG_WARNINGS_SUPPORTED +- png_ptr->warning_fn = warning_fn; +-#endif +- png_ptr->error_ptr = error_ptr; +-#ifdef PNG_USER_MEM_SUPPORTED +- png_ptr->free_fn = free_fn; +-#endif ++ if (png_ptr_ptr != NULL) ++ { ++ png_structrp png_ptr = *png_ptr_ptr; + +-#ifdef PNG_SETJMP_SUPPORTED +- png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); +-#endif ++ if (png_ptr != NULL) /* added in libpng 1.6.0 */ ++ { ++ png_destroy_info_struct(png_ptr, info_ptr_ptr); ++ ++ *png_ptr_ptr = NULL; ++ png_write_destroy(png_ptr); ++ png_destroy_png_struct(png_ptr); ++ } ++ } + } + + /* Allow the application to select one or more row filters to use. */ + void PNGAPI +-png_set_filter(png_structp png_ptr, int method, int filters) ++png_set_filter(png_structrp png_ptr, int method, int filters) + { + png_debug(1, "in png_set_filter"); + +@@ -1044,7 +1033,7 @@ + return; + + #ifdef PNG_MNG_FEATURES_SUPPORTED +- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && ++ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (method == PNG_INTRAPIXEL_DIFFERENCING)) + method = PNG_FILTER_TYPE_BASE; + +@@ -1056,8 +1045,9 @@ + #ifdef PNG_WRITE_FILTER_SUPPORTED + case 5: + case 6: +- case 7: png_warning(png_ptr, "Unknown row filter for method 0"); +-#endif /* PNG_WRITE_FILTER_SUPPORTED */ ++ case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); ++ /* FALL THROUGH */ ++#endif /* WRITE_FILTER */ + case PNG_FILTER_VALUE_NONE: + png_ptr->do_filter = PNG_FILTER_NONE; break; + +@@ -1078,8 +1068,8 @@ + png_ptr->do_filter = (png_byte)filters; break; + #else + default: +- png_warning(png_ptr, "Unknown row filter for method 0"); +-#endif /* PNG_WRITE_FILTER_SUPPORTED */ ++ png_app_error(png_ptr, "Unknown row filter for method 0"); ++#endif /* WRITE_FILTER */ + } + + /* If we have allocated the row_buf, this means we have already started +@@ -1094,14 +1084,16 @@ + if (png_ptr->row_buf != NULL) + { + #ifdef PNG_WRITE_FILTER_SUPPORTED +- if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) ++ if ((png_ptr->do_filter & PNG_FILTER_SUB) != 0 && ++ png_ptr->sub_row == NULL) + { + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, + (png_ptr->rowbytes + 1)); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; + } + +- if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) ++ if ((png_ptr->do_filter & PNG_FILTER_UP) != 0 && ++ png_ptr->up_row == NULL) + { + if (png_ptr->prev_row == NULL) + { +@@ -1118,7 +1110,8 @@ + } + } + +- if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) ++ if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0 && ++ png_ptr->avg_row == NULL) + { + if (png_ptr->prev_row == NULL) + { +@@ -1135,7 +1128,7 @@ + } + } + +- if ((png_ptr->do_filter & PNG_FILTER_PAETH) && ++ if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0 && + png_ptr->paeth_row == NULL) + { + if (png_ptr->prev_row == NULL) +@@ -1153,7 +1146,7 @@ + } + + if (png_ptr->do_filter == PNG_NO_FILTERS) +-#endif /* PNG_WRITE_FILTER_SUPPORTED */ ++#endif /* WRITE_FILTER */ + png_ptr->do_filter = PNG_FILTER_NONE; + } + } +@@ -1171,7 +1164,7 @@ + #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ + /* Convenience reset API. */ + static void +-png_reset_filter_heuristics(png_structp png_ptr) ++png_reset_filter_heuristics(png_structrp png_ptr) + { + /* Clear out any old values in the 'weights' - this must be done because if + * the app calls set_filter_heuristics multiple times with different +@@ -1204,7 +1197,7 @@ + } + + static int +-png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, ++png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method, + int num_weights) + { + if (png_ptr == NULL) +@@ -1224,7 +1217,7 @@ + if (num_weights > 0) + { + png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, +- (png_uint_32)(png_sizeof(png_byte) * num_weights)); ++ (png_uint_32)((sizeof (png_byte)) * num_weights)); + + /* To make sure that the weighting starts out fairly */ + for (i = 0; i < num_weights; i++) +@@ -1233,10 +1226,10 @@ + } + + png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, +- (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); ++ (png_uint_32)((sizeof (png_uint_16)) * num_weights)); + + png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, +- (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); ++ (png_uint_32)((sizeof (png_uint_16)) * num_weights)); + + for (i = 0; i < num_weights; i++) + { +@@ -1254,10 +1247,10 @@ + if (png_ptr->filter_costs == NULL) + { + png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, +- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); ++ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); + + png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, +- (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); ++ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); + } + + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) +@@ -1287,7 +1280,7 @@ + /* Provide floating and fixed point APIs */ + #ifdef PNG_FLOATING_POINT_SUPPORTED + void PNGAPI +-png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, ++png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, + int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs) + { +@@ -1296,7 +1289,7 @@ + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ +- if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) ++ if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) + return; + + /* If using the weighted method copy in the weights. */ +@@ -1342,7 +1335,7 @@ + + #ifdef PNG_FIXED_POINT_SUPPORTED + void PNGAPI +-png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, ++png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, + int num_weights, png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs) + { +@@ -1351,7 +1344,7 @@ + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ +- if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) ++ if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) + return; + + /* If using the weighted method copy in the weights. */ +@@ -1405,40 +1398,40 @@ + } + } + #endif /* FIXED_POINT */ +-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ ++#endif /* WRITE_WEIGHTED_FILTER */ + + void PNGAPI +-png_set_compression_level(png_structp png_ptr, int level) ++png_set_compression_level(png_structrp png_ptr, int level) + { + png_debug(1, "in png_set_compression_level"); + + if (png_ptr == NULL) + return; + +- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; + png_ptr->zlib_level = level; + } + + void PNGAPI +-png_set_compression_mem_level(png_structp png_ptr, int mem_level) ++png_set_compression_mem_level(png_structrp png_ptr, int mem_level) + { + png_debug(1, "in png_set_compression_mem_level"); + + if (png_ptr == NULL) + return; + +- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; + png_ptr->zlib_mem_level = mem_level; + } + + void PNGAPI +-png_set_compression_strategy(png_structp png_ptr, int strategy) ++png_set_compression_strategy(png_structrp png_ptr, int strategy) + { + png_debug(1, "in png_set_compression_strategy"); + + if (png_ptr == NULL) + return; + ++ /* The flag setting here prevents the libpng dynamic selection of strategy. ++ */ + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; + png_ptr->zlib_strategy = strategy; + } +@@ -1447,80 +1440,81 @@ + * smaller value of window_bits if it can do so safely. + */ + void PNGAPI +-png_set_compression_window_bits(png_structp png_ptr, int window_bits) ++png_set_compression_window_bits(png_structrp png_ptr, int window_bits) + { + if (png_ptr == NULL) + return; + ++ /* Prior to 1.6.0 this would warn but then set the window_bits value, this ++ * meant that negative window bits values could be selected which would cause ++ * libpng to write a non-standard PNG file with raw deflate or gzip ++ * compressed IDAT or ancillary chunks. Such files can be read and there is ++ * no warning on read, so this seems like a very bad idea. ++ */ + if (window_bits > 15) ++ { + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); ++ window_bits = 15; ++ } + + else if (window_bits < 8) ++ { + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); ++ window_bits = 8; ++ } + +-#ifndef WBITS_8_OK +- /* Avoid libpng bug with 256-byte windows */ +- if (window_bits == 8) +- { +- png_warning(png_ptr, "Compression window is being reset to 512"); +- window_bits = 9; +- } +- +-#endif +- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; + png_ptr->zlib_window_bits = window_bits; + } + + void PNGAPI +-png_set_compression_method(png_structp png_ptr, int method) ++png_set_compression_method(png_structrp png_ptr, int method) + { + png_debug(1, "in png_set_compression_method"); + + if (png_ptr == NULL) + return; + ++ /* This would produce an invalid PNG file if it worked, but it doesn't and ++ * deflate will fault it, so it is harmless to just warn here. ++ */ + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + +- png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; + png_ptr->zlib_method = method; + } + + /* The following were added to libpng-1.5.4 */ + #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + void PNGAPI +-png_set_text_compression_level(png_structp png_ptr, int level) ++png_set_text_compression_level(png_structrp png_ptr, int level) + { + png_debug(1, "in png_set_text_compression_level"); + + if (png_ptr == NULL) + return; + +- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; + png_ptr->zlib_text_level = level; + } + + void PNGAPI +-png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) ++png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level) + { + png_debug(1, "in png_set_text_compression_mem_level"); + + if (png_ptr == NULL) + return; + +- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; + png_ptr->zlib_text_mem_level = mem_level; + } + + void PNGAPI +-png_set_text_compression_strategy(png_structp png_ptr, int strategy) ++png_set_text_compression_strategy(png_structrp png_ptr, int strategy) + { + png_debug(1, "in png_set_text_compression_strategy"); + + if (png_ptr == NULL) + return; + +- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; + png_ptr->zlib_text_strategy = strategy; + } + +@@ -1528,32 +1522,28 @@ + * smaller value of window_bits if it can do so safely. + */ + void PNGAPI +-png_set_text_compression_window_bits(png_structp png_ptr, int window_bits) ++png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) + { + if (png_ptr == NULL) + return; + + if (window_bits > 15) ++ { + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); ++ window_bits = 15; ++ } + + else if (window_bits < 8) ++ { + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); ++ window_bits = 8; ++ } + +-#ifndef WBITS_8_OK +- /* Avoid libpng bug with 256-byte windows */ +- if (window_bits == 8) +- { +- png_warning(png_ptr, "Text compression window is being reset to 512"); +- window_bits = 9; +- } +- +-#endif +- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; + png_ptr->zlib_text_window_bits = window_bits; + } + + void PNGAPI +-png_set_text_compression_method(png_structp png_ptr, int method) ++png_set_text_compression_method(png_structrp png_ptr, int method) + { + png_debug(1, "in png_set_text_compression_method"); + +@@ -1563,14 +1553,13 @@ + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + +- png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD; + png_ptr->zlib_text_method = method; + } +-#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ ++#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ + /* end of API added to libpng-1.5.4 */ + + void PNGAPI +-png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) ++png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) + { + if (png_ptr == NULL) + return; +@@ -1580,7 +1569,7 @@ + + #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + void PNGAPI +-png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr ++png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr + write_user_transform_fn) + { + png_debug(1, "in png_set_write_user_transform_fn"); +@@ -1596,88 +1585,899 @@ + + #ifdef PNG_INFO_IMAGE_SUPPORTED + void PNGAPI +-png_write_png(png_structp png_ptr, png_infop info_ptr, ++png_write_png(png_structrp png_ptr, png_inforp info_ptr, + int transforms, voidp params) + { + if (png_ptr == NULL || info_ptr == NULL) + return; + ++ if ((info_ptr->valid & PNG_INFO_IDAT) == 0) ++ { ++ png_app_error(png_ptr, "no rows for png_write_image to write"); ++ return; ++ } ++ + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* ------ these transformations don't touch the info structure ------- */ + ++ /* Invert monochrome pixels */ ++ if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) + #ifdef PNG_WRITE_INVERT_SUPPORTED +- /* Invert monochrome pixels */ +- if (transforms & PNG_TRANSFORM_INVERT_MONO) + png_set_invert_mono(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); + #endif + +-#ifdef PNG_WRITE_SHIFT_SUPPORTED + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ +- if ((transforms & PNG_TRANSFORM_SHIFT) +- && (info_ptr->valid & PNG_INFO_sBIT)) +- png_set_shift(png_ptr, &info_ptr->sig_bit); ++ if ((transforms & PNG_TRANSFORM_SHIFT) != 0) ++#ifdef PNG_WRITE_SHIFT_SUPPORTED ++ if ((info_ptr->valid & PNG_INFO_sBIT) != 0) ++ png_set_shift(png_ptr, &info_ptr->sig_bit); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); + #endif + ++ /* Pack pixels into bytes */ ++ if ((transforms & PNG_TRANSFORM_PACKING) != 0) + #ifdef PNG_WRITE_PACK_SUPPORTED +- /* Pack pixels into bytes */ +- if (transforms & PNG_TRANSFORM_PACKING) +- png_set_packing(png_ptr); ++ png_set_packing(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); + #endif + ++ /* Swap location of alpha bytes from ARGB to RGBA */ ++ if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) + #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +- /* Swap location of alpha bytes from ARGB to RGBA */ +- if (transforms & PNG_TRANSFORM_SWAP_ALPHA) + png_set_swap_alpha(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); + #endif + ++ /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into ++ * RGB, note that the code expects the input color type to be G or RGB; no ++ * alpha channel. ++ */ ++ if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| ++ PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) ++ { + #ifdef PNG_WRITE_FILLER_SUPPORTED +- /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ +- if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) +- png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); ++ if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) ++ { ++ if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) ++ png_app_error(png_ptr, ++ "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); + +- else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) +- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); ++ /* Continue if ignored - this is the pre-1.6.10 behavior */ ++ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); ++ } ++ ++ else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) ++ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); ++#endif ++ } ++ ++ /* Flip BGR pixels to RGB */ ++ if ((transforms & PNG_TRANSFORM_BGR) != 0) ++#ifdef PNG_WRITE_BGR_SUPPORTED ++ png_set_bgr(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); + #endif + +-#ifdef PNG_WRITE_BGR_SUPPORTED +- /* Flip BGR pixels to RGB */ +- if (transforms & PNG_TRANSFORM_BGR) +- png_set_bgr(png_ptr); ++ /* Swap bytes of 16-bit files to most significant byte first */ ++ if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) ++#ifdef PNG_WRITE_SWAP_SUPPORTED ++ png_set_swap(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); + #endif + +-#ifdef PNG_WRITE_SWAP_SUPPORTED +- /* Swap bytes of 16-bit files to most significant byte first */ +- if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) +- png_set_swap(png_ptr); ++ /* Swap bits of 1, 2, 4 bit packed pixel formats */ ++ if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) ++#ifdef PNG_WRITE_PACKSWAP_SUPPORTED ++ png_set_packswap(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); + #endif + +-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED +- /* Swap bits of 1, 2, 4 bit packed pixel formats */ +- if (transforms & PNG_TRANSFORM_PACKSWAP) +- png_set_packswap(png_ptr); +-#endif +- ++ /* Invert the alpha channel from opacity to transparency */ ++ if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) + #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +- /* Invert the alpha channel from opacity to transparency */ +- if (transforms & PNG_TRANSFORM_INVERT_ALPHA) + png_set_invert_alpha(png_ptr); ++#else ++ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); + #endif + + /* ----------------------- end of transformations ------------------- */ + + /* Write the bits */ +- if (info_ptr->valid & PNG_INFO_IDAT) +- png_write_image(png_ptr, info_ptr->row_pointers); ++ png_write_image(png_ptr, info_ptr->row_pointers); + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); + +- PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) + } + #endif +-#endif /* PNG_WRITE_SUPPORTED */ ++ ++ ++#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED ++#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */ ++/* Initialize the write structure - general purpose utility. */ ++static int ++png_image_write_init(png_imagep image) ++{ ++ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, ++ png_safe_error, png_safe_warning); ++ ++ if (png_ptr != NULL) ++ { ++ png_infop info_ptr = png_create_info_struct(png_ptr); ++ ++ if (info_ptr != NULL) ++ { ++ png_controlp control = png_voidcast(png_controlp, ++ png_malloc_warn(png_ptr, (sizeof *control))); ++ ++ if (control != NULL) ++ { ++ memset(control, 0, (sizeof *control)); ++ ++ control->png_ptr = png_ptr; ++ control->info_ptr = info_ptr; ++ control->for_write = 1; ++ ++ image->opaque = control; ++ return 1; ++ } ++ ++ /* Error clean up */ ++ png_destroy_info_struct(png_ptr, &info_ptr); ++ } ++ ++ png_destroy_write_struct(&png_ptr, NULL); ++ } ++ ++ return png_image_error(image, "png_image_write_: out of memory"); ++} ++ ++/* Arguments to png_image_write_main: */ ++typedef struct ++{ ++ /* Arguments: */ ++ png_imagep image; ++ png_const_voidp buffer; ++ png_int_32 row_stride; ++ png_const_voidp colormap; ++ int convert_to_8bit; ++ /* Local variables: */ ++ png_const_voidp first_row; ++ ptrdiff_t row_bytes; ++ png_voidp local_row; ++} png_image_write_control; ++ ++/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to ++ * do any necessary byte swapping. The component order is defined by the ++ * png_image format value. ++ */ ++static int ++png_write_image_16bit(png_voidp argument) ++{ ++ png_image_write_control *display = png_voidcast(png_image_write_control*, ++ argument); ++ png_imagep image = display->image; ++ png_structrp png_ptr = image->opaque->png_ptr; ++ ++ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, ++ display->first_row); ++ png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); ++ png_uint_16p row_end; ++ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; ++ int aindex = 0; ++ png_uint_32 y = image->height; ++ ++ if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED ++ if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) ++ { ++ aindex = -1; ++ ++input_row; /* To point to the first component */ ++ ++output_row; ++ } ++ ++ else ++# endif ++ aindex = channels; ++ } ++ ++ else ++ png_error(png_ptr, "png_write_image: internal call error"); ++ ++ /* Work out the output row end and count over this, note that the increment ++ * above to 'row' means that row_end can actually be beyond the end of the ++ * row; this is correct. ++ */ ++ row_end = output_row + image->width * (channels+1); ++ ++ while (y-- > 0) ++ { ++ png_const_uint_16p in_ptr = input_row; ++ png_uint_16p out_ptr = output_row; ++ ++ while (out_ptr < row_end) ++ { ++ const png_uint_16 alpha = in_ptr[aindex]; ++ png_uint_32 reciprocal = 0; ++ int c; ++ ++ out_ptr[aindex] = alpha; ++ ++ /* Calculate a reciprocal. The correct calculation is simply ++ * component/alpha*65535 << 15. (I.e. 15 bits of precision); this ++ * allows correct rounding by adding .5 before the shift. 'reciprocal' ++ * is only initialized when required. ++ */ ++ if (alpha > 0 && alpha < 65535) ++ reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; ++ ++ c = channels; ++ do /* always at least one channel */ ++ { ++ png_uint_16 component = *in_ptr++; ++ ++ /* The following gives 65535 for an alpha of 0, which is fine, ++ * otherwise if 0/0 is represented as some other value there is more ++ * likely to be a discontinuity which will probably damage ++ * compression when moving from a fully transparent area to a ++ * nearly transparent one. (The assumption here is that opaque ++ * areas tend not to be 0 intensity.) ++ */ ++ if (component >= alpha) ++ component = 65535; ++ ++ /* component<alpha, so component/alpha is less than one and ++ * component*reciprocal is less than 2^31. ++ */ ++ else if (component > 0 && alpha < 65535) ++ { ++ png_uint_32 calc = component * reciprocal; ++ calc += 16384; /* round to nearest */ ++ component = (png_uint_16)(calc >> 15); ++ } ++ ++ *out_ptr++ = component; ++ } ++ while (--c > 0); ++ ++ /* Skip to next component (skip the intervening alpha channel) */ ++ ++in_ptr; ++ ++out_ptr; ++ } ++ ++ png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); ++ input_row += display->row_bytes/(sizeof (png_uint_16)); ++ } ++ ++ return 1; ++} ++ ++/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel ++ * is present it must be removed from the components, the components are then ++ * written in sRGB encoding. No components are added or removed. ++ * ++ * Calculate an alpha reciprocal to reverse pre-multiplication. As above the ++ * calculation can be done to 15 bits of accuracy; however, the output needs to ++ * be scaled in the range 0..255*65535, so include that scaling here. ++ */ ++#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) ++ ++static png_byte ++png_unpremultiply(png_uint_32 component, png_uint_32 alpha, ++ png_uint_32 reciprocal/*from the above macro*/) ++{ ++ /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 ++ * is represented as some other value there is more likely to be a ++ * discontinuity which will probably damage compression when moving from a ++ * fully transparent area to a nearly transparent one. (The assumption here ++ * is that opaque areas tend not to be 0 intensity.) ++ * ++ * There is a rounding problem here; if alpha is less than 128 it will end up ++ * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the ++ * output change for this too. ++ */ ++ if (component >= alpha || alpha < 128) ++ return 255; ++ ++ /* component<alpha, so component/alpha is less than one and ++ * component*reciprocal is less than 2^31. ++ */ ++ else if (component > 0) ++ { ++ /* The test is that alpha/257 (rounded) is less than 255, the first value ++ * that becomes 255 is 65407. ++ * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, ++ * be exact!) [Could also test reciprocal != 0] ++ */ ++ if (alpha < 65407) ++ { ++ component *= reciprocal; ++ component += 64; /* round to nearest */ ++ component >>= 7; ++ } ++ ++ else ++ component *= 255; ++ ++ /* Convert the component to sRGB. */ ++ return (png_byte)PNG_sRGB_FROM_LINEAR(component); ++ } ++ ++ else ++ return 0; ++} ++ ++static int ++png_write_image_8bit(png_voidp argument) ++{ ++ png_image_write_control *display = png_voidcast(png_image_write_control*, ++ argument); ++ png_imagep image = display->image; ++ png_structrp png_ptr = image->opaque->png_ptr; ++ ++ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, ++ display->first_row); ++ png_bytep output_row = png_voidcast(png_bytep, display->local_row); ++ png_uint_32 y = image->height; ++ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; ++ ++ if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ { ++ png_bytep row_end; ++ int aindex; ++ ++# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED ++ if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) ++ { ++ aindex = -1; ++ ++input_row; /* To point to the first component */ ++ ++output_row; ++ } ++ ++ else ++# endif ++ aindex = channels; ++ ++ /* Use row_end in place of a loop counter: */ ++ row_end = output_row + image->width * (channels+1); ++ ++ while (y-- > 0) ++ { ++ png_const_uint_16p in_ptr = input_row; ++ png_bytep out_ptr = output_row; ++ ++ while (out_ptr < row_end) ++ { ++ png_uint_16 alpha = in_ptr[aindex]; ++ png_byte alphabyte = (png_byte)PNG_DIV257(alpha); ++ png_uint_32 reciprocal = 0; ++ int c; ++ ++ /* Scale and write the alpha channel. */ ++ out_ptr[aindex] = alphabyte; ++ ++ if (alphabyte > 0 && alphabyte < 255) ++ reciprocal = UNP_RECIPROCAL(alpha); ++ ++ c = channels; ++ do /* always at least one channel */ ++ *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); ++ while (--c > 0); ++ ++ /* Skip to next component (skip the intervening alpha channel) */ ++ ++in_ptr; ++ ++out_ptr; ++ } /* while out_ptr < row_end */ ++ ++ png_write_row(png_ptr, png_voidcast(png_const_bytep, ++ display->local_row)); ++ input_row += display->row_bytes/(sizeof (png_uint_16)); ++ } /* while y */ ++ } ++ ++ else ++ { ++ /* No alpha channel, so the row_end really is the end of the row and it ++ * is sufficient to loop over the components one by one. ++ */ ++ png_bytep row_end = output_row + image->width * channels; ++ ++ while (y-- > 0) ++ { ++ png_const_uint_16p in_ptr = input_row; ++ png_bytep out_ptr = output_row; ++ ++ while (out_ptr < row_end) ++ { ++ png_uint_32 component = *in_ptr++; ++ ++ component *= 255; ++ *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component); ++ } ++ ++ png_write_row(png_ptr, output_row); ++ input_row += display->row_bytes/(sizeof (png_uint_16)); ++ } ++ } ++ ++ return 1; ++} ++ ++static void ++png_image_set_PLTE(png_image_write_control *display) ++{ ++ const png_imagep image = display->image; ++ const void *cmap = display->colormap; ++ const int entries = image->colormap_entries > 256 ? 256 : ++ (int)image->colormap_entries; ++ ++ /* NOTE: the caller must check for cmap != NULL and entries != 0 */ ++ const png_uint_32 format = image->format; ++ const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); ++ ++# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ ++ defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) ++ const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && ++ (format & PNG_FORMAT_FLAG_ALPHA) != 0; ++# else ++# define afirst 0 ++# endif ++ ++# ifdef PNG_FORMAT_BGR_SUPPORTED ++ const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; ++# else ++# define bgr 0 ++# endif ++ ++ int i, num_trans; ++ png_color palette[256]; ++ png_byte tRNS[256]; ++ ++ memset(tRNS, 255, (sizeof tRNS)); ++ memset(palette, 0, (sizeof palette)); ++ ++ for (i=num_trans=0; i<entries; ++i) ++ { ++ /* This gets automatically converted to sRGB with reversal of the ++ * pre-multiplication if the color-map has an alpha channel. ++ */ ++ if ((format & PNG_FORMAT_FLAG_LINEAR) != 0) ++ { ++ png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap); ++ ++ entry += i * channels; ++ ++ if ((channels & 1) != 0) /* no alpha */ ++ { ++ if (channels >= 3) /* RGB */ ++ { ++ palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * ++ entry[(2 ^ bgr)]); ++ palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * ++ entry[1]); ++ palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * ++ entry[bgr]); ++ } ++ ++ else /* Gray */ ++ palette[i].blue = palette[i].red = palette[i].green = ++ (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry); ++ } ++ ++ else /* alpha */ ++ { ++ png_uint_16 alpha = entry[afirst ? 0 : channels-1]; ++ png_byte alphabyte = (png_byte)PNG_DIV257(alpha); ++ png_uint_32 reciprocal = 0; ++ ++ /* Calculate a reciprocal, as in the png_write_image_8bit code above ++ * this is designed to produce a value scaled to 255*65535 when ++ * divided by 128 (i.e. asr 7). ++ */ ++ if (alphabyte > 0 && alphabyte < 255) ++ reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; ++ ++ tRNS[i] = alphabyte; ++ if (alphabyte < 255) ++ num_trans = i+1; ++ ++ if (channels >= 3) /* RGB */ ++ { ++ palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], ++ alpha, reciprocal); ++ palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, ++ reciprocal); ++ palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, ++ reciprocal); ++ } ++ ++ else /* gray */ ++ palette[i].blue = palette[i].red = palette[i].green = ++ png_unpremultiply(entry[afirst], alpha, reciprocal); ++ } ++ } ++ ++ else /* Color-map has sRGB values */ ++ { ++ png_const_bytep entry = png_voidcast(png_const_bytep, cmap); ++ ++ entry += i * channels; ++ ++ switch (channels) ++ { ++ case 4: ++ tRNS[i] = entry[afirst ? 0 : 3]; ++ if (tRNS[i] < 255) ++ num_trans = i+1; ++ /* FALL THROUGH */ ++ case 3: ++ palette[i].blue = entry[afirst + (2 ^ bgr)]; ++ palette[i].green = entry[afirst + 1]; ++ palette[i].red = entry[afirst + bgr]; ++ break; ++ ++ case 2: ++ tRNS[i] = entry[1 ^ afirst]; ++ if (tRNS[i] < 255) ++ num_trans = i+1; ++ /* FALL THROUGH */ ++ case 1: ++ palette[i].blue = palette[i].red = palette[i].green = ++ entry[afirst]; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ } ++ ++# ifdef afirst ++# undef afirst ++# endif ++# ifdef bgr ++# undef bgr ++# endif ++ ++ png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, ++ entries); ++ ++ if (num_trans > 0) ++ png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, ++ num_trans, NULL); ++ ++ image->colormap_entries = entries; ++} ++ ++static int ++png_image_write_main(png_voidp argument) ++{ ++ png_image_write_control *display = png_voidcast(png_image_write_control*, ++ argument); ++ png_imagep image = display->image; ++ png_structrp png_ptr = image->opaque->png_ptr; ++ png_inforp info_ptr = image->opaque->info_ptr; ++ png_uint_32 format = image->format; ++ ++ /* The following four ints are actually booleans */ ++ int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); ++ int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ ++ int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); ++ int write_16bit = linear && !colormap && (display->convert_to_8bit == 0); ++ ++# ifdef PNG_BENIGN_ERRORS_SUPPORTED ++ /* Make sure we error out on any bad situation */ ++ png_set_benign_errors(png_ptr, 0/*error*/); ++# endif ++ ++ /* Default the 'row_stride' parameter if required. */ ++ if (display->row_stride == 0) ++ display->row_stride = PNG_IMAGE_ROW_STRIDE(*image); ++ ++ /* Set the required transforms then write the rows in the correct order. */ ++ if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) ++ { ++ if (display->colormap != NULL && image->colormap_entries > 0) ++ { ++ png_uint_32 entries = image->colormap_entries; ++ ++ png_set_IHDR(png_ptr, info_ptr, image->width, image->height, ++ entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), ++ PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, ++ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); ++ ++ png_image_set_PLTE(display); ++ } ++ ++ else ++ png_error(image->opaque->png_ptr, ++ "no color-map for color-mapped image"); ++ } ++ ++ else ++ png_set_IHDR(png_ptr, info_ptr, image->width, image->height, ++ write_16bit ? 16 : 8, ++ ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + ++ ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), ++ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); ++ ++ /* Counter-intuitively the data transformations must be called *after* ++ * png_write_info, not before as in the read code, but the 'set' functions ++ * must still be called before. Just set the color space information, never ++ * write an interlaced image. ++ */ ++ ++ if (write_16bit != 0) ++ { ++ /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ ++ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); ++ ++ if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) ++ png_set_cHRM_fixed(png_ptr, info_ptr, ++ /* color x y */ ++ /* white */ 31270, 32900, ++ /* red */ 64000, 33000, ++ /* green */ 30000, 60000, ++ /* blue */ 15000, 6000 ++ ); ++ } ++ ++ else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) ++ png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); ++ ++ /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit ++ * space must still be gamma encoded. ++ */ ++ else ++ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); ++ ++ /* Write the file header. */ ++ png_write_info(png_ptr, info_ptr); ++ ++ /* Now set up the data transformations (*after* the header is written), ++ * remove the handled transformations from the 'format' flags for checking. ++ * ++ * First check for a little endian system if writing 16 bit files. ++ */ ++ if (write_16bit != 0) ++ { ++ PNG_CONST png_uint_16 le = 0x0001; ++ ++ if ((*(png_const_bytep) & le) != 0) ++ png_set_swap(png_ptr); ++ } ++ ++# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED ++ if ((format & PNG_FORMAT_FLAG_BGR) != 0) ++ { ++ if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) ++ png_set_bgr(png_ptr); ++ format &= ~PNG_FORMAT_FLAG_BGR; ++ } ++# endif ++ ++# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED ++ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) ++ { ++ if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) ++ png_set_swap_alpha(png_ptr); ++ format &= ~PNG_FORMAT_FLAG_AFIRST; ++ } ++# endif ++ ++ /* If there are 16 or fewer color-map entries we wrote a lower bit depth ++ * above, but the application data is still byte packed. ++ */ ++ if (colormap != 0 && image->colormap_entries <= 16) ++ png_set_packing(png_ptr); ++ ++ /* That should have handled all (both) the transforms. */ ++ if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | ++ PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) ++ png_error(png_ptr, "png_write_image: unsupported transformation"); ++ ++ { ++ png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); ++ ptrdiff_t row_bytes = display->row_stride; ++ ++ if (linear != 0) ++ row_bytes *= (sizeof (png_uint_16)); ++ ++ if (row_bytes < 0) ++ row += (image->height-1) * (-row_bytes); ++ ++ display->first_row = row; ++ display->row_bytes = row_bytes; ++ } ++ ++ /* Apply 'fast' options if the flag is set. */ ++ if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0) ++ { ++ png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS); ++ /* NOTE: determined by experiment using pngstest, this reflects some ++ * balance between the time to write the image once and the time to read ++ * it about 50 times. The speed-up in pngstest was about 10-20% of the ++ * total (user) time on a heavily loaded system. ++ */ ++ png_set_compression_level(png_ptr, 3); ++ } ++ ++ /* Check for the cases that currently require a pre-transform on the row ++ * before it is written. This only applies when the input is 16-bit and ++ * either there is an alpha channel or it is converted to 8-bit. ++ */ ++ if ((linear != 0 && alpha != 0 ) || ++ (colormap == 0 && display->convert_to_8bit != 0)) ++ { ++ png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, ++ png_get_rowbytes(png_ptr, info_ptr))); ++ int result; ++ ++ display->local_row = row; ++ if (write_16bit != 0) ++ result = png_safe_execute(image, png_write_image_16bit, display); ++ else ++ result = png_safe_execute(image, png_write_image_8bit, display); ++ display->local_row = NULL; ++ ++ png_free(png_ptr, row); ++ ++ /* Skip the 'write_end' on error: */ ++ if (result == 0) ++ return 0; ++ } ++ ++ /* Otherwise this is the case where the input is in a format currently ++ * supported by the rest of the libpng write code; call it directly. ++ */ ++ else ++ { ++ png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); ++ ptrdiff_t row_bytes = display->row_bytes; ++ png_uint_32 y = image->height; ++ ++ while (y-- > 0) ++ { ++ png_write_row(png_ptr, row); ++ row += row_bytes; ++ } ++ } ++ ++ png_write_end(png_ptr, info_ptr); ++ return 1; ++} ++ ++int PNGAPI ++png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, ++ const void *buffer, png_int_32 row_stride, const void *colormap) ++{ ++ /* Write the image to the given (FILE*). */ ++ if (image != NULL && image->version == PNG_IMAGE_VERSION) ++ { ++ if (file != NULL) ++ { ++ if (png_image_write_init(image) != 0) ++ { ++ png_image_write_control display; ++ int result; ++ ++ /* This is slightly evil, but png_init_io doesn't do anything other ++ * than this and we haven't changed the standard IO functions so ++ * this saves a 'safe' function. ++ */ ++ image->opaque->png_ptr->io_ptr = file; ++ ++ memset(&display, 0, (sizeof display)); ++ display.image = image; ++ display.buffer = buffer; ++ display.row_stride = row_stride; ++ display.colormap = colormap; ++ display.convert_to_8bit = convert_to_8bit; ++ ++ result = png_safe_execute(image, png_image_write_main, &display); ++ png_image_free(image); ++ return result; ++ } ++ ++ else ++ return 0; ++ } ++ ++ else ++ return png_image_error(image, ++ "png_image_write_to_stdio: invalid argument"); ++ } ++ ++ else if (image != NULL) ++ return png_image_error(image, ++ "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); ++ ++ else ++ return 0; ++} ++ ++int PNGAPI ++png_image_write_to_file(png_imagep image, const char *file_name, ++ int convert_to_8bit, const void *buffer, png_int_32 row_stride, ++ const void *colormap) ++{ ++ /* Write the image to the named file. */ ++ if (image != NULL && image->version == PNG_IMAGE_VERSION) ++ { ++ if (file_name != NULL) ++ { ++ FILE *fp = fopen(file_name, "wb"); ++ ++ if (fp != NULL) ++ { ++ if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, ++ row_stride, colormap) != 0) ++ { ++ int error; /* from fflush/fclose */ ++ ++ /* Make sure the file is flushed correctly. */ ++ if (fflush(fp) == 0 && ferror(fp) == 0) ++ { ++ if (fclose(fp) == 0) ++ return 1; ++ ++ error = errno; /* from fclose */ ++ } ++ ++ else ++ { ++ error = errno; /* from fflush or ferror */ ++ (void)fclose(fp); ++ } ++ ++ (void)remove(file_name); ++ /* The image has already been cleaned up; this is just used to ++ * set the error (because the original write succeeded). ++ */ ++ return png_image_error(image, strerror(error)); ++ } ++ ++ else ++ { ++ /* Clean up: just the opened file. */ ++ (void)fclose(fp); ++ (void)remove(file_name); ++ return 0; ++ } ++ } ++ ++ else ++ return png_image_error(image, strerror(errno)); ++ } ++ ++ else ++ return png_image_error(image, ++ "png_image_write_to_file: invalid argument"); ++ } ++ ++ else if (image != NULL) ++ return png_image_error(image, ++ "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); ++ ++ else ++ return 0; ++} ++#endif /* STDIO */ ++#endif /* SIMPLIFIED_WRITE */ ++#endif /* WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pngwtran.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngwtran.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -42,90 +42,14 @@ + #include "pngpriv.h" + + #ifdef PNG_WRITE_SUPPORTED +- + #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +-/* Transform the data according to the user's wishes. The order of +- * transformations is significant. +- */ +-void /* PRIVATE */ +-png_do_write_transformations(png_structp png_ptr) +-{ +- png_debug(1, "in png_do_write_transformations"); +- +- if (png_ptr == NULL) +- return; +- +-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +- if (png_ptr->transformations & PNG_USER_TRANSFORM) +- if (png_ptr->write_user_transform_fn != NULL) +- (*(png_ptr->write_user_transform_fn)) /* User write transform +- function */ +- (png_ptr, /* png_ptr */ +- &(png_ptr->row_info), /* row_info: */ +- /* png_uint_32 width; width of row */ +- /* png_size_t rowbytes; number of bytes in row */ +- /* png_byte color_type; color type of pixels */ +- /* png_byte bit_depth; bit depth of samples */ +- /* png_byte channels; number of channels (1-4) */ +- /* png_byte pixel_depth; bits per pixel (depth*channels) */ +- png_ptr->row_buf + 1); /* start of pixel data for row */ +-#endif +- +-#ifdef PNG_WRITE_FILLER_SUPPORTED +- if (png_ptr->transformations & PNG_FILLER) +- png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, +- !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); +-#endif +- +-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED +- if (png_ptr->transformations & PNG_PACKSWAP) +- png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_WRITE_PACK_SUPPORTED +- if (png_ptr->transformations & PNG_PACK) +- png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, +- (png_uint_32)png_ptr->bit_depth); +-#endif +- +-#ifdef PNG_WRITE_SWAP_SUPPORTED +- if (png_ptr->transformations & PNG_SWAP_BYTES) +- png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_WRITE_SHIFT_SUPPORTED +- if (png_ptr->transformations & PNG_SHIFT) +- png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, +- &(png_ptr->shift)); +-#endif +- +-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +- if (png_ptr->transformations & PNG_SWAP_ALPHA) +- png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +- if (png_ptr->transformations & PNG_INVERT_ALPHA) +- png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_WRITE_BGR_SUPPORTED +- if (png_ptr->transformations & PNG_BGR) +- png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +- +-#ifdef PNG_WRITE_INVERT_SUPPORTED +- if (png_ptr->transformations & PNG_INVERT_MONO) +- png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); +-#endif +-} + + #ifdef PNG_WRITE_PACK_SUPPORTED + /* Pack pixels into bytes. Pass the true bit depth in bit_depth. The + * row_info bit depth should be 8 (one pixel per byte). The channels + * should be 1 (this only happens on grayscale and paletted images). + */ +-void /* PRIVATE */ ++static void + png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) + { + png_debug(1, "in png_do_pack"); +@@ -270,7 +194,7 @@ + * would pass 3 as bit_depth, and this routine would translate the + * data to 0 to 15. + */ +-void /* PRIVATE */ ++static void + png_do_shift(png_row_infop row_info, png_bytep row, + png_const_color_8p bit_depth) + { +@@ -281,7 +205,7 @@ + int shift_start[4], shift_dec[4]; + int channels = 0; + +- if (row_info->color_type & PNG_COLOR_MASK_COLOR) ++ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + shift_start[channels] = row_info->bit_depth - bit_depth->red; + shift_dec[channels] = bit_depth->red; +@@ -303,7 +227,7 @@ + channels++; + } + +- if (row_info->color_type & PNG_COLOR_MASK_ALPHA) ++ if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + shift_start[channels] = row_info->bit_depth - bit_depth->alpha; + shift_dec[channels] = bit_depth->alpha; +@@ -315,7 +239,7 @@ + { + png_bytep bp = row; + png_size_t i; +- png_byte mask; ++ unsigned int mask; + png_size_t row_bytes = row_info->rowbytes; + + if (bit_depth->gray == 1 && row_info->bit_depth == 2) +@@ -329,20 +253,22 @@ + + for (i = 0; i < row_bytes; i++, bp++) + { +- png_uint_16 v; + int j; ++ unsigned int v, out; + + v = *bp; +- *bp = 0; ++ out = 0; + + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) + { + if (j > 0) +- *bp |= (png_byte)((v << j) & 0xff); ++ out |= v << j; + + else +- *bp |= (png_byte)((v >> (-j)) & mask); ++ out |= (v >> (-j)) & mask; + } ++ ++ *bp = (png_byte)(out & 0xff); + } + } + +@@ -355,21 +281,23 @@ + for (i = 0; i < istop; i++, bp++) + { + +- png_uint_16 v; ++ const unsigned int c = i%channels; + int j; +- int c = (int)(i%channels); ++ unsigned int v, out; + + v = *bp; +- *bp = 0; ++ out = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) +- *bp |= (png_byte)((v << j) & 0xff); ++ out |= v << j; + + else +- *bp |= (png_byte)((v >> (-j)) & 0xff); ++ out |= v >> (-j); + } ++ ++ *bp = (png_byte)(out & 0xff); + } + } + +@@ -381,22 +309,22 @@ + + for (bp = row, i = 0; i < istop; i++) + { +- int c = (int)(i%channels); +- png_uint_16 value, v; ++ const unsigned int c = i%channels; + int j; ++ unsigned int value, v; + +- v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); ++ v = png_get_uint_16(bp); + value = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) +- value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); ++ value |= v << j; + + else +- value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); ++ value |= v >> (-j); + } +- *bp++ = (png_byte)(value >> 8); ++ *bp++ = (png_byte)((value >> 8) & 0xff); + *bp++ = (png_byte)(value & 0xff); + } + } +@@ -405,7 +333,7 @@ + #endif + + #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +-void /* PRIVATE */ ++static void + png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) + { + png_debug(1, "in png_do_write_swap_alpha"); +@@ -453,7 +381,7 @@ + *(dp++) = save[1]; + } + } +-#endif /* PNG_WRITE_16BIT_SUPPORTED */ ++#endif /* WRITE_16BIT */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) +@@ -492,14 +420,14 @@ + *(dp++) = save[1]; + } + } +-#endif /* PNG_WRITE_16BIT_SUPPORTED */ ++#endif /* WRITE_16BIT */ + } + } + } + #endif + + #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +-void /* PRIVATE */ ++static void + png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) + { + png_debug(1, "in png_do_write_invert_alpha"); +@@ -549,7 +477,7 @@ + *(dp++) = (png_byte)(255 - *(sp++)); + } + } +-#endif /* PNG_WRITE_16BIT_SUPPORTED */ ++#endif /* WRITE_16BIT */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) +@@ -587,75 +515,88 @@ + *(dp++) = (png_byte)(255 - *(sp++)); + } + } +-#endif /* PNG_WRITE_16BIT_SUPPORTED */ ++#endif /* WRITE_16BIT */ + } + } + } + #endif +-#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +-#ifdef PNG_MNG_FEATURES_SUPPORTED +-/* Undoes intrapixel differencing */ ++/* Transform the data according to the user's wishes. The order of ++ * transformations is significant. ++ */ + void /* PRIVATE */ +-png_do_write_intrapixel(png_row_infop row_info, png_bytep row) ++png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) + { +- png_debug(1, "in png_do_write_intrapixel"); ++ png_debug(1, "in png_do_write_transformations"); + +- if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) +- { +- int bytes_per_pixel; +- png_uint_32 row_width = row_info->width; +- if (row_info->bit_depth == 8) +- { +- png_bytep rp; +- png_uint_32 i; ++ if (png_ptr == NULL) ++ return; + +- if (row_info->color_type == PNG_COLOR_TYPE_RGB) +- bytes_per_pixel = 3; ++#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED ++ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) ++ if (png_ptr->write_user_transform_fn != NULL) ++ (*(png_ptr->write_user_transform_fn)) /* User write transform ++ function */ ++ (png_ptr, /* png_ptr */ ++ row_info, /* row_info: */ ++ /* png_uint_32 width; width of row */ ++ /* png_size_t rowbytes; number of bytes in row */ ++ /* png_byte color_type; color type of pixels */ ++ /* png_byte bit_depth; bit depth of samples */ ++ /* png_byte channels; number of channels (1-4) */ ++ /* png_byte pixel_depth; bits per pixel (depth*channels) */ ++ png_ptr->row_buf + 1); /* start of pixel data for row */ ++#endif + +- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) +- bytes_per_pixel = 4; ++#ifdef PNG_WRITE_FILLER_SUPPORTED ++ if ((png_ptr->transformations & PNG_FILLER) != 0) ++ png_do_strip_channel(row_info, png_ptr->row_buf + 1, ++ !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); ++#endif + +- else +- return; ++#ifdef PNG_WRITE_PACKSWAP_SUPPORTED ++ if ((png_ptr->transformations & PNG_PACKSWAP) != 0) ++ png_do_packswap(row_info, png_ptr->row_buf + 1); ++#endif + +- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) +- { +- *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); +- *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); +- } +- } ++#ifdef PNG_WRITE_PACK_SUPPORTED ++ if ((png_ptr->transformations & PNG_PACK) != 0) ++ png_do_pack(row_info, png_ptr->row_buf + 1, ++ (png_uint_32)png_ptr->bit_depth); ++#endif + +-#ifdef PNG_WRITE_16BIT_SUPPORTED +- else if (row_info->bit_depth == 16) +- { +- png_bytep rp; +- png_uint_32 i; ++#ifdef PNG_WRITE_SWAP_SUPPORTED ++# ifdef PNG_16BIT_SUPPORTED ++ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) ++ png_do_swap(row_info, png_ptr->row_buf + 1); ++# endif ++#endif + +- if (row_info->color_type == PNG_COLOR_TYPE_RGB) +- bytes_per_pixel = 6; ++#ifdef PNG_WRITE_SHIFT_SUPPORTED ++ if ((png_ptr->transformations & PNG_SHIFT) != 0) ++ png_do_shift(row_info, png_ptr->row_buf + 1, ++ &(png_ptr->shift)); ++#endif + +- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) +- bytes_per_pixel = 8; ++#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED ++ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) ++ png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); ++#endif + +- else +- return; ++#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED ++ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) ++ png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); ++#endif + +- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) +- { +- png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); +- png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); +- png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); +- png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); +- png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); +- *(rp ) = (png_byte)((red >> 8) & 0xff); +- *(rp + 1) = (png_byte)(red & 0xff); +- *(rp + 4) = (png_byte)((blue >> 8) & 0xff); +- *(rp + 5) = (png_byte)(blue & 0xff); +- } +- } +-#endif /* PNG_WRITE_16BIT_SUPPORTED */ +- } ++#ifdef PNG_WRITE_BGR_SUPPORTED ++ if ((png_ptr->transformations & PNG_BGR) != 0) ++ png_do_bgr(row_info, png_ptr->row_buf + 1); ++#endif ++ ++#ifdef PNG_WRITE_INVERT_SUPPORTED ++ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) ++ png_do_invert(row_info, png_ptr->row_buf + 1); ++#endif + } +-#endif /* PNG_MNG_FEATURES_SUPPORTED */ +-#endif /* PNG_WRITE_SUPPORTED */ ++#endif /* WRITE_TRANSFORMS */ ++#endif /* WRITE */ +--- ./jdk/src/share/native/sun/awt/libpng/pngwutil.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/awt/libpng/pngwutil.c Thu Feb 05 13:00:26 2015 +0100 +@@ -29,8 +29,8 @@ + * However, the following notice accompanied the original version of this + * file and, per its terms, should not be removed: + * +- * Last changed in libpng 1.5.4 [July 7, 2011] +- * Copyright (c) 1998-2011 Glenn Randers-Pehrson ++ * Last changed in libpng 1.6.15 [November 20, 2014] ++ * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * +@@ -57,23 +57,6 @@ + buf[3] = (png_byte)(i & 0xff); + } + +-#ifdef PNG_SAVE_INT_32_SUPPORTED +-/* The png_save_int_32 function assumes integers are stored in two's +- * complement format. If this isn't the case, then this routine needs to +- * be modified to write data in two's complement format. Note that, +- * the following works correctly even if png_int_32 has more than 32 bits +- * (compare the more complex code required on read for sign extention.) +- */ +-void PNGAPI +-png_save_int_32(png_bytep buf, png_int_32 i) +-{ +- buf[0] = (png_byte)((i >> 24) & 0xff); +- buf[1] = (png_byte)((i >> 16) & 0xff); +- buf[2] = (png_byte)((i >> 8) & 0xff); +- buf[3] = (png_byte)(i & 0xff); +-} +-#endif +- + /* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. +@@ -93,7 +76,7 @@ + * bytes have already been written. + */ + void PNGAPI +-png_write_sig(png_structp png_ptr) ++png_write_sig(png_structrp png_ptr) + { + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + +@@ -110,6 +93,104 @@ + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; + } + ++/* Write the start of a PNG chunk. The type is the chunk type. ++ * The total_length is the sum of the lengths of all the data you will be ++ * passing in png_write_chunk_data(). ++ */ ++static void ++png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, ++ png_uint_32 length) ++{ ++ png_byte buf[8]; ++ ++#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) ++ PNG_CSTRING_FROM_CHUNK(buf, chunk_name); ++ png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); ++#endif ++ ++ if (png_ptr == NULL) ++ return; ++ ++#ifdef PNG_IO_STATE_SUPPORTED ++ /* Inform the I/O callback that the chunk header is being written. ++ * PNG_IO_CHUNK_HDR requires a single I/O call. ++ */ ++ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; ++#endif ++ ++ /* Write the length and the chunk name */ ++ png_save_uint_32(buf, length); ++ png_save_uint_32(buf + 4, chunk_name); ++ png_write_data(png_ptr, buf, 8); ++ ++ /* Put the chunk name into png_ptr->chunk_name */ ++ png_ptr->chunk_name = chunk_name; ++ ++ /* Reset the crc and run it over the chunk name */ ++ png_reset_crc(png_ptr); ++ ++ png_calculate_crc(png_ptr, buf + 4, 4); ++ ++#ifdef PNG_IO_STATE_SUPPORTED ++ /* Inform the I/O callback that chunk data will (possibly) be written. ++ * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. ++ */ ++ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; ++#endif ++} ++ ++void PNGAPI ++png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, ++ png_uint_32 length) ++{ ++ png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); ++} ++ ++/* Write the data of a PNG chunk started with png_write_chunk_header(). ++ * Note that multiple calls to this function are allowed, and that the ++ * sum of the lengths from these calls *must* add up to the total_length ++ * given to png_write_chunk_header(). ++ */ ++void PNGAPI ++png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, ++ png_size_t length) ++{ ++ /* Write the data, and run the CRC over it */ ++ if (png_ptr == NULL) ++ return; ++ ++ if (data != NULL && length > 0) ++ { ++ png_write_data(png_ptr, data, length); ++ ++ /* Update the CRC after writing the data, ++ * in case the user I/O routine alters it. ++ */ ++ png_calculate_crc(png_ptr, data, length); ++ } ++} ++ ++/* Finish a chunk started with png_write_chunk_header(). */ ++void PNGAPI ++png_write_chunk_end(png_structrp png_ptr) ++{ ++ png_byte buf[4]; ++ ++ if (png_ptr == NULL) return; ++ ++#ifdef PNG_IO_STATE_SUPPORTED ++ /* Inform the I/O callback that the chunk CRC is being written. ++ * PNG_IO_CHUNK_CRC requires a single I/O function call. ++ */ ++ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; ++#endif ++ ++ /* Write the crc in a single operation */ ++ png_save_uint_32(buf, png_ptr->crc); ++ ++ png_write_data(png_ptr, buf, (png_size_t)4); ++} ++ + /* Write a PNG chunk all at once. The type is an array of ASCII characters + * representing the chunk name. The array must be at least 4 bytes in + * length, and does not need to be null terminated. To be safe, pass the +@@ -119,569 +200,592 @@ + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() + * functions instead. + */ +-void PNGAPI +-png_write_chunk(png_structp png_ptr, png_const_bytep chunk_name, ++static void ++png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, + png_const_bytep data, png_size_t length) + { + if (png_ptr == NULL) + return; + +- png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); +- png_write_chunk_data(png_ptr, data, (png_size_t)length); ++ /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ ++ if (length > PNG_UINT_31_MAX) ++ png_error(png_ptr, "length exceeds PNG maximum"); ++ ++ png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); ++ png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); + } + +-/* Write the start of a PNG chunk. The type is the chunk type. +- * The total_length is the sum of the lengths of all the data you will be +- * passing in png_write_chunk_data(). ++/* This is the API that calls the internal function above. */ ++void PNGAPI ++png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, ++ png_const_bytep data, png_size_t length) ++{ ++ png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, ++ length); ++} ++ ++/* This is used below to find the size of an image to pass to png_deflate_claim, ++ * so it only needs to be accurate if the size is less than 16384 bytes (the ++ * point at which a lower LZ window size can be used.) + */ +-void PNGAPI +-png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, +- png_uint_32 length) ++static png_alloc_size_t ++png_image_size(png_structrp png_ptr) + { +- png_byte buf[8]; +- +- png_debug2(0, "Writing %s chunk, length = %lu", chunk_name, +- (unsigned long)length); +- +- if (png_ptr == NULL) +- return; +- +-#ifdef PNG_IO_STATE_SUPPORTED +- /* Inform the I/O callback that the chunk header is being written. +- * PNG_IO_CHUNK_HDR requires a single I/O call. ++ /* Only return sizes up to the maximum of a png_uint_32; do this by limiting ++ * the width and height used to 15 bits. + */ +- png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; +-#endif +- +- /* Write the length and the chunk name */ +- png_save_uint_32(buf, length); +- png_memcpy(buf + 4, chunk_name, 4); +- png_write_data(png_ptr, buf, (png_size_t)8); +- +- /* Put the chunk name into png_ptr->chunk_name */ +- png_memcpy(png_ptr->chunk_name, chunk_name, 4); +- +- /* Reset the crc and run it over the chunk name */ +- png_reset_crc(png_ptr); +- +- png_calculate_crc(png_ptr, chunk_name, 4); +- +-#ifdef PNG_IO_STATE_SUPPORTED +- /* Inform the I/O callback that chunk data will (possibly) be written. +- * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. ++ png_uint_32 h = png_ptr->height; ++ ++ if (png_ptr->rowbytes < 32768 && h < 32768) ++ { ++ if (png_ptr->interlaced != 0) ++ { ++ /* Interlacing makes the image larger because of the replication of ++ * both the filter byte and the padding to a byte boundary. ++ */ ++ png_uint_32 w = png_ptr->width; ++ unsigned int pd = png_ptr->pixel_depth; ++ png_alloc_size_t cb_base; ++ int pass; ++ ++ for (cb_base=0, pass=0; pass<=6; ++pass) ++ { ++ png_uint_32 pw = PNG_PASS_COLS(w, pass); ++ ++ if (pw > 0) ++ cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); ++ } ++ ++ return cb_base; ++ } ++ ++ else ++ return (png_ptr->rowbytes+1) * h; ++ } ++ ++ else ++ return 0xffffffffU; ++} ++ ++#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED ++ /* This is the code to hack the first two bytes of the deflate stream (the ++ * deflate header) to correct the windowBits value to match the actual data ++ * size. Note that the second argument is the *uncompressed* size but the ++ * first argument is the *compressed* data (and it must be deflate ++ * compressed.) + */ +- png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; +-#endif +-} +- +-/* Write the data of a PNG chunk started with png_write_chunk_start(). +- * Note that multiple calls to this function are allowed, and that the +- * sum of the lengths from these calls *must* add up to the total_length +- * given to png_write_chunk_start(). +- */ +-void PNGAPI +-png_write_chunk_data(png_structp png_ptr, png_const_bytep data, +- png_size_t length) ++static void ++optimize_cmf(png_bytep data, png_alloc_size_t data_size) + { +- /* Write the data, and run the CRC over it */ +- if (png_ptr == NULL) +- return; +- +- if (data != NULL && length > 0) ++ /* Optimize the CMF field in the zlib stream. The resultant zlib stream is ++ * still compliant to the stream specification. ++ */ ++ if (data_size <= 16384) /* else windowBits must be 15 */ + { +- png_write_data(png_ptr, data, length); +- +- /* Update the CRC after writing the data, +- * in case that the user I/O routine alters it. +- */ +- png_calculate_crc(png_ptr, data, length); ++ unsigned int z_cmf = data[0]; /* zlib compression method and flags */ ++ ++ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) ++ { ++ unsigned int z_cinfo; ++ unsigned int half_z_window_size; ++ ++ z_cinfo = z_cmf >> 4; ++ half_z_window_size = 1U << (z_cinfo + 7); ++ ++ if (data_size <= half_z_window_size) /* else no change */ ++ { ++ unsigned int tmp; ++ ++ do ++ { ++ half_z_window_size >>= 1; ++ --z_cinfo; ++ } ++ while (z_cinfo > 0 && data_size <= half_z_window_size); ++ ++ z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); ++ ++ data[0] = (png_byte)z_cmf; ++ tmp = data[1] & 0xe0; ++ tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; ++ data[1] = (png_byte)tmp; ++ } ++ } + } + } +- +-/* Finish a chunk started with png_write_chunk_start(). */ +-void PNGAPI +-png_write_chunk_end(png_structp png_ptr) ++#endif /* WRITE_OPTIMIZE_CMF */ ++ ++/* Initialize the compressor for the appropriate type of compression. */ ++static int ++png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, ++ png_alloc_size_t data_size) + { +- png_byte buf[4]; +- +- if (png_ptr == NULL) return; +- +-#ifdef PNG_IO_STATE_SUPPORTED +- /* Inform the I/O callback that the chunk CRC is being written. +- * PNG_IO_CHUNK_CRC requires a single I/O function call. +- */ +- png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; ++ if (png_ptr->zowner != 0) ++ { ++#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) ++ char msg[64]; ++ ++ PNG_STRING_FROM_CHUNK(msg, owner); ++ msg[4] = ':'; ++ msg[5] = ' '; ++ PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); ++ /* So the message that results is "<chunk> using zstream"; this is an ++ * internal error, but is very useful for debugging. i18n requirements ++ * are minimal. ++ */ ++ (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); + #endif +- +- /* Write the crc in a single operation */ +- png_save_uint_32(buf, png_ptr->crc); +- +- png_write_data(png_ptr, buf, (png_size_t)4); +-} +- +-/* Initialize the compressor for the appropriate type of compression. */ +-static void +-png_zlib_claim(png_structp png_ptr, png_uint_32 state) +-{ +- if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE)) ++#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC ++ png_warning(png_ptr, msg); ++ ++ /* Attempt sane error recovery */ ++ if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ ++ { ++ png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); ++ return Z_STREAM_ERROR; ++ } ++ ++ png_ptr->zowner = 0; ++#else ++ png_error(png_ptr, msg); ++#endif ++ } ++ + { +- /* If already initialized for 'state' do not re-init. */ +- if (png_ptr->zlib_state != state) ++ int level = png_ptr->zlib_level; ++ int method = png_ptr->zlib_method; ++ int windowBits = png_ptr->zlib_window_bits; ++ int memLevel = png_ptr->zlib_mem_level; ++ int strategy; /* set below */ ++ int ret; /* zlib return code */ ++ ++ if (owner == png_IDAT) + { +- int ret = Z_OK; +- png_const_charp who = "-"; +- +- /* If actually initialized for another state do a deflateEnd. */ +- if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) ++ if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) ++ strategy = png_ptr->zlib_strategy; ++ ++ else if (png_ptr->do_filter != PNG_FILTER_NONE) ++ strategy = PNG_Z_DEFAULT_STRATEGY; ++ ++ else ++ strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; ++ } ++ ++ else ++ { ++#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED ++ level = png_ptr->zlib_text_level; ++ method = png_ptr->zlib_text_method; ++ windowBits = png_ptr->zlib_text_window_bits; ++ memLevel = png_ptr->zlib_text_mem_level; ++ strategy = png_ptr->zlib_text_strategy; ++#else ++ /* If customization is not supported the values all come from the ++ * IDAT values except for the strategy, which is fixed to the ++ * default. (This is the pre-1.6.0 behavior too, although it was ++ * implemented in a very different way.) ++ */ ++ strategy = Z_DEFAULT_STRATEGY; ++#endif ++ } ++ ++ /* Adjust 'windowBits' down if larger than 'data_size'; to stop this ++ * happening just pass 32768 as the data_size parameter. Notice that zlib ++ * requires an extra 262 bytes in the window in addition to the data to be ++ * able to see the whole of the data, so if data_size+262 takes us to the ++ * next windowBits size we need to fix up the value later. (Because even ++ * though deflate needs the extra window, inflate does not!) ++ */ ++ if (data_size <= 16384) ++ { ++ /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to ++ * work round a Microsoft Visual C misbehavior which, contrary to C-90, ++ * widens the result of the following shift to 64-bits if (and, ++ * apparently, only if) it is used in a test. ++ */ ++ unsigned int half_window_size = 1U << (windowBits-1); ++ ++ while (data_size + 262 <= half_window_size) + { +- ret = deflateEnd(&png_ptr->zstream); +- who = "end"; +- png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; +- } +- +- /* zlib itself detects an incomplete state on deflateEnd */ +- if (ret == Z_OK) switch (state) +- { +-# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +- case PNG_ZLIB_FOR_TEXT: +- ret = deflateInit2(&png_ptr->zstream, +- png_ptr->zlib_text_level, png_ptr->zlib_text_method, +- png_ptr->zlib_text_window_bits, +- png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy); +- who = "text"; +- break; +-# endif +- +- case PNG_ZLIB_FOR_IDAT: +- ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, +- png_ptr->zlib_method, png_ptr->zlib_window_bits, +- png_ptr->zlib_mem_level, png_ptr->zlib_strategy); +- who = "IDAT"; +- break; +- +- default: +- png_error(png_ptr, "invalid zlib state"); +- } +- +- if (ret == Z_OK) +- png_ptr->zlib_state = state; +- +- else /* an error in deflateEnd or deflateInit2 */ +- { +- size_t pos = 0; +- char msg[64]; +- +- pos = png_safecat(msg, sizeof msg, pos, +- "zlib failed to initialize compressor ("); +- pos = png_safecat(msg, sizeof msg, pos, who); +- +- switch (ret) +- { +- case Z_VERSION_ERROR: +- pos = png_safecat(msg, sizeof msg, pos, ") version error"); +- break; +- +- case Z_STREAM_ERROR: +- pos = png_safecat(msg, sizeof msg, pos, ") stream error"); +- break; +- +- case Z_MEM_ERROR: +- pos = png_safecat(msg, sizeof msg, pos, ") memory error"); +- break; +- +- default: +- pos = png_safecat(msg, sizeof msg, pos, ") unknown error"); +- break; +- } +- +- png_error(png_ptr, msg); ++ half_window_size >>= 1; ++ --windowBits; + } + } + +- /* Here on success, claim the zstream: */ +- png_ptr->zlib_state |= PNG_ZLIB_IN_USE; ++ /* Check against the previous initialized values, if any. */ ++ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 && ++ (png_ptr->zlib_set_level != level || ++ png_ptr->zlib_set_method != method || ++ png_ptr->zlib_set_window_bits != windowBits || ++ png_ptr->zlib_set_mem_level != memLevel || ++ png_ptr->zlib_set_strategy != strategy)) ++ { ++ if (deflateEnd(&png_ptr->zstream) != Z_OK) ++ png_warning(png_ptr, "deflateEnd failed (ignored)"); ++ ++ png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; ++ } ++ ++ /* For safety clear out the input and output pointers (currently zlib ++ * doesn't use them on Init, but it might in the future). ++ */ ++ png_ptr->zstream.next_in = NULL; ++ png_ptr->zstream.avail_in = 0; ++ png_ptr->zstream.next_out = NULL; ++ png_ptr->zstream.avail_out = 0; ++ ++ /* Now initialize if required, setting the new parameters, otherwise just ++ * to a simple reset to the previous parameters. ++ */ ++ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) ++ ret = deflateReset(&png_ptr->zstream); ++ ++ else ++ { ++ ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, ++ memLevel, strategy); ++ ++ if (ret == Z_OK) ++ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; ++ } ++ ++ /* The return code is from either deflateReset or deflateInit2; they have ++ * pretty much the same set of error codes. ++ */ ++ if (ret == Z_OK) ++ png_ptr->zowner = owner; ++ ++ else ++ png_zstream_error(png_ptr, ret); ++ ++ return ret; + } +- +- else +- png_error(png_ptr, "zstream already in use (internal error)"); + } + +-/* The opposite: release the stream. It is also reset, this API will warn on +- * error but will not fail. +- */ +-static void +-png_zlib_release(png_structp png_ptr) ++/* Clean up (or trim) a linked list of compression buffers. */ ++void /* PRIVATE */ ++png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) + { +- if (png_ptr->zlib_state & PNG_ZLIB_IN_USE) ++ png_compression_bufferp list = *listp; ++ ++ if (list != NULL) + { +- int ret = deflateReset(&png_ptr->zstream); +- +- png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE; +- +- if (ret != Z_OK) ++ *listp = NULL; ++ ++ do + { +- png_const_charp err; +- PNG_WARNING_PARAMETERS(p) +- +- switch (ret) +- { +- case Z_VERSION_ERROR: +- err = "version"; +- break; +- +- case Z_STREAM_ERROR: +- err = "stream"; +- break; +- +- case Z_MEM_ERROR: +- err = "memory"; +- break; +- +- default: +- err = "unknown"; +- break; +- } +- +- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret); +- png_warning_parameter(p, 2, err); +- +- if (png_ptr->zstream.msg) +- err = png_ptr->zstream.msg; +- else +- err = "[no zlib message]"; +- +- png_warning_parameter(p, 3, err); +- +- png_formatted_warning(png_ptr, p, +- "zlib failed to reset compressor: @1(@2): @3"); ++ png_compression_bufferp next = list->next; ++ ++ png_free(png_ptr, list); ++ list = next; + } ++ while (list != NULL); + } +- +- else +- png_warning(png_ptr, "zstream not in use (internal error)"); + } + + #ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED + /* This pair of functions encapsulates the operation of (a) compressing a + * text string, and (b) issuing it later as a series of chunk data writes. + * The compression_state structure is shared context for these functions +- * set up by the caller in order to make the whole mess thread-safe. ++ * set up by the caller to allow access to the relevant local variables. ++ * ++ * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size ++ * temporary buffers. From 1.6.0 it is retained in png_struct so that it will ++ * be correctly freed in the event of a write error (previous implementations ++ * just leaked memory.) + */ +- + typedef struct + { +- png_const_bytep input; /* The uncompressed input data */ +- png_size_t input_len; /* Its length */ +- int num_output_ptr; /* Number of output pointers used */ +- int max_output_ptr; /* Size of output_ptr */ +- png_bytep *output_ptr; /* Array of pointers to output */ ++ png_const_bytep input; /* The uncompressed input data */ ++ png_alloc_size_t input_len; /* Its length */ ++ png_uint_32 output_len; /* Final compressed length */ ++ png_byte output[1024]; /* First block of output */ + } compression_state; + +-/* Compress given text into storage in the png_ptr structure */ +-static int /* PRIVATE */ +-png_text_compress(png_structp png_ptr, +- png_const_charp text, png_size_t text_len, int compression, +- compression_state *comp) ++static void ++png_text_compress_init(compression_state *comp, png_const_bytep input, ++ png_alloc_size_t input_len) ++{ ++ comp->input = input; ++ comp->input_len = input_len; ++ comp->output_len = 0; ++} ++ ++/* Compress the data in the compression state input */ ++static int ++png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, ++ compression_state *comp, png_uint_32 prefix_len) + { + int ret; + +- comp->num_output_ptr = 0; +- comp->max_output_ptr = 0; +- comp->output_ptr = NULL; +- comp->input = NULL; +- comp->input_len = text_len; +- +- /* We may just want to pass the text right through */ +- if (compression == PNG_TEXT_COMPRESSION_NONE) ++ /* To find the length of the output it is necessary to first compress the ++ * input. The result is buffered rather than using the two-pass algorithm ++ * that is used on the inflate side; deflate is assumed to be slower and a ++ * PNG writer is assumed to have more memory available than a PNG reader. ++ * ++ * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an ++ * upper limit on the output size, but it is always bigger than the input ++ * size so it is likely to be more efficient to use this linked-list ++ * approach. ++ */ ++ ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); ++ ++ if (ret != Z_OK) ++ return ret; ++ ++ /* Set up the compression buffers, we need a loop here to avoid overflowing a ++ * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited ++ * by the output buffer size, so there is no need to check that. Since this ++ * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits ++ * in size. ++ */ + { +- comp->input = (png_const_bytep)text; +- return((int)text_len); ++ png_compression_bufferp *end = &png_ptr->zbuffer_list; ++ png_alloc_size_t input_len = comp->input_len; /* may be zero! */ ++ png_uint_32 output_len; ++ ++ /* zlib updates these for us: */ ++ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); ++ png_ptr->zstream.avail_in = 0; /* Set below */ ++ png_ptr->zstream.next_out = comp->output; ++ png_ptr->zstream.avail_out = (sizeof comp->output); ++ ++ output_len = png_ptr->zstream.avail_out; ++ ++ do ++ { ++ uInt avail_in = ZLIB_IO_MAX; ++ ++ if (avail_in > input_len) ++ avail_in = (uInt)input_len; ++ ++ input_len -= avail_in; ++ ++ png_ptr->zstream.avail_in = avail_in; ++ ++ if (png_ptr->zstream.avail_out == 0) ++ { ++ png_compression_buffer *next; ++ ++ /* Chunk data is limited to 2^31 bytes in length, so the prefix ++ * length must be counted here. ++ */ ++ if (output_len + prefix_len > PNG_UINT_31_MAX) ++ { ++ ret = Z_MEM_ERROR; ++ break; ++ } ++ ++ /* Need a new (malloc'ed) buffer, but there may be one present ++ * already. ++ */ ++ next = *end; ++ if (next == NULL) ++ { ++ next = png_voidcast(png_compression_bufferp, png_malloc_base ++ (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); ++ ++ if (next == NULL) ++ { ++ ret = Z_MEM_ERROR; ++ break; ++ } ++ ++ /* Link in this buffer (so that it will be freed later) */ ++ next->next = NULL; ++ *end = next; ++ } ++ ++ png_ptr->zstream.next_out = next->output; ++ png_ptr->zstream.avail_out = png_ptr->zbuffer_size; ++ output_len += png_ptr->zstream.avail_out; ++ ++ /* Move 'end' to the next buffer pointer. */ ++ end = &next->next; ++ } ++ ++ /* Compress the data */ ++ ret = deflate(&png_ptr->zstream, ++ input_len > 0 ? Z_NO_FLUSH : Z_FINISH); ++ ++ /* Claw back input data that was not consumed (because avail_in is ++ * reset above every time round the loop). ++ */ ++ input_len += png_ptr->zstream.avail_in; ++ png_ptr->zstream.avail_in = 0; /* safety */ ++ } ++ while (ret == Z_OK); ++ ++ /* There may be some space left in the last output buffer. This needs to ++ * be subtracted from output_len. ++ */ ++ output_len -= png_ptr->zstream.avail_out; ++ png_ptr->zstream.avail_out = 0; /* safety */ ++ comp->output_len = output_len; ++ ++ /* Now double check the output length, put in a custom message if it is ++ * too long. Otherwise ensure the z_stream::msg pointer is set to ++ * something. ++ */ ++ if (output_len + prefix_len >= PNG_UINT_31_MAX) ++ { ++ png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); ++ ret = Z_MEM_ERROR; ++ } ++ ++ else ++ png_zstream_error(png_ptr, ret); ++ ++ /* Reset zlib for another zTXt/iTXt or image data */ ++ png_ptr->zowner = 0; ++ ++ /* The only success case is Z_STREAM_END, input_len must be 0; if not this ++ * is an internal error. ++ */ ++ if (ret == Z_STREAM_END && input_len == 0) ++ { ++#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED ++ /* Fix up the deflate header, if required */ ++ optimize_cmf(comp->output, comp->input_len); ++#endif ++ /* But Z_OK is returned, not Z_STREAM_END; this allows the claim ++ * function above to return Z_STREAM_END on an error (though it never ++ * does in the current versions of zlib.) ++ */ ++ return Z_OK; ++ } ++ ++ else ++ return ret; + } +- +- if (compression >= PNG_TEXT_COMPRESSION_LAST) ++} ++ ++/* Ship the compressed text out via chunk writes */ ++static void ++png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) ++{ ++ png_uint_32 output_len = comp->output_len; ++ png_const_bytep output = comp->output; ++ png_uint_32 avail = (sizeof comp->output); ++ png_compression_buffer *next = png_ptr->zbuffer_list; ++ ++ for (;;) ++ { ++ if (avail > output_len) ++ avail = output_len; ++ ++ png_write_chunk_data(png_ptr, output, avail); ++ ++ output_len -= avail; ++ ++ if (output_len == 0 || next == NULL) ++ break; ++ ++ avail = png_ptr->zbuffer_size; ++ output = next->output; ++ next = next->next; ++ } ++ ++ /* This is an internal error; 'next' must have been NULL! */ ++ if (output_len > 0) ++ png_error(png_ptr, "error writing ancillary chunked compressed data"); ++} ++#endif /* WRITE_COMPRESSED_TEXT */ ++ ++#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ ++ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) ++/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, ++ * and if invalid, correct the keyword rather than discarding the entire ++ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in ++ * length, forbids leading or trailing whitespace, multiple internal spaces, ++ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. ++ * ++ * The 'new_key' buffer must be 80 characters in size (for the keyword plus a ++ * trailing '\0'). If this routine returns 0 then there was no keyword, or a ++ * valid one could not be generated, and the caller must png_error. ++ */ ++static png_uint_32 ++png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) ++{ ++ png_const_charp orig_key = key; ++ png_uint_32 key_len = 0; ++ int bad_character = 0; ++ int space = 1; ++ ++ png_debug(1, "in png_check_keyword"); ++ ++ if (key == NULL) ++ { ++ *new_key = 0; ++ return 0; ++ } ++ ++ while (*key && key_len < 79) ++ { ++ png_byte ch = (png_byte)(0xff & *key++); ++ ++ if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) ++ *new_key++ = ch, ++key_len, space = 0; ++ ++ else if (space == 0) ++ { ++ /* A space or an invalid character when one wasn't seen immediately ++ * before; output just a space. ++ */ ++ *new_key++ = 32, ++key_len, space = 1; ++ ++ /* If the character was not a space then it is invalid. */ ++ if (ch != 32) ++ bad_character = ch; ++ } ++ ++ else if (bad_character == 0) ++ bad_character = ch; /* just skip it, record the first error */ ++ } ++ ++ if (key_len > 0 && space != 0) /* trailing space */ ++ { ++ --key_len, --new_key; ++ if (bad_character == 0) ++ bad_character = 32; ++ } ++ ++ /* Terminate the keyword */ ++ *new_key = 0; ++ ++ if (key_len == 0) ++ return 0; ++ ++#ifdef PNG_WARNINGS_SUPPORTED ++ /* Try to only output one warning per keyword: */ ++ if (*key != 0) /* keyword too long */ ++ png_warning(png_ptr, "keyword truncated"); ++ ++ else if (bad_character != 0) + { + PNG_WARNING_PARAMETERS(p) + +- png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, +- compression); +- png_formatted_warning(png_ptr, p, "Unknown compression type @1"); ++ png_warning_parameter(p, 1, orig_key); ++ png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); ++ ++ png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); + } +- +- /* We can't write the chunk until we find out how much data we have, +- * which means we need to run the compressor first and save the +- * output. This shouldn't be a problem, as the vast majority of +- * comments should be reasonable, but we will set up an array of +- * malloc'd pointers to be sure. +- * +- * If we knew the application was well behaved, we could simplify this +- * greatly by assuming we can always malloc an output buffer large +- * enough to hold the compressed text ((1001 * text_len / 1000) + 12) +- * and malloc this directly. The only time this would be a bad idea is +- * if we can't malloc more than 64K and we have 64K of random input +- * data, or if the input string is incredibly large (although this +- * wouldn't cause a failure, just a slowdown due to swapping). +- */ +- png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT); +- +- /* Set up the compression buffers */ +- /* TODO: the following cast hides a potential overflow problem. */ +- png_ptr->zstream.avail_in = (uInt)text_len; +- +- /* NOTE: assume zlib doesn't overwrite the input */ +- png_ptr->zstream.next_in = (Bytef *)text; +- png_ptr->zstream.avail_out = png_ptr->zbuf_size; +- png_ptr->zstream.next_out = png_ptr->zbuf; +- +- /* This is the same compression loop as in png_write_row() */ +- do +- { +- /* Compress the data */ +- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); +- +- if (ret != Z_OK) +- { +- /* Error */ +- if (png_ptr->zstream.msg != NULL) +- png_error(png_ptr, png_ptr->zstream.msg); +- +- else +- png_error(png_ptr, "zlib error"); +- } +- +- /* Check to see if we need more room */ +- if (!(png_ptr->zstream.avail_out)) +- { +- /* Make sure the output array has room */ +- if (comp->num_output_ptr >= comp->max_output_ptr) +- { +- int old_max; +- +- old_max = comp->max_output_ptr; +- comp->max_output_ptr = comp->num_output_ptr + 4; +- if (comp->output_ptr != NULL) +- { +- png_bytepp old_ptr; +- +- old_ptr = comp->output_ptr; +- +- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, +- (png_alloc_size_t) +- (comp->max_output_ptr * png_sizeof(png_charpp))); +- +- png_memcpy(comp->output_ptr, old_ptr, old_max +- * png_sizeof(png_charp)); +- +- png_free(png_ptr, old_ptr); +- } +- else +- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, +- (png_alloc_size_t) +- (comp->max_output_ptr * png_sizeof(png_charp))); +- } +- +- /* Save the data */ +- comp->output_ptr[comp->num_output_ptr] = +- (png_bytep)png_malloc(png_ptr, +- (png_alloc_size_t)png_ptr->zbuf_size); +- +- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, +- png_ptr->zbuf_size); +- +- comp->num_output_ptr++; +- +- /* and reset the buffer */ +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +- png_ptr->zstream.next_out = png_ptr->zbuf; +- } +- /* Continue until we don't have any more to compress */ +- } while (png_ptr->zstream.avail_in); +- +- /* Finish the compression */ +- do +- { +- /* Tell zlib we are finished */ +- ret = deflate(&png_ptr->zstream, Z_FINISH); +- +- if (ret == Z_OK) +- { +- /* Check to see if we need more room */ +- if (!(png_ptr->zstream.avail_out)) +- { +- /* Check to make sure our output array has room */ +- if (comp->num_output_ptr >= comp->max_output_ptr) +- { +- int old_max; +- +- old_max = comp->max_output_ptr; +- comp->max_output_ptr = comp->num_output_ptr + 4; +- if (comp->output_ptr != NULL) +- { +- png_bytepp old_ptr; +- +- old_ptr = comp->output_ptr; +- +- /* This could be optimized to realloc() */ +- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, +- (png_alloc_size_t)(comp->max_output_ptr * +- png_sizeof(png_charp))); +- +- png_memcpy(comp->output_ptr, old_ptr, +- old_max * png_sizeof(png_charp)); +- +- png_free(png_ptr, old_ptr); +- } +- +- else +- comp->output_ptr = (png_bytepp)png_malloc(png_ptr, +- (png_alloc_size_t)(comp->max_output_ptr * +- png_sizeof(png_charp))); +- } +- +- /* Save the data */ +- comp->output_ptr[comp->num_output_ptr] = +- (png_bytep)png_malloc(png_ptr, +- (png_alloc_size_t)png_ptr->zbuf_size); +- +- png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, +- png_ptr->zbuf_size); +- +- comp->num_output_ptr++; +- +- /* and reset the buffer pointers */ +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +- png_ptr->zstream.next_out = png_ptr->zbuf; +- } +- } +- else if (ret != Z_STREAM_END) +- { +- /* We got an error */ +- if (png_ptr->zstream.msg != NULL) +- png_error(png_ptr, png_ptr->zstream.msg); +- +- else +- png_error(png_ptr, "zlib error"); +- } +- } while (ret != Z_STREAM_END); +- +- /* Text length is number of buffers plus last buffer */ +- text_len = png_ptr->zbuf_size * comp->num_output_ptr; +- +- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) +- text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; +- +- return((int)text_len); ++#endif /* WARNINGS */ ++ ++ return key_len; + } +- +-/* Ship the compressed text out via chunk writes */ +-static void /* PRIVATE */ +-png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) +-{ +- int i; +- +- /* Handle the no-compression case */ +- if (comp->input) +- { +- png_write_chunk_data(png_ptr, comp->input, comp->input_len); +- +- return; +- } +- +-#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +- if (comp->input_len >= 2 && comp->input_len < 16384) +- { +- unsigned int z_cmf; /* zlib compression method and flags */ +- +- /* Optimize the CMF field in the zlib stream. This hack of the zlib +- * stream is compliant to the stream specification. +- */ +- +- if (comp->num_output_ptr) +- z_cmf = comp->output_ptr[0][0]; +- else +- z_cmf = png_ptr->zbuf[0]; +- +- if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) +- { +- unsigned int z_cinfo; +- unsigned int half_z_window_size; +- png_size_t uncompressed_text_size = comp->input_len; +- +- z_cinfo = z_cmf >> 4; +- half_z_window_size = 1 << (z_cinfo + 7); +- +- while (uncompressed_text_size <= half_z_window_size && +- half_z_window_size >= 256) +- { +- z_cinfo--; +- half_z_window_size >>= 1; +- } +- +- z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); +- +- if (comp->num_output_ptr) +- { +- +- if (comp->output_ptr[0][0] != z_cmf) +- { +- int tmp; +- +- comp->output_ptr[0][0] = (png_byte)z_cmf; +- tmp = comp->output_ptr[0][1] & 0xe0; +- tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; +- comp->output_ptr[0][1] = (png_byte)tmp; +- } +- } +- else +- { +- int tmp; +- +- png_ptr->zbuf[0] = (png_byte)z_cmf; +- tmp = png_ptr->zbuf[1] & 0xe0; +- tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; +- png_ptr->zbuf[1] = (png_byte)tmp; +- } +- } +- +- else +- png_error(png_ptr, +- "Invalid zlib compression method or flags in non-IDAT chunk"); +- } +-#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ +- +- /* Write saved output buffers, if any */ +- for (i = 0; i < comp->num_output_ptr; i++) +- { +- png_write_chunk_data(png_ptr, comp->output_ptr[i], +- (png_size_t)png_ptr->zbuf_size); +- +- png_free(png_ptr, comp->output_ptr[i]); +- } +- +- if (comp->max_output_ptr != 0) +- png_free(png_ptr, comp->output_ptr); +- +- /* Write anything left in zbuf */ +- if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) +- png_write_chunk_data(png_ptr, png_ptr->zbuf, +- (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); +- +- /* Reset zlib for another zTXt/iTXt or image data */ +- png_zlib_release(png_ptr); +-} +-#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ ++#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */ + + /* Write the IHDR chunk, and update the png_struct with the necessary + * information. Note that the rest of this code depends upon this + * information being correct. + */ + void /* PRIVATE */ +-png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, ++png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, + int bit_depth, int color_type, int compression_type, int filter_type, + int interlace_type) + { +- PNG_IHDR; +- + png_byte buf[13]; /* Buffer to store the IHDR info */ + + png_debug(1, "in png_write_IHDR"); +@@ -772,8 +876,8 @@ + */ + if ( + #ifdef PNG_MNG_FEATURES_SUPPORTED +- !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && +- ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && ++ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && ++ ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && +@@ -823,14 +927,9 @@ + buf[12] = (png_byte)interlace_type; + + /* Write the chunk */ +- png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); +- +- /* Initialize zlib with PNG info */ +- png_ptr->zstream.zalloc = png_zalloc; +- png_ptr->zstream.zfree = png_zfree; +- png_ptr->zstream.opaque = (voidpf)png_ptr; +- +- if (!(png_ptr->do_filter)) ++ png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); ++ ++ if ((png_ptr->do_filter) == PNG_NO_FILTERS) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || + png_ptr->bit_depth < 8) +@@ -840,55 +939,6 @@ + png_ptr->do_filter = PNG_ALL_FILTERS; + } + +- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) +- { +- if (png_ptr->do_filter != PNG_FILTER_NONE) +- png_ptr->zlib_strategy = Z_FILTERED; +- +- else +- png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; +- } +- +- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) +- png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; +- +- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) +- png_ptr->zlib_mem_level = 8; +- +- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) +- png_ptr->zlib_window_bits = 15; +- +- if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) +- png_ptr->zlib_method = 8; +- +-#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY)) +- png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; +- +- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL)) +- png_ptr->zlib_text_level = png_ptr->zlib_level; +- +- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL)) +- png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; +- +- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS)) +- png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; +- +- if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD)) +- png_ptr->zlib_text_method = png_ptr->zlib_method; +-#else +- png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; +- png_ptr->zlib_text_level = png_ptr->zlib_level; +- png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; +- png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; +- png_ptr->zlib_text_method = png_ptr->zlib_method; +-#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ +-#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ +- +- /* Record that the compressor has not yet been initialized. */ +- png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; +- + png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ + } + +@@ -897,10 +947,9 @@ + * structure. + */ + void /* PRIVATE */ +-png_write_PLTE(png_structp png_ptr, png_const_colorp palette, ++png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, + png_uint_32 num_pal) + { +- PNG_PLTE; + png_uint_32 i; + png_const_colorp pal_ptr; + png_byte buf[3]; +@@ -909,7 +958,7 @@ + + if (( + #ifdef PNG_MNG_FEATURES_SUPPORTED +- !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && ++ (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && + #endif + num_pal == 0) || num_pal > 256) + { +@@ -925,7 +974,7 @@ + } + } + +- if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) ++ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + { + png_warning(png_ptr, + "Ignoring request to write a PLTE chunk in grayscale PNG"); +@@ -936,7 +985,7 @@ + png_ptr->num_palette = (png_uint_16)num_pal; + png_debug1(3, "num_palette = %d", png_ptr->num_palette); + +- png_write_chunk_start(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); ++ png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); + #ifdef PNG_POINTER_INDEXING_SUPPORTED + + for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) +@@ -966,127 +1015,192 @@ + png_ptr->mode |= PNG_HAVE_PLTE; + } + +-/* Write an IDAT chunk */ ++/* This is similar to png_text_compress, above, except that it does not require ++ * all of the data at once and, instead of buffering the compressed result, ++ * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out ++ * because it calls the write interface. As a result it does its own error ++ * reporting and does not return an error code. In the event of error it will ++ * just call png_error. The input data length may exceed 32-bits. The 'flush' ++ * parameter is exactly the same as that to deflate, with the following ++ * meanings: ++ * ++ * Z_NO_FLUSH: normal incremental output of compressed data ++ * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush ++ * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up ++ * ++ * The routine manages the acquire and release of the png_ptr->zstream by ++ * checking and (at the end) clearing png_ptr->zowner; it does some sanity ++ * checks on the 'mode' flags while doing this. ++ */ + void /* PRIVATE */ +-png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) ++png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, ++ png_alloc_size_t input_len, int flush) + { +- PNG_IDAT; +- +- png_debug(1, "in png_write_IDAT"); +- ++ if (png_ptr->zowner != png_IDAT) ++ { ++ /* First time. Ensure we have a temporary buffer for compression and ++ * trim the buffer list if it has more than one entry to free memory. ++ * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been ++ * created at this point, but the check here is quick and safe. ++ */ ++ if (png_ptr->zbuffer_list == NULL) ++ { ++ png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, ++ png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); ++ png_ptr->zbuffer_list->next = NULL; ++ } ++ ++ else ++ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); ++ ++ /* It is a terminal error if we can't claim the zstream. */ ++ if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) ++ png_error(png_ptr, png_ptr->zstream.msg); ++ ++ /* The output state is maintained in png_ptr->zstream, so it must be ++ * initialized here after the claim. ++ */ ++ png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; ++ png_ptr->zstream.avail_out = png_ptr->zbuffer_size; ++ } ++ ++ /* Now loop reading and writing until all the input is consumed or an error ++ * terminates the operation. The _out values are maintained across calls to ++ * this function, but the input must be reset each time. ++ */ ++ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); ++ png_ptr->zstream.avail_in = 0; /* set below */ ++ for (;;) ++ { ++ int ret; ++ ++ /* INPUT: from the row data */ ++ uInt avail = ZLIB_IO_MAX; ++ ++ if (avail > input_len) ++ avail = (uInt)input_len; /* safe because of the check */ ++ ++ png_ptr->zstream.avail_in = avail; ++ input_len -= avail; ++ ++ ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); ++ ++ /* Include as-yet unconsumed input */ ++ input_len += png_ptr->zstream.avail_in; ++ png_ptr->zstream.avail_in = 0; ++ ++ /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note ++ * that these two zstream fields are preserved across the calls, therefore ++ * there is no need to set these up on entry to the loop. ++ */ ++ if (png_ptr->zstream.avail_out == 0) ++ { ++ png_bytep data = png_ptr->zbuffer_list->output; ++ uInt size = png_ptr->zbuffer_size; ++ ++ /* Write an IDAT containing the data then reset the buffer. The ++ * first IDAT may need deflate header optimization. ++ */ + #ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +- if (!(png_ptr->mode & PNG_HAVE_IDAT) && +- png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) +- { +- /* Optimize the CMF field in the zlib stream. This hack of the zlib +- * stream is compliant to the stream specification. ++ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && ++ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) ++ optimize_cmf(data, png_image_size(png_ptr)); ++#endif ++ ++ png_write_complete_chunk(png_ptr, png_IDAT, data, size); ++ png_ptr->mode |= PNG_HAVE_IDAT; ++ ++ png_ptr->zstream.next_out = data; ++ png_ptr->zstream.avail_out = size; ++ ++ /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with ++ * the same flush parameter until it has finished output, for NO_FLUSH ++ * it doesn't matter. ++ */ ++ if (ret == Z_OK && flush != Z_NO_FLUSH) ++ continue; ++ } ++ ++ /* The order of these checks doesn't matter much; it just affects which ++ * possible error might be detected if multiple things go wrong at once. + */ +- unsigned int z_cmf = data[0]; /* zlib compression method and flags */ +- +- if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) ++ if (ret == Z_OK) /* most likely return code! */ + { +- /* Avoid memory underflows and multiplication overflows. +- * +- * The conditions below are practically always satisfied; +- * however, they still must be checked. ++ /* If all the input has been consumed then just return. If Z_FINISH ++ * was used as the flush parameter something has gone wrong if we get ++ * here. + */ +- if (length >= 2 && +- png_ptr->height < 16384 && png_ptr->width < 16384) ++ if (input_len == 0) + { +- /* Compute the maximum possible length of the datastream */ +- +- /* Number of pixels, plus for each row a filter byte +- * and possibly a padding byte, so increase the maximum +- * size to account for these. +- */ +- unsigned int z_cinfo; +- unsigned int half_z_window_size; +- png_uint_32 uncompressed_idat_size = png_ptr->height * +- ((png_ptr->width * +- png_ptr->channels * png_ptr->bit_depth + 15) >> 3); +- +- /* If it's interlaced, each block of 8 rows is sent as up to +- * 14 rows, i.e., 6 additional rows, each with a filter byte +- * and possibly a padding byte +- */ +- if (png_ptr->interlaced) +- uncompressed_idat_size += ((png_ptr->height + 7)/8) * +- (png_ptr->bit_depth < 8 ? 12 : 6); +- +- z_cinfo = z_cmf >> 4; +- half_z_window_size = 1 << (z_cinfo + 7); +- +- while (uncompressed_idat_size <= half_z_window_size && +- half_z_window_size >= 256) +- { +- z_cinfo--; +- half_z_window_size >>= 1; +- } +- +- z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); +- +- if (data[0] != z_cmf) +- { +- int tmp; +- data[0] = (png_byte)z_cmf; +- tmp = data[1] & 0xe0; +- tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; +- data[1] = (png_byte)tmp; +- } ++ if (flush == Z_FINISH) ++ png_error(png_ptr, "Z_OK on Z_FINISH with output space"); ++ ++ return; + } + } + ++ else if (ret == Z_STREAM_END && flush == Z_FINISH) ++ { ++ /* This is the end of the IDAT data; any pending output must be ++ * flushed. For small PNG files we may still be at the beginning. ++ */ ++ png_bytep data = png_ptr->zbuffer_list->output; ++ uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; ++ ++#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED ++ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && ++ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) ++ optimize_cmf(data, png_image_size(png_ptr)); ++#endif ++ ++ png_write_complete_chunk(png_ptr, png_IDAT, data, size); ++ png_ptr->zstream.avail_out = 0; ++ png_ptr->zstream.next_out = NULL; ++ png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; ++ ++ png_ptr->zowner = 0; /* Release the stream */ ++ return; ++ } ++ + else +- png_error(png_ptr, +- "Invalid zlib compression method or flags in IDAT"); ++ { ++ /* This is an error condition. */ ++ png_zstream_error(png_ptr, ret); ++ png_error(png_ptr, png_ptr->zstream.msg); ++ } + } +-#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ +- +- png_write_chunk(png_ptr, png_IDAT, data, length); +- png_ptr->mode |= PNG_HAVE_IDAT; +- +- /* Prior to 1.5.4 this code was replicated in every caller (except at the +- * end, where it isn't technically necessary). Since this function has +- * flushed the data we can safely reset the zlib output buffer here. +- */ +- png_ptr->zstream.next_out = png_ptr->zbuf; +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + + /* Write an IEND chunk */ + void /* PRIVATE */ +-png_write_IEND(png_structp png_ptr) ++png_write_IEND(png_structrp png_ptr) + { +- PNG_IEND; +- + png_debug(1, "in png_write_IEND"); + +- png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); ++ png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); + png_ptr->mode |= PNG_HAVE_IEND; + } + + #ifdef PNG_WRITE_gAMA_SUPPORTED + /* Write a gAMA chunk */ + void /* PRIVATE */ +-png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) ++png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) + { +- PNG_gAMA; + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA"); + + /* file_gamma is saved in 1/100,000ths */ + png_save_uint_32(buf, (png_uint_32)file_gamma); +- png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); ++ png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); + } + #endif + + #ifdef PNG_WRITE_sRGB_SUPPORTED + /* Write a sRGB chunk */ + void /* PRIVATE */ +-png_write_sRGB(png_structp png_ptr, int srgb_intent) ++png_write_sRGB(png_structrp png_ptr, int srgb_intent) + { +- PNG_sRGB; + png_byte buf[1]; + + png_debug(1, "in png_write_sRGB"); +@@ -1096,104 +1210,79 @@ + "Invalid sRGB rendering intent specified"); + + buf[0]=(png_byte)srgb_intent; +- png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); ++ png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); + } + #endif + + #ifdef PNG_WRITE_iCCP_SUPPORTED + /* Write an iCCP chunk */ + void /* PRIVATE */ +-png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, +- png_const_charp profile, int profile_len) ++png_write_iCCP(png_structrp png_ptr, png_const_charp name, ++ png_const_bytep profile) + { +- PNG_iCCP; +- png_size_t name_len; +- png_charp new_name; ++ png_uint_32 name_len; ++ png_uint_32 profile_len; ++ png_byte new_name[81]; /* 1 byte for the compression byte */ + compression_state comp; +- int embedded_profile_len = 0; ++ png_uint_32 temp; + + png_debug(1, "in png_write_iCCP"); + +- comp.num_output_ptr = 0; +- comp.max_output_ptr = 0; +- comp.output_ptr = NULL; +- comp.input = NULL; +- comp.input_len = 0; +- +- if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) +- return; +- +- if (compression_type != PNG_COMPRESSION_TYPE_BASE) +- png_warning(png_ptr, "Unknown compression type in iCCP chunk"); +- ++ /* These are all internal problems: the profile should have been checked ++ * before when it was stored. ++ */ + if (profile == NULL) +- profile_len = 0; +- +- if (profile_len > 3) +- embedded_profile_len = +- ((*( (png_const_bytep)profile ))<<24) | +- ((*( (png_const_bytep)profile + 1))<<16) | +- ((*( (png_const_bytep)profile + 2))<< 8) | +- ((*( (png_const_bytep)profile + 3)) ); +- +- if (embedded_profile_len < 0) ++ png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ ++ ++ profile_len = png_get_uint_32(profile); ++ ++ if (profile_len < 132) ++ png_error(png_ptr, "ICC profile too short"); ++ ++ temp = (png_uint_32) (*(profile+8)); ++ if (temp > 3 && (profile_len & 0x03)) ++ png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); ++ + { +- png_warning(png_ptr, +- "Embedded profile length in iCCP chunk is negative"); +- +- png_free(png_ptr, new_name); +- return; ++ png_uint_32 embedded_profile_len = png_get_uint_32(profile); ++ ++ if (profile_len != embedded_profile_len) ++ png_error(png_ptr, "Profile length does not match profile"); + } + +- if (profile_len < embedded_profile_len) +- { +- png_warning(png_ptr, +- "Embedded profile length too large in iCCP chunk"); +- +- png_free(png_ptr, new_name); +- return; +- } +- +- if (profile_len > embedded_profile_len) +- { +- png_warning(png_ptr, +- "Truncating profile to actual length in iCCP chunk"); +- +- profile_len = embedded_profile_len; +- } +- +- if (profile_len) +- profile_len = png_text_compress(png_ptr, profile, +- (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); ++ name_len = png_check_keyword(png_ptr, name, new_name); ++ ++ if (name_len == 0) ++ png_error(png_ptr, "iCCP: invalid keyword"); ++ ++ new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; + + /* Make sure we include the NULL after the name and the compression type */ +- png_write_chunk_start(png_ptr, png_iCCP, +- (png_uint_32)(name_len + profile_len + 2)); +- +- new_name[name_len + 1] = 0x00; +- +- png_write_chunk_data(png_ptr, (png_bytep)new_name, +- (png_size_t)(name_len + 2)); +- +- if (profile_len) +- { +- comp.input_len = profile_len; +- png_write_compressed_data_out(png_ptr, &comp); +- } ++ ++name_len; ++ ++ png_text_compress_init(&comp, profile, profile_len); ++ ++ /* Allow for keyword terminator and compression byte */ ++ if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) ++ png_error(png_ptr, png_ptr->zstream.msg); ++ ++ png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); ++ ++ png_write_chunk_data(png_ptr, new_name, name_len); ++ ++ png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); +- png_free(png_ptr, new_name); + } + #endif + + #ifdef PNG_WRITE_sPLT_SUPPORTED + /* Write a sPLT chunk */ + void /* PRIVATE */ +-png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) ++png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) + { +- PNG_sPLT; +- png_size_t name_len; +- png_charp new_name; ++ png_uint_32 name_len; ++ png_byte new_name[80]; + png_byte entrybuf[10]; + png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); + png_size_t palette_size = entry_size * spalette->nentries; +@@ -1204,11 +1293,13 @@ + + png_debug(1, "in png_write_sPLT"); + +- if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) +- return; ++ name_len = png_check_keyword(png_ptr, spalette->name, new_name); ++ ++ if (name_len == 0) ++ png_error(png_ptr, "sPLT: invalid keyword"); + + /* Make sure we include the NULL after the name */ +- png_write_chunk_start(png_ptr, png_sPLT, ++ png_write_chunk_header(png_ptr, png_sPLT, + (png_uint_32)(name_len + 2 + palette_size)); + + png_write_chunk_data(png_ptr, (png_bytep)new_name, +@@ -1238,7 +1329,7 @@ + png_save_uint_16(entrybuf + 8, ep->frequency); + } + +- png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); ++ png_write_chunk_data(png_ptr, entrybuf, entry_size); + } + #else + ep=spalette->entries; +@@ -1262,28 +1353,26 @@ + png_save_uint_16(entrybuf + 8, ep[i].frequency); + } + +- png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); ++ png_write_chunk_data(png_ptr, entrybuf, entry_size); + } + #endif + + png_write_chunk_end(png_ptr); +- png_free(png_ptr, new_name); + } + #endif + + #ifdef PNG_WRITE_sBIT_SUPPORTED + /* Write the sBIT chunk */ + void /* PRIVATE */ +-png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) ++png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) + { +- PNG_sBIT; + png_byte buf[4]; + png_size_t size; + + png_debug(1, "in png_write_sBIT"); + + /* Make sure we don't depend upon the order of PNG_COLOR_8 */ +- if (color_type & PNG_COLOR_MASK_COLOR) ++ if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_byte maxbits; + +@@ -1316,7 +1405,7 @@ + size = 1; + } + +- if (color_type & PNG_COLOR_MASK_ALPHA) ++ if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) + { +@@ -1327,53 +1416,42 @@ + buf[size++] = sbit->alpha; + } + +- png_write_chunk(png_ptr, png_sBIT, buf, size); ++ png_write_complete_chunk(png_ptr, png_sBIT, buf, size); + } + #endif + + #ifdef PNG_WRITE_cHRM_SUPPORTED + /* Write the cHRM chunk */ + void /* PRIVATE */ +-png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, +- png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, +- png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, +- png_fixed_point blue_y) ++png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) + { +- PNG_cHRM; + png_byte buf[32]; + + png_debug(1, "in png_write_cHRM"); + + /* Each value is saved in 1/100,000ths */ +-#ifdef PNG_CHECK_cHRM_SUPPORTED +- if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, +- green_x, green_y, blue_x, blue_y)) +-#endif +- { +- png_save_uint_32(buf, (png_uint_32)white_x); +- png_save_uint_32(buf + 4, (png_uint_32)white_y); +- +- png_save_uint_32(buf + 8, (png_uint_32)red_x); +- png_save_uint_32(buf + 12, (png_uint_32)red_y); +- +- png_save_uint_32(buf + 16, (png_uint_32)green_x); +- png_save_uint_32(buf + 20, (png_uint_32)green_y); +- +- png_save_uint_32(buf + 24, (png_uint_32)blue_x); +- png_save_uint_32(buf + 28, (png_uint_32)blue_y); +- +- png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); +- } ++ png_save_int_32(buf, xy->whitex); ++ png_save_int_32(buf + 4, xy->whitey); ++ ++ png_save_int_32(buf + 8, xy->redx); ++ png_save_int_32(buf + 12, xy->redy); ++ ++ png_save_int_32(buf + 16, xy->greenx); ++ png_save_int_32(buf + 20, xy->greeny); ++ ++ png_save_int_32(buf + 24, xy->bluex); ++ png_save_int_32(buf + 28, xy->bluey); ++ ++ png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); + } + #endif + + #ifdef PNG_WRITE_tRNS_SUPPORTED + /* Write the tRNS chunk */ + void /* PRIVATE */ +-png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, ++png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, + png_const_color_16p tran, int num_trans, int color_type) + { +- PNG_tRNS; + png_byte buf[6]; + + png_debug(1, "in png_write_tRNS"); +@@ -1382,12 +1460,14 @@ + { + if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) + { +- png_warning(png_ptr, "Invalid number of transparent colors specified"); ++ png_app_warning(png_ptr, ++ "Invalid number of transparent colors specified"); + return; + } + + /* Write the chunk out as it is */ +- png_write_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); ++ png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, ++ (png_size_t)num_trans); + } + + else if (color_type == PNG_COLOR_TYPE_GRAY) +@@ -1395,14 +1475,14 @@ + /* One 16 bit value */ + if (tran->gray >= (1 << png_ptr->bit_depth)) + { +- png_warning(png_ptr, ++ png_app_warning(png_ptr, + "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + + return; + } + + png_save_uint_16(buf, tran->gray); +- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); ++ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); + } + + else if (color_type == PNG_COLOR_TYPE_RGB) +@@ -1412,22 +1492,22 @@ + png_save_uint_16(buf + 2, tran->green); + png_save_uint_16(buf + 4, tran->blue); + #ifdef PNG_WRITE_16BIT_SUPPORTED +- if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) ++ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) + #else +- if (buf[0] | buf[2] | buf[4]) ++ if ((buf[0] | buf[2] | buf[4]) != 0) + #endif + { +- png_warning(png_ptr, ++ png_app_warning(png_ptr, + "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); + return; + } + +- png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); ++ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); + } + + else + { +- png_warning(png_ptr, "Can't write tRNS with an alpha channel"); ++ png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); + } + } + #endif +@@ -1435,9 +1515,8 @@ + #ifdef PNG_WRITE_bKGD_SUPPORTED + /* Write the background chunk */ + void /* PRIVATE */ +-png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) ++png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) + { +- PNG_bKGD; + png_byte buf[6]; + + png_debug(1, "in png_write_bKGD"); +@@ -1446,8 +1525,8 @@ + { + if ( + #ifdef PNG_MNG_FEATURES_SUPPORTED +- (png_ptr->num_palette || +- (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && ++ (png_ptr->num_palette != 0 || ++ (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && + #endif + back->index >= png_ptr->num_palette) + { +@@ -1456,18 +1535,18 @@ + } + + buf[0] = back->index; +- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); ++ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); + } + +- else if (color_type & PNG_COLOR_MASK_COLOR) ++ else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_save_uint_16(buf, back->red); + png_save_uint_16(buf + 2, back->green); + png_save_uint_16(buf + 4, back->blue); + #ifdef PNG_WRITE_16BIT_SUPPORTED +- if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) ++ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) + #else +- if (buf[0] | buf[2] | buf[4]) ++ if ((buf[0] | buf[2] | buf[4]) != 0) + #endif + { + png_warning(png_ptr, +@@ -1476,7 +1555,7 @@ + return; + } + +- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); ++ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); + } + + else +@@ -1490,7 +1569,7 @@ + } + + png_save_uint_16(buf, back->gray); +- png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); ++ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); + } + } + #endif +@@ -1498,9 +1577,8 @@ + #ifdef PNG_WRITE_hIST_SUPPORTED + /* Write the histogram */ + void /* PRIVATE */ +-png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) ++png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) + { +- PNG_hIST; + int i; + png_byte buf[3]; + +@@ -1515,7 +1593,7 @@ + return; + } + +- png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); ++ png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); + + for (i = 0; i < num_hist; i++) + { +@@ -1527,236 +1605,93 @@ + } + #endif + +-#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ +- defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +-/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, +- * and if invalid, correct the keyword rather than discarding the entire +- * chunk. The PNG 1.0 specification requires keywords 1-79 characters in +- * length, forbids leading or trailing whitespace, multiple internal spaces, +- * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. +- * +- * The new_key is allocated to hold the corrected keyword and must be freed +- * by the calling routine. This avoids problems with trying to write to +- * static keywords without having to have duplicate copies of the strings. +- */ +-png_size_t /* PRIVATE */ +-png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key) +-{ +- png_size_t key_len; +- png_const_charp ikp; +- png_charp kp, dp; +- int kflag; +- int kwarn=0; +- +- png_debug(1, "in png_check_keyword"); +- +- *new_key = NULL; +- +- if (key == NULL || (key_len = png_strlen(key)) == 0) +- { +- png_warning(png_ptr, "zero length keyword"); +- return ((png_size_t)0); +- } +- +- png_debug1(2, "Keyword to be checked is '%s'", key); +- +- *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); +- +- if (*new_key == NULL) +- { +- png_warning(png_ptr, "Out of memory while procesing keyword"); +- return ((png_size_t)0); +- } +- +- /* Replace non-printing characters with a blank and print a warning */ +- for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) +- { +- if ((png_byte)*ikp < 0x20 || +- ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) +- { +- PNG_WARNING_PARAMETERS(p) +- +- png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x, +- (png_byte)*ikp); +- png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1"); +- *dp = ' '; +- } +- +- else +- { +- *dp = *ikp; +- } +- } +- *dp = '\0'; +- +- /* Remove any trailing white space. */ +- kp = *new_key + key_len - 1; +- if (*kp == ' ') +- { +- png_warning(png_ptr, "trailing spaces removed from keyword"); +- +- while (*kp == ' ') +- { +- *(kp--) = '\0'; +- key_len--; +- } +- } +- +- /* Remove any leading white space. */ +- kp = *new_key; +- if (*kp == ' ') +- { +- png_warning(png_ptr, "leading spaces removed from keyword"); +- +- while (*kp == ' ') +- { +- kp++; +- key_len--; +- } +- } +- +- png_debug1(2, "Checking for multiple internal spaces in '%s'", kp); +- +- /* Remove multiple internal spaces. */ +- for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) +- { +- if (*kp == ' ' && kflag == 0) +- { +- *(dp++) = *kp; +- kflag = 1; +- } +- +- else if (*kp == ' ') +- { +- key_len--; +- kwarn = 1; +- } +- +- else +- { +- *(dp++) = *kp; +- kflag = 0; +- } +- } +- *dp = '\0'; +- if (kwarn) +- png_warning(png_ptr, "extra interior spaces removed from keyword"); +- +- if (key_len == 0) +- { +- png_free(png_ptr, *new_key); +- png_warning(png_ptr, "Zero length keyword"); +- } +- +- if (key_len > 79) +- { +- png_warning(png_ptr, "keyword length must be 1 - 79 characters"); +- (*new_key)[79] = '\0'; +- key_len = 79; +- } +- +- return (key_len); +-} +-#endif +- + #ifdef PNG_WRITE_tEXt_SUPPORTED + /* Write a tEXt chunk */ + void /* PRIVATE */ +-png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, ++png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len) + { +- PNG_tEXt; +- png_size_t key_len; +- png_charp new_key; ++ png_uint_32 key_len; ++ png_byte new_key[80]; + + png_debug(1, "in png_write_tEXt"); + +- if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) +- return; ++ key_len = png_check_keyword(png_ptr, key, new_key); ++ ++ if (key_len == 0) ++ png_error(png_ptr, "tEXt: invalid keyword"); + + if (text == NULL || *text == '\0') + text_len = 0; + + else +- text_len = png_strlen(text); ++ text_len = strlen(text); ++ ++ if (text_len > PNG_UINT_31_MAX - (key_len+1)) ++ png_error(png_ptr, "tEXt: text too long"); + + /* Make sure we include the 0 after the key */ +- png_write_chunk_start(png_ptr, png_tEXt, +- (png_uint_32)(key_len + text_len + 1)); ++ png_write_chunk_header(png_ptr, png_tEXt, ++ (png_uint_32)/*checked above*/(key_len + text_len + 1)); + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ +- png_write_chunk_data(png_ptr, (png_bytep)new_key, +- (png_size_t)(key_len + 1)); +- +- if (text_len) +- png_write_chunk_data(png_ptr, (png_const_bytep)text, +- (png_size_t)text_len); ++ png_write_chunk_data(png_ptr, new_key, key_len + 1); ++ ++ if (text_len != 0) ++ png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); + + png_write_chunk_end(png_ptr); +- png_free(png_ptr, new_key); + } + #endif + + #ifdef PNG_WRITE_zTXt_SUPPORTED + /* Write a compressed text chunk */ + void /* PRIVATE */ +-png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, +- png_size_t text_len, int compression) ++png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, ++ int compression) + { +- PNG_zTXt; +- png_size_t key_len; +- png_byte buf; +- png_charp new_key; ++ png_uint_32 key_len; ++ png_byte new_key[81]; + compression_state comp; + + png_debug(1, "in png_write_zTXt"); + +- comp.num_output_ptr = 0; +- comp.max_output_ptr = 0; +- comp.output_ptr = NULL; +- comp.input = NULL; +- comp.input_len = 0; +- +- if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) ++ if (compression == PNG_TEXT_COMPRESSION_NONE) + { +- png_free(png_ptr, new_key); ++ png_write_tEXt(png_ptr, key, text, 0); + return; + } + +- if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) +- { +- png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); +- png_free(png_ptr, new_key); +- return; +- } +- +- text_len = png_strlen(text); ++ if (compression != PNG_TEXT_COMPRESSION_zTXt) ++ png_error(png_ptr, "zTXt: invalid compression type"); ++ ++ key_len = png_check_keyword(png_ptr, key, new_key); ++ ++ if (key_len == 0) ++ png_error(png_ptr, "zTXt: invalid keyword"); ++ ++ /* Add the compression method and 1 for the keyword separator. */ ++ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; ++ ++key_len; + + /* Compute the compressed data; do it now for the length */ +- text_len = png_text_compress(png_ptr, text, text_len, compression, +- &comp); ++ png_text_compress_init(&comp, (png_const_bytep)text, ++ text == NULL ? 0 : strlen(text)); ++ ++ if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) ++ png_error(png_ptr, png_ptr->zstream.msg); + + /* Write start of chunk */ +- png_write_chunk_start(png_ptr, png_zTXt, +- (png_uint_32)(key_len+text_len + 2)); ++ png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); + + /* Write key */ +- png_write_chunk_data(png_ptr, (png_bytep)new_key, +- (png_size_t)(key_len + 1)); +- +- png_free(png_ptr, new_key); +- +- buf = (png_byte)compression; +- +- /* Write compression */ +- png_write_chunk_data(png_ptr, &buf, (png_size_t)1); ++ png_write_chunk_data(png_ptr, new_key, key_len); + + /* Write the compressed data */ +- comp.input_len = text_len; + png_write_compressed_data_out(png_ptr, &comp); + + /* Close the chunk */ +@@ -1767,104 +1702,109 @@ + #ifdef PNG_WRITE_iTXt_SUPPORTED + /* Write an iTXt chunk */ + void /* PRIVATE */ +-png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, ++png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, + png_const_charp lang, png_const_charp lang_key, png_const_charp text) + { +- PNG_iTXt; +- png_size_t lang_len, key_len, lang_key_len, text_len; +- png_charp new_lang; +- png_charp new_key = NULL; +- png_byte cbuf[2]; ++ png_uint_32 key_len, prefix_len; ++ png_size_t lang_len, lang_key_len; ++ png_byte new_key[82]; + compression_state comp; + + png_debug(1, "in png_write_iTXt"); + +- comp.num_output_ptr = 0; +- comp.max_output_ptr = 0; +- comp.output_ptr = NULL; +- comp.input = NULL; +- +- if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) +- return; +- +- if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) ++ key_len = png_check_keyword(png_ptr, key, new_key); ++ ++ if (key_len == 0) ++ png_error(png_ptr, "iTXt: invalid keyword"); ++ ++ /* Set the compression flag */ ++ switch (compression) + { +- png_warning(png_ptr, "Empty language field in iTXt chunk"); +- new_lang = NULL; +- lang_len = 0; ++ case PNG_ITXT_COMPRESSION_NONE: ++ case PNG_TEXT_COMPRESSION_NONE: ++ compression = new_key[++key_len] = 0; /* no compression */ ++ break; ++ ++ case PNG_TEXT_COMPRESSION_zTXt: ++ case PNG_ITXT_COMPRESSION_zTXt: ++ compression = new_key[++key_len] = 1; /* compressed */ ++ break; ++ ++ default: ++ png_error(png_ptr, "iTXt: invalid compression"); + } + +- if (lang_key == NULL) +- lang_key_len = 0; +- +- else +- lang_key_len = png_strlen(lang_key); +- +- if (text == NULL) +- text_len = 0; +- +- else +- text_len = png_strlen(text); +- +- /* Compute the compressed data; do it now for the length */ +- text_len = png_text_compress(png_ptr, text, text_len, compression - 2, +- &comp); +- +- +- /* Make sure we include the compression flag, the compression byte, +- * and the NULs after the key, lang, and lang_key parts +- */ +- +- png_write_chunk_start(png_ptr, png_iTXt, (png_uint_32)( +- 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ +- + key_len +- + lang_len +- + lang_key_len +- + text_len)); ++ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; ++ ++key_len; /* for the keywod separator */ + + /* We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of +- * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. ++ * any non-Latin-1 characters except for NEWLINE. ISO PNG, however, ++ * specifies that the text is UTF-8 and this really doesn't require any ++ * checking. ++ * + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. ++ * ++ * TODO: validate the language tag correctly (see the spec.) + */ +- png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); +- +- /* Set the compression flag */ +- if (compression == PNG_ITXT_COMPRESSION_NONE || +- compression == PNG_TEXT_COMPRESSION_NONE) +- cbuf[0] = 0; +- +- else /* compression == PNG_ITXT_COMPRESSION_zTXt */ +- cbuf[0] = 1; +- +- /* Set the compression method */ +- cbuf[1] = 0; +- +- png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); +- +- cbuf[0] = 0; +- png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), +- (png_size_t)(lang_len + 1)); +- +- png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), +- (png_size_t)(lang_key_len + 1)); +- +- png_write_compressed_data_out(png_ptr, &comp); ++ if (lang == NULL) lang = ""; /* empty language is valid */ ++ lang_len = strlen(lang)+1; ++ if (lang_key == NULL) lang_key = ""; /* may be empty */ ++ lang_key_len = strlen(lang_key)+1; ++ if (text == NULL) text = ""; /* may be empty */ ++ ++ prefix_len = key_len; ++ if (lang_len > PNG_UINT_31_MAX-prefix_len) ++ prefix_len = PNG_UINT_31_MAX; ++ else ++ prefix_len = (png_uint_32)(prefix_len + lang_len); ++ ++ if (lang_key_len > PNG_UINT_31_MAX-prefix_len) ++ prefix_len = PNG_UINT_31_MAX; ++ else ++ prefix_len = (png_uint_32)(prefix_len + lang_key_len); ++ ++ png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); ++ ++ if (compression != 0) ++ { ++ if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) ++ png_error(png_ptr, png_ptr->zstream.msg); ++ } ++ ++ else ++ { ++ if (comp.input_len > PNG_UINT_31_MAX-prefix_len) ++ png_error(png_ptr, "iTXt: uncompressed text too long"); ++ ++ /* So the string will fit in a chunk: */ ++ comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; ++ } ++ ++ png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); ++ ++ png_write_chunk_data(png_ptr, new_key, key_len); ++ ++ png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); ++ ++ png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); ++ ++ if (compression != 0) ++ png_write_compressed_data_out(png_ptr, &comp); ++ ++ else ++ png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len); + + png_write_chunk_end(png_ptr); +- +- png_free(png_ptr, new_key); +- png_free(png_ptr, new_lang); + } + #endif + + #ifdef PNG_WRITE_oFFs_SUPPORTED + /* Write the oFFs chunk */ + void /* PRIVATE */ +-png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, ++png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, + int unit_type) + { +- PNG_oFFs; + png_byte buf[9]; + + png_debug(1, "in png_write_oFFs"); +@@ -1876,52 +1816,57 @@ + png_save_int_32(buf + 4, y_offset); + buf[8] = (png_byte)unit_type; + +- png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); ++ png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); + } + #endif + #ifdef PNG_WRITE_pCAL_SUPPORTED + /* Write the pCAL chunk (described in the PNG extensions document) */ + void /* PRIVATE */ +-png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, ++png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, + png_int_32 X1, int type, int nparams, png_const_charp units, + png_charpp params) + { +- PNG_pCAL; +- png_size_t purpose_len, units_len, total_len; +- png_uint_32p params_len; ++ png_uint_32 purpose_len; ++ png_size_t units_len, total_len; ++ png_size_tp params_len; + png_byte buf[10]; +- png_charp new_purpose; ++ png_byte new_purpose[80]; + int i; + + png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); + + if (type >= PNG_EQUATION_LAST) +- png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); +- +- purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; ++ png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); ++ ++ purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); ++ ++ if (purpose_len == 0) ++ png_error(png_ptr, "pCAL: invalid keyword"); ++ ++ ++purpose_len; /* terminator */ ++ + png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); +- units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); ++ units_len = strlen(units) + (nparams == 0 ? 0 : 1); + png_debug1(3, "pCAL units length = %d", (int)units_len); + total_len = purpose_len + units_len + 10; + +- params_len = (png_uint_32p)png_malloc(png_ptr, +- (png_alloc_size_t)(nparams * png_sizeof(png_uint_32))); ++ params_len = (png_size_tp)png_malloc(png_ptr, ++ (png_alloc_size_t)(nparams * (sizeof (png_size_t)))); + + /* Find the length of each parameter, making sure we don't count the + * null terminator for the last parameter. + */ + for (i = 0; i < nparams; i++) + { +- params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); ++ params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); + png_debug2(3, "pCAL parameter %d length = %lu", i, + (unsigned long)params_len[i]); +- total_len += (png_size_t)params_len[i]; ++ total_len += params_len[i]; + } + + png_debug1(3, "pCAL total length = %d", (int)total_len); +- png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); +- png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, +- (png_size_t)purpose_len); ++ png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); ++ png_write_chunk_data(png_ptr, new_purpose, purpose_len); + png_save_int_32(buf, X0); + png_save_int_32(buf + 4, X1); + buf[8] = (png_byte)type; +@@ -1929,12 +1874,9 @@ + png_write_chunk_data(png_ptr, buf, (png_size_t)10); + png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); + +- png_free(png_ptr, new_purpose); +- + for (i = 0; i < nparams; i++) + { +- png_write_chunk_data(png_ptr, (png_const_bytep)params[i], +- (png_size_t)params_len[i]); ++ png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); + } + + png_free(png_ptr, params_len); +@@ -1945,17 +1887,16 @@ + #ifdef PNG_WRITE_sCAL_SUPPORTED + /* Write the sCAL chunk */ + void /* PRIVATE */ +-png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, ++png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, + png_const_charp height) + { +- PNG_sCAL; + png_byte buf[64]; + png_size_t wlen, hlen, total_len; + + png_debug(1, "in png_write_sCAL_s"); + +- wlen = png_strlen(width); +- hlen = png_strlen(height); ++ wlen = strlen(width); ++ hlen = strlen(height); + total_len = wlen + hlen + 2; + + if (total_len > 64) +@@ -1965,22 +1906,21 @@ + } + + buf[0] = (png_byte)unit; +- png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ +- png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ ++ memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ ++ memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ + + png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); +- png_write_chunk(png_ptr, png_sCAL, buf, total_len); ++ png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); + } + #endif + + #ifdef PNG_WRITE_pHYs_SUPPORTED + /* Write the pHYs chunk */ + void /* PRIVATE */ +-png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, ++png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, + png_uint_32 y_pixels_per_unit, + int unit_type) + { +- PNG_pHYs; + png_byte buf[9]; + + png_debug(1, "in png_write_pHYs"); +@@ -1992,7 +1932,7 @@ + png_save_uint_32(buf + 4, y_pixels_per_unit); + buf[8] = (png_byte)unit_type; + +- png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); ++ png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); + } + #endif + +@@ -2001,9 +1941,8 @@ + * or png_convert_from_time_t(), or fill in the structure yourself. + */ + void /* PRIVATE */ +-png_write_tIME(png_structp png_ptr, png_const_timep mod_time) ++png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) + { +- PNG_tIME; + png_byte buf[7]; + + png_debug(1, "in png_write_tIME"); +@@ -2023,40 +1962,44 @@ + buf[5] = mod_time->minute; + buf[6] = mod_time->second; + +- png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); ++ png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); + } + #endif + + /* Initializes the row writing capability of libpng */ + void /* PRIVATE */ +-png_write_start_row(png_structp png_ptr) ++png_write_start_row(png_structrp png_ptr) + { + #ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ +- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; ++ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ +- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ +- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; ++ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ +- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; ++ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + #endif + +- png_size_t buf_size; ++ png_alloc_size_t buf_size; ++ int usr_pixel_depth; + + png_debug(1, "in png_write_start_row"); + +- buf_size = (png_size_t)(PNG_ROWBYTES( +- png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); ++ usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; ++ buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; ++ ++ /* 1.5.6: added to allow checking in the row write code. */ ++ png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; ++ png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; + + /* Set up row buffer */ +- png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, +- (png_alloc_size_t)buf_size); ++ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); + + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; + +@@ -2070,13 +2013,13 @@ + } + + /* We only need to keep the previous row if we are using one of these. */ +- if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) ++ if ((png_ptr->do_filter & ++ (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) + { + /* Set up previous row buffer */ +- png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, +- (png_alloc_size_t)buf_size); +- +- if (png_ptr->do_filter & PNG_FILTER_UP) ++ png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); ++ ++ if ((png_ptr->do_filter & PNG_FILTER_UP) != 0) + { + png_ptr->up_row = (png_bytep)png_malloc(png_ptr, + png_ptr->rowbytes + 1); +@@ -2084,7 +2027,7 @@ + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; + } + +- if (png_ptr->do_filter & PNG_FILTER_AVG) ++ if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0) + { + png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, + png_ptr->rowbytes + 1); +@@ -2092,7 +2035,7 @@ + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; + } + +- if (png_ptr->do_filter & PNG_FILTER_PAETH) ++ if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0) + { + png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, + png_ptr->rowbytes + 1); +@@ -2100,13 +2043,13 @@ + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; + } + } +-#endif /* PNG_WRITE_FILTER_SUPPORTED */ ++#endif /* WRITE_FILTER */ + + #ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced, we need to set up width and height of pass */ +- if (png_ptr->interlaced) ++ if (png_ptr->interlaced != 0) + { +- if (!(png_ptr->transformations & PNG_INTERLACE)) ++ if ((png_ptr->transformations & PNG_INTERLACE) == 0) + { + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; +@@ -2128,34 +2071,28 @@ + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } +- +- png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT); +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +- png_ptr->zstream.next_out = png_ptr->zbuf; + } + + /* Internal use only. Called when finished processing a row of data. */ + void /* PRIVATE */ +-png_write_finish_row(png_structp png_ptr) ++png_write_finish_row(png_structrp png_ptr) + { + #ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ +- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; ++ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ +- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* Start of interlace block in the y direction */ +- int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; ++ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* Offset to next interlace block in the y direction */ +- int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; ++ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + #endif + +- int ret; +- + png_debug(1, "in png_write_finish_row"); + + /* Next row */ +@@ -2167,10 +2104,10 @@ + + #ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced, go to next pass */ +- if (png_ptr->interlaced) ++ if (png_ptr->interlaced != 0) + { + png_ptr->row_number = 0; +- if (png_ptr->transformations & PNG_INTERLACE) ++ if ((png_ptr->transformations & PNG_INTERLACE) != 0) + { + png_ptr->pass++; + } +@@ -2195,7 +2132,7 @@ + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + +- if (png_ptr->transformations & PNG_INTERLACE) ++ if ((png_ptr->transformations & PNG_INTERLACE) != 0) + break; + + } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); +@@ -2206,7 +2143,7 @@ + if (png_ptr->pass < 7) + { + if (png_ptr->prev_row != NULL) +- png_memset(png_ptr->prev_row, 0, ++ memset(png_ptr->prev_row, 0, + (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* + png_ptr->usr_bit_depth, png_ptr->width)) + 1); + +@@ -2217,42 +2154,7 @@ + + /* If we get here, we've just written the last row, so we need + to flush the compressor */ +- do +- { +- /* Tell the compressor we are done */ +- ret = deflate(&png_ptr->zstream, Z_FINISH); +- +- /* Check for an error */ +- if (ret == Z_OK) +- { +- /* Check to see if we need more room */ +- if (!(png_ptr->zstream.avail_out)) +- { +- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); +- png_ptr->zstream.next_out = png_ptr->zbuf; +- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; +- } +- } +- +- else if (ret != Z_STREAM_END) +- { +- if (png_ptr->zstream.msg != NULL) +- png_error(png_ptr, png_ptr->zstream.msg); +- +- else +- png_error(png_ptr, "zlib error"); +- } +- } while (ret != Z_STREAM_END); +- +- /* Write any extra space */ +- if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) +- { +- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - +- png_ptr->zstream.avail_out); +- } +- +- png_zlib_release(png_ptr); +- png_ptr->zstream.data_type = Z_BINARY; ++ png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); + } + + #ifdef PNG_WRITE_INTERLACING_SUPPORTED +@@ -2269,10 +2171,10 @@ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* Start of interlace block */ +- int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; ++ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* Offset to next interlace block */ +- int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; ++ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + png_debug(1, "in png_do_write_interlace"); + +@@ -2416,7 +2318,7 @@ + + /* Move the pixel */ + if (dp != sp) +- png_memcpy(dp, sp, pixel_bytes); ++ memcpy(dp, sp, pixel_bytes); + + /* Next pixel */ + dp += pixel_bytes; +@@ -2440,14 +2342,16 @@ + * been specified by the application, and then writes the row out with the + * chosen filter. + */ +-static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row); ++static void ++png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, ++ png_size_t row_bytes); + + #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) + #define PNG_HISHIFT 10 + #define PNG_LOMASK ((png_uint_32)0xffffL) + #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) + void /* PRIVATE */ +-png_write_find_filter(png_structp png_ptr, png_row_infop row_info) ++png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) + { + png_bytep best_row; + #ifdef PNG_WRITE_FILTER_SUPPORTED +@@ -2456,7 +2360,7 @@ + png_byte filter_to_do = png_ptr->do_filter; + png_size_t row_bytes = row_info->rowbytes; + #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +- int num_p_filters = (int)png_ptr->num_prev_filters; ++ int num_p_filters = png_ptr->num_prev_filters; + #endif + + png_debug(1, "in png_write_find_filter"); +@@ -2507,7 +2411,7 @@ + /* We don't need to test the 'no filter' case if this is the only filter + * that has been chosen, as it doesn't actually do anything to the data. + */ +- if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) ++ if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE) + { + png_bytep rp; + png_uint_32 sum = 0; +@@ -2583,7 +2487,7 @@ + best_row = png_ptr->sub_row; + } + +- else if (filter_to_do & PNG_FILTER_SUB) ++ else if ((filter_to_do & PNG_FILTER_SUB) != 0) + { + png_bytep rp, dp, lp; + png_uint_32 sum = 0, lmins = mins; +@@ -2704,7 +2608,7 @@ + best_row = png_ptr->up_row; + } + +- else if (filter_to_do & PNG_FILTER_UP) ++ else if ((filter_to_do & PNG_FILTER_UP) != 0) + { + png_bytep rp, dp, pp; + png_uint_32 sum = 0, lmins = mins; +@@ -2818,7 +2722,7 @@ + best_row = png_ptr->avg_row; + } + +- else if (filter_to_do & PNG_FILTER_AVG) ++ else if ((filter_to_do & PNG_FILTER_AVG) != 0) + { + png_bytep rp, dp, pp, lp; + png_uint_32 sum = 0, lmins = mins; +@@ -2920,7 +2824,7 @@ + } + + /* Paeth filter */ +- if (filter_to_do == PNG_FILTER_PAETH) ++ if ((filter_to_do == PNG_FILTER_PAETH) != 0) + { + png_bytep rp, dp, pp, cp, lp; + png_size_t i; +@@ -2959,7 +2863,7 @@ + best_row = png_ptr->paeth_row; + } + +- else if (filter_to_do & PNG_FILTER_PAETH) ++ else if ((filter_to_do & PNG_FILTER_PAETH) != 0) + { + png_bytep rp, dp, pp, cp, lp; + png_uint_32 sum = 0, lmins = mins; +@@ -3029,7 +2933,7 @@ + pc = (p + pc) < 0 ? -(p + pc) : p + pc; + #endif + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; +-#else /* PNG_SLOW_PAETH */ ++#else /* SLOW_PAETH */ + p = a + b - c; + pa = abs(p - a); + pb = abs(p - b); +@@ -3043,7 +2947,7 @@ + + else + p = c; +-#endif /* PNG_SLOW_PAETH */ ++#endif /* SLOW_PAETH */ + + v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + +@@ -3092,10 +2996,10 @@ + best_row = png_ptr->paeth_row; + } + } +-#endif /* PNG_WRITE_FILTER_SUPPORTED */ ++#endif /* WRITE_FILTER */ ++ + /* Do the actual writing of the filtered row data from the chosen filter. */ +- +- png_write_filtered_row(png_ptr, best_row); ++ png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); + + #ifdef PNG_WRITE_FILTER_SUPPORTED + #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +@@ -3112,74 +3016,20 @@ + png_ptr->prev_filters[j] = best_row[0]; + } + #endif +-#endif /* PNG_WRITE_FILTER_SUPPORTED */ ++#endif /* WRITE_FILTER */ + } + + + /* Do the actual writing of a previously filtered row. */ + static void +-png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) ++png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, ++ png_size_t full_row_length/*includes filter byte*/) + { +- png_size_t avail; +- + png_debug(1, "in png_write_filtered_row"); + + png_debug1(2, "filter = %d", filtered_row[0]); +- /* Set up the zlib input buffer */ +- +- png_ptr->zstream.next_in = filtered_row; +- png_ptr->zstream.avail_in = 0; +- avail = png_ptr->row_info.rowbytes + 1; +- /* Repeat until we have compressed all the data */ +- do +- { +- int ret; /* Return of zlib */ +- +- /* Record the number of bytes available - zlib supports at least 65535 +- * bytes at one step, depending on the size of the zlib type 'uInt', the +- * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). +- * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. +- * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a +- * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called +- * with smaller chunks of data. +- */ +- if (png_ptr->zstream.avail_in == 0) +- { +- if (avail > ZLIB_IO_MAX) +- { +- png_ptr->zstream.avail_in = ZLIB_IO_MAX; +- avail -= ZLIB_IO_MAX; +- } +- +- else +- { +- /* So this will fit in the available uInt space: */ +- png_ptr->zstream.avail_in = (uInt)avail; +- avail = 0; +- } +- } +- +- /* Compress the data */ +- ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); +- +- /* Check for compression errors */ +- if (ret != Z_OK) +- { +- if (png_ptr->zstream.msg != NULL) +- png_error(png_ptr, png_ptr->zstream.msg); +- +- else +- png_error(png_ptr, "zlib error"); +- } +- +- /* See if it is time to write another IDAT */ +- if (!(png_ptr->zstream.avail_out)) +- { +- /* Write the IDAT and reset the zlib output buffer */ +- png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); +- } +- /* Repeat until all data has been compressed */ +- } while (avail > 0 || png_ptr->zstream.avail_in > 0); ++ ++ png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); + + /* Swap the current and previous rows */ + if (png_ptr->prev_row != NULL) +@@ -3202,6 +3052,6 @@ + { + png_write_flush(png_ptr); + } +-#endif ++#endif /* WRITE_FLUSH */ + } +-#endif /* PNG_WRITE_SUPPORTED */ ++#endif /* WRITE */ +--- ./jdk/src/share/native/sun/font/layout/LETableReference.h Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/font/layout/LETableReference.h Thu Feb 05 13:00:26 2015 +0100 +@@ -150,8 +150,8 @@ + if(isEmpty()) { + //err = LE_MISSING_FONT_TABLE_ERROR; + clear(); // it's just empty. Not an error. +- } else if(offset >= fParent->fLength) { +- LE_DEBUG_TR3("offset out of range: (%p) +%d", NULL, offset); ++ } else if(offset >= fParent->fLength || (offset & 0x01)) { ++ LE_DEBUG_TR3("offset out of range or odd alignment: (%p) +%d", NULL, offset); + err = LE_INDEX_OUT_OF_BOUNDS_ERROR; + clear(); + } else { +--- ./jdk/src/share/native/sun/font/layout/LigatureSubstProc.cpp Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/font/layout/LigatureSubstProc.cpp Thu Feb 05 13:00:26 2015 +0100 +@@ -115,7 +115,7 @@ + LE_DEBUG_BAD_FONT("off end of ligature substitution header"); + return newState; // get out! bad font + } +- if(componentGlyph > glyphStorage.getGlyphCount()) { ++ if(componentGlyph >= glyphStorage.getGlyphCount()) { + LE_DEBUG_BAD_FONT("preposterous componentGlyph"); + currGlyph++; + return newState; // get out! bad font +--- ./jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Thu Feb 05 13:00:26 2015 +0100 +@@ -119,7 +119,7 @@ + + offset = action & lafComponentOffsetMask; + if (offset != 0) { +- if(componentGlyph > glyphStorage.getGlyphCount()) { ++ if(componentGlyph >= glyphStorage.getGlyphCount()) { + LE_DEBUG_BAD_FONT("preposterous componentGlyph"); + currGlyph+= dir; + return nextStateIndex; // get out! bad font +--- ./jdk/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Thu Feb 05 13:00:26 2015 +0100 +@@ -58,7 +58,7 @@ + if( LE_FAILURE(success) ) { return 0; } + le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount); + +- LEReferenceTo<Offset> ligatureTableOffsetArray(base, success, ligSetTable->ligatureTableOffsetArray, ligCount); ++ LEReferenceToArrayOf<Offset> ligatureTableOffsetArray(base, success, ligSetTable->ligatureTableOffsetArray, ligCount); + for (le_uint16 lig = 0; LE_SUCCESS(success) && lig < ligCount; lig += 1) { + Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]); + LEReferenceTo<LigatureTable> ligTable(ligSetTable, success, ligTableOffset); +--- ./jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/font/layout/LookupProcessor.cpp Thu Feb 05 13:00:26 2015 +0100 +@@ -255,6 +255,7 @@ + + if (requiredFeatureIndex != 0xFFFF) { + requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success); ++ if (LE_FAILURE(success)) return; + featureReferences += SWAPW(requiredFeatureTable->lookupCount); + } + +@@ -292,7 +293,7 @@ + } + + featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success); +- ++ if (LE_FAILURE(success)) continue; + if (featureTag == fm.tag) { + count += selectLookups(featureTable, fm.mask, order + count, success); + } +@@ -319,7 +320,7 @@ + #endif + + featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success); +- ++ if (LE_FAILURE(success)) continue; + if (featureTag == fm.tag) { + order += selectLookups(featureTable, fm.mask, order, success); + } +--- ./jdk/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Thu Feb 05 13:00:26 2015 +0100 +@@ -71,7 +71,12 @@ + if (coverageIndex >= 0 && coverageIndex < seqCount) { + Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]); + LEReferenceTo<SequenceTable> sequenceTable(base, success, sequenceTableOffset); ++ if (LE_FAILURE(success)) { ++ return 0; ++ } + le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount); ++ LEReferenceToArrayOf<Offset> ++ substituteArrayRef(base, success, sequenceTable->substituteArray, glyphCount); + + if (glyphCount == 0) { + glyphIterator->setCurrGlyphID(0xFFFF); +--- ./jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_sys.c Thu Feb 05 13:00:26 2015 +0100 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it +@@ -281,9 +281,7 @@ + /* for changing the visible shape of a window to an nonrectangular form */ + void + SplashUpdateShape(Splash * splash) { +- if (!shapeSupported) +- return; +- if (!splash->maskRequired) { ++ if (splash->currentFrame < 0 || !shapeSupported || !splash->maskRequired) { + return; + } + XShapeCombineRectangles(splash->display, splash->window, ShapeClip, 0, 0, +@@ -324,6 +322,10 @@ + + void + SplashRedrawWindow(Splash * splash) { ++ if (splash->currentFrame < 0) { ++ return; ++ } ++ + XImage *ximage; + + // making this method redraw a part of the image does not make +--- ./jdk/test/Makefile Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/Makefile Thu Feb 05 13:00:26 2015 +0100 +@@ -262,8 +262,8 @@ + EXTRA_JTREG_OPTIONS += -concurrency:$(CONCURRENCY) + endif + +-# Default JTREG to run (win32 script works for everybody) +-JTREG = $(JT_HOME)/win32/bin/jtreg ++# Default JTREG to run ++JTREG = $(JT_HOME)/bin/jtreg + # run in agentvm mode + JTREG_BASIC_OPTIONS += -agentvm + # Only run automatic tests +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ ./jdk/test/java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java Thu Feb 05 13:00:26 2015 +0100 +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++import java.awt.Color; ++import java.awt.Font; ++import java.awt.Graphics2D; ++import java.awt.RenderingHints; ++import java.awt.geom.AffineTransform; ++import java.awt.image.BufferedImage; ++import java.io.File; ++import java.io.IOException; ++ ++import javax.imageio.ImageIO; ++ ++import static java.awt.image.BufferedImage.TYPE_INT_RGB; ++import static java.lang.Math.toRadians; ++ ++/** ++ * @test ++ * @bug 8065373 ++ * @summary Verifies that we get correct direction, when draw rotated string. ++ * @author Sergey Bylokhov ++ * @run main DrawRotatedStringUsingRotatedFont ++ */ ++public final class DrawRotatedStringUsingRotatedFont { ++ ++ private static final int SIZE = 500; ++ private static final String STR = "MMMMMMMMMMMMMMMM"; ++ ++ private static AffineTransform[] txs = { ++ AffineTransform.getRotateInstance(toRadians(00)), ++ AffineTransform.getRotateInstance(toRadians(45)), ++ AffineTransform.getRotateInstance(toRadians(-45)), ++ AffineTransform.getRotateInstance(toRadians(90)), ++ AffineTransform.getRotateInstance(toRadians(-90)), ++ AffineTransform.getRotateInstance(toRadians(135)), ++ AffineTransform.getRotateInstance(toRadians(-135)), ++ AffineTransform.getRotateInstance(toRadians(180)), ++ AffineTransform.getRotateInstance(toRadians(-180)), ++ AffineTransform.getRotateInstance(toRadians(225)), ++ AffineTransform.getRotateInstance(toRadians(-225)), ++ AffineTransform.getRotateInstance(toRadians(270)), ++ AffineTransform.getRotateInstance(toRadians(-270)), ++ AffineTransform.getRotateInstance(toRadians(315)), ++ AffineTransform.getRotateInstance(toRadians(-315)), ++ AffineTransform.getRotateInstance(toRadians(360)), ++ AffineTransform.getRotateInstance(toRadians(-360)) ++ }; ++ ++ public static void main(final String[] args) throws IOException { ++ for (final AffineTransform tx2 : txs) { ++ for (final AffineTransform tx1 : txs) { ++ for (final boolean aa : new boolean[]{true, false}) { ++ final BufferedImage bi1 = createImage(aa, tx1, tx2); ++ final BufferedImage bi2 = createImage(aa, tx2, tx1); ++ compareImage(bi1, bi2); ++ fillTextArea(bi1, tx1, tx2); ++ fillTextArea(bi2, tx2, tx1); ++ checkColors(bi1, bi2); ++ } ++ } ++ } ++ System.out.println("Passed"); ++ } ++ ++ /** ++ * Compares two images. ++ */ ++ private static void compareImage(final BufferedImage bi1, ++ final BufferedImage bi2) ++ throws IOException { ++ for (int i = 0; i < SIZE; ++i) { ++ for (int j = 0; j < SIZE; ++j) { ++ if (bi1.getRGB(i, j) != bi2.getRGB(i, j)) { ++ ImageIO.write(bi1, "png", new File("image1.png")); ++ ImageIO.write(bi2, "png", new File("image2.png")); ++ throw new RuntimeException("Failed: wrong text location"); ++ } ++ } ++ } ++ } ++ ++ /** ++ * Checks an image color. RED and GREEN are allowed only. ++ */ ++ private static void checkColors(final BufferedImage bi1, ++ final BufferedImage bi2) ++ throws IOException { ++ for (int i = 0; i < SIZE; ++i) { ++ for (int j = 0; j < SIZE; ++j) { ++ final int rgb1 = bi1.getRGB(i, j); ++ final int rgb2 = bi2.getRGB(i, j); ++ if (rgb1 != rgb2 || rgb1 != 0xFFFF0000 && rgb1 != 0xFF00FF00) { ++ ImageIO.write(bi1, "png", new File("image1.png")); ++ ImageIO.write(bi2, "png", new File("image2.png")); ++ throw new RuntimeException("Failed: wrong text location"); ++ } ++ } ++ } ++ } ++ ++ /** ++ * Creates an BufferedImage and draws a text, using two transformations, ++ * one for graphics and one for font. ++ */ ++ private static BufferedImage createImage(final boolean aa, ++ final AffineTransform gtx, ++ final AffineTransform ftx) { ++ final BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_RGB); ++ final Graphics2D bg = bi.createGraphics(); ++ bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, ++ aa ? RenderingHints.VALUE_ANTIALIAS_ON ++ : RenderingHints.VALUE_ANTIALIAS_OFF); ++ bg.setColor(Color.RED); ++ bg.fillRect(0, 0, SIZE, SIZE); ++ bg.translate(100, 100); ++ bg.transform(gtx); ++ bg.setColor(Color.BLACK); ++ bg.setFont(bg.getFont().deriveFont(20.0f).deriveFont(ftx)); ++ bg.drawString(STR, 0, 0); ++ bg.dispose(); ++ return bi; ++ } ++ ++ /** ++ * Fills the area of text using green solid color. ++ */ ++ private static void fillTextArea(final BufferedImage bi, ++ final AffineTransform tx1, ++ final AffineTransform tx2) { ++ final Graphics2D bg = bi.createGraphics(); ++ bg.translate(100, 100); ++ bg.transform(tx1); ++ bg.transform(tx2); ++ bg.setColor(Color.GREEN); ++ final Font font = bg.getFont().deriveFont(20.0f); ++ bg.setFont(font); ++ bg.fill(font.getStringBounds(STR, bg.getFontRenderContext())); ++ bg.dispose(); ++ } ++} ++ +--- ./jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Thu Feb 05 13:00:26 2015 +0100 +@@ -36,7 +36,7 @@ + import sun.java2d.SunGraphics2D; + + /** +- * @test ++ * test + * @bug 8043869 + * @author Alexander Scherbatiy + * @summary [macosx] java -splash does not honor 2x hi dpi notation for retina +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ ./jdk/test/java/net/Socks/BadProxySelector.java Thu Feb 05 13:00:26 2015 +0100 +@@ -0,0 +1,85 @@ ++/* ++ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/* ++ * @test ++ * @bug 7178362 ++ * @run main/othervm BadProxySelector ++ */ ++ ++import java.net.InetSocketAddress; ++import java.net.Proxy; ++import java.net.ProxySelector; ++import java.net.Socket; ++import java.net.SocketAddress; ++import java.net.ServerSocket; ++import java.net.URI; ++import java.util.ArrayList; ++import java.util.List; ++import java.io.*; ++ ++public class BadProxySelector { ++ public static void main(String[] args) throws Exception { ++ ProxySelector.setDefault(new HTTPProxySelector()); ++ try (ServerSocket ss = new ServerSocket(0); ++ Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); ++ Socket s2 = ss.accept()) { ++ } ++ ++ ProxySelector.setDefault(new NullHTTPProxySelector()); ++ try (ServerSocket ss = new ServerSocket(0); ++ Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); ++ Socket s2 = ss.accept()) { ++ } ++ } ++ ++ // always returns bogus HTTP proxies ++ private static class HTTPProxySelector extends ProxySelector { ++ @Override ++ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {} ++ ++ @Override ++ public List<Proxy> select(URI uri) { ++ List<Proxy> proxies = new ArrayList<>(); ++ proxies.add(new Proxy(Proxy.Type.HTTP, ++ new InetSocketAddress("localhost", 0))); ++ proxies.add(new Proxy(Proxy.Type.HTTP, ++ new InetSocketAddress("localhost", 0))); ++ return proxies; ++ } ++ } ++ ++ private static class NullHTTPProxySelector extends ProxySelector { ++ @Override ++ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {} ++ ++ @Override ++ public List<Proxy> select(URI uri) { ++ List<Proxy> proxies = new ArrayList<>(); ++ proxies.add(null); ++ proxies.add(new Proxy(Proxy.Type.HTTP, ++ new InetSocketAddress("localhost", 0))); ++ return proxies; ++ } ++ } ++} +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ ./jdk/test/javax/xml/jaxp/transform/8062923/XslSubstringTest.java Thu Feb 05 13:00:26 2015 +0100 +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/** ++ * @test ++ * @bug 8062923 8062924 ++ * @run testng XslSubstringTest ++ * @summary Test xsl substring function with negative, Inf and ++ * NaN length and few other use cases ++ */ ++ ++import java.io.StringReader; ++import java.io.StringWriter; ++import javax.xml.transform.Source; ++import javax.xml.transform.Templates; ++import javax.xml.transform.Transformer; ++import javax.xml.transform.TransformerFactory; ++import javax.xml.transform.stream.StreamResult; ++import javax.xml.transform.stream.StreamSource; ++ ++import static org.testng.Assert.assertEquals; ++import org.testng.annotations.Test; ++ ++public class XslSubstringTest { ++ ++ final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test></test>"; ++ final String xslPre = "<xsl:stylesheet version='1.0'" ++ + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" ++ + "<xsl:output method='xml' indent='yes' omit-xml-declaration='yes'/>" ++ + "<xsl:template match='/'><t>"; ++ final String xslPost = "</t></xsl:template></xsl:stylesheet>"; ++ ++ private String testTransform(String xsl) throws Exception { ++ //Prepare sources for transormation ++ Source src = new StreamSource(new StringReader(xml)); ++ Source xslsrc = new StreamSource(new StringReader(xslPre + xsl + xslPost)); ++ //Create factory, template and transformer ++ TransformerFactory tf = TransformerFactory.newInstance(); ++ Templates tmpl = tf.newTemplates(xslsrc); ++ Transformer t = tmpl.newTransformer(); ++ //Prepare output stream ++ StringWriter xmlResultString = new StringWriter(); ++ StreamResult xmlResultStream = new StreamResult(xmlResultString); ++ //Transform ++ t.transform(src, xmlResultStream); ++ return xmlResultString.toString().trim(); ++ } ++ ++ @Test ++ public void test8062923() throws Exception { ++ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1)\"/>|"), ++ "<t>||</t>"); ++ } ++ ++ @Test ++ public void test8062924() throws Exception { ++ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1 div 0)\"/>|"), ++ "<t>||</t>"); ++ } ++ ++ @Test ++ public void testGeneral1() throws Exception { ++ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 1)\"/>|"), ++ "<t>|s|</t>"); ++ } ++ ++ @Test ++ public void testGeneral2() throws Exception { ++ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 1 div 0)\"/>|"), ++ "<t>|sdf|</t>"); ++ } ++ ++ @Test ++ public void testGeneral3() throws Exception { ++ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, -0 div 0)\"/>|"), ++ "<t>||</t>"); ++ } ++ ++ @Test ++ public void testGeneral4() throws Exception { ++ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 0 div 0)\"/>|"), ++ "<t>||</t>"); ++ } ++} +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ ./jdk/test/javax/xml/ws/8046817/GenerateEnumSchema.java Thu Feb 05 13:00:26 2015 +0100 +@@ -0,0 +1,134 @@ ++/* ++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/* ++ * @test ++ * @bug 8046817 ++ * @summary schemagen fails to generate xsd for enum types ++ * @run main/othervm GenerateEnumSchema ++ */ ++import java.io.BufferedReader; ++import java.io.File; ++import java.io.FileNotFoundException; ++import java.io.IOException; ++import java.io.InputStreamReader; ++import java.nio.file.Paths; ++import java.util.Scanner; ++ ++public class GenerateEnumSchema { ++ ++ private static final String SCHEMA_OUTPUT_FILENAME = "schema1.xsd"; ++ private static final File schemaOutputFile = new File(SCHEMA_OUTPUT_FILENAME); ++ ++ public static void main(String[] args) throws Exception, IOException { ++ //Check schema generation for class type ++ runSchemaGen("TestClassType.java"); ++ checkIfSchemaGenerated(); ++ checkSchemaContent("<xs:complexType name=\"testClassType\">"); ++ checkSchemaContent("<xs:element name=\"a\" type=\"xs:int\"/>"); ++ schemaOutputFile.delete(); ++ //Check schema generation for enum type ++ runSchemaGen("TestEnumType.java"); ++ checkIfSchemaGenerated(); ++ checkSchemaContent("<xs:simpleType name=\"testEnumType\">"); ++ checkSchemaContent("<xs:enumeration value=\"ONE\"/>"); ++ checkSchemaContent("<xs:enumeration value=\"TWO\"/>"); ++ checkSchemaContent("<xs:enumeration value=\"THREE\"/>"); ++ schemaOutputFile.delete(); ++ } ++ ++ private static void checkIfSchemaGenerated() { ++ if (!schemaOutputFile.exists()) { ++ throw new RuntimeException("FAIL:" + SCHEMA_OUTPUT_FILENAME + " was not generated by schemagen tool"); ++ } ++ } ++ ++ private static void checkSchemaContent(String exp_token) throws FileNotFoundException { ++ System.out.print("Check if generated schema contains '" + exp_token + "' string: "); ++ try (Scanner scanner = new Scanner(schemaOutputFile)) { ++ if (scanner.findWithinHorizon(exp_token, 0) != null) { ++ System.out.println("OK"); ++ return; ++ } ++ } ++ System.out.println("FAIL"); ++ throw new RuntimeException("The '" + exp_token + "' is not found in generated schema"); ++ ++ } ++ ++ private static String getClassFilePath(String filename) { ++ String testSrc = System.getProperty("test.src"); ++ if (testSrc == null) { ++ testSrc = "."; ++ } ++ return Paths.get(testSrc).resolve(filename).toString(); ++ } ++ ++ private static String getSchemagen() { ++ String javaHome = System.getProperty("java.home"); ++ if (javaHome.endsWith("jre")) { ++ javaHome = new File(javaHome).getParent(); ++ } ++ String schemagen = javaHome + File.separator + "bin" + File.separator + "schemagen"; ++ if (System.getProperty("os.name").startsWith("Windows")) { ++ schemagen = schemagen.concat(".exe"); ++ } ++ return schemagen; ++ } ++ ++ private static void logOutput(Process p) throws IOException { ++ BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); ++ String s = r.readLine(); ++ while (s != null) { ++ System.out.println(s.trim()); ++ s = r.readLine(); ++ } ++ } ++ ++ private static void runSchemaGen(String classFile) { ++ String schemagen = getSchemagen(); ++ ++ try { ++ System.out.println("Call to schemagen: " + schemagen + " " + classFile); ++ String[] schemagen_args = { ++ schemagen, ++ getClassFilePath(classFile) ++ }; ++ ++ ProcessBuilder pb = new ProcessBuilder(schemagen_args); ++ pb.redirectErrorStream(true); ++ Process p = pb.start(); ++ logOutput(p); ++ int result = p.waitFor(); ++ p.destroy(); ++ ++ if (result != 0) { ++ throw new RuntimeException("schemagen failed"); ++ } ++ } catch (IOException | InterruptedException e) { ++ System.err.println("Can't run schemagen tool. Exception:"); ++ e.printStackTrace(System.err); ++ throw new RuntimeException("Error launching schemagen tool"); ++ } ++ } ++} +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ ./jdk/test/javax/xml/ws/8046817/TestClassType.java Thu Feb 05 13:00:26 2015 +0100 +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++import javax.xml.bind.annotation.XmlType; ++ ++@XmlType ++public class TestClassType { ++ public int a; ++} +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ ./jdk/test/javax/xml/ws/8046817/TestEnumType.java Thu Feb 05 13:00:26 2015 +0100 +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++import javax.xml.bind.annotation.XmlEnum; ++ ++@XmlEnum(String.class) ++public enum TestEnumType { ++ ONE, TWO, THREE ++} +--- ./jdk/test/sun/security/krb5/ParseConfig.java Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/security/krb5/ParseConfig.java Thu Feb 05 13:00:26 2015 +0100 +@@ -22,7 +22,7 @@ + */ + /* + * @test +- * @bug 6319046 ++ * @bug 6319046 8055045 + * @compile -XDignore.symbol.file ParseConfig.java + * @run main/othervm ParseConfig + * @summary Problem with parsing krb5.conf +@@ -32,7 +32,8 @@ + + public class ParseConfig { + public static void main(String[] args) throws Exception { +- System.setProperty("java.security.krb5.conf", System.getProperty("test.src", ".") +"/krb5.conf"); ++ System.setProperty("java.security.krb5.conf", ++ System.getProperty("test.src", ".") + "/krb5.conf"); + Config config = Config.getInstance(); + config.listTable(); + +@@ -44,5 +45,11 @@ + expected + "\""); + } + } ++ ++ // JDK-8055045: IOOBE when reading an empty value ++ config.get("empty1", "NOVAL.COM"); ++ config.get("empty2", "NOVAL.COM"); ++ config.get("quote1", "NOVAL.COM"); ++ config.get("quote2", "NOVAL.COM"); + } + } +--- ./jdk/test/sun/security/krb5/krb5.conf Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/security/krb5/krb5.conf Thu Feb 05 13:00:26 2015 +0100 +@@ -27,3 +27,9 @@ + } + } + ++ NOVAL.COM = { ++ empty1 = ++ empty2 =. ++ quote1 = " ++ quote2 = ' ++ } +--- ./jdk/test/sun/security/tools/keytool/ListKeychainStore.sh Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/security/tools/keytool/ListKeychainStore.sh Thu Feb 05 13:00:26 2015 +0100 +@@ -1,5 +1,5 @@ + # +-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. ++# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + # + # This code is free software; you can redistribute it and/or modify it +@@ -22,7 +22,7 @@ + # + + # @test +-# @bug 7133495 ++# @bug 7133495 8041740 + # @summary [macosx] KeyChain KeyStore implementation retrieves only one private key entry + + if [ "${TESTJAVA}" = "" ] ; then +@@ -49,8 +49,10 @@ + KEYTOOL="${TESTJAVA}/bin/keytool -storetype KeychainStore -keystore NONE -storepass $PWD" + TEMPORARY_P12="$TESTCLASSES/7133495.p12" + TEMPORARY_KC="$TESTCLASSES/7133495.keychain" ++TEMPORARY_LIST="$TESTCLASSES/7133495.tmp" + CLEANUP_P12="rm -f $TEMPORARY_P12" + CLEANUP_KC="security delete-keychain $TEMPORARY_KC" ++CLEANUP_LIST="rm -f $TEMPORARY_LIST" + + # Count the number of private key entries in the Keychain keystores + +@@ -115,6 +117,15 @@ + fi + echo "Imported keypairs from PKCS12 keystore into the keychain" + ++# Adjust the keychain search order ++ ++echo "\"$TEMPORARY_KC\"" > $TEMPORARY_LIST ++security list-keychains >> $TEMPORARY_LIST ++security list-keychains -s `xargs < ${TEMPORARY_LIST}` ++`$CLEANUP_LIST` ++echo "Temporary keychain search order:" ++security list-keychains ++ + # Recount the number of private key entries in the Keychain keystores + + COUNT=`$KEYTOOL -list | grep PrivateKeyEntry | wc -l` +--- ./jdk/test/sun/security/util/HostnameMatcher/TestHostnameChecker.java Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/security/util/HostnameMatcher/TestHostnameChecker.java Thu Feb 05 13:00:26 2015 +0100 +@@ -187,6 +187,9 @@ + in = new FileInputStream(new File(PATH, "cert4.crt")); + X509Certificate cert4 = (X509Certificate)cf.generateCertificate(in); + in.close(); ++ in = new FileInputStream(new File(PATH, "cert5.crt")); ++ X509Certificate cert5 = (X509Certificate)cf.generateCertificate(in); ++ in.close(); + + HostnameChecker checker = HostnameChecker.getInstance( + HostnameChecker.TYPE_TLS); +@@ -202,6 +205,9 @@ + check(checker, "5.6.7.8", cert3, true); + check(checker, "foo.bar.com", cert4, true); + check(checker, "altfoo.bar.com", cert4, true); ++ check(checker, "2001:db8:3c4d:15::1a2f:1a2b", cert5, true); ++ check(checker, "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b", cert5, true); ++ check(checker, "2002:db8:3c4d:15::1a2f:1a2b", cert5, false); + + checker = HostnameChecker.getInstance( + HostnameChecker.TYPE_LDAP); +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ ./jdk/test/sun/security/util/HostnameMatcher/cert5.crt Thu Feb 05 13:00:26 2015 +0100 +@@ -0,0 +1,24 @@ ++-----BEGIN CERTIFICATE----- ++MIIECDCCAvCgAwIBAgIJAJaBmuUlfY8sMA0GCSqGSIb3DQEBBQUAMIGmMQswCQYD ++VQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJU29tZS1DaXR5 ++MSowKAYDVQQKDCFVbmNvbmZpZ3VyZWQgT3BlblNTTCBJbnN0YWxsYXRpb24xEDAO ++BgNVBAsMB3NlY3Rpb24xMDAuBgNVBAMMJzIwMDE6MGRiODozYzRkOjAwMTU6MDAw ++MDowMDAwOjFhMmY6MWEyYjAeFw0xNTAyMTAxODMzMjBaFw0xNTAzMTIxODMzMjBa ++MIGmMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJ ++U29tZS1DaXR5MSowKAYDVQQKDCFVbmNvbmZpZ3VyZWQgT3BlblNTTCBJbnN0YWxs ++YXRpb24xEDAOBgNVBAsMB3NlY3Rpb24xMDAuBgNVBAMMJzIwMDE6MGRiODozYzRk ++OjAwMTU6MDAwMDowMDAwOjFhMmY6MWEyYjCCASIwDQYJKoZIhvcNAQEBBQADggEP ++ADCCAQoCggEBAMcigWxmeF6Dmo3xAw3y/8d3vB8Th4YsmvwXb9DxwNWV+B3vxJgq ++ww6T6VBxrle1bgu/RtZDJwLf5vMhVElxuuE86di2qyurKFbpe29C9xnCxuMlXpje ++X2pNknz4ZzOqD4opmIAFjXZ2Xp1kLt+HJX7ABoz7Uga+IbVfDRPPf2KOqYNpBQkp ++dgI5VOZDQNVNb+8vdXDwyanMQ0TgPXKL4BQIkGB4RM8sgpPMUvB+tEB7zmUtgSco ++2a5M84wIhxv85CmFFoTVSzXsRCDhVAZj0aHRkkmAsMSmzPa4HiPnuVRV740oQjDy ++oMGLndaEs2nxIqckUFHOHcSTf0/wmcvPbIsCAwEAAaM3MDUwCQYDVR0TBAIwADAL ++BgNVHQ8EBAMCBeAwGwYDVR0RBBQwEocQIAENuDxNABUAAAAAGi8aKzANBgkqhkiG ++9w0BAQUFAAOCAQEAtnelRbYPPZRgTd4oxOiPqwc01EE9JgtkFWlooCwVUDChOR2k ++us1qlhKsvbN2Tcsm1Ss3p0Uxk/g1o2/mY8rA/dJ8qiN6jbfjpEi8b2MirP5tQSE0 ++QNXbVGr5FnLbuUmn+82pB0vBSaq7gxehbV6S7dteyQUnb2imltC5wS9PwYb8wWx7 ++IpyXWt0jkYkC8KJEevVYI7qtwpjYhyc1FqwzUiPmdqGz2AFLQ4RgTXJi93SPoyKM ++s65oPV+r6/0qwnslScxVfszHxxFn1Yfsc5Oseare1MnlNzH69PmWs523C/fBvnB2 ++MsHKLPdoN7uSpBLB7j46g5jQG/ceri/cquZKYA== ++-----END CERTIFICATE----- +--- ./jdk/test/sun/util/calendar/zi/tzdata/VERSION Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/VERSION Thu Feb 05 13:00:26 2015 +0100 +@@ -21,4 +21,4 @@ + # or visit www.oracle.com if you need additional information or have any + # questions. + # +-tzdata2014j ++tzdata2015a +--- ./jdk/test/sun/util/calendar/zi/tzdata/antarctica Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/antarctica Thu Feb 05 13:00:26 2015 +0100 +@@ -70,8 +70,8 @@ + Rule ChileAQ 2010 only - Apr Sun>=1 3:00u 0 - + Rule ChileAQ 2011 only - May Sun>=2 3:00u 0 - + Rule ChileAQ 2011 only - Aug Sun>=16 4:00u 1:00 S +-Rule ChileAQ 2012 max - Apr Sun>=23 3:00u 0 - +-Rule ChileAQ 2012 max - Sep Sun>=2 4:00u 1:00 S ++Rule ChileAQ 2012 2015 - Apr Sun>=23 3:00u 0 - ++Rule ChileAQ 2012 2014 - Sep Sun>=2 4:00u 1:00 S + + # Argentina - year-round bases + # Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05 +@@ -377,9 +377,10 @@ + # + # Zone NAME GMTOFF RULES FORMAT [UNTIL] + Zone Antarctica/Palmer 0 - zzz 1965 +- -4:00 ArgAQ AR%sT 1969 Oct 5 ++ -4:00 ArgAQ AR%sT 1969 Oct 5 + -3:00 ArgAQ AR%sT 1982 May +- -4:00 ChileAQ CL%sT ++ -4:00 ChileAQ CL%sT 2015 Apr 26 3:00u ++ -3:00 - CLT + # + # + # McMurdo Station, Ross Island, since 1955-12 +--- ./jdk/test/sun/util/calendar/zi/tzdata/asia Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/asia Thu Feb 05 13:00:26 2015 +0100 +@@ -168,10 +168,7 @@ + 4:00 Azer AZ%sT + + # Bahrain +-# Zone NAME GMTOFF RULES FORMAT [UNTIL] +-Zone Asia/Bahrain 3:22:20 - LMT 1920 # Manamah +- 4:00 - GST 1972 Jun +- 3:00 - AST ++# See Asia/Qatar. + + # Bangladesh + # From Alexander Krivenyshev (2009-05-13): +@@ -1754,9 +1751,7 @@ + ############################################################################### + + # Kuwait +-# Zone NAME GMTOFF RULES FORMAT [UNTIL] +-Zone Asia/Kuwait 3:11:56 - LMT 1950 +- 3:00 - AST ++# See Asia/Riyadh. + + # Laos + # See Asia/Bangkok. +@@ -1977,12 +1972,7 @@ + 5:45 - NPT # Nepal Time + + # Oman +- +-# Milne says 3:54:24 was the meridian of the Muscat Tidal Observatory. +- +-# Zone NAME GMTOFF RULES FORMAT [UNTIL] +-Zone Asia/Muscat 3:54:24 - LMT 1920 +- 4:00 - GST ++# See Asia/Dubai. + + # Pakistan + +@@ -2476,6 +2466,7 @@ + Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah / Doha + 4:00 - GST 1972 Jun + 3:00 - AST ++Link Asia/Qatar Asia/Bahrain + + # Saudi Arabia + # +@@ -2502,6 +2493,8 @@ + # Zone NAME GMTOFF RULES FORMAT [UNTIL] + Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14 + 3:00 - AST ++Link Asia/Riyadh Asia/Aden # Yemen ++Link Asia/Riyadh Asia/Kuwait + + # Singapore + # taken from Mok Ly Yng (2003-10-30) +@@ -2790,6 +2783,7 @@ + # Zone NAME GMTOFF RULES FORMAT [UNTIL] + Zone Asia/Dubai 3:41:12 - LMT 1920 + 4:00 - GST ++Link Asia/Dubai Asia/Muscat # Oman + + # Uzbekistan + # Byalokoz 1919 says Uzbekistan was 4:27:53. +@@ -2874,10 +2868,4 @@ + 7:00 - ICT + + # Yemen +- +-# Milne says 2:59:54 was the meridian of the saluting battery at Aden, +-# and that Yemen was at 1:55:56, the meridian of the Hagia Sophia. +- +-# Zone NAME GMTOFF RULES FORMAT [UNTIL] +-Zone Asia/Aden 2:59:54 - LMT 1950 +- 3:00 - AST ++# See Asia/Riyadh. +--- ./jdk/test/sun/util/calendar/zi/tzdata/backward Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/backward Thu Feb 05 13:00:26 2015 +0100 +@@ -28,7 +28,7 @@ + # and their old names. Many names changed in late 1993. + + # Link TARGET LINK-NAME +-Link Africa/Asmara Africa/Asmera ++Link Africa/Nairobi Africa/Asmera + Link Africa/Abidjan Africa/Timbuktu + Link America/Argentina/Catamarca America/Argentina/ComodRivadavia + Link America/Adak America/Atka +--- ./jdk/test/sun/util/calendar/zi/tzdata/europe Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/europe Thu Feb 05 13:00:26 2015 +0100 +@@ -1430,35 +1430,32 @@ + # might be a reference to the Julian calendar as opposed to Gregorian, or it + # might mean something else (???). + # +-# From Paul Eggert (2006-03-22): +-# The Iceland Almanak, Shanks & Pottenger, and Whitman disagree on many points. +-# We go with the Almanak, except for one claim from Shanks & Pottenger, namely +-# that Reykavik was 21W57 from 1837 to 1908, local mean time before that. ++# From Paul Eggert (2014-11-22): ++# The information below is taken from the 1988 Almanak; see ++# http://www.almanak.hi.is/klukkan.html + # + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +-Rule Iceland 1917 1918 - Feb 19 23:00 1:00 S ++Rule Iceland 1917 1919 - Feb 19 23:00 1:00 S + Rule Iceland 1917 only - Oct 21 1:00 0 - +-Rule Iceland 1918 only - Nov 16 1:00 0 - ++Rule Iceland 1918 1919 - Nov 16 1:00 0 - ++Rule Iceland 1921 only - Mar 19 23:00 1:00 S ++Rule Iceland 1921 only - Jun 23 1:00 0 - + Rule Iceland 1939 only - Apr 29 23:00 1:00 S +-Rule Iceland 1939 only - Nov 29 2:00 0 - ++Rule Iceland 1939 only - Oct 29 2:00 0 - + Rule Iceland 1940 only - Feb 25 2:00 1:00 S +-Rule Iceland 1940 only - Nov 3 2:00 0 - +-Rule Iceland 1941 only - Mar 2 1:00s 1:00 S +-Rule Iceland 1941 only - Nov 2 1:00s 0 - +-Rule Iceland 1942 only - Mar 8 1:00s 1:00 S +-Rule Iceland 1942 only - Oct 25 1:00s 0 - ++Rule Iceland 1940 1941 - Nov Sun>=2 1:00s 0 - ++Rule Iceland 1941 1942 - Mar Sun>=2 1:00s 1:00 S + # 1943-1946 - first Sunday in March until first Sunday in winter + Rule Iceland 1943 1946 - Mar Sun>=1 1:00s 1:00 S +-Rule Iceland 1943 1948 - Oct Sun>=22 1:00s 0 - ++Rule Iceland 1942 1948 - Oct Sun>=22 1:00s 0 - + # 1947-1967 - first Sunday in April until first Sunday in winter + Rule Iceland 1947 1967 - Apr Sun>=1 1:00s 1:00 S +-# 1949 Oct transition delayed by 1 week ++# 1949 and 1967 Oct transitions delayed by 1 week + Rule Iceland 1949 only - Oct 30 1:00s 0 - + Rule Iceland 1950 1966 - Oct Sun>=22 1:00s 0 - + Rule Iceland 1967 only - Oct 29 1:00s 0 - + # Zone NAME GMTOFF RULES FORMAT [UNTIL] +-Zone Atlantic/Reykjavik -1:27:24 - LMT 1837 +- -1:27:48 - RMT 1908 # Reykjavik Mean Time? ++Zone Atlantic/Reykjavik -1:28 - LMT 1908 + -1:00 Iceland IS%sT 1968 Apr 7 1:00s + 0:00 - GMT + +--- ./jdk/test/sun/util/calendar/zi/tzdata/leapseconds Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/leapseconds Thu Feb 05 13:00:26 2015 +0100 +@@ -77,3 +77,7 @@ + Leap 2005 Dec 31 23:59:60 + S + Leap 2008 Dec 31 23:59:60 + S + Leap 2012 Jun 30 23:59:60 + S ++Leap 2015 Jun 30 23:59:60 + S ++ ++# Updated through IERS Bulletin C49 ++# File expires on: 28 December 2015 +--- ./jdk/test/sun/util/calendar/zi/tzdata/northamerica Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/northamerica Thu Feb 05 13:00:26 2015 +0100 +@@ -147,7 +147,7 @@ + Rule US 1918 1919 - Oct lastSun 2:00 0 S + Rule US 1942 only - Feb 9 2:00 1:00 W # War + Rule US 1945 only - Aug 14 23:00u 1:00 P # Peace +-Rule US 1945 only - Sep 30 2:00 0 S ++Rule US 1945 only - Sep lastSun 2:00 0 S + Rule US 1967 2006 - Oct lastSun 2:00 0 S + Rule US 1967 1973 - Apr lastSun 2:00 1:00 D + Rule US 1974 only - Jan 6 2:00 1:00 D +@@ -2147,11 +2147,11 @@ + + # Mexico + +-# From Paul Eggert (2001-03-05): ++# From Paul Eggert (2014-12-07): + # The Investigation and Analysis Service of the + # Mexican Library of Congress (MLoC) has published a + # history of Mexican local time (in Spanish) +-# http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/ ++# http://www.diputados.gob.mx/bibliot/publica/inveyana/polisoc/horver/index.htm + # + # Here are the discrepancies between Shanks & Pottenger (S&P) and the MLoC. + # (In all cases we go with the MLoC.) +@@ -2320,6 +2320,24 @@ + # efecto desde las dos horas del segundo domingo de marzo y concluirá a + # las dos horas del primer domingo de noviembre. + ++# From Steffen Thorsen (2014-12-08), translated by Gwillim Law: ++# The Mexican state of Quintana Roo will likely change to EST in 2015. ++# ++# http://www.unioncancun.mx/articulo/2014/12/04/medio-ambiente/congreso-aprueba-una-hora-mas-de-sol-en-qroo ++# "With this change, the time conflict that has existed between the municipios ++# of Quintana Roo and the municipio of Felipe Carrillo Puerto may come to an ++# end. The latter declared itself in rebellion 15 years ago when a time change ++# was initiated in Mexico, and since then it has refused to change its time ++# zone along with the rest of the country." ++# ++# From Steffen Thorsen (2015-01-14), translated by Gwillim Law: ++# http://sipse.com/novedades/confirman-aplicacion-de-nueva-zona-horaria-para-quintana-roo-132331.html ++# "...the new time zone will come into effect at two o'clock on the first Sunday ++# of February, when we will have to advance the clock one hour from its current ++# time..." ++# ++# Also, the new zone will not use DST. ++ + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S + Rule Mexico 1939 only - Feb 5 0:00 1:00 D + Rule Mexico 1939 only - Jun 25 0:00 0 S +@@ -2340,7 +2358,8 @@ + Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56 + -6:00 - CST 1981 Dec 23 + -5:00 Mexico E%sT 1998 Aug 2 2:00 +- -6:00 Mexico C%sT ++ -6:00 Mexico C%sT 2015 Feb 1 2:00 ++ -5:00 - EST + # Campeche, Yucatán; represented by Mérida + Zone America/Merida -5:58:28 - LMT 1922 Jan 1 0:01:32 + -6:00 - CST 1981 Dec 23 +--- ./jdk/test/sun/util/calendar/zi/tzdata/southamerica Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/southamerica Thu Feb 05 13:00:26 2015 +0100 +@@ -1229,6 +1229,11 @@ + # DST Start: first Saturday of September 2014 (Sun 07 Sep 2014 04:00 UTC) + # http://www.diariooficial.interior.gob.cl//media/2014/02/19/do-20140219.pdf + ++# From Juan Correa (2015-01-28): ++# ... today the Ministry of Energy announced that Chile will drop DST, will keep ++# "summer time" (UTC -3 / UTC -5) all year round.... ++# http://www.minenergia.cl/ministerio/noticias/generales/ministerio-de-energia-anuncia.html ++ + # NOTE: ChileAQ rules for Antarctic bases are stored separately in the + # 'antarctica' file. + +@@ -1270,8 +1275,8 @@ + Rule Chile 2010 only - Apr Sun>=1 3:00u 0 - + Rule Chile 2011 only - May Sun>=2 3:00u 0 - + Rule Chile 2011 only - Aug Sun>=16 4:00u 1:00 S +-Rule Chile 2012 max - Apr Sun>=23 3:00u 0 - +-Rule Chile 2012 max - Sep Sun>=2 4:00u 1:00 S ++Rule Chile 2012 2015 - Apr Sun>=23 3:00u 0 - ++Rule Chile 2012 2014 - Sep Sun>=2 4:00u 1:00 S + # IATA SSIM anomalies: (1992-02) says 1992-03-14; + # (1996-09) says 1998-03-08. Ignore these. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] +@@ -1282,11 +1287,13 @@ + -4:00 - CLT 1919 Jul 1 # Chile Time + -4:42:46 - SMT 1927 Sep 1 # Santiago Mean Time + -5:00 Chile CL%sT 1947 May 22 # Chile Time +- -4:00 Chile CL%sT ++ -4:00 Chile CL%sT 2015 Apr 26 3:00u ++ -3:00 - CLT + Zone Pacific/Easter -7:17:44 - LMT 1890 + -7:17:28 - EMT 1932 Sep # Easter Mean Time +- -7:00 Chile EAS%sT 1982 Mar 13 21:00 # Easter Time +- -6:00 Chile EAS%sT ++ -7:00 Chile EAS%sT 1982 Mar 13 3:00u # Easter Time ++ -6:00 Chile EAS%sT 2015 Apr 26 3:00u ++ -5:00 - EAST + # + # Salas y Gómez Island is uninhabited. + # Other Chilean locations, including Juan Fernández Is, Desventuradas Is, +--- ./jdk/test/sun/util/calendar/zi/tzdata/zone.tab Mon Feb 02 10:12:21 2015 -0800 ++++ ./jdk/test/sun/util/calendar/zi/tzdata/zone.tab Thu Feb 05 13:00:26 2015 +0100 +@@ -297,7 +297,7 @@ + MV +0410+07330 Indian/Maldives + MW -1547+03500 Africa/Blantyre + MX +1924-09909 America/Mexico_City Central Time - most locations +-MX +2105-08646 America/Cancun Central Time - Quintana Roo ++MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo + MX +2058-08937 America/Merida Central Time - Campeche, Yucatan + MX +2540-10019 America/Monterrey Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border + MX +2550-09730 America/Matamoros US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border +--- ./langtools/.hgtags Wed Jan 28 12:08:47 2015 -0800 ++++ ./langtools/.hgtags Tue Mar 17 11:25:42 2015 -0700 +@@ -334,6 +334,8 @@ + 53ca196be1ae098466976c017b166d4ce180c36f jdk8u25-b17 + a4f0c6dd8f97d4dd89baf09463c748abea9b3ed7 jdk8u25-b18 + c4de614efd7affc001715aa5a7040620924ac44a jdk8u25-b31 ++a2a922ccc00f29af625cbecde8e77643c60f147c jdk8u25-b32 ++b72a49d88cc3f5394b69b861455552476341558d jdk8u25-b33 + c4bd223559aad3d152968a09d56241175d82c561 jdk8u31-b00 + 6b5e2c190f3023162a33b798e57a0d78e027c843 jdk8u31-b01 + 8b4ea00b438d7f99ecd6a8345cb018d8a0379620 jdk8u31-b02 +@@ -348,6 +350,8 @@ + e72be544fa9e247fba3c6bb61e291d80e127a461 jdk8u31-b11 + c956b12b30ee21a4fc5df1871fa3b01e84310ebe jdk8u31-b12 + 7a34ec7bb1c831e82ac88da578a028572b676260 jdk8u31-b13 ++b813a76f10911ac8db2c775e52b29f36ab0005f4 jdk8u31-b31 ++8dc0c7e42d90c9f323582b742a7f228bad57b124 jdk8u31-b32 + d231957fe3103e790465fcf058fb8cb33bbc4c4e jdk8u40-b00 + bf89a471779d13a9407f7d1c86f7716258bc4aa6 jdk8u40-b01 + 0b6cc4ea670f5d17b56c088f202869bdbb80a5ce jdk8u40-b02 +@@ -372,3 +376,21 @@ + 9113c7c8d902ec94b28ca0ef4a6466bdba65fcfc jdk8u40-b21 + 79177246b3dbe5296fb53755d8695acdaef59fc8 jdk8u40-b22 + fb294b49373bda0b3afc7f011d64ecefed73b42e jdk8u40-b23 ++c5d4ffa220f3824c2ea5d39dc99d41a9df9e5ae5 jdk8u40-b24 ++991141080b2078e67179ff307a5051e59431762c jdk8u40-b25 ++2904142783dd0a9e12195a84c7dcdb3d8278b1b1 jdk8u40-b26 ++83eca922346e27ec42645e9630c04fbaec5eaf0f jdk8u40-b27 ++dbae37f50c43453f7d6f22d96adc8b5b6cd1e90d jdk8u45-b00 ++244e6dc772877dfae6286530f58e11a210a48a3c jdk8u45-b01 ++401ec76887623a29d3f868f9f9b18b42838d2e92 jdk8u45-b02 ++79d31ae9990e28b99dd64beda6dd247993138431 jdk8u45-b03 ++47292f3c0da7dd197a28765004b588bc3141d189 jdk8u45-b04 ++77d7dd7f35d63f9fe60ed0b7ef32e4e9a8b46c0b jdk8u45-b05 ++22cc48973eae62c63e68c4c4e3f22ff2d89012a8 jdk8u45-b06 ++460238ab73ce27112b3d0d7236366960f9898259 jdk8u45-b07 ++6dd7fd9f027bf037517feae2a571848aa8fbc20f jdk8u45-b08 ++db16aa5c73c99d0050246660ebebb6166002ff57 jdk8u45-b09 ++572895f19937b7aadc8c27c5e83887bf40f5bcff jdk8u45-b10 ++0547ef2be3b303923b30ce78e1ab832725483f4e jdk8u45-b11 ++4f89bbda7b4532b9f6eeee8c41b7a3b38570ae93 jdk8u45-b12 ++5ce022bca792453a7efedaed419a9d763d7a9fc3 jdk8u45-b13 +--- ./langtools/THIRD_PARTY_README Wed Jan 28 12:08:47 2015 -0800 ++++ ./langtools/THIRD_PARTY_README Tue Mar 17 11:25:42 2015 -0700 +@@ -1250,7 +1250,7 @@ + + ------------------------------------------------------------------------------- + +-%% This notice is provided with respect to libpng 1.5.4, which may be ++%% This notice is provided with respect to libpng 1.6.16, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + + --- begin of LICENSE --- +@@ -1266,8 +1266,8 @@ + + This code is released under the libpng license. + +-libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are +-Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are ++libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are ++Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are + distributed according to the same disclaimer and license as libpng-1.2.5 + with the following individual added to the list of Contributing Authors + +@@ -1364,7 +1364,7 @@ + + Glenn Randers-Pehrson + glennrp at users.sourceforge.net +-July 7, 2011 ++December 22, 2014 + + --- end of LICENSE --- + +--- ./nashorn/.hgtags Wed Jan 28 12:08:49 2015 -0800 ++++ ./nashorn/.hgtags Tue Mar 17 11:25:52 2015 -0700 +@@ -322,6 +322,8 @@ + 4b9cc65dd24d398c4f921c0beccfb8caeaaaf584 jdk8u25-b17 + cdbf34dbef404b47805c8c85b11c65c2afaa6674 jdk8u25-b18 + 4f9e65387c21831d0ea5726641a302c2ce73a4cc jdk8u25-b31 ++be20e9a00818df15af12544c21839c3a3d5768d9 jdk8u25-b32 ++a8526abf70a8c98aee5fed64eb727210745a6e5a jdk8u25-b33 + 9b692a6e5f22228f822973d35610d37cb9dd9693 jdk8u31-b00 + 6bf53bb6c969678488b1c073d56dd55df1a0ea17 jdk8u31-b01 + 809bf97d7e70dcb3873fcbc10f12f62580b1c11d jdk8u31-b02 +@@ -336,6 +338,8 @@ + 599bd596fa549d882aa8fc5104c322a75a3af728 jdk8u31-b11 + f36c71a03e4ed467f630cc46d076a5bb4c58b6d5 jdk8u31-b12 + ec36fa3b35eb00f053d624ae837579c6b8e446ac jdk8u31-b13 ++34a64e22b81bd78cf29603a80ff1f4cfc1694df8 jdk8u31-b31 ++d2b5784a3452a4fd9d1ccfefe93ee2d36662842c jdk8u31-b32 + f2925491b61b22ac42f8c30ee9c6723ffa401a4c jdk8u40-b00 + 62468d841b842769d875bd97d10370585c296eb7 jdk8u40-b01 + b476c69c820ac1e05071f4de5abab8e2dff80e87 jdk8u40-b02 +@@ -360,3 +364,21 @@ + dbb663a9d9aa2807ef501c7d20f29415816a1973 jdk8u40-b21 + f9f70a0f60f48fbb95275b6c1110cedf740c6177 jdk8u40-b22 + 6ca090832d30fd0e46214ccc00816490ad75a8ab jdk8u40-b23 ++b2ce5df33715583c898530560d4202853b9ff9bc jdk8u40-b24 ++fb7b6c2b95c5661f15e8e747a63ec6d95d49fe46 jdk8u40-b25 ++b142a2d8e35e54abb08a7ded1dbfb5d7ce534c93 jdk8u40-b26 ++c2dd88e89edc85b1bcb731d3296d0fcec1b78447 jdk8u40-b27 ++05a3614ed5276e5db2a73cce918be04b1a2922fb jdk8u45-b00 ++21ec16eb7e6346c78b4fa67ccd6d2a9c58f0b696 jdk8u45-b01 ++37b3ef9a07323afd2556d6837824db154cccc874 jdk8u45-b02 ++ed3a4177da50d75d6da55ff521bf3f971cfe5214 jdk8u45-b03 ++65f24dedfd29ec02af43f745742647412d90f005 jdk8u45-b04 ++de2ee4c1341fd4eeaba39b81194df0c4274e7c8b jdk8u45-b05 ++cf0097b8987d2d2f480d8a6d2a8f235509bd4421 jdk8u45-b06 ++bb112473c7314146bebb75fb5220b4ec641b0b7a jdk8u45-b07 ++8ab14ee47c8b1558854d3cd71006eceb6c6804d1 jdk8u45-b08 ++397ea4a1bff8adbceaa1a40ff826b3d2d3b09e81 jdk8u45-b09 ++c650c13d2bdf0e869ae86685de6bbb8a4e983ca3 jdk8u45-b10 ++6ae873ddbe195aa966fc348e468c0ecd2702f5e3 jdk8u45-b11 ++9b9fee0f99cd07fba62abaafe705665a5ab89067 jdk8u45-b12 ++6fda38586f73de706ecde311711a587ac49d51d8 jdk8u45-b13 +--- ./nashorn/THIRD_PARTY_README Wed Jan 28 12:08:49 2015 -0800 ++++ ./nashorn/THIRD_PARTY_README Tue Mar 17 11:25:52 2015 -0700 +@@ -1250,7 +1250,7 @@ + + ------------------------------------------------------------------------------- + +-%% This notice is provided with respect to libpng 1.5.4, which may be ++%% This notice is provided with respect to libpng 1.6.16, which may be + included with JRE 8, JDK 8, and OpenJDK 8. + + --- begin of LICENSE --- +@@ -1266,8 +1266,8 @@ + + This code is released under the libpng license. + +-libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are +-Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are ++libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are ++Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are + distributed according to the same disclaimer and license as libpng-1.2.5 + with the following individual added to the list of Contributing Authors + +@@ -1364,7 +1364,7 @@ + + Glenn Randers-Pehrson + glennrp at users.sourceforge.net +-July 7, 2011 ++December 22, 2014 + + --- end of LICENSE --- + 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 |